mirror of https://github.com/buster-so/buster.git
date picker updates
This commit is contained in:
parent
0d7159f569
commit
fa6e5b88d4
|
@ -210,7 +210,7 @@ const LinkExpiration: React.FC<{
|
||||||
return createDayjsDate(new Date()).add(2, 'year');
|
return createDayjsDate(new Date()).add(2, 'year');
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const onSelect: SelectSingleEventHandler = useMemoizedFn((date) => {
|
const onSelect = useMemoizedFn((date: Date | undefined) => {
|
||||||
onChangeLinkExpiry(date || null);
|
onChangeLinkExpiry(date || null);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -219,7 +219,7 @@ const LinkExpiration: React.FC<{
|
||||||
<Text truncate>Link expiration</Text>
|
<Text truncate>Link expiration</Text>
|
||||||
|
|
||||||
<DatePicker
|
<DatePicker
|
||||||
selected={linkExpiry || new Date()}
|
selected={linkExpiry || undefined}
|
||||||
onSelect={onSelect}
|
onSelect={onSelect}
|
||||||
mode="single"
|
mode="single"
|
||||||
dateFormat={dateFormat}
|
dateFormat={dateFormat}
|
||||||
|
|
|
@ -26,7 +26,7 @@ function Calendar({ className, classNames, showOutsideDays = true, ...props }: C
|
||||||
nav_button_next: 'absolute right-1',
|
nav_button_next: 'absolute right-1',
|
||||||
table: 'w-full border-collapse space-y-1',
|
table: 'w-full border-collapse space-y-1',
|
||||||
head_row: 'flex',
|
head_row: 'flex',
|
||||||
head_cell: 'text-muted-foreground rounded-md w-8 font-normal text-[0.8rem]',
|
head_cell: 'text-gray-light rounded-md w-8 font-normal text-[0.8rem]',
|
||||||
row: 'flex w-full mt-2',
|
row: 'flex w-full mt-2',
|
||||||
cell: cn(
|
cell: cn(
|
||||||
'relative p-0 text-center text-sm focus-within:relative focus-within:z-20 [&:has([aria-selected])]:bg-accent [&:has([aria-selected].day-outside)]:bg-accent/50 [&:has([aria-selected].day-range-end)]:rounded-r-md',
|
'relative p-0 text-center text-sm focus-within:relative focus-within:z-20 [&:has([aria-selected])]:bg-accent [&:has([aria-selected].day-outside)]:bg-accent/50 [&:has([aria-selected].day-range-end)]:rounded-r-md',
|
||||||
|
@ -35,16 +35,16 @@ function Calendar({ className, classNames, showOutsideDays = true, ...props }: C
|
||||||
: '[&:has([aria-selected])]:rounded-md'
|
: '[&:has([aria-selected])]:rounded-md'
|
||||||
),
|
),
|
||||||
day: cn(
|
day: cn(
|
||||||
'h-8 w-8 p-0 cursor-pointer font-normal aria-selected:opacity-100 hover:bg-item-hover rounded'
|
'h-8 w-8 p-0 cursor-pointer font-normal aria-selected:opacity-100 hover:bg-item-hover rounded flex items-center justify-center'
|
||||||
),
|
),
|
||||||
day_range_start: 'day-range-start',
|
day_range_start: 'day-range-start',
|
||||||
day_range_end: 'day-range-end',
|
day_range_end: 'day-range-end',
|
||||||
day_selected:
|
day_selected:
|
||||||
'bg-primary text-background hover:bg-primary hover:text-primary-foreground focus:bg-primary focus:text-primary-foreground',
|
'bg-primary swag text-background hover:bg-primary hover:text-background focus:bg-primary focus:text-background',
|
||||||
day_today: 'bg-accent text-accent-foreground',
|
day_today: 'bg-accent text-accent-foreground',
|
||||||
day_outside:
|
day_outside:
|
||||||
'day-outside text-muted-foreground aria-selected:bg-accent/50 aria-selected:text-muted-foreground',
|
'day-outside text-gray-light aria-selected:bg-accent/50 aria-selected:text-gray-light cursor-not-allowed!',
|
||||||
day_disabled: 'text-muted-foreground opacity-50 cursor-not-allowed!',
|
day_disabled: 'text-gray-light opacity-50 cursor-not-allowed!',
|
||||||
day_range_middle: 'aria-selected:bg-accent aria-selected:text-accent-foreground',
|
day_range_middle: 'aria-selected:bg-accent aria-selected:text-accent-foreground',
|
||||||
day_hidden: 'invisible',
|
day_hidden: 'invisible',
|
||||||
...classNames
|
...classNames
|
||||||
|
|
|
@ -0,0 +1,99 @@
|
||||||
|
import type { Meta, StoryObj } from '@storybook/react';
|
||||||
|
import { DatePicker } from './DatePicker';
|
||||||
|
import { action } from '@storybook/addon-actions';
|
||||||
|
import { useState } from 'react';
|
||||||
|
|
||||||
|
const meta: Meta<typeof DatePicker> = {
|
||||||
|
title: 'UI/Date/DatePicker',
|
||||||
|
component: DatePicker,
|
||||||
|
tags: ['autodocs'],
|
||||||
|
argTypes: {
|
||||||
|
dateFormat: {
|
||||||
|
control: 'text',
|
||||||
|
description: 'Format for displaying the selected date'
|
||||||
|
},
|
||||||
|
placeholder: {
|
||||||
|
control: 'text',
|
||||||
|
description: 'Text to display when no date is selected'
|
||||||
|
},
|
||||||
|
selected: {
|
||||||
|
control: 'date',
|
||||||
|
description: 'The currently selected date'
|
||||||
|
},
|
||||||
|
onSelect: {
|
||||||
|
action: 'date selected',
|
||||||
|
description: 'Callback when a date is selected'
|
||||||
|
},
|
||||||
|
mode: {
|
||||||
|
control: 'select',
|
||||||
|
options: ['single', 'range', 'multiple'],
|
||||||
|
description: 'Selection mode for the calendar'
|
||||||
|
},
|
||||||
|
disabled: {
|
||||||
|
control: 'boolean',
|
||||||
|
description: 'Whether the date picker is disabled'
|
||||||
|
},
|
||||||
|
fromDate: {
|
||||||
|
control: 'date',
|
||||||
|
description: 'Minimum selectable date'
|
||||||
|
},
|
||||||
|
toDate: {
|
||||||
|
control: 'date',
|
||||||
|
description: 'Maximum selectable date'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export default meta;
|
||||||
|
type Story = StoryObj<typeof DatePicker>;
|
||||||
|
|
||||||
|
// Create interactive wrappers for each story
|
||||||
|
const InteractiveDatePicker = ({ initialDate, ...args }: any) => {
|
||||||
|
const [date, setDate] = useState<Date | undefined>(initialDate);
|
||||||
|
|
||||||
|
const handleDateSelect = (newDate: Date | undefined) => {
|
||||||
|
setDate(newDate);
|
||||||
|
action('onSelect')(newDate);
|
||||||
|
};
|
||||||
|
|
||||||
|
return <DatePicker {...args} selected={date} onSelect={handleDateSelect} />;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const Default: Story = {
|
||||||
|
render: (args) => <InteractiveDatePicker {...args} initialDate={undefined} />,
|
||||||
|
args: {
|
||||||
|
placeholder: 'Select a date'
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export const WithSelectedDate: Story = {
|
||||||
|
render: (args) => <InteractiveDatePicker {...args} initialDate={new Date()} />,
|
||||||
|
args: {
|
||||||
|
placeholder: 'Select a date'
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export const CustomDateFormat: Story = {
|
||||||
|
render: (args) => <InteractiveDatePicker {...args} initialDate={new Date()} />,
|
||||||
|
args: {
|
||||||
|
dateFormat: 'MMMM dd, yyyy',
|
||||||
|
placeholder: 'Select a date'
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export const Disabled: Story = {
|
||||||
|
render: (args) => <InteractiveDatePicker {...args} initialDate={new Date()} />,
|
||||||
|
args: {
|
||||||
|
disabled: true,
|
||||||
|
placeholder: 'Date selection disabled'
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export const WithDateRange: Story = {
|
||||||
|
render: (args) => <InteractiveDatePicker {...args} initialDate={undefined} />,
|
||||||
|
args: {
|
||||||
|
fromDate: new Date(new Date().setDate(new Date().getDate() - 30)),
|
||||||
|
toDate: new Date(new Date().setDate(new Date().getDate() + 30)),
|
||||||
|
placeholder: 'Select within 30 day range'
|
||||||
|
}
|
||||||
|
};
|
|
@ -12,18 +12,19 @@ import {
|
||||||
PopoverTrigger
|
PopoverTrigger
|
||||||
} from '@/components/ui/tooltip/PopoverBase';
|
} from '@/components/ui/tooltip/PopoverBase';
|
||||||
import { formatDate } from '@/lib';
|
import { formatDate } from '@/lib';
|
||||||
import { DayPickerProps } from 'react-day-picker';
|
|
||||||
|
|
||||||
export type DatePickerProps = CalendarProps & {
|
export type DatePickerProps = Omit<CalendarProps, 'selected'> & {
|
||||||
dateFormat?: string;
|
dateFormat?: string;
|
||||||
placeholder?: string;
|
placeholder?: string;
|
||||||
|
selected?: Date;
|
||||||
|
onSelect: (date: Date | undefined) => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
export function DatePicker({
|
export function DatePicker({
|
||||||
dateFormat = 'lll',
|
dateFormat = 'lll',
|
||||||
placeholder = 'Pick a date',
|
placeholder = 'Pick a date',
|
||||||
selected,
|
selected,
|
||||||
|
onSelect,
|
||||||
...props
|
...props
|
||||||
}: DatePickerProps) {
|
}: DatePickerProps) {
|
||||||
return (
|
return (
|
||||||
|
@ -47,7 +48,7 @@ export function DatePicker({
|
||||||
</Button>
|
</Button>
|
||||||
</PopoverTrigger>
|
</PopoverTrigger>
|
||||||
<PopoverContent className="w-auto p-0">
|
<PopoverContent className="w-auto p-0">
|
||||||
<Calendar {...props} />
|
<Calendar mode="single" selected={selected} onSelect={onSelect} initialFocus />
|
||||||
</PopoverContent>
|
</PopoverContent>
|
||||||
</Popover>
|
</Popover>
|
||||||
);
|
);
|
||||||
|
|
Loading…
Reference in New Issue