Skip to content

Commit

Permalink
feat(Calendar): add isWeekend prop
Browse files Browse the repository at this point in the history
  • Loading branch information
ValeraS committed Aug 23, 2024
1 parent a34501d commit 693f1af
Show file tree
Hide file tree
Showing 8 changed files with 55 additions and 3 deletions.
1 change: 1 addition & 0 deletions src/components/Calendar/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,7 @@ LANDING_BLOCK-->
| [focusedValue](#focused-value) | Set the default view of uncontrolled component which includes this value | `DateTime` `null` | |
| id | The control's `id` attribute | `string` | |
| isDateUnavailable | Callback that is called for each date of the calendar. If it returns true, then the date is unavailable. | `((date: DateTime) => boolean)` | |
| isWeekend | Callback that is called for each date of the calendar. If it returns true, then the date is weekend. | `((date: DateTime) => boolean)` | |
| [maxValue](#min-and-max-value) | The maximum allowed date that a user may select. | `DateTime` | |
| [minValue](#min-and-max-value) | The minimum allowed date that a user may select. | `DateTime` | |
| [mode](#mode) | Defines the time interval that `Calendar` should display in colttrolled way. | `days` `months` `quarters` `years` | |
Expand Down
19 changes: 19 additions & 0 deletions src/components/Calendar/__stories__/Calendar.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ export const Default = {
? dateTimeParse(args.defaultFocusedValue, {timeZone})
: undefined,
isDateUnavailable: getIsDateUnavailable(args.isDateUnavailable as unknown as string),
isWeekend: getIsWeekend(args.isWeekend as unknown as string),
};
return <Calendar {...props} />;
},
Expand Down Expand Up @@ -96,6 +97,12 @@ export const Default = {
type: 'radio',
},
},
isWeekend: {
options: ['default', 'none', 'Friday and Saturday'],
control: {
type: 'radio',
},
},
timeZone: timeZoneControl,
},
} satisfies Story;
Expand Down Expand Up @@ -126,6 +133,18 @@ function getIsDateUnavailable(variant: string) {
return undefined;
}

function getIsWeekend(variant: string) {
if (variant === 'Friday and Saturday') {
return (date: DateTime) => [5, 6].includes(date.day());
}

if (variant === 'none') {
return () => false;
}

return undefined;
}

export const Custom: Story = {
...Default,
render: function Custom(args) {
Expand Down
2 changes: 1 addition & 1 deletion src/components/CalendarView/Calendar.scss
Original file line number Diff line number Diff line change
Expand Up @@ -286,7 +286,7 @@ $block: '.#{variables.$ns}calendar';
content: '';

border-radius: 50%;
background-color: var(--g-color-text-primary);
background-color: currentColor;

transform: translateY(8px);
}
Expand Down
2 changes: 2 additions & 0 deletions src/components/CalendarView/hooks/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ export interface CalendarStateOptionsBase extends InputBase {
maxValue?: DateTime;
/** Callback that is called for each date of the calendar. If it returns true, then the date is unavailable. */
isDateUnavailable?: (date: DateTime) => boolean;
/** Callback that is called for each date of the calendar. If it returns true, then the date is weekend. */
isWeekend?: (date: DateTime) => boolean;
/**
* Which timezone use to show values. Example: 'default', 'system', 'Europe/Amsterdam'.
* @default The timezone of the `value` or `defaultValue` or `focusedValue` or `defaultFocusedValue`, 'default' otherwise.
Expand Down
10 changes: 8 additions & 2 deletions src/components/CalendarView/hooks/useCalendarState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import type {DateTime} from '@gravity-ui/date-utils';
import {useControlledState} from '@gravity-ui/uikit';

import type {ValueBase} from '../../types';
import {constrainValue, createPlaceholderValue, mergeDateTime} from '../../utils/dates';
import {constrainValue, createPlaceholderValue, isWeekend, mergeDateTime} from '../../utils/dates';
import {useDefaultTimeZone} from '../../utils/useDefaultTimeZone';
import {calendarLayouts} from '../utils';

Expand Down Expand Up @@ -231,7 +231,13 @@ export function useCalendarState(props: CalendarStateOptions): CalendarState {
return this.disabled || this.isInvalid(date);
},
isWeekend(date: DateTime) {
return this.mode === 'days' && [0, 6].includes(date.day());
if (this.mode !== 'days') {
return false;
}
if (typeof props.isWeekend === 'function') {
return props.isWeekend(date);
}
return isWeekend(date);
},
isCurrent(date: DateTime) {
return dateTime({timeZone}).isSame(date, this.mode);
Expand Down
1 change: 1 addition & 0 deletions src/components/RangeCalendar/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,7 @@ LANDING_BLOCK-->
| [focusedValue](#focused-value) | Set the default view of uncontrolled component which includes this value | `DateTime` `null` | |
| id | The control's `id` attribute | `string` | |
| isDateUnavailable | Callback that is called for each date of the calendar. If it returns true, then the date is unavailable. | `((date: DateTime) => boolean)` | |
| isWeekend | Callback that is called for each date of the calendar. If it returns true, then the date is weekend. | `((date: DateTime) => boolean)` | |
| [maxValue](#min-and-max-value) | The maximum allowed date that a user may select. | `DateTime` | |
| [minValue](#min-and-max-value) | The minimum allowed date that a user may select. | `DateTime` | |
| [mode](#mode) | Defines the time interval that `RangeCalendar` should display in colttrolled way. | `days` `months` `quarters` `years` | |
Expand Down
19 changes: 19 additions & 0 deletions src/components/RangeCalendar/__stories__/RangeCalendar.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ export const Default = {
? dateTimeParse(args.defaultFocusedValue, {timeZone})
: undefined,
isDateUnavailable: getIsDateUnavailable(args.isDateUnavailable as unknown as string),
isWeekend: getIsWeekend(args.isWeekend as unknown as string),
};

const [value, setValue] = React.useState<RangeValue<DateTime> | null>(null);
Expand Down Expand Up @@ -100,6 +101,12 @@ export const Default = {
type: 'radio',
},
},
isWeekend: {
options: ['default', 'none', 'Friday and Saturday'],
control: {
type: 'radio',
},
},
timeZone: timeZoneControl,
},
} satisfies Story;
Expand Down Expand Up @@ -130,6 +137,18 @@ function getIsDateUnavailable(variant: string) {
return undefined;
}

function getIsWeekend(variant: string) {
if (variant === 'Friday and Saturday') {
return (date: DateTime) => [5, 6].includes(date.day());
}

if (variant === 'none') {
return () => false;
}

return undefined;
}

export const Custom: Story = {
...Default,
render: function Custom(args) {
Expand Down
4 changes: 4 additions & 0 deletions src/components/utils/dates.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
import {dateTime} from '@gravity-ui/date-utils';
import type {DateTime} from '@gravity-ui/date-utils';

export function isWeekend(date: DateTime) {
return [0, 6].includes(date.day());
}

export interface PlaceholderValueOptions {
placeholderValue?: DateTime;
timeZone?: string;
Expand Down

0 comments on commit 693f1af

Please sign in to comment.