Skip to content

Commit b32f54d

Browse files
committed
chore: add type overloads
1 parent 0274984 commit b32f54d

File tree

2 files changed

+61
-48
lines changed

2 files changed

+61
-48
lines changed

src/components/experimental/DatePicker/DatePicker.tsx

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
// DatePicker.tsx
12
import { format as dfFormat } from 'date-fns';
23
import React from 'react';
34
import styled from 'styled-components';
@@ -82,17 +83,20 @@ type LegacyCompatProps = {
8283
isInvalid?: boolean;
8384
};
8485

85-
export type DatePickerProps = (SingleProps | MultipleProps | RangeProps) & LegacyCompatProps;
86+
type DatePickerProps = (SingleProps | MultipleProps | RangeProps) & LegacyCompatProps;
8687

8788
const StyledPopover = styled(Popover)`
8889
padding: 1.5rem;
8990
border-radius: 1.5rem;
9091
`;
9192

92-
export function DatePicker(props: SingleProps & LegacyCompatProps): JSX.Element;
93-
export function DatePicker(props: MultipleProps & LegacyCompatProps): JSX.Element;
94-
export function DatePicker(props: RangeProps & LegacyCompatProps): JSX.Element;
95-
export function DatePicker(props: DatePickerProps): JSX.Element {
93+
export interface DatePickerOverloads {
94+
(props: SingleProps & LegacyCompatProps): JSX.Element;
95+
(props: MultipleProps & LegacyCompatProps): JSX.Element;
96+
(props: RangeProps & LegacyCompatProps): JSX.Element;
97+
}
98+
99+
function DatePickerImpl(props: DatePickerProps): JSX.Element {
96100
const {
97101
label,
98102
description,
@@ -363,7 +367,7 @@ export function DatePicker(props: DatePickerProps): JSX.Element {
363367
description={description}
364368
errorMessage={errorMessage}
365369
isInvalid={isInvalid}
366-
isDisabled={legacyIsDisabled || isDisabled}
370+
isDisabled={legacyIsDisabled}
367371
isVisuallyFocused={open}
368372
leadingIcon={<CalendarTodayOutlineIcon />}
369373
value={inputValue}
@@ -436,7 +440,7 @@ export function DatePicker(props: DatePickerProps): JSX.Element {
436440
const key = stripTime(d).getTime(); // stable per day
437441
return (
438442
<Chip key={key}>
439-
{dfFormat(d, displayFormat, { locale })} {/* ensure same format */}
443+
{dfFormat(d, displayFormat, { locale })}
440444
<ChipRemoveButton
441445
onPress={() =>
442446
(props as MultipleProps).onChange(
@@ -507,3 +511,10 @@ export function DatePicker(props: DatePickerProps): JSX.Element {
507511
</div>
508512
);
509513
}
514+
515+
DatePickerImpl.displayName = 'DatePicker';
516+
517+
export type { DatePickerProps, LegacyCompatProps, SingleProps, MultipleProps, RangeProps };
518+
519+
// exported component with proper overloads at the value level
520+
export const DatePicker = DatePickerImpl as unknown as DatePickerOverloads;
Lines changed: 43 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,70 +1,72 @@
11
import React from 'react';
22
import type { DateRange as RdpRange } from 'react-day-picker';
33
import { getLocalTimeZone, today } from '@internationalized/date';
4-
import { Meta, StoryObj } from '@storybook/react';
4+
import type { Meta, StoryObj } from '@storybook/react';
55
import { DatePicker } from '../DatePicker';
6+
import type {
7+
DatePickerProps,
8+
SingleProps,
9+
MultipleProps,
10+
RangeProps,
11+
LegacyCompatProps // <-- import
12+
} from '../DatePicker';
613

7-
const meta: Meta = {
14+
const meta = {
815
title: 'Experimental/Components/DatePicker',
9-
component: DatePicker,
10-
parameters: {
11-
layout: 'centered'
12-
},
13-
args: {
14-
label: 'Pickup date'
15-
}
16-
};
16+
component: DatePicker as unknown as React.ComponentType<DatePickerProps>,
17+
parameters: { layout: 'centered' },
18+
args: { label: 'Pickup date' }
19+
} satisfies Meta<DatePickerProps>;
1720

1821
export default meta;
1922

20-
type Story = StoryObj<typeof DatePicker>;
23+
type SingleStory = StoryObj<SingleProps & LegacyCompatProps>;
24+
type MultipleStory = StoryObj<MultipleProps & LegacyCompatProps>;
25+
type RangeStory = StoryObj<RangeProps & LegacyCompatProps>;
2126

2227
const TZ = getLocalTimeZone();
2328
const TODAY = today(TZ);
2429

25-
export const Default: Story = {};
30+
// Single mode
31+
export const Default: SingleStory = { args: { mode: 'single' } };
2632

27-
export const WithDefaultValue: Story = {
28-
args: {
29-
defaultValue: TODAY
30-
}
33+
export const WithDefaultValue: SingleStory = {
34+
args: { mode: 'single', defaultValue: TODAY }
3135
};
3236

33-
export const WithDescription: Story = {
34-
args: {
35-
description: 'Enter current date'
36-
}
37+
export const WithDescription: SingleStory = {
38+
args: { mode: 'single', description: 'Enter current date' }
3739
};
3840

39-
export const WithValidation: Story = {
40-
args: {
41-
label: 'Only from today'
42-
},
41+
export const WithValidation: SingleStory = {
42+
args: { mode: 'single', label: 'Only from today' },
4343
render: args => <DatePicker {...args} minValue={TODAY} />
4444
};
4545

46-
export const MultipleSelection: Story = {
47-
render: args => {
48-
const [dates, setDates] = React.useState<Date[]>([]);
49-
return <DatePicker {...args} mode="multiple" visibleMonths={2} value={dates} onChange={setDates} />;
50-
}
46+
export const AutoFocus: SingleStory = {
47+
args: { mode: 'single', autoFocus: true, defaultValue: TODAY }
5148
};
5249

53-
export const RangeSelection: Story = {
54-
render: args => {
55-
const [range, setRange] = React.useState<RdpRange | undefined>(undefined);
56-
return <DatePicker {...args} mode="range" visibleMonths={2} value={range} onChange={setRange} />;
57-
}
50+
export const Disabled: SingleStory = {
51+
args: { mode: 'single', isDisabled: true }
52+
};
53+
54+
export const Invalid: SingleStory = {
55+
args: { mode: 'single', isInvalid: true, errorMessage: 'Error' }
5856
};
59-
export const Disabled: Story = {
60-
args: {
61-
isDisabled: true
57+
58+
export const MultipleSelection: MultipleStory = {
59+
args: { mode: 'multiple', visibleMonths: 2 },
60+
render: args => {
61+
const [dates, setDates] = React.useState<Date[]>([]);
62+
return <DatePicker {...args} value={dates} onChange={setDates} />;
6263
}
6364
};
6465

65-
export const Invalid: Story = {
66-
args: {
67-
isInvalid: true,
68-
errorMessage: 'Error'
66+
export const RangeSelection: RangeStory = {
67+
args: { mode: 'range', visibleMonths: 2 },
68+
render: args => {
69+
const [range, setRange] = React.useState<RdpRange | undefined>();
70+
return <DatePicker {...args} value={range} onChange={setRange} />;
6971
}
7072
};

0 commit comments

Comments
 (0)