diff --git a/example/src/App.js b/example/src/App.js
index 2dbba28f..dc049cc9 100644
--- a/example/src/App.js
+++ b/example/src/App.js
@@ -32,6 +32,7 @@ import {
Loader,
Select,
Option,
+ DatePicker,
// IMPORT_INJECTOR
} from '@cision/rover-ui';
@@ -49,6 +50,8 @@ const App = () => {
const [inputTimeValue, setInputTimeValue] = useState('');
const [isModalOpen, setIsModalOpen] = useState(false);
const [isKiteVisible, setIsKiteVisible] = useState(false);
+ const [selectedDay, setSelectedDay] = useState(new Date());
+ const [showInlineCalendar, setShowInlineCalendar] = useState(false);
const toggleTooltip = function () {
setTooltipOpen((prev) => !prev);
@@ -61,6 +64,15 @@ const App = () => {
);
+ const handleDateClick = (day) => {
+ setSelectedDay(day);
+ };
+
+ const handleInlineDateClick = (day) => {
+ setSelectedDay(day);
+ setShowInlineCalendar(false);
+ };
+
return (
@@ -518,6 +530,34 @@ const App = () => {
{' '}
(required)
+
{/** USAGE_INJECTOR */}
diff --git a/package.json b/package.json
index bd82228b..dec92450 100644
--- a/package.json
+++ b/package.json
@@ -158,6 +158,7 @@
"@cision/react-container-query": "1.0.0-alpha.3",
"classnames": "^2.2.6",
"lodash": "^4.17.19",
- "nanoid": "^3.1.23"
+ "nanoid": "^3.1.23",
+ "react-day-picker": "^7.4.10"
}
}
diff --git a/src/components/DatePicker/DatePicker.module.css b/src/components/DatePicker/DatePicker.module.css
new file mode 100644
index 00000000..f0fe6ca8
--- /dev/null
+++ b/src/components/DatePicker/DatePicker.module.css
@@ -0,0 +1,132 @@
+.container {
+ display: inline-block;
+}
+
+.wrapper {
+ border-radius: var(--rvr-border-radius);
+}
+
+.interactionDisabled {
+ cursor: default;
+}
+
+.navBar {
+ position: relative;
+}
+
+.navButtonPrev,
+.navButtonNext {
+ position: absolute;
+ border: solid var(--rvr-color-font);
+ border-width: 3px 3px 0px 0px;
+ display: inline-block;
+ padding: 5px;
+}
+
+.navButtonPrev {
+ transform: rotate(-135deg);
+ top: 18px;
+ left: 18px;
+}
+
+.navButtonNext {
+ transform: rotate(45deg);
+ top: 18px;
+ right: 18px;
+}
+
+.navButtonInteractionDisabled {
+ opacity: 0;
+}
+
+.months {
+ display: flex;
+ flex-wrap: wrap;
+ justify-content: center;
+}
+
+.month {
+ padding: 12px;
+}
+
+.caption {
+ font-weight: var(--rvr-font-weight-bold);
+ text-align: center;
+ color: var(--rvr-black);
+}
+
+.weekdaysBody {
+ display: table-header-group;
+}
+
+.weekdaysRow {
+ display: table-row;
+}
+
+.weekday {
+ color: var(--rvr-color-font);
+ display: table-cell;
+ text-align: center;
+ padding: 4px 6px;
+}
+.weekday > abbr {
+ text-decoration: none;
+}
+
+.weekNumber {
+ display: table-cell;
+ color: var(--rvr-color-font);
+ padding: 4px 6px;
+ border-right: solid 1px var(--rvr-color-disabled);
+}
+
+.body {
+ display: table-row-group;
+}
+
+.week {
+ display: table-row;
+}
+
+.day {
+ display: table-cell;
+ text-align: center;
+ padding: 4px 6px;
+ border-radius: var(--rvr-border-radius);
+ color: var(--rvr-black);
+}
+
+.day[aria-disabled='false'] {
+ cursor: pointer;
+}
+
+.day:hover[aria-disabled='false'][aria-selected='false'] {
+ background-color: var(--rvr-color-highlight);
+}
+
+.footer {
+ display: flex;
+ justify-content: center;
+}
+
+.todayButton {
+ color: var(--rvr-btn-color-link-active);
+}
+
+.today {
+ text-decoration: underline;
+ font-weight: var(--rvr-font-weight-bold);
+}
+
+.selected {
+ background-color: var(--rvr-color-primary);
+ color: var(--rvr-white);
+}
+
+.disabled {
+ color: var(--rvr-color-disabled);
+}
+
+.outside {
+ color: var(--rvr-color-disabled);
+}
diff --git a/src/components/DatePicker/DatePicker.test.tsx b/src/components/DatePicker/DatePicker.test.tsx
new file mode 100644
index 00000000..11cb8495
--- /dev/null
+++ b/src/components/DatePicker/DatePicker.test.tsx
@@ -0,0 +1,29 @@
+import React from 'react';
+
+import { render } from '@testing-library/react';
+import '@testing-library/jest-dom';
+
+import DatePicker from '.';
+
+describe('DatePicker', () => {
+ it('renders', () => {
+ render();
+ });
+
+ describe('when rendered with classnames props', () => {
+ it('should append the custom class to the exisiting class', () => {
+ const styleOverride = { wrapper: 'customWrapperClass' };
+ const { getByTestId } = render(
+
+
+
+ );
+
+ const DatePickerElem = getByTestId('datePickerElem') as HTMLDivElement;
+ const wrapperElem = DatePickerElem.firstChild
+ ?.firstChild as HTMLDivElement;
+
+ expect(wrapperElem.className).toContain('customWrapperClass');
+ });
+ });
+});
diff --git a/src/components/DatePicker/DatePicker.tsx b/src/components/DatePicker/DatePicker.tsx
new file mode 100644
index 00000000..e4a0df89
--- /dev/null
+++ b/src/components/DatePicker/DatePicker.tsx
@@ -0,0 +1,78 @@
+import React from 'react';
+
+import DayPicker from 'react-day-picker';
+import { DayPickerProps } from 'react-day-picker/types/Props';
+
+import 'react-day-picker/lib/style.css';
+import { ClassNames } from 'react-day-picker/types/ClassNames';
+import styles from './DatePicker.module.css';
+
+interface DatePickerProps extends Omit {
+ classNames?: {
+ container?: string;
+ wrapper?: string;
+ interactionDisabled?: string;
+ navBar?: string;
+ navButtonPrev?: string;
+ navButtonNext?: string;
+ navButtonInteractionDisabled?: string;
+ months?: string;
+ month?: string;
+ caption?: string;
+ weekdays?: string;
+ weekdaysRow?: string;
+ weekday?: string;
+ weekNumber?: string;
+ body?: string;
+ week?: string;
+ day?: string;
+ footer?: string;
+ todayButton?: string;
+ today?: string;
+ selected?: string;
+ disabled?: string;
+ outside?: string;
+ };
+}
+
+const DatePicker: React.FC = ({ ...passedProps }) => {
+ const styleOverride = {
+ container: styles.container,
+ wrapper: styles.wrapper,
+ interactionDisabled: styles.interactionDisabled,
+ navBar: styles.navBar,
+ navButtonPrev: styles.navButtonPrev,
+ navButtonNext: styles.navButtonNext,
+ navButtonInteractionDisabled: styles.navButtonInteractionDisabled,
+ months: styles.months,
+ month: styles.month,
+ caption: styles.caption,
+ weekdays: styles.weekdaysBody,
+ weekdaysRow: styles.weekdaysRow,
+ weekday: styles.weekday,
+ weekNumber: styles.weekNumber,
+ body: styles.body,
+ week: styles.week,
+ day: styles.day,
+ footer: styles.footer,
+ todayButton: styles.todayButton,
+ today: styles.today,
+ selected: styles.selected,
+ disabled: styles.disabled,
+ outside: styles.outside,
+ } as ClassNames;
+
+ if (passedProps.classNames) {
+ Object.entries(passedProps.classNames).forEach((classes) => {
+ if (classes.length === 2) {
+ styleOverride[classes[0]] = `${styleOverride[classes[0]]} ${
+ classes[1]
+ }`;
+ }
+ });
+ }
+
+ return ;
+};
+
+export default DatePicker;
diff --git a/src/components/DatePicker/README.md b/src/components/DatePicker/README.md
new file mode 100644
index 00000000..fb3334e3
--- /dev/null
+++ b/src/components/DatePicker/README.md
@@ -0,0 +1,11 @@
+# \
+
+Render a date picker UI, this is a pass-through component to the [react-day-picker](https://react-day-picker.js.org/) library.
+
+### Override Classes
+
+This date picker has been restyle using rover-ui themes/colors. Consuming application can override these classes with their own classes via `classNames` prop, see [/api/Daypicker#classNames](https://react-day-picker.js.org/api/DayPicker#classNames)
+
+```jsx
+
+```
diff --git a/src/components/DatePicker/index.ts b/src/components/DatePicker/index.ts
new file mode 100644
index 00000000..2ef49e25
--- /dev/null
+++ b/src/components/DatePicker/index.ts
@@ -0,0 +1 @@
+export { default } from './DatePicker';
diff --git a/src/components/DatePicker/story.tsx b/src/components/DatePicker/story.tsx
new file mode 100644
index 00000000..abd79c42
--- /dev/null
+++ b/src/components/DatePicker/story.tsx
@@ -0,0 +1,88 @@
+import React from 'react';
+import { storiesOf } from '@storybook/react';
+import { boolean, number, date } from '@storybook/addon-knobs';
+
+import { action } from '@storybook/addon-actions';
+import DatePicker from './DatePicker';
+import Readme from './README.md';
+
+import { Wrap } from '../../stories/storybook-helpers';
+
+storiesOf('Planets/DatePicker', module)
+ .addParameters({
+ readme: {
+ sidebar: Readme,
+ },
+ })
+ .add('Overview', () => (
+
+
+
+ ))
+ .add('Examples', () => (
+ <>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ >
+ ));
diff --git a/src/index.ts b/src/index.ts
index a6c5071b..a0d964a6 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -33,6 +33,7 @@ export {
export { default as Tooltip, EasyRichTooltip } from './components/Tooltip';
export { default as Input, Checkbox, Toggle } from './components/Input';
export { default as InputTime } from './components/InputTime';
+export { default as DatePicker } from './components/DatePicker';
export { default as Typography } from './components/Typography';
export { default as Modal } from './components/Modal';
export { default as Kite } from './components/Kite';
diff --git a/src/stories/index.js b/src/stories/index.js
index 539b5558..f59ff5fd 100644
--- a/src/stories/index.js
+++ b/src/stories/index.js
@@ -24,6 +24,7 @@ import '../components/Input/story';
import '../components/Input/Checkbox/story';
import '../components/Input/Toggle/story';
import '../components/InputTime/story';
+import '../components/DatePicker/story';
import '../components/Select/story';
import '../components/Typography/story';
import '../components/Loader/story';
diff --git a/yarn.lock b/yarn.lock
index 63ac6cdb..ef01254f 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -13704,6 +13704,13 @@ react-color@^2.17.0:
reactcss "^1.2.0"
tinycolor2 "^1.4.1"
+react-day-picker@^7.4.10:
+ version "7.4.10"
+ resolved "https://registry.yarnpkg.com/react-day-picker/-/react-day-picker-7.4.10.tgz#d3928fa65c04379ad28c76de22aa85374a8361e1"
+ integrity sha512-/QkK75qLKdyLmv0kcVzhL7HoJPazoZXS8a6HixbVoK6vWey1Od1WRLcxfyEiUsRfccAlIlf6oKHShqY2SM82rA==
+ dependencies:
+ prop-types "^15.6.2"
+
react-dev-utils@^10.2.1:
version "10.2.1"
resolved "https://registry.yarnpkg.com/react-dev-utils/-/react-dev-utils-10.2.1.tgz#f6de325ae25fa4d546d09df4bb1befdc6dd19c19"