Skip to content

Commit

Permalink
Fix hover styling, add range story
Browse files Browse the repository at this point in the history
  • Loading branch information
nighto committed Dec 5, 2024
1 parent 1f7bb96 commit e5e749e
Show file tree
Hide file tree
Showing 4 changed files with 109 additions and 31 deletions.
57 changes: 43 additions & 14 deletions src/components/forms/controls/DatePicker/DatePicker.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -97,16 +97,17 @@ $navigation-distance: 1rem;
color: bk.$theme-date-picker-text-default;
}

// TODO check if both are actually needed
:global(.react-datepicker__day-name--outside-month),
:global(.react-datepicker__day--outside-month) {
color: bk.$theme-date-picker-text-disabled;
:global(.react-datepicker__day--today) {
font-weight: bk.$font-weight-semibold;
}

// TODO check if both are actually needed
:global(.react-datepicker__day-name--disabled),
:global(.react-datepicker__day--outside-month),
:global(.react-datepicker__day--disabled) {
opacity: .35;
color: bk.$theme-date-picker-text-disabled;
}

:global(.react-datepicker__day--outside-month.react-datepicker__day--disabled) {
color: bk.$theme-date-picker-text-unavailable;
}

:global(.react-datepicker__day--selected),
Expand All @@ -116,25 +117,53 @@ $navigation-distance: 1rem;
color: bk.$theme-date-picker-text-selected;
}

:global(.react-datepicker__day:not([aria-disabled=true]):hover),
:global(.react-datepicker__day--selected:not([aria-disabled=true]):hover),
:global(.react-datepicker__day--keyboard-selected:not([aria-disabled=true]):hover) {
background: bk.$theme-date-picker-background-hover;
border-radius: bk.$border-radius-circle;
color: bk.$theme-date-picker-text-hover;
}

:global(.react-datepicker__day--in-range),
:global(.react-datepicker__day--in-selecting-range:not(
.react-datepicker__month-text--in-range,
.react-datepicker__quarter-text--in-range,
.react-datepicker__year-text--in-range
)) {
background: bk.$theme-date-picker-background-selected;
border-radius: 0;
color: bk.$theme-date-picker-text-selected;
}
:global(.react-datepicker__day--in-range:not([aria-disabled=true]):hover),
:global(.react-datepicker__day--in-selecting-range:not([aria-disabled=true]):hover) {
background: bk.$theme-date-picker-background-hover;
border-radius: 0;
color: bk.$theme-date-picker-text-hover;
}

:global(.react-datepicker__day--range-start),
:global(.react-datepicker__day--selecting-range-start),
:global(.react-datepicker__day--range-start:not([aria-disabled=true]):hover) {
border-radius: bk.$border-radius-circle 0 0 bk.$border-radius-circle;
}

:global(.react-datepicker__day--range-end),
:global(.react-datepicker__day--selecting-range-end),
:global(.react-datepicker__day--range-end:not([aria-disabled=true]):hover) {
border-radius: 0 bk.$border-radius-circle bk.$border-radius-circle 0;
}

:global(.react-datepicker__day--range-start.react-datepicker__day--range-end),
:global(.react-datepicker__day--range-start.react-datepicker__day--range-end:not([aria-disabled=true]):hover) {
border-radius: bk.$border-radius-circle;
}

:global(.react-datepicker__day:not(&--selected):hover) {
background: rgba(bk.$color-blueberry-500, 0.5); // TODO use proper variable
border-radius: 50%;
}

:global(.react-datepicker__day--in-range),
:global(.react-datepicker__day--in-selecting-range) {
background: transparent;
background-color: transparent;
border-radius: 0;
}

:global(.react-datepicker-popper[data-placement^="bottom"]) {
margin-top: 0;
}
Expand Down
61 changes: 59 additions & 2 deletions src/components/forms/controls/DatePicker/DatePicker.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ type DatePickerArgs = React.ComponentProps<typeof DatePicker>;
type Story = StoryObj<DatePickerArgs>;

