Skip to content

Instantly share code, notes, and snippets.

@baumandm
Last active May 29, 2024 05:29
Show Gist options
  • Save baumandm/8665a34bc418574737847f7394f98bd9 to your computer and use it in GitHub Desktop.
Save baumandm/8665a34bc418574737847f7394f98bd9 to your computer and use it in GitHub Desktop.
Chakra-UI x React-datepicker

⚠️ I'd recommend using this fork by @igoro00 which has better theme support.


Tiny wrapper component for React-Datepicker to stylistically fit with Chakra-UI 1.x.

<DatePicker selectedDate={myDate} onChange={(d) => console.log(d)} />

Clearable version:

<DatePicker selectedDate={myDate} onChange={(d) => console.log(d)} isClearable={true} />

The HTMLAttributes interface is included to support passing additional properties like id, className, aria-*, etc., for example:

<FormControl>
  <FormLabel htmlFor="published-date">Published Date</FormLabel>
  <DatePicker
    id="published-date"
    selectedDate={publishedDate}
    onChange={onChange}
    showPopperArrow={true}
  />
  <FormHelperText>Date this widget was published</FormHelperText>
</FormControl>

Adapted from this comment

.react-datepicker {
font-family: unset;
font-size: 0.9rem;
}
.react-datepicker-wrapper,
.react-datepicker__input-container {
display: block;
}
.react-datepicker__input-container {
font-size: 1rem;
padding-left: 1rem;
padding-right: 1rem;
height: 2.5rem;
border-radius: 0.25rem;
border: 1px solid;
border-color: hsl(0,0%,80%);
}
.react-datepicker__input-container:hover {
border-color: hsl(0,0%,70%);
}
.react-datepicker__input-container:focus-within {
z-index: 1;
border-color: #3182ce;
box-shadow: 0 0 0 1px #3182ce;
}
.react-datepicker__input-container > input {
width: 100%;
height: 100%;
outline: 0;
}
.react-datepicker__navigation--next--with-time:not(.react-datepicker__navigation--next--with-today-button) {
right: 90px;
}
.react-datepicker__navigation--previous,
.react-datepicker__navigation--next {
height: 8px;
}
.react-datepicker__navigation--previous {
border-right-color: #cbd5e0;
}
.react-datepicker__navigation--previous:hover {
border-right-color: #a0aec0;
}
.react-datepicker__navigation--next {
border-left-color: #cbd5e0;
}
.react-datepicker__navigation--next:hover {
border-left-color: #a0aec0;
}
.react-datepicker__header {
background: #f7fafc;
}
.react-datepicker__header,
.react-datepicker__time-container {
border-color: #E2E8F0;
}
.react-datepicker__current-month,
.react-datepicker-time__header,
.react-datepicker-year-header {
font-size: inherit;
font-weight: 600;
}
.react-datepicker__time-container .react-datepicker__time .react-datepicker__time-box ul.react-datepicker__time-list li.react-datepicker__time-list-item {
margin: 0 1px 0 0;
height: auto;
padding: 7px 10px;
}
.react-datepicker__time-container .react-datepicker__time .react-datepicker__time-box ul.react-datepicker__time-list li.react-datepicker__time-list-item:hover {
background: #edf2f7;
}
.react-datepicker__day:hover {
background: #edf2f7;
}
.react-datepicker__day--selected,
.react-datepicker__day--in-selecting-range,
.react-datepicker__day--in-range,
.react-datepicker__month-text--selected,
.react-datepicker__month-text--in-selecting-range,
.react-datepicker__month-text--in-range,
.react-datepicker__time-container .react-datepicker__time .react-datepicker__time-box ul.react-datepicker__time-list li.react-datepicker__time-list-item--selected {
background: #3182ce;
font-weight: normal;
}
.react-datepicker__time-container .react-datepicker__time .react-datepicker__time-box ul.react-datepicker__time-list li.react-datepicker__time-list-item--selected:hover {
background: #2a69ac;
}
.react-datepicker__close-icon::after {
background-color: unset;
border-radius: unset;
font-size: 1.5rem;
font-weight: bold;
color: hsl(0,0%,80%);
height: 20px;
width: 20px;
}
.react-datepicker__close-icon::after:hover {
color: hsl(0,0%,70%)
}
import React, { HTMLAttributes } from 'react';
import ReactDatePicker from 'react-datepicker';
import 'react-datepicker/dist/react-datepicker.css';
import './date-picker.css';
interface Props {
isClearable?: boolean;
onChange: (date: Date) => any;
selectedDate: Date | undefined;
showPopperArrow?: boolean;
}
const DatePicker = ({
selectedDate,
onChange,
isClearable = false,
showPopperArrow = false,
...props
}: Props & HTMLAttributes<HTMLElement>) => {
return (
<ReactDatePicker
selected={selectedDate}
onChange={onChange}
isClearable={isClearable}
showPopperArrow={showPopperArrow}
{...props}
/>
);
};
export default DatePicker;
@walker-tx
Copy link

Hey man! Thank you for sharing this.

Question: is the BoxProps addition to the DatePicker prop typings really necessary?

@baumandm
Copy link
Author

Nope it's optional, just something I add if I want to be able add additional styles to the component.

@mingbackmountain
Copy link

When I use FormEvenHandler the typescript said No overload match this call, what type use I use for the handleChange?

@estyrke
Copy link

estyrke commented Nov 4, 2020

@mingbackmountain You can use handleChange: (date: Date | [Date, Date] | null) => any;, but I also had to remove & BoxProps on line 14 since it apparently contains some props that are incompatible with ReactDatePicker.

(note: I use Chakra 1.0.0rc8)

@baumandm
Copy link
Author

baumandm commented Nov 6, 2020

Thanks for all the feedback, I've updated it accordingly. Also added support for isClearable

I swapped out BoxProps for HTMLAttributes<HTMLElement> since it doesn't make sense to use a Chakra-UI type on a 3rd-party component. The reason that interface is there is to allow setting id, className, etc.

@ahmedsmae
Copy link

'date-picker.tsx' could be

import React from 'react';
import ReactDatePicker, { ReactDatePickerProps } from 'react-datepicker';

import 'react-datepicker/dist/react-datepicker.css';
import './date-picker.css';

const DatePicker: React.FC = props => {
return <ReactDatePicker {...props} />;
};

export default DatePicker;

@igoro00
Copy link

igoro00 commented Mar 8, 2021

It not very darkmode-friendly and it doesn't use chakra's theme(which is kinda the Chakra UI's thing). I fixed it in my fork. I used css variables so the color values could be easily changed globally(the names are not perfect but oh well) and I filled those variables with chakra's theme css variables. I assumed you're using the default theme so I based my colors on that. Its not perfect but for me it's good enough so maybe you'll find it useful too.

Oh, and BTW I didn't do the clock part as I don't use it in my website so some colors might be off and probably text wouldn't be inverted(all you need to do is to find the text class name and set color:var(--text); on it in the css file)

@danielmaartens-sovtech
Copy link

@baumandm I'm getting this typescript error when implementing your code above. Any solutions?

image

@walker-tx
Copy link

remove typings, change file extension to js/jsx

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment