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');
|
||||
}, []);
|
||||
|
||||
const onSelect: SelectSingleEventHandler = useMemoizedFn((date) => {
|
||||
const onSelect = useMemoizedFn((date: Date | undefined) => {
|
||||
onChangeLinkExpiry(date || null);
|
||||
});
|
||||
|
||||
|
@ -219,7 +219,7 @@ const LinkExpiration: React.FC<{
|
|||
<Text truncate>Link expiration</Text>
|
||||
|
||||
<DatePicker
|
||||
selected={linkExpiry || new Date()}
|
||||
selected={linkExpiry || undefined}
|
||||
onSelect={onSelect}
|
||||
mode="single"
|
||||
dateFormat={dateFormat}
|
||||
|
|
|
@ -26,7 +26,7 @@ function Calendar({ className, classNames, showOutsideDays = true, ...props }: C
|
|||
nav_button_next: 'absolute right-1',
|
||||
table: 'w-full border-collapse space-y-1',
|
||||
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',
|
||||
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',
|
||||
|
@ -35,16 +35,16 @@ function Calendar({ className, classNames, showOutsideDays = true, ...props }: C
|
|||
: '[&:has([aria-selected])]:rounded-md'
|
||||
),
|
||||
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_end: 'day-range-end',
|
||||
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_outside:
|
||||
'day-outside text-muted-foreground aria-selected:bg-accent/50 aria-selected:text-muted-foreground',
|
||||
day_disabled: 'text-muted-foreground opacity-50 cursor-not-allowed!',
|
||||
'day-outside text-gray-light aria-selected:bg-accent/50 aria-selected:text-gray-light 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_hidden: 'invisible',
|
||||
...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
|
||||
} from '@/components/ui/tooltip/PopoverBase';
|
||||
import { formatDate } from '@/lib';
|
||||
import { DayPickerProps } from 'react-day-picker';
|
||||
|
||||
export type DatePickerProps = CalendarProps & {
|
||||
export type DatePickerProps = Omit<CalendarProps, 'selected'> & {
|
||||
dateFormat?: string;
|
||||
placeholder?: string;
|
||||
selected?: Date;
|
||||
onSelect: (date: Date | undefined) => void;
|
||||
};
|
||||
|
||||
export function DatePicker({
|
||||
dateFormat = 'lll',
|
||||
placeholder = 'Pick a date',
|
||||
selected,
|
||||
|
||||
onSelect,
|
||||
...props
|
||||
}: DatePickerProps) {
|
||||
return (
|
||||
|
@ -47,7 +48,7 @@ export function DatePicker({
|
|||
</Button>
|
||||
</PopoverTrigger>
|
||||
<PopoverContent className="w-auto p-0">
|
||||
<Calendar {...props} />
|
||||
<Calendar mode="single" selected={selected} onSelect={onSelect} initialFocus />
|
||||
</PopoverContent>
|
||||
</Popover>
|
||||
);
|
||||
|
|
Loading…
Reference in New Issue