export default {
// TODO: Why this error???
component: DatePicker,

Check failure on line 17 in src/components/forms/controls/DatePicker/DatePicker.stories.tsx

View workflow job for this annotation

GitHub Actions / build (22.x)

Type '(props: DatePickerProps) => React.JSX.Element' is not assignable to type 'ComponentType<DatePickerProps>'.
parameters: {
layout: 'centered',
Expand All @@ -29,12 +30,68 @@ export default {
export const DatePickerStory: Story = {
name: 'Date Picker',
render: (args) => {
const [startDate, setStartDate] = React.useState(new Date());
const [startDate, setStartDate] = React.useState<Date | null>(new Date());

return (
<div style={{height: '500px'}}>
<DatePicker {...args} selected={startDate} onChange={(date) => setStartDate(date)} />
<DatePicker
{...args}
// TODO: why this error? selected is defined as Date | null on
// node_modules/react-datepicker/dist/index.d.ts, line 67
selected={startDate}

Check failure on line 41 in src/components/forms/controls/DatePicker/DatePicker.stories.tsx

View workflow job for this annotation

GitHub Actions / build (22.x)

Type '{ selected: Date | null; onChange: (date: Date) => void; children?: ReactNode; inline?: boolean; date?: Date; minDate: Date; maxDate: Date; scrollableYearDropdown?: boolean; yearDropdownItemNumber?: number; adjustDateOnChange?: boolean; locale?: Locale; useShortMonthInDropdown?: boolean; scrollableMonthYearDropdown?: boolean; selectingDate?: Date; onYearMouseEnter?: (event: MouseEvent<HTMLDivElement, MouseEvent>, year: number) => void; onYearMouseLeave?: (event: MouseEvent<HTMLDivElement, MouseEvent>, year: number) => void; excludeDates?: { date: Date; message?: string; }[] | Date[]; includeDates?: Date[]; filterDate?: (date: Date) => boolean; disabledKeyboardNavigation?: boolean; endDate?: Date; usePointerEvent?: boolean; renderYearContent?: (year: number) => ReactNode; selectsEnd?: boolean; selectsStart?: boolean; startDate?: Date; yearItemNumber?: number; yearClassName?: (date: Date) => string; onDayMouseEnter?: (date: Date) => void; chooseDayAriaLabelPrefix?: string | undefined; disabledDayAriaLabelPrefix?: string | undefined; excludeDateIntervals?: { start: Date; end: Date; }[]; includeDateIntervals?: { start: Date; end: Date; }[]; dayClassName?: (date: Date) => string; showWeekPicker?: boolean; selectsDisabledDaysInRange?: boolean; selectedDates?: Date[]; renderDayContents?: (day: number, date: Date) => ReactNode; containerRef?: RefObject<HTMLDivElement>; calendarStartDay?: Day; shouldCloseOnSelect?: boolean; formatWeekNumber?: (date: Date) => number; onWeekSelect?: (day: Date, weekNumber: number, event: MouseEvent<HTMLDivElement, MouseEvent>) => void; monthClassName?: (date: Date) => string; renderMonthContent?: (m: number, shortMonthText: string, fullMonthText: string, day: Date) => ReactNode; renderQuarterContent?: (q: number, shortQuarter: string) => ReactNode; fixedHeight?: boolean; peekNextMonth?: boolean; showWeekNumbers?: boolean | undefined; showMonthYearPicker?: boolean; showFullMonthYearPicker?: boolean; showTwoColumnMonthYearPicker?: boolean; showFourColumnMonthYearPicker?: boolean; showQuarterYearPicker?: boolean; weekAriaLabelPrefix?: string | undefined; minTime?: Date; maxTime?: Date; excludeTimes?: Date[]; includeTimes?: Date[]; filterTime?: (time: Date) => boolean; openToDate?: Date; timeClassName?: (time: Date) => string; todayButton?: ReactNode; timeCaption?: string; injectTimes?: Date[]; showTimeSelectOnly?: boolean; showTimeCaption?: boolean; timeInputLabel?: string; customTimeInput?: any; showYearPicker?: boolean; showTimeSelect?: boolean; showTimeInput?: boolean; showYearDropdown?: boolean; showMonthDropdown?: boolean; useWeekdaysShort?: boolean; forceShowMonthNavigation?: boolean; showDisabledMonthNavigation?: boolean; formatWeekDay?: (date: string) => string; weekDayClassName?: (date: Date) => string; onMonthChange?: (date: Date) => void; onYearChange?: (date: Date) => void; onMonthMouseLeave?: VoidFunction; weekLabel?: string; previousMonthButtonLabel?: ReactNode; previousYearButtonLabel?: string; previousMonthAriaLabel?: string; previousYearAriaLabel?: string; nextMonthButtonLabel?: ReactNode; nextYearButtonLabel?: string; nextMonthAriaLabel?: string; nextYearAriaLabel?: string; showPreviousMonths?: boolean; monthsShown?: number; renderCustomHeader?: (props: ReactDatePickerCustomHeaderProps) => JSX.Element; monthAriaLabelPrefix?: string | undefined; timeFormat?: string | undefined; timeIntervals?: number | undefined; showMonthYearDropdown: true; icon?: ReactNode; portalHost?: ShadowRoot; portalId?: string; popperProps?: Omit<UseFloatingOptions<ReferenceType>, "middleware">; enableTabLoop?: boolean; wrapperClassName?: string; popperContainer?: FC<{ children?: ReactNode; }>; popperModifiers?: { name: string; options?: any; fn: (state: { x: number; y: number; platform: Platform; placement: Placement; strategy: Strategy; middlewareData: MiddlewareData; initialPlacement: Placement; rects: ElementRects; elements: Elements; }) => Promisable<MiddlewareReturn>; }[]; popperPlacement?: Placement; dateFormatCalendar?: string; calendarClassName?: string | undefined; calendarContainer?: ElementTy
onChange={(date: Date) => setStartDate(date)}
/>
</div>
);
}
};

export const DatePickerStoryWithRange: Story = {
name: 'Date Picker with Dates Range',
render: (args) => {
const [startDate, setStartDate] = React.useState<Date | null>(new Date());
const [endDate, setEndDate] = React.useState<Date | null>(new Date());
const onChange = (dates: (Date | null)[]) => {
let [start, end] = dates;
// TODO: should I make sure start and end are not undefined in a different way?
// apparently linter thinks they can be undefined because of the destructuring.
if (start !== undefined && end !== undefined) {
setStartDate(start);
setEndDate(end);
}
};

return (
<div style={{height: '500px'}}>
<DatePicker
{...args}
// TODO: same error as previous story
selected={startDate}

Check failure on line 69 in src/components/forms/controls/DatePicker/DatePicker.stories.tsx

View workflow job for this annotation

GitHub Actions / build (22.x)

Type '{ selected: Date | null; onChange: (dates: (Date | null)[]) => void; startDate: Date | null; endDate: Date | null; selectsRange: boolean; inline: boolean; children?: ReactNode; date?: Date; minDate: Date; maxDate: Date; scrollableYearDropdown?: boolean; yearDropdownItemNumber?: number; adjustDateOnChange?: boolean; locale?: Locale; useShortMonthInDropdown?: boolean; scrollableMonthYearDropdown?: boolean; selectingDate?: Date; onYearMouseEnter?: (event: MouseEvent<HTMLDivElement, MouseEvent>, year: number) => void; onYearMouseLeave?: (event: MouseEvent<HTMLDivElement, MouseEvent>, year: number) => void; excludeDates?: { date: Date; message?: string; }[] | Date[]; includeDates?: Date[]; filterDate?: (date: Date) => boolean; disabledKeyboardNavigation?: boolean; usePointerEvent?: boolean; renderYearContent?: (year: number) => ReactNode; selectsEnd?: boolean; selectsStart?: boolean; yearItemNumber?: number; yearClassName?: (date: Date) => string; onDayMouseEnter?: (date: Date) => void; chooseDayAriaLabelPrefix?: string | undefined; disabledDayAriaLabelPrefix?: string | undefined; excludeDateIntervals?: { start: Date; end: Date; }[]; includeDateIntervals?: { start: Date; end: Date; }[]; dayClassName?: (date: Date) => string; showWeekPicker?: boolean; selectsDisabledDaysInRange?: boolean; selectedDates?: Date[]; renderDayContents?: (day: number, date: Date) => ReactNode; containerRef?: RefObject<HTMLDivElement>; calendarStartDay?: Day; shouldCloseOnSelect?: boolean; formatWeekNumber?: (date: Date) => number; onWeekSelect?: (day: Date, weekNumber: number, event: MouseEvent<HTMLDivElement, MouseEvent>) => void; monthClassName?: (date: Date) => string; renderMonthContent?: (m: number, shortMonthText: string, fullMonthText: string, day: Date) => ReactNode; renderQuarterContent?: (q: number, shortQuarter: string) => ReactNode; fixedHeight?: boolean; peekNextMonth?: boolean; showWeekNumbers?: boolean | undefined; showMonthYearPicker?: boolean; showFullMonthYearPicker?: boolean; showTwoColumnMonthYearPicker?: boolean; showFourColumnMonthYearPicker?: boolean; showQuarterYearPicker?: boolean; weekAriaLabelPrefix?: string | undefined; minTime?: Date; maxTime?: Date; excludeTimes?: Date[]; includeTimes?: Date[]; filterTime?: (time: Date) => boolean; openToDate?: Date; timeClassName?: (time: Date) => string; todayButton?: ReactNode; timeCaption?: string; injectTimes?: Date[]; showTimeSelectOnly?: boolean; showTimeCaption?: boolean; timeInputLabel?: string; customTimeInput?: any; showYearPicker?: boolean; showTimeSelect?: boolean; showTimeInput?: boolean; showYearDropdown?: boolean; showMonthDropdown?: boolean; useWeekdaysShort?: boolean; forceShowMonthNavigation?: boolean; showDisabledMonthNavigation?: boolean; formatWeekDay?: (date: string) => string; weekDayClassName?: (date: Date) => string; onMonthChange?: (date: Date) => void; onYearChange?: (date: Date) => void; onMonthMouseLeave?: VoidFunction; weekLabel?: string; previousMonthButtonLabel?: ReactNode; previousYearButtonLabel?: string; previousMonthAriaLabel?: string; previousYearAriaLabel?: string; nextMonthButtonLabel?: ReactNode; nextYearButtonLabel?: string; nextMonthAriaLabel?: string; nextYearAriaLabel?: string; showPreviousMonths?: boolean; monthsShown?: number; renderCustomHeader?: (props: ReactDatePickerCustomHeaderProps) => JSX.Element; monthAriaLabelPrefix?: string | undefined; timeFormat?: string | undefined; timeIntervals?: number | undefined; showMonthYearDropdown: true; icon?: ReactNode; portalHost?: ShadowRoot; portalId?: string; popperProps?: Omit<UseFloatingOptions<ReferenceType>, "middleware">; enableTabLoop?: boolean; wrapperClassName?: string; popperContainer?: FC<{ children?: ReactNode; }>; popperModifiers?: { name: string; options?: any; fn: (state: { x: number; y: number; platform: Platform; placement: Placement; strategy: Strategy; middlewareData: MiddlewareData; initialPlacement: Placement; rects: ElementRects; elements: Elements; }) => Promisable<MiddlewareReturn>; }[]; popperPlacement?: Placement; dateFormatCalendar?: string; calendarClassName?: str
onChange={onChange}
startDate={startDate}
endDate={endDate}
selectsRange={true}
inline={true}
/>
</div>
);

// const [startDate, setStartDate] = React.useState(new Date());
// const [endDate, setEndDate] = React.useState(null);
// const onChange = (dates: any) => {
// const [start, end] = dates;
// setStartDate(start);
// setEndDate(end);
// };
// return (
// <DatePicker
// selected={startDate}
// onChange={onChange}
// startDate={startDate}
// endDate={endDate}
// selectsRange
// inline
// />
// );
}
};
17 changes: 3 additions & 14 deletions src/components/forms/controls/DatePicker/DatePicker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,27 +11,20 @@ import 'react-datepicker/dist/react-datepicker.css';
import cl from './DatePicker.module.scss';


export type DatePickerProps = Omit<ComponentPropsWithoutRef<typeof ReactDatePicker>, 'onChange'> & {
// Omit<ComponentPropsWithoutRef<typeof ReactDatePicker>, 'onChange'> & {
export type DatePickerProps = typeof ReactDatePicker & {
/** Whether this component should be unstyled. */
unstyled?: undefined | boolean,

/** An optional class name to be appended to the class list. */
className?: ClassNameArgument,

date: Date,
maxDate?: Date,
minDate?: Date,
onChange: (date: Date) => void,
};

/** A wrapper for ReactDatePicker */
export const DatePicker = (props: DatePickerProps) => {
const {
unstyled = false,
className,
date,
maxDate,
minDate,
onChange,
...propsRest
} = props;

Expand All @@ -46,11 +39,7 @@ export const DatePicker = (props: DatePickerProps) => {
cl['bk-date-picker__date'],
)}
dateFormat="MM/dd/yyyy"
maxDate={maxDate}
minDate={minDate}
placeholderText="MM/DD/YYYY"
selected={date}
onChange={onChange}
{...propsRest}
/>
</div>
Expand Down
5 changes: 4 additions & 1 deletion src/styling/variables.scss
Original file line number Diff line number Diff line change
Expand Up @@ -418,6 +418,7 @@ $light-date-picker-background-selected: $color-blueberry-600 !default;
$light-date-picker-text-selected: $color-neutral-0 !default;
$light-date-picker-background-hover: $color-blueberry-700 !default;
$light-date-picker-text-hover: $color-neutral-0 !default;
$light-date-picker-text-unavailable: $color-neutral-50 !default;
$light-date-picker-rule-default: $color-blackberry-20 !default;
$light-scroll-bar-thumb-default: $color-neutral-90 !default;
$light-scroll-bar-slider-default: $color-neutral-50 !default;
Expand Down Expand Up @@ -659,6 +660,7 @@ $dark-date-picker-background-selected: $color-blueberry-500 !default;
$dark-date-picker-text-hover: $color-neutral-10 !default;
$dark-date-picker-background-hover: $color-blueberry-600 !default;
$dark-date-picker-text-selected: $color-neutral-10 !default;
$dark-date-picker-text-unavailable: $color-neutral-700 !default;
$dark-date-picker-rule-default: $color-blackberry-300 !default;
$dark-scroll-bar-thumb-default: $color-blackberry-200 !default;
$dark-scroll-bar-slider-default: $color-blackberry-800 !default;
Expand Down Expand Up @@ -899,7 +901,8 @@ $theme-date-picker-text-disabled: #{ld($light-date-picker-text-disabled, $dark-d
$theme-date-picker-background-selected: #{ld($light-date-picker-background-selected, $dark-date-picker-background-selected)} !default;
$theme-date-picker-text-selected: #{ld($light-date-picker-text-selected, $dark-date-picker-text-selected)} !default;
$theme-date-picker-background-hover: #{ld($light-date-picker-background-selected, $dark-date-picker-background-selected)} !default;
$theme-date-picker-text-hover: #{ld($light-date-picker-text-selected, $dark-date-picker-text-selected)} !default;
$theme-date-picker-text-hover: #{ld($light-date-picker-text-hover, $dark-date-picker-text-hover)} !default;
$theme-date-picker-text-unavailable: #{ld($light-date-picker-text-unavailable, $dark-date-picker-text-unavailable)} !default;
$theme-date-picker-rule-default: #{ld($light-date-picker-rule-default, $dark-date-picker-rule-default)} !default;
$theme-scroll-bar-thumb-default: #{ld($light-scroll-bar-thumb-default, $dark-scroll-bar-thumb-default)} !default;
$theme-scroll-bar-slider-default: #{ld($light-scroll-bar-slider-default, $dark-scroll-bar-slider-default)} !default;
Expand Down

0 comments on commit e5e749e

Please sign in to comment.