mirror of
https://github.com/nextui-org/nextui.git
synced 2025-12-08 19:26:11 +00:00
* refactor(input): input ref test (#2613) * refactor(input): remove duplicate test * refactor(input): remove unncessary waitFor * fix(radio): isRequired & missing warning message in Form (#2597) * fix(radio): avoid overriding required props * fix(radio): merge with domRef * feat(changeset): fixed missing required props and validationMessage * fix(radio): unnecessary mergeRefs * Calendar component 📅 (#2456) * feat(calendar): initial structure * feat(calendar): calendar structure completed, styles in progress * chore(calendar): dark colors adjusted * feat(calendar): styles improved, variants added, animations added with framer motion * chore(calendar): animation changed, shadow improved * chore(calendar): disableAnimation support added as well as weekDays format * feat(calendar): more stories added * chore(calendar): refactor calendar cell styling * feat(calendar): create calendar function added to the root provider * feat(calendar): invalid state and error message added * feat(calendar): calendar picker added, provider modified * feat(root): object.values deps replaced by new func, intersection hoook added, types version unified * feat(calendar): calendar pickers in progress * feat(calendar): calendar pickers added * fix(calendar): year label formatting * chore(calendar): add layout parameter to Calendar stories * feat(calendar): pickers completed, context added * feat(calendar): visibleMonths supported, warnings fixed, tests added * chore(root): changeset * chore(calendar): add topContent and bottomContent props to calendar * feat(calendar): add @nextui-org/radio package and update calendar component * refactor: assigned type(DateValue) to focusedDate(ControlledFocusedVaue) (#2637) Co-authored-by: shrinidhi.upadhyaya <shrinidhi.upadhyaya@stud.uni-bamberg.de> * Range Calendar 📆 (#2634) * feat(calendar): range calendar added, calendar and context adapted * feat(calendar): range calendar stories added * chore(calendar): range calendar tests added * fix(calendar): update calendar styles to adjust to dynamic width * Date Input 🗓️ (#2641) * feat(date-picker): date field component initialized * chore(date-picker): date field renamed to date-input * feat(date-picker): date input completed * chore(date-input): commented code removed * feat(avatar): support slots in AvatarGroup (#2669) * feat: rename newPost to new (#2665) * fix(avatar): spread getAvatarGroupCountProps in avatar count * feat(avatar): support slots in avatarGroup * feat(avatar): support classNames and add getAvatarGroupCountProps * feat(docs): add classNames to avatar group * feat(avatar): add CustomSlots in avatar group * feat(changeset): support slots in avatar group --------- Co-authored-by: winches <96854855+winchesHe@users.noreply.github.com> * Date Picker Component 🗓️ (#2652) * feat(date-picker): first iteration * chore(date-picker): update date-picker README.md with improved description * feat(date-picker): code organized, integration done * fix(date-picker): min and max value + styles * fix(date-picker): popover offset adn calendar styles * feat(date-picker): stories added * fix(date-picker): calendar width properly handled * feat(date-picker): styles simplified * chore(date-picker): almost all test passing * fix(date-picker): test and styles * chore(date-picker): calendar popover tests added * fix(date-picker): props to be passed to the date-input * TimeInput Component 🕒 (#2672) * feat(time-input): time input added with some stories, tests and date-picker integration missing * feat(time-input): tests added, date-picker integration added, missing stories added * chore(react): missing packages added * chore(time-input): fix stories names * fix(time-input): time value type * fix: date-picker visibleMonth width does not get widen enough (#2703) * DateRangePicker Component 🗓️ (#2682) * chore(date-range-picker): in progress * chore(date-range-picker): in progress * feat(date-input): components separated into multiple pieces to be able to implement the date range picker * feat(date-range-picker): first version of it working * chore(date-picker): hyphen symbol changed * feat(date-range-picker): stories done * fix(range-calendar): styles * docs: Calendar & RangeCalendar (#2686) * feat(docs): add calendar in routes.json * feat(docs): refresh search-meta.json * feat(docs): add calendar examples * feat(docs): calendar content * feat(deps): add @internationalized/date * refactor(docs): remove div wrapper * feat(docs): add calendar doc * fix(docs): calendar presets * fix(docs): preset styles * chore(docs): remove calendar iframe examples * refactor(docs): discard iframe in calendar doc * fix(docs): incorrect DateValue import * feat(docs): include @internationalized/date in live demo scope * feat(docs): add presets description * chore(docs): update search-meta.json * fix(docs): remove DateValue * feat(docs): include reactAriaI18n in react live demo scope * fix(docs): presets import issue * chore(docs): update search-meta.json * feat(docs): add api reference for nextui provider * fix(calendar): ixExpanded typo * feat(docs): add missing props & event * chore(docs): update search-meta.json * chore(docs): update route keywords * chore(docs): revise value style add defaultFocusedValue * chore(docs): remove padding and revise gap * feat(docs): range calendar * chore(docs): update search-meta.json * feat(docs): add reactAriaHook * fix(docs): incorrect component and add storybook and reactAriaHook * fix(docs): incorrect import path * chore(docs): reorder range calendar position in sidebar * chore(Docs): remove custom styles & implementation * chore(docs): remove last item from accessibility * chore(docs): onValueChange -> onChange * feat(docs): add ts example for range calendar * chore(docs): remove unwanted content in range calendar * feat(docs): add ts examples for calendar * chore(docs): update import path * chore(docs): update import path * chore(docs): styles adjusted, routes updated --------- Co-authored-by: Junior Garcia <jrgarciadev@gmail.com> * docs: TimeInput (#2698) * feat(docs): add time input to routes.json * feat(deps): add @internationalized/date * feat(docs): add @internationalized/date and @react-aria/i18n to code demo scopes * feat(docs): time input contetnt * chore(docs): revise time input examples * feat(docs): time input content * chore(time-input): update description * feat(docs): add ts examples in time-input * chore(docs): revise TimeValue import --------- Co-authored-by: Junior Garcia <jrgarciadev@gmail.com> * chore(date-picker): exports updated * docs: DatePicker (#2700) * docs: created the doc for datepicker and its examples * docs: regenerate search-meta.json * fix: reverted the unncessary change to Input component * fix: fixed the component-link for date-picker * fix: fixed the component-link for date-picker * fix: added variants section to the doc * fix: made adjustment to the explanations for the props of DatePicker comp --------- Co-authored-by: Junior Garcia <jrgarciadev@gmail.com> * doc: DateInput (#2711) * docs: created base examples and the document * chore: created search-meta and follow-up fix for each date-input example cases * fix: fixed some example components styles * fix(docs): updated routes.json * fix(docs): fixed typo in the docs * fix: fixed the component-link for date-input * fix: fixed the component-link for date-input * fix: label-placements example flex style adjustment * fix: added variants section to the doc --------- Co-authored-by: HaRuki Kuriwada <haruki.kuriwada@hennge.com> Co-authored-by: Junior Garcia <jrgarciadev@gmail.com> * refactor(theme): units removed, tailwind-variants upgraded (#2713) * fix(theme): units replaced by spacing * fix(select): positioning the label if a description is used (#2553) Co-authored-by: Poli Sour <polisour.work@gmail.com> * Upgrade to new react aria version (#2561) * chore(root): pkg upgraded * fix: type error * fix: build error * chore: update packages from a~d * chore: update packages from i~r * chore: update packages from s~u * chore: update core, hooks, and utilities packages * feat: add support radio group validationBehavior props * fix: validationBehavior default to native * chore: add validationBehavior props in RadioGroup Stories * fix: handling of errorMessage * chore: add support validationBehavior autocomplete * chore: partial support for validation of select * chore: add support validationBehavior checkbox * chore: change validationBehavior default to native * Merge branch 'v.2.3.0' into feat/upgrade-react-aria * fix: validation logic * fix: add default value for autocomplete * chore: add example using error message function * chore: fixed error displayed in storybook * chore: omit validationBehavior from component props * chore: update docs and storybook on validate * fix: pnpm-lock version --------- Co-authored-by: Junior Garcia <jrgarciadev@gmail.com> * fix(core): build and date input / time input apis * chore(date-picker): omit validation behavior * chore(docs): add missing props to calendar and range calendar * docs: add nextui-cli page (#2714) * docs: add nextui-cli page * docs: update search meta * docs: typo * docs: typo * docs: typo * feat(docs): cli docs done --------- Co-authored-by: Junior Garcia <jrgarciadev@gmail.com> * chore(docs): add cli commands to installation docs * fix(checkbox): prettier * fix(docs): incorrect cli api references link * doc: DateRangePicker (#2712) * chore: created base for date-range-picker doc * fix: added follow-up story examples to the doc * fix: fixed bugs happening on the doc * fix: fixed bugs happening on the doc * fix(docs): incorrect file path and revise title * fix: component examples style fixes * fix: component presets typo fix * refactor(core): date range picker docs completed, standaline date picker field fixed --------- Co-authored-by: HaRuki Kuriwada <haruki.kuriwada@hennge.com> Co-authored-by: աɨռɢӄաօռɢ <wingkwong.code@gmail.com> Co-authored-by: Junior Garcia <jrgarciadev@gmail.com> * fix: only two keyframes currently supported with spring and inertia animations (#2596) * chore(deps): bump framer-motion * feat(changeset): fixed framer motion issue * chore(changeset): revise changeset message * chore(deps): update pnpm-lock.yaml * fix: react hook form issue (#2603) * fix(input): pass domRef?.current?.value to controlled state * fix(input): pass domRef?.current?.value to useTextField instead * fix(checkbox): handle RHF case * fix(checkbox): add missing isSelected case * chore(checkbox): update ref type * chore(deps): add @nextui-org/use-safe-layout-effect * chore(deps): update pnpm-lock.yaml * chore(deps): update pnpm-lock.yaml * fix(select): handle RHF case * chore(deps): add @nextui-org/use-safe-layout-effect to select * fix(autocomplete): handle RHF case * chore(deps): add @nextui-org/use-safe-layout-effect to autocomplete * refactor(components): revise comments * feat(changeset): react-hook-form uncontrolled components * chore(deps): pnpm-lock.yaml * fix(input): domRef.current.value has higher precedence * fix(checkbox): set isChecked based on input ref checked * feat(components): tabs component add tabPosition prop (#2398) * feat(components): tabs component add tabPosition prop * fix: review problem change * test: add tabs position vertical test * docs: update changeset * fix(tabs): optimize return of tabs * fix(tabs): rename orientation to placement * fix(tabs): optimize description * chore(docs): routes * fix: isReadOnly in Autocomplete MDX (#2444) * feat(autocomplete): add isReadOnly example * fix(autocomplete): isReadOnly logic in Autocomplete * feat(root): add changeset - fixed isReadOnly logic in Autocomplete * chore(autocomplete component) isReadOnly property demo isReadOnly property demo in website MDX for autocomplete component. * Update apps/docs/content/docs/components/autocomplete.mdx Co-authored-by: Junior Garcia <jrgarciadev@gmail.com> --------- Co-authored-by: աɨռɢӄաօռɢ <wingkwong.code@gmail.com> Co-authored-by: Alpha <116849110+alpha-xek@users.noreply.github.com> Co-authored-by: Junior Garcia <jrgarciadev@gmail.com> * fix(select): only trigger setSelectedKeys when domRef.current.value is true (#2722) * chore(docs): blog changes (#2724) * chore(docs): blog changes * feat(docs): blog improved * chore(blog): draft param added * chore: version changeset added * feat(blog): v2.3.0 almost done * chore(docs): tailwind colors updated, calendar overflow fixed * chore(blog): add presets demo * fix(calendar): overflow on windows * chore(docs): improve popover placements demo * fix(autocomplete): set shouldUseVirtualFocus to false in getListboxProps (#2731) * chore(blog): add cotributors * chore(blog): draft --------- Co-authored-by: աӄա <wingkwong.code@gmail.com> Co-authored-by: Shrinidhi Upadhyaya <shrinidhiupadhyaya1195@gmail.com> Co-authored-by: shrinidhi.upadhyaya <shrinidhi.upadhyaya@stud.uni-bamberg.de> Co-authored-by: winches <96854855+winchesHe@users.noreply.github.com> Co-authored-by: HaRuki <soccer_haruki15@me.com> Co-authored-by: HaRuki Kuriwada <haruki.kuriwada@hennge.com> Co-authored-by: Poli Sour <57824881+novsource@users.noreply.github.com> Co-authored-by: Poli Sour <polisour.work@gmail.com> Co-authored-by: Ryo Matsukawa <76232929+ryo-manba@users.noreply.github.com> Co-authored-by: winches <329487092@qq.com> Co-authored-by: Alpha Xek <116849110+alphaxek@users.noreply.github.com> Co-authored-by: Alpha <116849110+alpha-xek@users.noreply.github.com>
581 lines
14 KiB
TypeScript
581 lines
14 KiB
TypeScript
import React from "react";
|
|
import {Meta} from "@storybook/react";
|
|
import {dateInput} from "@nextui-org/theme";
|
|
import {
|
|
endOfMonth,
|
|
endOfWeek,
|
|
getLocalTimeZone,
|
|
isWeekend,
|
|
parseAbsoluteToLocal,
|
|
parseDate,
|
|
parseZonedDateTime,
|
|
startOfMonth,
|
|
startOfWeek,
|
|
today,
|
|
} from "@internationalized/date";
|
|
import {RangeValue} from "@react-types/shared";
|
|
import {DateValue} from "@react-types/datepicker";
|
|
import {I18nProvider, useDateFormatter, useLocale} from "@react-aria/i18n";
|
|
import {Button, ButtonGroup} from "@nextui-org/button";
|
|
import {Radio, RadioGroup} from "@nextui-org/radio";
|
|
import {cn} from "@nextui-org/system";
|
|
|
|
import {DateRangePicker, DateRangePickerProps} from "../src";
|
|
|
|
export default {
|
|
title: "Components/DateRangePicker",
|
|
component: DateRangePicker,
|
|
argTypes: {
|
|
variant: {
|
|
control: {
|
|
type: "select",
|
|
},
|
|
options: ["flat", "faded", "bordered", "underlined"],
|
|
},
|
|
color: {
|
|
control: {
|
|
type: "select",
|
|
},
|
|
options: ["default", "primary", "secondary", "success", "warning", "danger"],
|
|
},
|
|
radius: {
|
|
control: {
|
|
type: "select",
|
|
},
|
|
options: ["none", "sm", "md", "lg", "full"],
|
|
},
|
|
size: {
|
|
control: {
|
|
type: "select",
|
|
},
|
|
options: ["sm", "md", "lg"],
|
|
},
|
|
labelPlacement: {
|
|
control: {
|
|
type: "select",
|
|
},
|
|
options: ["inside", "outside", "outside-left"],
|
|
},
|
|
isDisabled: {
|
|
control: {
|
|
type: "boolean",
|
|
},
|
|
},
|
|
},
|
|
decorators: [
|
|
(Story) => (
|
|
<div className="flex items-center justify-start">
|
|
<Story />
|
|
</div>
|
|
),
|
|
],
|
|
} as Meta<typeof DateRangePicker>;
|
|
|
|
const defaultProps = {
|
|
label: "Stay duration",
|
|
...dateInput.defaultVariants,
|
|
};
|
|
|
|
const Template = (args: DateRangePickerProps) => <DateRangePicker {...args} />;
|
|
|
|
const LabelPlacementTemplate = (args: DateRangePickerProps) => (
|
|
<div className="w-full max-w-xl flex flex-col items-start gap-4">
|
|
<DateRangePicker {...args} description="inside" />
|
|
<DateRangePicker {...args} description="outside" labelPlacement="outside" />
|
|
<DateRangePicker {...args} description="outside-left" labelPlacement="outside-left" />
|
|
</div>
|
|
);
|
|
|
|
const ControlledTemplate = (args: DateRangePickerProps) => {
|
|
const [value, setValue] = React.useState<RangeValue<DateValue>>({
|
|
start: parseDate("2024-04-01"),
|
|
end: parseDate("2024-04-08"),
|
|
});
|
|
|
|
let formatter = useDateFormatter({dateStyle: "long"});
|
|
|
|
return (
|
|
<div className="flex flex-row gap-2">
|
|
<div className="w-full flex flex-col gap-y-2">
|
|
<DateRangePicker
|
|
{...args}
|
|
label="Date range (controlled)"
|
|
value={value}
|
|
onChange={setValue}
|
|
/>
|
|
<p className="text-default-500 text-sm">
|
|
Selected date:{" "}
|
|
{value
|
|
? formatter.formatRange(
|
|
value.start.toDate(getLocalTimeZone()),
|
|
value.end.toDate(getLocalTimeZone()),
|
|
)
|
|
: "--"}
|
|
</p>
|
|
</div>
|
|
<DateRangePicker
|
|
{...args}
|
|
defaultValue={{
|
|
start: parseDate("2024-04-01"),
|
|
end: parseDate("2024-04-08"),
|
|
}}
|
|
label="Date range (uncontrolled)"
|
|
/>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
const TimeZonesTemplate = (args: DateRangePickerProps) => (
|
|
<div className="w-full max-w-xl flex flex-col items-start gap-4">
|
|
<DateRangePicker
|
|
{...args}
|
|
className="max-w-xs"
|
|
defaultValue={{
|
|
start: parseZonedDateTime("2024-04-01T00:45[America/Los_Angeles]"),
|
|
end: parseZonedDateTime("2024-04-14T11:15[America/Los_Angeles]"),
|
|
}}
|
|
labelPlacement="outside"
|
|
/>
|
|
<DateRangePicker
|
|
// {...args}
|
|
className="max-w-xs"
|
|
defaultValue={{
|
|
start: parseAbsoluteToLocal("2024-04-01T07:45:00Z"),
|
|
end: parseAbsoluteToLocal("2024-04-14T19:15:00Z"),
|
|
}}
|
|
labelPlacement="outside"
|
|
/>
|
|
</div>
|
|
);
|
|
|
|
const GranularityTemplate = (args: DateRangePickerProps) => {
|
|
let [date, setDate] = React.useState<RangeValue<DateValue>>({
|
|
start: parseAbsoluteToLocal("2024-04-01T18:45:22Z"),
|
|
end: parseAbsoluteToLocal("2024-04-08T19:15:22Z"),
|
|
});
|
|
|
|
return (
|
|
<div className="w-full max-w-xl flex flex-col items-start gap-4">
|
|
<DateRangePicker
|
|
{...args}
|
|
fullWidth
|
|
granularity="second"
|
|
label="Date and time range"
|
|
value={date}
|
|
onChange={setDate}
|
|
/>
|
|
<DateRangePicker
|
|
{...args}
|
|
fullWidth
|
|
granularity="day"
|
|
label="Date range"
|
|
value={date}
|
|
onChange={setDate}
|
|
/>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
const InternationalCalendarsTemplate = (args: DateRangePickerProps) => {
|
|
let [date, setDate] = React.useState<RangeValue<DateValue>>({
|
|
start: parseAbsoluteToLocal("2021-04-01T18:45:22Z"),
|
|
end: parseAbsoluteToLocal("2021-04-14T19:15:22Z"),
|
|
});
|
|
|
|
return (
|
|
<div className="flex flex-col gap-4">
|
|
<I18nProvider locale="hi-IN-u-ca-indian">
|
|
<DateRangePicker {...args} label="Appointment date" value={date} onChange={setDate} />
|
|
</I18nProvider>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
const UnavailableDatesTemplate = (args: DateRangePickerProps) => {
|
|
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})],
|
|
];
|
|
|
|
return (
|
|
<DateRangePicker
|
|
aria-label="Appointment date"
|
|
isDateUnavailable={(date) =>
|
|
disabledRanges.some(
|
|
(interval) => date.compare(interval[0]) >= 0 && date.compare(interval[1]) <= 0,
|
|
)
|
|
}
|
|
minValue={today(getLocalTimeZone())}
|
|
validate={(value) =>
|
|
disabledRanges.some(
|
|
(interval) =>
|
|
value && value.end.compare(interval[0]) >= 0 && value.start.compare(interval[1]) <= 0,
|
|
)
|
|
? "Selected date range may not include unavailable dates."
|
|
: null
|
|
}
|
|
{...args}
|
|
/>
|
|
);
|
|
};
|
|
|
|
const NonContiguousRangesTemplate = (args: DateRangePickerProps) => {
|
|
let {locale} = useLocale();
|
|
|
|
return (
|
|
<DateRangePicker
|
|
{...args}
|
|
allowsNonContiguousRanges
|
|
isDateUnavailable={(date) => isWeekend(date, locale)}
|
|
label="Time off request"
|
|
minValue={today(getLocalTimeZone())}
|
|
visibleMonths={2}
|
|
/>
|
|
);
|
|
};
|
|
|
|
const PresetsTemplate = (args: DateRangePickerProps) => {
|
|
let defaultDate = {
|
|
start: today(getLocalTimeZone()),
|
|
end: today(getLocalTimeZone()).add({days: 7}),
|
|
};
|
|
|
|
const [value, setValue] = React.useState<RangeValue<DateValue>>(defaultDate);
|
|
|
|
let {locale} = useLocale();
|
|
let formatter = useDateFormatter({dateStyle: "full"});
|
|
|
|
let now = today(getLocalTimeZone());
|
|
let nextWeek = {
|
|
start: startOfWeek(now.add({weeks: 1}), locale),
|
|
end: endOfWeek(now.add({weeks: 1}), locale),
|
|
};
|
|
let nextMonth = {
|
|
start: startOfMonth(now.add({months: 1})),
|
|
end: endOfMonth(now.add({months: 1})),
|
|
};
|
|
|
|
const CustomRadio = (props) => {
|
|
const {children, ...otherProps} = props;
|
|
|
|
return (
|
|
<Radio
|
|
{...otherProps}
|
|
classNames={{
|
|
base: cn(
|
|
"flex-none m-0 h-8 bg-content1 hover:bg-content2 items-center justify-between",
|
|
"cursor-pointer rounded-full border-2 border-default-200/60",
|
|
"data-[selected=true]:border-primary",
|
|
),
|
|
label: "text-tiny text-default-500",
|
|
labelWrapper: "px-1 m-0",
|
|
wrapper: "hidden",
|
|
}}
|
|
>
|
|
{children}
|
|
</Radio>
|
|
);
|
|
};
|
|
|
|
return (
|
|
<div className="flex flex-col gap-4 w-full max-w-sm">
|
|
<DateRangePicker
|
|
CalendarBottomContent={
|
|
<RadioGroup
|
|
aria-label="Date precision"
|
|
classNames={{
|
|
base: "w-full pb-2",
|
|
wrapper:
|
|
"-my-2.5 py-2.5 px-3 gap-1 flex-nowrap max-w-[w-[calc(var(--visible-months)_*_var(--calendar-width))]] overflow-scroll",
|
|
}}
|
|
defaultValue="exact_dates"
|
|
orientation="horizontal"
|
|
>
|
|
<CustomRadio value="exact_dates">Exact dates</CustomRadio>
|
|
<CustomRadio value="1_day">1 day</CustomRadio>
|
|
<CustomRadio value="2_days">2 days</CustomRadio>
|
|
<CustomRadio value="3_days">3 days</CustomRadio>
|
|
<CustomRadio value="7_days">7 days</CustomRadio>
|
|
<CustomRadio value="14_days">14 days</CustomRadio>
|
|
</RadioGroup>
|
|
}
|
|
CalendarTopContent={
|
|
<ButtonGroup
|
|
fullWidth
|
|
className="px-3 pb-2 pt-3 bg-content1 [&>button]:text-default-500 [&>button]:border-default-200/60"
|
|
radius="full"
|
|
size="sm"
|
|
variant="bordered"
|
|
>
|
|
<Button
|
|
onPress={() =>
|
|
setValue({
|
|
start: now,
|
|
end: now.add({days: 7}),
|
|
})
|
|
}
|
|
>
|
|
This week
|
|
</Button>
|
|
<Button onPress={() => setValue(nextWeek)}>Next week</Button>
|
|
<Button onPress={() => setValue(nextMonth)}>Next month</Button>
|
|
</ButtonGroup>
|
|
}
|
|
calendarProps={{
|
|
focusedValue: value.start,
|
|
onFocusChange: (val) => setValue({...value, start: val}),
|
|
nextButtonProps: {
|
|
variant: "bordered",
|
|
},
|
|
prevButtonProps: {
|
|
variant: "bordered",
|
|
},
|
|
}}
|
|
value={value}
|
|
onChange={setValue}
|
|
{...args}
|
|
label="Event date"
|
|
/>
|
|
<p className="text-default-500 text-sm">
|
|
Selected date:{" "}
|
|
{value
|
|
? formatter.formatRange(
|
|
value.start.toDate(getLocalTimeZone()),
|
|
value.end.toDate(getLocalTimeZone()),
|
|
)
|
|
: "--"}
|
|
</p>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export const Default = {
|
|
render: Template,
|
|
args: {
|
|
...defaultProps,
|
|
},
|
|
};
|
|
|
|
export const VisibleMonths = {
|
|
render: Template,
|
|
args: {
|
|
...defaultProps,
|
|
visibleMonths: 2,
|
|
},
|
|
};
|
|
|
|
export const LabelPlacement = {
|
|
render: LabelPlacementTemplate,
|
|
|
|
args: {
|
|
...defaultProps,
|
|
},
|
|
};
|
|
|
|
export const WithTimeField = {
|
|
render: Template,
|
|
args: {
|
|
...defaultProps,
|
|
label: "Event duration",
|
|
hideTimeZone: true,
|
|
visibleMonths: 2,
|
|
defaultValue: {
|
|
start: parseZonedDateTime("2024-04-01T00:45[America/Los_Angeles]"),
|
|
end: parseZonedDateTime("2024-04-08T11:15[America/Los_Angeles]"),
|
|
},
|
|
},
|
|
};
|
|
|
|
export const Controlled = {
|
|
render: ControlledTemplate,
|
|
args: {
|
|
...defaultProps,
|
|
},
|
|
};
|
|
|
|
export const Required = {
|
|
render: Template,
|
|
args: {
|
|
...defaultProps,
|
|
isRequired: true,
|
|
},
|
|
};
|
|
|
|
export const Disabled = {
|
|
render: Template,
|
|
args: {
|
|
...defaultProps,
|
|
isDisabled: true,
|
|
defaultValue: {
|
|
start: parseDate("2024-04-01"),
|
|
end: parseDate("2024-04-08"),
|
|
},
|
|
},
|
|
};
|
|
|
|
export const ReadOnly = {
|
|
render: Template,
|
|
args: {
|
|
...defaultProps,
|
|
isReadOnly: true,
|
|
defaultValue: {
|
|
start: parseDate("2024-04-01"),
|
|
end: parseDate("2024-04-08"),
|
|
},
|
|
},
|
|
};
|
|
|
|
export const WithoutLabel = {
|
|
render: Template,
|
|
|
|
args: {
|
|
...defaultProps,
|
|
label: null,
|
|
"aria-label": "Stay duration",
|
|
},
|
|
};
|
|
|
|
export const WithDescription = {
|
|
render: Template,
|
|
|
|
args: {
|
|
...defaultProps,
|
|
description: "Please enter your stay duration",
|
|
},
|
|
};
|
|
|
|
export const SelectorIcon = {
|
|
render: Template,
|
|
|
|
args: {
|
|
...defaultProps,
|
|
selectorIcon: (
|
|
<svg height="1em" viewBox="0 0 24 24" width="1em">
|
|
<g
|
|
fill="none"
|
|
stroke="currentColor"
|
|
strokeLinecap="round"
|
|
strokeLinejoin="round"
|
|
strokeWidth="2"
|
|
>
|
|
<path d="M8 2v4m8-4v4" />
|
|
<rect height="18" rx="2" width="18" x="3" y="4" />
|
|
<path d="M3 10h18M8 14h.01M12 14h.01M16 14h.01M8 18h.01M12 18h.01M16 18h.01" />
|
|
</g>
|
|
</svg>
|
|
),
|
|
},
|
|
};
|
|
|
|
export const WithErrorMessage = {
|
|
render: Template,
|
|
|
|
args: {
|
|
...defaultProps,
|
|
errorMessage: "Please enter your stay duration",
|
|
},
|
|
};
|
|
|
|
export const IsInvalid = {
|
|
render: Template,
|
|
|
|
args: {
|
|
...defaultProps,
|
|
variant: "bordered",
|
|
isInvalid: true,
|
|
defaultValue: {
|
|
start: parseDate("2024-04-01"),
|
|
end: parseDate("2024-04-08"),
|
|
},
|
|
errorMessage: "Please enter a valid date",
|
|
},
|
|
};
|
|
|
|
export const TimeZones = {
|
|
render: TimeZonesTemplate,
|
|
|
|
args: {
|
|
...defaultProps,
|
|
label: "Event date",
|
|
defaultValue: parseZonedDateTime("2022-11-07T00:45[America/Los_Angeles]"),
|
|
},
|
|
};
|
|
|
|
export const Granularity = {
|
|
render: GranularityTemplate,
|
|
|
|
args: {
|
|
...defaultProps,
|
|
visibleMonths: 2,
|
|
},
|
|
};
|
|
|
|
export const InternationalCalendars = {
|
|
render: InternationalCalendarsTemplate,
|
|
|
|
args: {
|
|
...defaultProps,
|
|
hideTimeZone: true,
|
|
},
|
|
};
|
|
|
|
export const MinDateValue = {
|
|
render: Template,
|
|
|
|
args: {
|
|
...defaultProps,
|
|
minValue: today(getLocalTimeZone()),
|
|
defaultValue: {
|
|
start: today(getLocalTimeZone()).subtract({days: 1}),
|
|
end: parseDate("2024-04-08"),
|
|
},
|
|
},
|
|
};
|
|
|
|
export const MaxDateValue = {
|
|
render: Template,
|
|
|
|
args: {
|
|
...defaultProps,
|
|
maxValue: today(getLocalTimeZone()),
|
|
defaultValue: {
|
|
start: parseDate("2024-04-01"),
|
|
end: today(getLocalTimeZone()).add({days: 1}),
|
|
},
|
|
},
|
|
};
|
|
|
|
export const UnavailableDates = {
|
|
render: UnavailableDatesTemplate,
|
|
args: {
|
|
...defaultProps,
|
|
},
|
|
};
|
|
|
|
export const PageBehavior = {
|
|
render: Template,
|
|
args: {
|
|
...defaultProps,
|
|
visibleMonths: 2,
|
|
pageBehavior: "single",
|
|
},
|
|
};
|
|
|
|
export const NonContiguous = {
|
|
render: NonContiguousRangesTemplate,
|
|
args: {
|
|
...defaultProps,
|
|
},
|
|
};
|
|
|
|
export const Presets = {
|
|
render: PresetsTemplate,
|
|
args: {
|
|
...defaultProps,
|
|
visibleMonths: 2,
|
|
},
|
|
};
|