Skip to content

Commit

Permalink
feat: add date pickers (#54)
Browse files Browse the repository at this point in the history
adds:
- DateField
- Calendar
- DatePicker
- RangeCalendar
- DateRangePicker
  • Loading branch information
arturbien authored Jan 5, 2024
1 parent aa937c9 commit 7499e36
Show file tree
Hide file tree
Showing 19 changed files with 3,561 additions and 206 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
import type { Meta, StoryObj } from '@storybook/react';

import {
DateValue,
getLocalTimeZone,
isWeekend,
parseDate,
today,
} from '@internationalized/date';
import { useLocale } from '@react-aria/i18n';
import React from 'react';
import { Calendar } from '../../../src/components';

// More on how to set up stories at: https://storybook.js.org/docs/react/writing-stories/introduction#default-export
const meta = {
title: 'Controls/Dates/Calendar',
component: Calendar,
args: {
isDisabled: false,
},
parameters: {
// Optional parameter to center the component in the Canvas. More info: https://storybook.js.org/docs/react/configure/story-layout
layout: 'centered',
},
// This component will have an automatically generated Autodocs entry: https://storybook.js.org/docs/react/writing-docs/autodocs
tags: ['autodocs'],
} satisfies Meta<typeof Calendar>;

export default meta;
type Story = StoryObj<typeof meta>;

// More on writing stories with args: https://storybook.js.org/docs/react/writing-stories/args
export const Default: Story = {
args: {},
render: (args) => (
<div>
<Calendar
{...args}
minValue={parseDate('1900-02-03')}
defaultValue={parseDate('2020-02-03')}
onChange={(date) => console.log(date.toString())}
/>
</div>
),
};
export const Disabled: Story = {
args: {},
render: (args) => (
<div>
<Calendar
{...args}
isDisabled
defaultValue={parseDate('2020-02-03')}
onChange={(date) => console.log(date.toString())}
/>
</div>
),
};

export const UnavailableDates: Story = {
name: 'Unavailable Dates',
args: {},
render: (args) => {
let now = today(getLocalTimeZone());
let disabledRanges = [
[now, now.add({ days: 5 })],
[now.add({ days: 14 }), now.add({ days: 16 })],
[now.add({ days: 23 }), now.add({ days: 24 })],
];

let { locale } = useLocale();
let isDateUnavailable = (date: DateValue) =>
isWeekend(date, locale) ||
disabledRanges.some(
(interval) =>
date.compare(interval[0]) >= 0 && date.compare(interval[1]) <= 0,
);

return (
<div style={{ width: 300 }}>
<Calendar
{...args}
aria-label="Appointment date"
minValue={today(getLocalTimeZone())}
isDateUnavailable={isDateUnavailable}
/>
</div>
);
},
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
import type { Meta, StoryObj } from '@storybook/react';

import {
getLocalTimeZone,
parseDate,
parseZonedDateTime,
today,
} from '@internationalized/date';
import React from 'react';
import { DateField, Flex, dateFieldPropDefs } from '../../../src/components';
// More on how to set up stories at: https://storybook.js.org/docs/react/writing-stories/introduction#default-export
const meta = {
title: 'Controls/Dates/DateField',
component: DateField,
args: {
size: dateFieldPropDefs.size.default,
color: dateFieldPropDefs.color.default,
'aria-label': 'Birth date',
},
parameters: {
// Optional parameter to center the component in the Canvas. More info: https://storybook.js.org/docs/react/configure/story-layout
layout: 'centered',
},
// This component will have an automatically generated Autodocs entry: https://storybook.js.org/docs/react/writing-docs/autodocs
tags: ['autodocs'],
} satisfies Meta<typeof DateField>;

export default meta;
type Story = StoryObj<typeof meta>;

// More on writing stories with args: https://storybook.js.org/docs/react/writing-stories/args
export const Default: Story = {
args: {},
render: (args) => (
<div style={{ width: 300 }}>
<DateField
{...args}
defaultValue={parseDate('2020-02-03')}
onChange={(date) => console.log(date?.toString())}
/>
</div>
),
};

export const Size: Story = {
args: {},
render: (args) => (
<Flex direction={'column'} gap="4" style={{ width: 300 }}>
<DateField {...args} defaultValue={parseDate('2020-02-03')} size="1" />
<DateField {...args} defaultValue={parseDate('2020-02-03')} size="2" />
<DateField {...args} defaultValue={parseDate('2020-02-03')} size="3" />
</Flex>
),
};

export const MinValue: Story = {
args: {},
render: (args) => (
<Flex direction={'column'} gap="4" style={{ width: 300 }}>
<DateField
{...args}
minValue={today(getLocalTimeZone())}
defaultValue={parseDate('2020-02-03')}
validationBehavior="aria"
/>
</Flex>
),
};

export const WithTime: Story = {
name: 'With time',
args: {},
render: (args) => (
<Flex direction={'column'} gap="4" style={{ width: 300 }}>
<DateField
{...args}
defaultValue={parseZonedDateTime(
'2022-11-07T00:45[America/Los_Angeles]',
)}
/>
<DateField
{...args}
defaultValue={parseZonedDateTime(
'2022-11-07T00:45[America/Los_Angeles]',
)}
hideTimeZone
/>
<DateField
{...args}
defaultValue={parseZonedDateTime(
'2022-11-07T00:45[America/Los_Angeles]',
)}
hideTimeZone
granularity="second"
/>
</Flex>
),
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
import type { Meta, StoryObj } from '@storybook/react';

import { DateValue, parseDate } from '@internationalized/date';
import React from 'react';
import {
Button,
Calendar,
DatePicker,
Flex,
Popover,
datePickerPropDefs,
} from '../../../src/components';

// More on how to set up stories at: https://storybook.js.org/docs/react/writing-stories/introduction#default-export
const meta = {
title: 'Controls/Dates/DatePicker',
component: DatePicker,
args: {
size: datePickerPropDefs.size.default,
color: datePickerPropDefs.color.default,
defaultValue: parseDate('2020-02-03'),
onChange: (date) => console.log(date?.toString()),
'aria-label': 'Birth date',
isDisabled: false,
},
parameters: {
// Optional parameter to center the component in the Canvas. More info: https://storybook.js.org/docs/react/configure/story-layout
layout: 'centered',
},
// This component will have an automatically generated Autodocs entry: https://storybook.js.org/docs/react/writing-docs/autodocs
tags: ['autodocs'],
} satisfies Meta<typeof DatePicker>;

export default meta;
type Story = StoryObj<typeof meta>;

// More on writing stories with args: https://storybook.js.org/docs/react/writing-stories/args
export const Default: Story = {
args: {},
render: (args) => (
<Flex direction="column" gap="5">
<DatePicker {...args} />
</Flex>
),
};

export const Sizes: Story = {
args: {},
render: (args) => (
<Flex direction="column" gap="5">
<DatePicker {...args} size="1" />
<DatePicker {...args} size="2" />
<DatePicker {...args} size="3" />
</Flex>
),
};

export const Custom: Story = {
args: {},
render: () => {
const [date, setDate] = React.useState<DateValue>(parseDate('2020-02-03'));
const [open, setOpen] = React.useState(true);
return (
<div style={{ marginTop: -200 }}>
<Popover.Root open={open} onOpenChange={setOpen}>
<Popover.Trigger>
<Button size="3">
{' '}
<CalendarIcon /> {date.toString()}
</Button>
</Popover.Trigger>
<Popover.Content
variant="translucent"
align="center"
style={{ width: 'unset' }}
>
<Calendar
minValue={parseDate('2020-01-03')}
defaultValue={date}
maxValue={parseDate('2020-03-03')}
onChange={(value) => {
setDate(value);
setOpen(false);
}}
/>
</Popover.Content>
</Popover.Root>
</div>
);
},
};

const CalendarIcon = () => (
<svg
width="16"
height="16"
viewBox="0 0 16 16"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<g clipPath="url(#clip0_1869_102855)">
<path
fillRule="evenodd"
clipRule="evenodd"
d="M4 0C4.41421 0 4.75 0.335786 4.75 0.75V2H11.25V0.75C11.25 0.335786 11.5858 0 12 0C12.4142 0 12.75 0.335786 12.75 0.75V2.03304C14.5847 2.27749 16 3.84846 16 5.75V12.25C16 14.3211 14.3211 16 12.25 16H3.75C1.67893 16 0 14.3211 0 12.25V5.75C0 3.84846 1.41532 2.27749 3.25 2.03304V0.75C3.25 0.335786 3.58579 0 4 0ZM12 3.5H4H3.75C2.50736 3.5 1.5 4.50736 1.5 5.75V6H14.5V5.75C14.5 4.50736 13.4926 3.5 12.25 3.5H12ZM1.5 7.5V12.25C1.5 13.4926 2.50736 14.5 3.75 14.5H12.25C13.4926 14.5 14.5 13.4926 14.5 12.25V7.5H1.5Z"
fill="var(--gray-10)"
/>
</g>
<defs>
<clipPath id="clip0_1869_102855">
<rect width="16" height="16" fill="var(--gray-10)" />
</clipPath>
</defs>
</svg>
);
Loading

0 comments on commit 7499e36

Please sign in to comment.