@windmorph/react 0.2.2 → 0.2.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (134) hide show
  1. package/dist/components/autocomplete/Autocomplete.d.ts +4 -1
  2. package/dist/components/autocomplete/Autocomplete.js +3 -5
  3. package/dist/components/autocomplete/Autocomplete.js.map +1 -1
  4. package/dist/components/badge/Badge.d.ts +5 -2
  5. package/dist/components/badge/Badge.js +7 -3
  6. package/dist/components/badge/Badge.js.map +1 -1
  7. package/dist/components/button/Button.d.ts +4 -2
  8. package/dist/components/button/Button.js.map +1 -1
  9. package/dist/components/button/ButtonContext.d.ts +1 -1
  10. package/dist/components/button/button-pending.js +2 -4
  11. package/dist/components/button/button-pending.js.map +1 -1
  12. package/dist/{composites → components}/button-group/ButtonGroup.d.ts +4 -4
  13. package/dist/{composites → components}/button-group/ButtonGroup.js +9 -7
  14. package/dist/components/button-group/ButtonGroup.js.map +1 -0
  15. package/dist/{composites → components}/button-group/button-group-styles.d.ts +1 -1
  16. package/dist/{composites → components}/button-group/button-group-styles.js +1 -1
  17. package/dist/{composites → components}/button-group/button-group-styles.js.map +1 -1
  18. package/dist/{composites → components}/button-group/lazy-overflow-menu.js +2 -2
  19. package/dist/components/button-group/lazy-overflow-menu.js.map +1 -0
  20. package/dist/{composites → components}/button-group/overflow-menu-list.js +2 -2
  21. package/dist/components/button-group/overflow-menu-list.js.map +1 -0
  22. package/dist/{composites → components}/button-group/use-overflow.js +1 -1
  23. package/dist/{composites → components}/button-group/use-overflow.js.map +1 -1
  24. package/dist/{composites → components}/button-group/use-press-expansion.js +1 -1
  25. package/dist/{composites → components}/button-group/use-press-expansion.js.map +1 -1
  26. package/dist/components/carousel/Carousel.d.ts +4 -1
  27. package/dist/components/carousel/Carousel.js +2 -4
  28. package/dist/components/carousel/Carousel.js.map +1 -1
  29. package/dist/components/checkbox/checkbox-styles.d.ts +3 -3
  30. package/dist/components/chip/Chip.d.ts +8 -2
  31. package/dist/components/chip/Chip.js +3 -8
  32. package/dist/components/chip/Chip.js.map +1 -1
  33. package/dist/components/chip/chip-tokens.d.ts +4 -4
  34. package/dist/components/date-picker/DateField.d.ts +4 -1
  35. package/dist/components/date-picker/DateField.js +3 -1
  36. package/dist/components/date-picker/DateField.js.map +1 -1
  37. package/dist/components/date-picker/DatePicker.d.ts +4 -1
  38. package/dist/components/date-picker/DatePicker.js +5 -2
  39. package/dist/components/date-picker/DatePicker.js.map +1 -1
  40. package/dist/components/date-picker/PickerDialog.d.ts +4 -1
  41. package/dist/components/date-picker/PickerDialog.js +3 -1
  42. package/dist/components/date-picker/PickerDialog.js.map +1 -1
  43. package/dist/components/date-picker/date-picker-styles.d.ts +12 -12
  44. package/dist/components/date-picker/date-picker-tokens.d.ts +1 -1
  45. package/dist/components/dialog/Dialog.d.ts +5 -2
  46. package/dist/components/dialog/Dialog.js +4 -2
  47. package/dist/components/dialog/Dialog.js.map +1 -1
  48. package/dist/components/dialog/dialog-tokens.d.ts +1 -1
  49. package/dist/components/fab-menu/FabMenu.js +2 -2
  50. package/dist/components/fab-menu/FabMenu.js.map +1 -1
  51. package/dist/components/icon-button/IconButton.d.ts +4 -2
  52. package/dist/components/icon-button/IconButton.js.map +1 -1
  53. package/dist/components/labels/LabelsProvider.d.ts +35 -0
  54. package/dist/components/labels/LabelsProvider.js +47 -0
  55. package/dist/components/labels/LabelsProvider.js.map +1 -0
  56. package/dist/components/labels/use-labels.d.ts +16 -0
  57. package/dist/components/labels/use-labels.js +42 -0
  58. package/dist/components/labels/use-labels.js.map +1 -0
  59. package/dist/components/menu/Menu.d.ts +17 -1
  60. package/dist/components/menu/Menu.js +21 -11
  61. package/dist/components/menu/Menu.js.map +1 -1
  62. package/dist/components/menu/menu-styles.js +12 -12
  63. package/dist/components/menu/menu-styles.js.map +1 -1
  64. package/dist/components/menu/menu-tokens.d.ts +1 -1
  65. package/dist/components/menu/menu-tokens.js.map +1 -1
  66. package/dist/components/navigation/NavItem.d.ts +1 -1
  67. package/dist/components/navigation/NavItem.js +9 -6
  68. package/dist/components/navigation/NavItem.js.map +1 -1
  69. package/dist/components/navigation/navigation-styles.js +1 -1
  70. package/dist/components/navigation/navigation-styles.js.map +1 -1
  71. package/dist/components/pull-to-refresh/PullToRefresh.d.ts +1 -1
  72. package/dist/components/pull-to-refresh/PullToRefresh.js +2 -4
  73. package/dist/components/pull-to-refresh/PullToRefresh.js.map +1 -1
  74. package/dist/components/search/SearchField.d.ts +4 -1
  75. package/dist/components/search/SearchField.js +2 -4
  76. package/dist/components/search/SearchField.js.map +1 -1
  77. package/dist/components/search/search-styles.js +2 -2
  78. package/dist/components/search/search-styles.js.map +1 -1
  79. package/dist/components/select/Select.d.ts +4 -1
  80. package/dist/components/select/Select.js +2 -4
  81. package/dist/components/select/Select.js.map +1 -1
  82. package/dist/components/sheet/BottomSheet.d.ts +4 -1
  83. package/dist/components/sheet/BottomSheet.js +2 -4
  84. package/dist/components/sheet/BottomSheet.js.map +1 -1
  85. package/dist/components/sheet/SideSheet.d.ts +4 -1
  86. package/dist/components/sheet/SideSheet.js +2 -4
  87. package/dist/components/sheet/SideSheet.js.map +1 -1
  88. package/dist/components/slider/Slider.d.ts +4 -1
  89. package/dist/components/slider/Slider.js +7 -5
  90. package/dist/components/slider/Slider.js.map +1 -1
  91. package/dist/components/snackbar/Snackbar.d.ts +8 -2
  92. package/dist/components/snackbar/Snackbar.js +2 -4
  93. package/dist/components/snackbar/Snackbar.js.map +1 -1
  94. package/dist/components/snackbar/snackbar-tokens.d.ts +1 -1
  95. package/dist/components/split-button/SplitButton.d.ts +4 -1
  96. package/dist/components/split-button/SplitButton.js +4 -2
  97. package/dist/components/split-button/SplitButton.js.map +1 -1
  98. package/dist/components/switch/switch-styles.d.ts +3 -3
  99. package/dist/components/text-field/TextField.d.ts +4 -1
  100. package/dist/components/text-field/TextField.js +2 -4
  101. package/dist/components/text-field/TextField.js.map +1 -1
  102. package/dist/components/text-field/text-field-styles.js +2 -2
  103. package/dist/components/text-field/text-field-styles.js.map +1 -1
  104. package/dist/components/time-picker/TimeField.d.ts +24 -2
  105. package/dist/components/time-picker/TimeField.js +40 -12
  106. package/dist/components/time-picker/TimeField.js.map +1 -1
  107. package/dist/components/time-picker/TimeFieldList.js +95 -0
  108. package/dist/components/time-picker/TimeFieldList.js.map +1 -0
  109. package/dist/components/time-picker/TimePicker.d.ts +9 -5
  110. package/dist/components/time-picker/TimePicker.js +5 -2
  111. package/dist/components/time-picker/TimePicker.js.map +1 -1
  112. package/dist/components/time-picker/time-list.js +33 -0
  113. package/dist/components/time-picker/time-list.js.map +1 -0
  114. package/dist/components/tooltip/Tooltip.d.ts +1 -1
  115. package/dist/components/tooltip/tooltip-tokens.d.ts +1 -1
  116. package/dist/index.d.ts +40 -38
  117. package/dist/index.js +4 -3
  118. package/dist/primitives/use-m3-interaction.js +10 -6
  119. package/dist/primitives/use-m3-interaction.js.map +1 -1
  120. package/dist/primitives.d.ts +7 -4
  121. package/dist/primitives.js +4 -1
  122. package/dist/styles/utilities.css +22 -15
  123. package/dist/styles.compiled.css +1 -1
  124. package/dist/utils/use-scroll-keys.d.ts +29 -0
  125. package/dist/utils/use-scroll-keys.js +66 -0
  126. package/dist/utils/use-scroll-keys.js.map +1 -0
  127. package/dist/utils/use-scroll-restoration.d.ts +43 -0
  128. package/dist/utils/use-scroll-restoration.js +173 -0
  129. package/dist/utils/use-scroll-restoration.js.map +1 -0
  130. package/dist/windmorph-labels.d.ts +101 -0
  131. package/package.json +1 -1
  132. package/dist/composites/button-group/ButtonGroup.js.map +0 -1
  133. package/dist/composites/button-group/lazy-overflow-menu.js.map +0 -1
  134. package/dist/composites/button-group/overflow-menu-list.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"DatePicker.js","names":[],"sources":["../../../src/components/date-picker/DatePicker.tsx"],"sourcesContent":["'use client';\n\nimport {\n CalendarDate,\n createCalendar,\n getLocalTimeZone,\n maxDate,\n minDate,\n startOfWeek,\n toCalendarDate,\n today,\n type DateValue,\n} from '@internationalized/date';\nimport {\n useContext,\n useLayoutEffect,\n useRef,\n useState,\n type CSSProperties,\n type HTMLAttributes,\n type ReactNode,\n type Ref,\n type TransitionEvent,\n} from 'react';\nimport {\n mergeProps,\n useCalendar,\n useDateFormatter,\n useLocale,\n useRangeCalendar,\n type AriaButtonProps,\n} from 'react-aria';\nimport {\n useCalendarState,\n useRangeCalendarState,\n type CalendarState,\n type RangeCalendarState,\n} from 'react-stately';\nimport { useControlledState } from 'react-stately/useControlledState';\nimport { DomDirectionLocale } from '../../primitives/DomDirectionLocale';\nimport { useSizeTransform } from './use-size-transform';\nimport { useViewExit } from './use-view-exit';\nimport { usePresence } from '../../primitives/use-presence';\nimport { cn } from '../../utils/cn';\nimport { mergeDataTokens } from '../../utils/merge-data-tokens';\nimport {\n splitRootProps,\n type DescriptionAria,\n type WrapperRootDOMProps,\n} from '../../utils/root-props';\nimport { Button } from '../button/Button';\nimport { IconButton } from '../icon-button/IconButton';\nimport { LazyTooltip } from '../tooltip/lazy-tooltip';\nimport { TooltipTrigger } from '../tooltip/tooltip-trigger';\nimport { CalendarGrid } from './CalendarGrid';\nimport { ChoiceButton, ShortcutIconButton, useMonthSwipe, usePickerKeys } from './calendar-parts';\nimport type { Density } from '../../tokens/density';\nimport { DateInput, type DateInputLabels } from './DateInput';\nimport { datePickerStyles } from './date-picker-styles';\nimport { PickerDialogContext } from './picker-dialog-context';\nimport {\n ArrowDropDownIcon,\n CalendarIcon,\n ChevronLeftIcon,\n ChevronRightIcon,\n EditIcon,\n} from './picker-icons';\n\n/** The picker's labels, for localisation. */\nexport interface DatePickerLabels extends DateInputLabels {\n /** The header's title in calendar mode. @default \"Select date\", or \"Select dates\" for a range */\n title: string;\n /**\n * The title in text input mode (the M3 modal date input's \"Enter date\").\n * @default \"Enter date\", or \"Enter dates\" for a range\n */\n inputTitle: string;\n /** Headline when nothing is selected. @default \"Selected date\" / \"Start date – End date\" */\n noSelection: string;\n /** The previous month button. @default \"Previous month\" */\n previousMonth: string;\n /** The next month button. @default \"Next month\" */\n nextMonth: string;\n /** Tooltip of the previous-month button, naming its shortcut. @default \"Previous month (Page Up)\" */\n previousMonthTooltip: string;\n /** Tooltip of the next-month button, naming its shortcut. @default \"Next month (Page Down)\" */\n nextMonthTooltip: string;\n /** The month and year button while the days show. @default \"Switch to selecting a year\" */\n showYears: string;\n /** The month and year button while the years show. @default \"Switch to selecting a day\" */\n showDays: string;\n /** Tooltip of the month and year button, naming its shortcut. @default \"Choose a year (Shift+Y)\" */\n yearsTooltip: string;\n /** Name of the year list. @default \"Year\" */\n yearList: string;\n /** The mode toggle in calendar mode. @default \"Switch to text input mode\" */\n inputMode: string;\n /** The mode toggle in text input mode. @default \"Switch to calendar input mode\" */\n calendarMode: string;\n /** Label of the input mode's field. @default \"Date\" */\n dateLabel: string;\n /** Label of a range's start field in input mode. @default \"Start date\" */\n startDateLabel: string;\n /**\n * Label of a range's end field in input mode, and the headline's end while a range is\n * being picked (\"Mar 20 – End date\"). @default \"End date\"\n */\n endDateLabel: string;\n}\n\nexport interface DatePickerClassNames {\n /** The picker's root; `className` is merged here too. */\n root?: string;\n /** The header: title, headline and mode toggle. */\n header?: string;\n /** The header's title (\"Select date\"). */\n title?: string;\n /** The header's headline: the chosen date or range. */\n headline?: string;\n /** The calendar or the text input below the header. */\n body?: string;\n /** The weekday names above the days. */\n weekday?: string;\n /** Each day of the calendar. */\n day?: string;\n /** Each year of the year list. */\n year?: string;\n /** The month and year button above the days, which shows the year list. */\n yearButton?: string;\n /** Each month's subhead in the range picker's scrolling month list. */\n monthSubhead?: string;\n}\n\nexport interface DateRangePickerClassNames extends DatePickerClassNames {\n /**\n * The band behind a range's days: each calendar cell it spans (`data-range` is `start`,\n * `middle` or `end`), whose background paints it.\n */\n rangeBand?: string;\n}\n\n// No `aria-description` and the like: the picker's root is a plain container, and no single\n// element in it stands for the whole picker.\ninterface DatePickerCommonProps extends Omit<WrapperRootDOMProps, DescriptionAria> {\n /** Earliest date allowed; earlier days are disabled. */\n min?: DateValue;\n /** Latest date allowed; later days are disabled. */\n max?: DateValue;\n /** Returns `true` for a day that can't be picked (it shows disabled). */\n isDateUnavailable?: (date: DateValue) => boolean;\n /** Show the header (title, headline and mode toggle). @default true */\n header?: boolean;\n /** Show the calendar ↔ text input toggle. @default true */\n modeToggle?: boolean;\n /** Start in calendar or text input mode. @default \"calendar\" */\n defaultMode?: 'calendar' | 'input';\n /**\n * First and last years of the year list (and of a range's month list). Years outside\n * `min` / `max` are shown disabled. @default [1900, 2100]\n */\n yearRange?: [number, number];\n /** Words the picker shows and announces, with English defaults. */\n labels?: Partial<DatePickerLabels>;\n /**\n * Web density of the input mode's text fields, `0` to `-3`: each step takes 4px off them\n * (56px at 0, 44px at -3). The calendar keeps its size: M3 doesn't make date pickers denser,\n * since their 48px day targets are part of their accessibility. Left out, the fields take\n * the density of the nearest `ThemeProvider` or `ThemeScope`.\n * @default 0\n */\n density?: Density;\n /** The root `<div>`'s id. */\n id?: string;\n /** Ref to the root `<div>` element. */\n ref?: Ref<HTMLDivElement>;\n /** Classes for the root element, merged with `classNames.root`; consumer classes win. */\n className?: string;\n /** Inline styles for the root element. */\n style?: CSSProperties;\n /** Classes for each part, by slot. */\n classNames?: DatePickerClassNames;\n /** `data-*` attributes go to the root. */\n [data: `data-${string}`]: string | number | boolean | undefined;\n}\n\nexport type DatePickerProps = DatePickerCommonProps & {\n /** The selected date (controlled); `null` for none. */\n value?: CalendarDate | null;\n /** Initial date when uncontrolled. @default null */\n defaultValue?: CalendarDate | null;\n /** Called with the date the user picks or types. */\n onChange?: (value: CalendarDate) => void;\n};\n\nexport interface DateRange {\n start: CalendarDate;\n end: CalendarDate;\n}\n\nexport type DateRangePickerProps = Omit<DatePickerCommonProps, 'classNames'> & {\n /** Classes for each part, by slot. */\n classNames?: DateRangePickerClassNames;\n /** The selected range (controlled); `null` for none. */\n value?: DateRange | null;\n /** Initial range when uncontrolled. @default null */\n defaultValue?: DateRange | null;\n /** Called with the range once both its start and end are picked or typed. */\n onChange?: (value: DateRange) => void;\n /**\n * `scroll` lists the months one under another and scrolls vertically, as the M3 modal\n * range picker does; `paged` shows one month at a time with previous / next buttons and\n * a year list, like the date picker. @default \"scroll\"\n */\n monthLayout?: 'scroll' | 'paged';\n};\n\n/**\n * M3 modal date picker (Compose's `DatePicker`): a header with the selected date, a month\n * grid you page with the arrows, a horizontal swipe or Page Up / Down, a year list, and a\n * text input mode. Put it in a {@link PickerDialog} for the modal form; {@link DateField}\n * is the docked form. Values are `@internationalized/date` dates.\n *\n * @example\n * <DatePicker value={date} onChange={setDate} />\n */\nexport function DatePicker(props: DatePickerProps) {\n return (\n <DomDirectionLocale>\n {(directionRef) => <SingleDatePicker {...props} directionRef={directionRef} />}\n </DomDirectionLocale>\n );\n}\n\n/**\n * M3 date range picker (Compose's `DateRangePicker`): select a start and an end date on a\n * vertically scrolling list of months, or type them in input mode.\n *\n * @example\n * <DateRangePicker value={range} onChange={setRange} />\n */\nexport function DateRangePicker(props: DateRangePickerProps) {\n return (\n <DomDirectionLocale>\n {(directionRef) => <RangeDatePicker {...props} directionRef={directionRef} />}\n </DomDirectionLocale>\n );\n}\n\ntype Inner<P> = P & { directionRef: (element: HTMLElement | null) => void };\n\nfunction SingleDatePicker(props: Inner<DatePickerProps>) {\n const { locale } = useLocale();\n const confirm = useContext(PickerDialogContext);\n const [value, setValue] = useControlledState(\n props.value,\n props.defaultValue ?? null,\n props.onChange as (value: CalendarDate | null) => void,\n );\n const state = useCalendarState({\n value,\n onChange: (date) => setValue(date as CalendarDate),\n minValue: props.min,\n maxValue: props.max,\n isDateUnavailable: props.isDateUnavailable,\n locale,\n createCalendar,\n });\n const formatter = useDateFormatter({ dateStyle: 'medium' });\n const labels = props.labels ?? {};\n const headline = value\n ? formatter.format(value.toDate(getLocalTimeZone()))\n : (labels.noSelection ?? 'Selected date');\n return (\n <PickerFrame\n {...props}\n range={false}\n state={state}\n headline={headline}\n input={\n <DateInput\n label={labels.dateLabel ?? 'Date'}\n value={value}\n onCommit={(date) => date && setValue(date)}\n onEnter={(date) => date && confirm?.requestConfirm()}\n min={props.min}\n max={props.max}\n isDateUnavailable={props.isDateUnavailable}\n labels={labels}\n density={props.density}\n className=\"w-full\"\n />\n }\n />\n );\n}\n\n/** Whole months from `from` to `to`. */\nconst monthsBetween = (from: CalendarDate, to: CalendarDate) =>\n (to.year - from.year) * 12 + (to.month - from.month);\n\nfunction RangeDatePicker({ monthLayout = 'scroll', ...props }: Inner<DateRangePickerProps>) {\n const { locale } = useLocale();\n const confirm = useContext(PickerDialogContext);\n const [value, setValue] = useControlledState(\n props.value,\n props.defaultValue ?? null,\n props.onChange as (value: DateRange | null) => void,\n );\n // The scrolling list shows every month of the year range (within min / max) at once.\n const [firstYear, lastYear] = props.yearRange ?? [1900, 2100];\n const scroll = monthLayout === 'scroll';\n const listStart = maxDate(\n new CalendarDate(firstYear, 1, 1),\n props.min ? toCalendarDate(props.min) : null,\n )!;\n const listEnd = minDate(\n new CalendarDate(lastYear, 12, 31),\n props.max ? toCalendarDate(props.max) : null,\n )!;\n const state = useRangeCalendarState({\n value,\n onChange: (range) => setValue(range as DateRange),\n minValue: scroll ? listStart : props.min,\n maxValue: scroll ? listEnd : props.max,\n isDateUnavailable: props.isDateUnavailable,\n visibleDuration: scroll ? { months: monthsBetween(listStart, listEnd) + 1 } : undefined,\n locale,\n createCalendar,\n });\n const formatter = useDateFormatter({ month: 'short', day: 'numeric' });\n const labels = props.labels ?? {};\n const format = (date: CalendarDate) => formatter.format(date.toDate(getLocalTimeZone()));\n // While a new range is being picked, its first day is the start and the end is still open\n // (Compose's headline: \"Mar 20 – End date\"), not the range it replaces.\n const anchor = state.anchorDate;\n const headline = anchor\n ? `${format(anchor)} – ${labels.endDateLabel ?? 'End date'}`\n : value\n ? `${format(value.start)} – ${format(value.end)}`\n : (labels.noSelection ?? 'Start date – End date');\n const common = {\n min: props.min,\n max: props.max,\n isDateUnavailable: props.isDateUnavailable,\n labels,\n density: props.density,\n className: 'w-full',\n };\n return (\n <PickerFrame\n {...props}\n range\n scroll={scroll}\n state={state}\n headline={headline}\n input={\n <>\n <DateInput\n {...common}\n label={labels.startDateLabel ?? 'Start date'}\n value={value?.start ?? null}\n onCommit={(start) =>\n start && setValue({ start, end: value && value.end >= start ? value.end : start })\n }\n />\n <DateInput\n {...common}\n label={labels.endDateLabel ?? 'End date'}\n value={value?.end ?? null}\n onCommit={(end) =>\n end && setValue({ start: value && value.start <= end ? value.start : end, end })\n }\n onEnter={(end) => end && value && confirm?.requestConfirm()}\n />\n </>\n }\n />\n );\n}\n\nfunction PickerFrame({\n range,\n scroll = false,\n state,\n headline,\n input,\n header = true,\n modeToggle = true,\n defaultMode = 'calendar',\n yearRange = [1900, 2100],\n labels = {},\n id,\n ref,\n className,\n style,\n classNames,\n directionRef,\n ...rest\n}: Inner<Omit<DatePickerCommonProps, 'classNames'>> & {\n classNames?: DateRangePickerClassNames | undefined;\n range: boolean;\n scroll?: boolean;\n state: CalendarState | RangeCalendarState;\n headline: string;\n input: ReactNode;\n value?: unknown;\n defaultValue?: unknown;\n onChange?: unknown;\n}) {\n const { root: data } = splitRootProps(rest, { wrapper: true });\n const [mode, setMode] = useState(defaultMode);\n // Set once the mode has been switched, so only a switch animates (not the first render).\n const [switched, setSwitched] = useState(false);\n const [years, setYears] = useState(false);\n // The picker's height follows the view on the default spatial spring (Compose's\n // `SizeTransform` in its display mode animation), as the views swap.\n const { attach: attachSize, capture: captureSize } = useSizeTransform<HTMLDivElement>(mode);\n // The outgoing view fades out as it slides away (Compose: up 48px as the input comes in,\n // down by its whole height as the calendar comes back), clipped with the new one.\n const {\n attachView: attachExitView,\n attachSlot: attachExitSlot,\n capture: captureExit,\n } = useViewExit(mode);\n const styles = datePickerStyles({ range });\n const title =\n mode === 'input'\n ? (labels.inputTitle ?? (range ? 'Enter dates' : 'Enter date'))\n : (labels.title ?? (range ? 'Select dates' : 'Select date'));\n const bodyProps = {\n styles,\n years,\n setYears,\n yearRange,\n labels,\n className: classNames?.body,\n classNames,\n };\n return (\n <div\n {...data}\n id={id}\n ref={(element) => {\n attachSize(element);\n directionRef(element);\n if (typeof ref === 'function') ref(element);\n else if (ref) ref.current = element;\n }}\n style={style}\n // The modal date picker's component tokens (date-picker-tokens.ts).\n data-tokens={mergeDataTokens('md-comp-date-picker-modal', data)}\n data-years={years || undefined}\n data-mode={mode}\n className={styles.root({ class: cn(classNames?.root, className) })}\n >\n {header && (\n <div className={styles.header({ class: classNames?.header })}>\n <div className={styles.title({ class: classNames?.title })}>{title}</div>\n <div className={styles.headlineRow()}>\n <div\n aria-live=\"polite\"\n data-slot=\"headline\"\n className={styles.headline({ class: classNames?.headline })}\n >\n {headline}\n </div>\n {modeToggle && (\n <IconButton\n variant=\"standard\"\n // The picker's surface isn't dense, only its input mode's fields.\n density={0}\n icon={mode === 'calendar' ? <EditIcon /> : <CalendarIcon />}\n aria-label={\n mode === 'calendar'\n ? (labels.inputMode ?? 'Switch to text input mode')\n : (labels.calendarMode ?? 'Switch to calendar input mode')\n }\n onPress={() => {\n captureSize();\n captureExit(mode === 'calendar' ? '-48px' : '100%');\n setSwitched(true);\n setMode(mode === 'calendar' ? 'input' : 'calendar');\n }}\n />\n )}\n </div>\n </div>\n )}\n <div className={styles.modeStack()}>\n <div\n key={mode}\n ref={attachExitView}\n data-enter={switched ? mode : undefined}\n className={styles.modeView()}\n >\n {mode === 'input' ? (\n <div className={styles.input({ class: classNames?.body })}>{input}</div>\n ) : range && scroll ? (\n <RangeMonthList state={state as RangeCalendarState} {...bodyProps} />\n ) : range ? (\n <RangeCalendarBody state={state as RangeCalendarState} {...bodyProps} />\n ) : (\n <SingleCalendarBody state={state as CalendarState} {...bodyProps} />\n )}\n </div>\n <div ref={attachExitSlot} aria-hidden=\"true\" inert className={styles.modeExit()} />\n </div>\n </div>\n );\n}\n\ninterface BodyProps {\n styles: ReturnType<typeof datePickerStyles>;\n years: boolean;\n setYears: (open: boolean) => void;\n yearRange: [number, number];\n labels: Partial<DatePickerLabels>;\n className?: string | undefined;\n classNames?: DateRangePickerClassNames | undefined;\n}\n\nfunction SingleCalendarBody({ state, ...props }: BodyProps & { state: CalendarState }) {\n const { calendarProps, prevButtonProps, nextButtonProps } = useCalendar({}, state);\n return (\n <CalendarBody\n {...props}\n state={state}\n calendarProps={calendarProps}\n prevButtonProps={prevButtonProps}\n nextButtonProps={nextButtonProps}\n />\n );\n}\n\nfunction RangeCalendarBody({ state, ...props }: BodyProps & { state: RangeCalendarState }) {\n const ref = useRef<HTMLDivElement>(null);\n const { calendarProps, prevButtonProps, nextButtonProps } = useRangeCalendar({}, state, ref);\n return (\n <CalendarBody\n {...props}\n bodyRef={ref}\n state={state}\n calendarProps={calendarProps}\n prevButtonProps={prevButtonProps}\n nextButtonProps={nextButtonProps}\n />\n );\n}\n\nfunction CalendarBody({\n state,\n calendarProps,\n prevButtonProps,\n nextButtonProps,\n styles,\n years,\n setYears,\n yearRange,\n labels,\n className,\n classNames,\n bodyRef,\n}: BodyProps & {\n state: CalendarState | RangeCalendarState;\n calendarProps: HTMLAttributes<HTMLElement>;\n prevButtonProps: AriaButtonProps;\n nextButtonProps: AriaButtonProps;\n bodyRef?: Ref<HTMLDivElement>;\n}) {\n const confirm = useContext(PickerDialogContext);\n const monthFormatter = useDateFormatter({ month: 'long', year: 'numeric' });\n const monthLabel = monthFormatter.format(state.visibleRange.start.toDate(getLocalTimeZone()));\n const menuRef = useRef<HTMLButtonElement>(null);\n const [focusYears, setFocusYears] = useState(false);\n // Compose shrinks the year list and fades it out (`shrinkVertically` + `fadeOut`); the\n // first of the two transitions to end removes it.\n const yearsPresence = usePresence(years, ['clip-path', 'opacity']);\n const { swipeProps, slideKey, slideDirection } = useMonthSwipe(state);\n const onKeyDownCapture = usePickerKeys(state, {\n onConfirm: confirm?.requestConfirm,\n onMonthMenu: () => menuRef.current?.focus(),\n onYearMenu: () => {\n setFocusYears(true);\n setYears(true);\n },\n });\n return (\n <div\n {...calendarProps}\n ref={bodyRef}\n onKeyDownCapture={onKeyDownCapture}\n className={styles.body({ class: className })}\n >\n <div className={styles.nav()}>\n <TooltipTrigger>\n <Button\n ref={menuRef}\n variant=\"text\"\n className={cn('text-on-surface-variant', classNames?.yearButton)}\n aria-label={`${monthLabel}, ${years ? (labels.showDays ?? 'Switch to selecting a day') : (labels.showYears ?? 'Switch to selecting a year')}`}\n onPress={() => {\n setFocusYears(false);\n setYears(!years);\n }}\n >\n {/* The drop-down arrow trails the label here, which Button's one leading icon can't do. */}\n <span className=\"inline-flex items-center gap-[8px]\">\n <span aria-live=\"polite\">{monthLabel}</span>\n <span\n aria-hidden=\"true\"\n className=\"inline-flex size-[20px] items-center justify-center\"\n >\n <span className={styles.yearButtonIcon()}>\n <ArrowDropDownIcon />\n </span>\n </span>\n </span>\n </Button>\n <LazyTooltip>{labels.yearsTooltip ?? 'Choose a year (Shift+Y)'}</LazyTooltip>\n </TooltipTrigger>\n {!years && (\n <div className={styles.navButtons()}>\n <ShortcutIconButton\n icon={<ChevronLeftIcon />}\n label={labels.previousMonth ?? 'Previous month'}\n tooltip={labels.previousMonthTooltip ?? 'Previous month (Page Up)'}\n onPress={prevButtonProps.onPress as () => void}\n disabled={prevButtonProps.isDisabled}\n />\n <ShortcutIconButton\n icon={<ChevronRightIcon />}\n label={labels.nextMonth ?? 'Next month'}\n tooltip={labels.nextMonthTooltip ?? 'Next month (Page Down)'}\n onPress={nextButtonProps.onPress as () => void}\n disabled={nextButtonProps.isDisabled}\n />\n </div>\n )}\n </div>\n {!years && (\n <div {...swipeProps} className={styles.swipe()}>\n <div key={slideKey} data-direction={slideDirection} className={styles.slide()}>\n <CalendarGrid state={state} styles={styles} classNames={classNames} />\n </div>\n </div>\n )}\n {/* Closing, the list stays over the grid until it has shrunk and faded away. */}\n {yearsPresence.isPresent && (\n <YearList\n state={state}\n styles={styles}\n yearRange={yearRange}\n className={classNames?.year}\n label={labels.yearList ?? 'Year'}\n autoFocus={focusYears}\n exiting={yearsPresence.isExiting}\n exitProps={yearsPresence.exitProps}\n onPick={() => setYears(false)}\n />\n )}\n </div>\n );\n}\n\n/**\n * The range picker's months, one under another in a vertical scroll (M3: \"To navigate\n * across months, scroll vertically\"), under a single weekday row. Only the months in view\n * (and the focused one) are rendered; the rest are spacers of the same fixed height.\n */\nfunction RangeMonthList({\n state,\n styles,\n className,\n classNames,\n}: BodyProps & { state: RangeCalendarState }) {\n const confirm = useContext(PickerDialogContext);\n const ref = useRef<HTMLDivElement>(null);\n const listRef = useRef<HTMLDivElement>(null);\n const { calendarProps } = useRangeCalendar({}, state, ref);\n const { locale } = useLocale();\n const first = state.visibleRange.start;\n const count = monthsBetween(first, state.visibleRange.end) + 1;\n const focusedIndex = monthsBetween(first, state.focusedDate);\n const [view, setView] = useState(() => ({ top: focusedIndex * MONTH_HEIGHT, height: 0 }));\n const weekdays = useDateFormatter({ weekday: 'narrow' });\n const longWeekdays = useDateFormatter({ weekday: 'long' });\n const subhead = useDateFormatter({ month: 'long', year: 'numeric' });\n const onKeyDownCapture = usePickerKeys(state, {\n onConfirm: confirm?.requestConfirm,\n onMonthMenu: () => undefined,\n onYearMenu: () => undefined,\n });\n\n // Open on the focused month (the range's start, or today), then follow the scroll.\n const initialTop = useRef(view.top);\n useLayoutEffect(() => {\n const list = listRef.current;\n if (!list) return;\n // A list out of sight (`display: none` above it) can't scroll, so it scrolls to the focused\n // month once it shows; it used to open on the range's first month.\n let opened = list.getClientRects().length > 0;\n list.scrollTop = initialTop.current;\n const measure = () => {\n if (!opened && list.clientHeight > 0) {\n opened = true;\n list.scrollTop = initialTop.current;\n }\n setView({ top: list.scrollTop, height: list.clientHeight });\n };\n measure();\n const observer = typeof ResizeObserver === 'undefined' ? null : new ResizeObserver(measure);\n observer?.observe(list);\n list.addEventListener('scroll', measure, { passive: true });\n return () => {\n observer?.disconnect();\n list.removeEventListener('scroll', measure);\n };\n }, []);\n\n const height = view.height || MONTH_HEIGHT;\n let from = Math.max(0, Math.floor(view.top / MONTH_HEIGHT) - 1);\n let to = Math.min(count - 1, Math.floor((view.top + height) / MONTH_HEIGHT) + 1);\n if (state.isFocused) {\n from = Math.min(from, focusedIndex);\n to = Math.max(to, focusedIndex);\n }\n const weekStart = startOfWeek(today(getLocalTimeZone()), locale);\n\n return (\n <div\n {...mergeProps(calendarProps, { onKeyDownCapture })}\n ref={ref}\n className={styles.body({ class: cn('min-h-0 flex-1', className) })}\n >\n <div aria-hidden=\"true\" className={styles.weekdayRow()}>\n {Array.from({ length: 7 }, (_, index) => {\n const day = weekStart.add({ days: index }).toDate(getLocalTimeZone());\n return (\n <span\n key={index}\n title={longWeekdays.format(day)}\n className={styles.weekdayCell({ class: classNames?.weekday })}\n >\n {weekdays.format(day)}\n </span>\n );\n })}\n </div>\n <div ref={listRef} className={styles.months()}>\n <div style={{ height: from * MONTH_HEIGHT }} />\n {Array.from({ length: to - from + 1 }, (_, i) => {\n const month = first.add({ months: from + i });\n return (\n <div key={month.toString()} className=\"h-[336px]\">\n <div\n aria-hidden=\"true\"\n className={styles.monthSubhead({ class: classNames?.monthSubhead })}\n >\n {subhead.format(month.toDate(getLocalTimeZone()))}\n </div>\n <CalendarGrid state={state} styles={styles} month={month} classNames={classNames} />\n </div>\n );\n })}\n <div style={{ height: (count - 1 - to) * MONTH_HEIGHT }} />\n </div>\n </div>\n );\n}\n\n/** A month in the scrolling list: its 48px subhead and six 48px weeks. */\nconst MONTH_HEIGHT = 336;\n\nfunction YearList({\n state,\n styles,\n yearRange,\n className,\n label,\n autoFocus,\n exiting,\n exitProps,\n onPick,\n}: {\n state: CalendarState | RangeCalendarState;\n styles: ReturnType<typeof datePickerStyles>;\n yearRange: [number, number];\n className: string | undefined;\n label: string;\n autoFocus: boolean;\n /** Closing: drawn over the grid, out of the accessibility tree and taking no presses. */\n exiting: boolean;\n exitProps: { onTransitionEnd: (event: TransitionEvent<HTMLElement>) => void };\n onPick: () => void;\n}) {\n const current = today(getLocalTimeZone()).year;\n const focusedYear = state.focusedDate.year;\n const minYear = state.minValue?.year ?? -Infinity;\n const maxYear = state.maxValue?.year ?? Infinity;\n return (\n <div\n {...exitProps}\n role=\"radiogroup\"\n aria-label={label}\n aria-hidden={exiting || undefined}\n inert={exiting || undefined}\n data-exiting={exiting || undefined}\n className={styles.years()}\n ref={(element) => {\n if (exiting) return;\n // Open on the focused year, as Compose scrolls the year list to it.\n const selected = element?.querySelector<HTMLElement>('[aria-checked=\"true\"]');\n selected?.scrollIntoView?.({ block: 'center' });\n if (autoFocus) selected?.focus({ preventScroll: true });\n }}\n >\n {Array.from({ length: yearRange[1] - yearRange[0] + 1 }, (_, i) => yearRange[0] + i).map(\n (year) => (\n <ChoiceButton\n key={year}\n selected={year === focusedYear}\n disabled={year < minYear || year > maxYear}\n data-current={year === current || undefined}\n steps={YEAR_STEPS}\n className={styles.year({ class: className })}\n onPick={() => {\n state.setFocusedDate(state.focusedDate.set({ year }));\n onPick();\n }}\n >\n {year}\n </ChoiceButton>\n ),\n )}\n </div>\n );\n}\n\n/** Three years to a row. */\nconst YEAR_STEPS = { ArrowLeft: -1, ArrowRight: 1, ArrowUp: -3, ArrowDown: 3 };\n"],"mappings":"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"}
1
+ {"version":3,"file":"DatePicker.js","names":[],"sources":["../../../src/components/date-picker/DatePicker.tsx"],"sourcesContent":["'use client';\n\nimport {\n CalendarDate,\n createCalendar,\n getLocalTimeZone,\n maxDate,\n minDate,\n startOfWeek,\n toCalendarDate,\n today,\n type DateValue,\n} from '@internationalized/date';\nimport {\n useContext,\n useLayoutEffect,\n useRef,\n useState,\n type CSSProperties,\n type HTMLAttributes,\n type ReactNode,\n type Ref,\n type TransitionEvent,\n} from 'react';\nimport {\n mergeProps,\n useCalendar,\n useDateFormatter,\n useLocale,\n useRangeCalendar,\n type AriaButtonProps,\n} from 'react-aria';\nimport {\n useCalendarState,\n useRangeCalendarState,\n type CalendarState,\n type RangeCalendarState,\n} from 'react-stately';\nimport { useControlledState } from 'react-stately/useControlledState';\nimport { NO_DEFAULT_LABELS, useLabels } from '../labels/use-labels';\nimport { DomDirectionLocale } from '../../primitives/DomDirectionLocale';\nimport { useSizeTransform } from './use-size-transform';\nimport { useViewExit } from './use-view-exit';\nimport { usePresence } from '../../primitives/use-presence';\nimport { cn } from '../../utils/cn';\nimport { mergeDataTokens } from '../../utils/merge-data-tokens';\nimport {\n splitRootProps,\n type DescriptionAria,\n type WrapperRootDOMProps,\n} from '../../utils/root-props';\nimport { Button } from '../button/Button';\nimport { IconButton } from '../icon-button/IconButton';\nimport { LazyTooltip } from '../tooltip/lazy-tooltip';\nimport { TooltipTrigger } from '../tooltip/tooltip-trigger';\nimport { CalendarGrid } from './CalendarGrid';\nimport { ChoiceButton, ShortcutIconButton, useMonthSwipe, usePickerKeys } from './calendar-parts';\nimport type { Density } from '../../tokens/density';\nimport { DateInput, type DateInputLabels } from './DateInput';\nimport { datePickerStyles } from './date-picker-styles';\nimport { PickerDialogContext } from './picker-dialog-context';\nimport {\n ArrowDropDownIcon,\n CalendarIcon,\n ChevronLeftIcon,\n ChevronRightIcon,\n EditIcon,\n} from './picker-icons';\n\n/** The picker's labels, for localisation. */\nexport interface DatePickerLabels extends DateInputLabels {\n /** The header's title in calendar mode. @default \"Select date\", or \"Select dates\" for a range */\n title: string;\n /**\n * The title in text input mode (the M3 modal date input's \"Enter date\").\n * @default \"Enter date\", or \"Enter dates\" for a range\n */\n inputTitle: string;\n /** Headline when nothing is selected. @default \"Selected date\" / \"Start date – End date\" */\n noSelection: string;\n /** The previous month button. @default \"Previous month\" */\n previousMonth: string;\n /** The next month button. @default \"Next month\" */\n nextMonth: string;\n /** Tooltip of the previous-month button, naming its shortcut. @default \"Previous month (Page Up)\" */\n previousMonthTooltip: string;\n /** Tooltip of the next-month button, naming its shortcut. @default \"Next month (Page Down)\" */\n nextMonthTooltip: string;\n /** The month and year button while the days show. @default \"Switch to selecting a year\" */\n showYears: string;\n /** The month and year button while the years show. @default \"Switch to selecting a day\" */\n showDays: string;\n /** Tooltip of the month and year button, naming its shortcut. @default \"Choose a year (Shift+Y)\" */\n yearsTooltip: string;\n /** Name of the year list. @default \"Year\" */\n yearList: string;\n /** The mode toggle in calendar mode. @default \"Switch to text input mode\" */\n inputMode: string;\n /** The mode toggle in text input mode. @default \"Switch to calendar input mode\" */\n calendarMode: string;\n /** Label of the input mode's field. @default \"Date\" */\n dateLabel: string;\n /** Label of a range's start field in input mode. @default \"Start date\" */\n startDateLabel: string;\n /**\n * Label of a range's end field in input mode, and the headline's end while a range is\n * being picked (\"Mar 20 – End date\"). @default \"End date\"\n */\n endDateLabel: string;\n}\n\nexport interface DatePickerClassNames {\n /** The picker's root; `className` is merged here too. */\n root?: string;\n /** The header: title, headline and mode toggle. */\n header?: string;\n /** The header's title (\"Select date\"). */\n title?: string;\n /** The header's headline: the chosen date or range. */\n headline?: string;\n /** The calendar or the text input below the header. */\n body?: string;\n /** The weekday names above the days. */\n weekday?: string;\n /** Each day of the calendar. */\n day?: string;\n /** Each year of the year list. */\n year?: string;\n /** The month and year button above the days, which shows the year list. */\n yearButton?: string;\n /** Each month's subhead in the range picker's scrolling month list. */\n monthSubhead?: string;\n}\n\nexport interface DateRangePickerClassNames extends DatePickerClassNames {\n /**\n * The band behind a range's days: each calendar cell it spans (`data-range` is `start`,\n * `middle` or `end`), whose background paints it.\n */\n rangeBand?: string;\n}\n\n// No `aria-description` and the like: the picker's root is a plain container, and no single\n// element in it stands for the whole picker.\ninterface DatePickerCommonProps extends Omit<WrapperRootDOMProps, DescriptionAria> {\n /** Earliest date allowed; earlier days are disabled. */\n min?: DateValue;\n /** Latest date allowed; later days are disabled. */\n max?: DateValue;\n /** Returns `true` for a day that can't be picked (it shows disabled). */\n isDateUnavailable?: (date: DateValue) => boolean;\n /** Show the header (title, headline and mode toggle). @default true */\n header?: boolean;\n /** Show the calendar ↔ text input toggle. @default true */\n modeToggle?: boolean;\n /** Start in calendar or text input mode. @default \"calendar\" */\n defaultMode?: 'calendar' | 'input';\n /**\n * First and last years of the year list (and of a range's month list). Years outside\n * `min` / `max` are shown disabled. @default [1900, 2100]\n */\n yearRange?: [number, number];\n /**\n * Words the picker shows and announces, with English defaults. A {@link LabelsProvider} sets them\n * for the whole app.\n */\n labels?: Partial<DatePickerLabels>;\n /**\n * Web density of the input mode's text fields, `0` to `-3`: each step takes 4px off them\n * (56px at 0, 44px at -3). The calendar keeps its size: M3 doesn't make date pickers denser,\n * since their 48px day targets are part of their accessibility. Left out, the fields take\n * the density of the nearest `ThemeProvider` or `ThemeScope`.\n * @default 0\n */\n density?: Density;\n /** The root `<div>`'s id. */\n id?: string;\n /** Ref to the root `<div>` element. */\n ref?: Ref<HTMLDivElement>;\n /** Classes for the root element, merged with `classNames.root`; consumer classes win. */\n className?: string;\n /** Inline styles for the root element. */\n style?: CSSProperties;\n /** Classes for each part, by slot. */\n classNames?: DatePickerClassNames;\n /** `data-*` attributes go to the root. */\n [data: `data-${string}`]: string | number | boolean | undefined;\n}\n\nexport type DatePickerProps = DatePickerCommonProps & {\n /** The selected date (controlled); `null` for none. */\n value?: CalendarDate | null;\n /** Initial date when uncontrolled. @default null */\n defaultValue?: CalendarDate | null;\n /** Called with the date the user picks or types. */\n onChange?: (value: CalendarDate) => void;\n};\n\nexport interface DateRange {\n start: CalendarDate;\n end: CalendarDate;\n}\n\nexport type DateRangePickerProps = Omit<DatePickerCommonProps, 'classNames'> & {\n /** Classes for each part, by slot. */\n classNames?: DateRangePickerClassNames;\n /** The selected range (controlled); `null` for none. */\n value?: DateRange | null;\n /** Initial range when uncontrolled. @default null */\n defaultValue?: DateRange | null;\n /** Called with the range once both its start and end are picked or typed. */\n onChange?: (value: DateRange) => void;\n /**\n * `scroll` lists the months one under another and scrolls vertically, as the M3 modal\n * range picker does; `paged` shows one month at a time with previous / next buttons and\n * a year list, like the date picker. @default \"scroll\"\n */\n monthLayout?: 'scroll' | 'paged';\n};\n\n/**\n * M3 modal date picker (Compose's `DatePicker`): a header with the selected date, a month\n * grid you page with the arrows, a horizontal swipe or Page Up / Down, a year list, and a\n * text input mode. Put it in a {@link PickerDialog} for the modal form; {@link DateField}\n * is the docked form. Values are `@internationalized/date` dates.\n *\n * @example\n * <DatePicker value={date} onChange={setDate} />\n */\nexport function DatePicker(props: DatePickerProps) {\n return (\n <DomDirectionLocale>\n {(directionRef) => <SingleDatePicker {...props} directionRef={directionRef} />}\n </DomDirectionLocale>\n );\n}\n\n/**\n * M3 date range picker (Compose's `DateRangePicker`): select a start and an end date on a\n * vertically scrolling list of months, or type them in input mode.\n *\n * @example\n * <DateRangePicker value={range} onChange={setRange} />\n */\nexport function DateRangePicker(props: DateRangePickerProps) {\n return (\n <DomDirectionLocale>\n {(directionRef) => <RangeDatePicker {...props} directionRef={directionRef} />}\n </DomDirectionLocale>\n );\n}\n\ntype Inner<P> = P & { directionRef: (element: HTMLElement | null) => void };\n\nfunction SingleDatePicker(props: Inner<DatePickerProps>) {\n const { locale } = useLocale();\n const confirm = useContext(PickerDialogContext);\n const [value, setValue] = useControlledState(\n props.value,\n props.defaultValue ?? null,\n props.onChange as (value: CalendarDate | null) => void,\n );\n const state = useCalendarState({\n value,\n onChange: (date) => setValue(date as CalendarDate),\n minValue: props.min,\n maxValue: props.max,\n isDateUnavailable: props.isDateUnavailable,\n locale,\n createCalendar,\n });\n const formatter = useDateFormatter({ dateStyle: 'medium' });\n const labels = useLabels('DatePicker', NO_DEFAULT_LABELS, props.labels);\n const headline = value\n ? formatter.format(value.toDate(getLocalTimeZone()))\n : (labels.noSelection ?? 'Selected date');\n return (\n <PickerFrame\n {...props}\n labels={labels}\n range={false}\n state={state}\n headline={headline}\n input={\n <DateInput\n label={labels.dateLabel ?? 'Date'}\n value={value}\n onCommit={(date) => date && setValue(date)}\n onEnter={(date) => date && confirm?.requestConfirm()}\n min={props.min}\n max={props.max}\n isDateUnavailable={props.isDateUnavailable}\n labels={labels}\n density={props.density}\n className=\"w-full\"\n />\n }\n />\n );\n}\n\n/** Whole months from `from` to `to`. */\nconst monthsBetween = (from: CalendarDate, to: CalendarDate) =>\n (to.year - from.year) * 12 + (to.month - from.month);\n\nfunction RangeDatePicker({ monthLayout = 'scroll', ...props }: Inner<DateRangePickerProps>) {\n const { locale } = useLocale();\n const confirm = useContext(PickerDialogContext);\n const [value, setValue] = useControlledState(\n props.value,\n props.defaultValue ?? null,\n props.onChange as (value: DateRange | null) => void,\n );\n // The scrolling list shows every month of the year range (within min / max) at once.\n const [firstYear, lastYear] = props.yearRange ?? [1900, 2100];\n const scroll = monthLayout === 'scroll';\n const listStart = maxDate(\n new CalendarDate(firstYear, 1, 1),\n props.min ? toCalendarDate(props.min) : null,\n )!;\n const listEnd = minDate(\n new CalendarDate(lastYear, 12, 31),\n props.max ? toCalendarDate(props.max) : null,\n )!;\n const state = useRangeCalendarState({\n value,\n onChange: (range) => setValue(range as DateRange),\n minValue: scroll ? listStart : props.min,\n maxValue: scroll ? listEnd : props.max,\n isDateUnavailable: props.isDateUnavailable,\n visibleDuration: scroll ? { months: monthsBetween(listStart, listEnd) + 1 } : undefined,\n locale,\n createCalendar,\n });\n const formatter = useDateFormatter({ month: 'short', day: 'numeric' });\n const labels = useLabels('DatePicker', NO_DEFAULT_LABELS, props.labels);\n const format = (date: CalendarDate) => formatter.format(date.toDate(getLocalTimeZone()));\n // While a new range is being picked, its first day is the start and the end is still open\n // (Compose's headline: \"Mar 20 – End date\"), not the range it replaces.\n const anchor = state.anchorDate;\n const headline = anchor\n ? `${format(anchor)} – ${labels.endDateLabel ?? 'End date'}`\n : value\n ? `${format(value.start)} – ${format(value.end)}`\n : (labels.noSelection ?? 'Start date – End date');\n const common = {\n min: props.min,\n max: props.max,\n isDateUnavailable: props.isDateUnavailable,\n labels,\n density: props.density,\n className: 'w-full',\n };\n return (\n <PickerFrame\n {...props}\n labels={labels}\n range\n scroll={scroll}\n state={state}\n headline={headline}\n input={\n <>\n <DateInput\n {...common}\n label={labels.startDateLabel ?? 'Start date'}\n value={value?.start ?? null}\n onCommit={(start) =>\n start && setValue({ start, end: value && value.end >= start ? value.end : start })\n }\n />\n <DateInput\n {...common}\n label={labels.endDateLabel ?? 'End date'}\n value={value?.end ?? null}\n onCommit={(end) =>\n end && setValue({ start: value && value.start <= end ? value.start : end, end })\n }\n onEnter={(end) => end && value && confirm?.requestConfirm()}\n />\n </>\n }\n />\n );\n}\n\nfunction PickerFrame({\n range,\n scroll = false,\n state,\n headline,\n input,\n header = true,\n modeToggle = true,\n defaultMode = 'calendar',\n yearRange = [1900, 2100],\n labels = {},\n id,\n ref,\n className,\n style,\n classNames,\n directionRef,\n ...rest\n}: Inner<Omit<DatePickerCommonProps, 'classNames'>> & {\n classNames?: DateRangePickerClassNames | undefined;\n range: boolean;\n scroll?: boolean;\n state: CalendarState | RangeCalendarState;\n headline: string;\n input: ReactNode;\n value?: unknown;\n defaultValue?: unknown;\n onChange?: unknown;\n}) {\n const { root: data } = splitRootProps(rest, { wrapper: true });\n const [mode, setMode] = useState(defaultMode);\n // Set once the mode has been switched, so only a switch animates (not the first render).\n const [switched, setSwitched] = useState(false);\n const [years, setYears] = useState(false);\n // The picker's height follows the view on the default spatial spring (Compose's\n // `SizeTransform` in its display mode animation), as the views swap.\n const { attach: attachSize, capture: captureSize } = useSizeTransform<HTMLDivElement>(mode);\n // The outgoing view fades out as it slides away (Compose: up 48px as the input comes in,\n // down by its whole height as the calendar comes back), clipped with the new one.\n const {\n attachView: attachExitView,\n attachSlot: attachExitSlot,\n capture: captureExit,\n } = useViewExit(mode);\n const styles = datePickerStyles({ range });\n const title =\n mode === 'input'\n ? (labels.inputTitle ?? (range ? 'Enter dates' : 'Enter date'))\n : (labels.title ?? (range ? 'Select dates' : 'Select date'));\n const bodyProps = {\n styles,\n years,\n setYears,\n yearRange,\n labels,\n className: classNames?.body,\n classNames,\n };\n return (\n <div\n {...data}\n id={id}\n ref={(element) => {\n attachSize(element);\n directionRef(element);\n if (typeof ref === 'function') ref(element);\n else if (ref) ref.current = element;\n }}\n style={style}\n // The modal date picker's component tokens (date-picker-tokens.ts).\n data-tokens={mergeDataTokens('md-comp-date-picker-modal', data)}\n data-years={years || undefined}\n data-mode={mode}\n className={styles.root({ class: cn(classNames?.root, className) })}\n >\n {header && (\n <div className={styles.header({ class: classNames?.header })}>\n <div className={styles.title({ class: classNames?.title })}>{title}</div>\n <div className={styles.headlineRow()}>\n <div\n aria-live=\"polite\"\n data-slot=\"headline\"\n className={styles.headline({ class: classNames?.headline })}\n >\n {headline}\n </div>\n {modeToggle && (\n <IconButton\n variant=\"standard\"\n // The picker's surface isn't dense, only its input mode's fields.\n density={0}\n icon={mode === 'calendar' ? <EditIcon /> : <CalendarIcon />}\n aria-label={\n mode === 'calendar'\n ? (labels.inputMode ?? 'Switch to text input mode')\n : (labels.calendarMode ?? 'Switch to calendar input mode')\n }\n onPress={() => {\n captureSize();\n captureExit(mode === 'calendar' ? '-48px' : '100%');\n setSwitched(true);\n setMode(mode === 'calendar' ? 'input' : 'calendar');\n }}\n />\n )}\n </div>\n </div>\n )}\n <div className={styles.modeStack()}>\n <div\n key={mode}\n ref={attachExitView}\n data-enter={switched ? mode : undefined}\n className={styles.modeView()}\n >\n {mode === 'input' ? (\n <div className={styles.input({ class: classNames?.body })}>{input}</div>\n ) : range && scroll ? (\n <RangeMonthList state={state as RangeCalendarState} {...bodyProps} />\n ) : range ? (\n <RangeCalendarBody state={state as RangeCalendarState} {...bodyProps} />\n ) : (\n <SingleCalendarBody state={state as CalendarState} {...bodyProps} />\n )}\n </div>\n <div ref={attachExitSlot} aria-hidden=\"true\" inert className={styles.modeExit()} />\n </div>\n </div>\n );\n}\n\ninterface BodyProps {\n styles: ReturnType<typeof datePickerStyles>;\n years: boolean;\n setYears: (open: boolean) => void;\n yearRange: [number, number];\n labels: Partial<DatePickerLabels>;\n className?: string | undefined;\n classNames?: DateRangePickerClassNames | undefined;\n}\n\nfunction SingleCalendarBody({ state, ...props }: BodyProps & { state: CalendarState }) {\n const { calendarProps, prevButtonProps, nextButtonProps } = useCalendar({}, state);\n return (\n <CalendarBody\n {...props}\n state={state}\n calendarProps={calendarProps}\n prevButtonProps={prevButtonProps}\n nextButtonProps={nextButtonProps}\n />\n );\n}\n\nfunction RangeCalendarBody({ state, ...props }: BodyProps & { state: RangeCalendarState }) {\n const ref = useRef<HTMLDivElement>(null);\n const { calendarProps, prevButtonProps, nextButtonProps } = useRangeCalendar({}, state, ref);\n return (\n <CalendarBody\n {...props}\n bodyRef={ref}\n state={state}\n calendarProps={calendarProps}\n prevButtonProps={prevButtonProps}\n nextButtonProps={nextButtonProps}\n />\n );\n}\n\nfunction CalendarBody({\n state,\n calendarProps,\n prevButtonProps,\n nextButtonProps,\n styles,\n years,\n setYears,\n yearRange,\n labels,\n className,\n classNames,\n bodyRef,\n}: BodyProps & {\n state: CalendarState | RangeCalendarState;\n calendarProps: HTMLAttributes<HTMLElement>;\n prevButtonProps: AriaButtonProps;\n nextButtonProps: AriaButtonProps;\n bodyRef?: Ref<HTMLDivElement>;\n}) {\n const confirm = useContext(PickerDialogContext);\n const monthFormatter = useDateFormatter({ month: 'long', year: 'numeric' });\n const monthLabel = monthFormatter.format(state.visibleRange.start.toDate(getLocalTimeZone()));\n const menuRef = useRef<HTMLButtonElement>(null);\n const [focusYears, setFocusYears] = useState(false);\n // Compose shrinks the year list and fades it out (`shrinkVertically` + `fadeOut`); the\n // first of the two transitions to end removes it.\n const yearsPresence = usePresence(years, ['clip-path', 'opacity']);\n const { swipeProps, slideKey, slideDirection } = useMonthSwipe(state);\n const onKeyDownCapture = usePickerKeys(state, {\n onConfirm: confirm?.requestConfirm,\n onMonthMenu: () => menuRef.current?.focus(),\n onYearMenu: () => {\n setFocusYears(true);\n setYears(true);\n },\n });\n return (\n <div\n {...calendarProps}\n ref={bodyRef}\n onKeyDownCapture={onKeyDownCapture}\n className={styles.body({ class: className })}\n >\n <div className={styles.nav()}>\n <TooltipTrigger>\n <Button\n ref={menuRef}\n variant=\"text\"\n className={cn('text-on-surface-variant', classNames?.yearButton)}\n aria-label={`${monthLabel}, ${years ? (labels.showDays ?? 'Switch to selecting a day') : (labels.showYears ?? 'Switch to selecting a year')}`}\n onPress={() => {\n setFocusYears(false);\n setYears(!years);\n }}\n >\n {/* The drop-down arrow trails the label here, which Button's one leading icon can't do. */}\n <span className=\"inline-flex items-center gap-[8px]\">\n <span aria-live=\"polite\">{monthLabel}</span>\n <span\n aria-hidden=\"true\"\n className=\"inline-flex size-[20px] items-center justify-center\"\n >\n <span className={styles.yearButtonIcon()}>\n <ArrowDropDownIcon />\n </span>\n </span>\n </span>\n </Button>\n <LazyTooltip>{labels.yearsTooltip ?? 'Choose a year (Shift+Y)'}</LazyTooltip>\n </TooltipTrigger>\n {!years && (\n <div className={styles.navButtons()}>\n <ShortcutIconButton\n icon={<ChevronLeftIcon />}\n label={labels.previousMonth ?? 'Previous month'}\n tooltip={labels.previousMonthTooltip ?? 'Previous month (Page Up)'}\n onPress={prevButtonProps.onPress as () => void}\n disabled={prevButtonProps.isDisabled}\n />\n <ShortcutIconButton\n icon={<ChevronRightIcon />}\n label={labels.nextMonth ?? 'Next month'}\n tooltip={labels.nextMonthTooltip ?? 'Next month (Page Down)'}\n onPress={nextButtonProps.onPress as () => void}\n disabled={nextButtonProps.isDisabled}\n />\n </div>\n )}\n </div>\n {!years && (\n <div {...swipeProps} className={styles.swipe()}>\n <div key={slideKey} data-direction={slideDirection} className={styles.slide()}>\n <CalendarGrid state={state} styles={styles} classNames={classNames} />\n </div>\n </div>\n )}\n {/* Closing, the list stays over the grid until it has shrunk and faded away. */}\n {yearsPresence.isPresent && (\n <YearList\n state={state}\n styles={styles}\n yearRange={yearRange}\n className={classNames?.year}\n label={labels.yearList ?? 'Year'}\n autoFocus={focusYears}\n exiting={yearsPresence.isExiting}\n exitProps={yearsPresence.exitProps}\n onPick={() => setYears(false)}\n />\n )}\n </div>\n );\n}\n\n/**\n * The range picker's months, one under another in a vertical scroll (M3: \"To navigate\n * across months, scroll vertically\"), under a single weekday row. Only the months in view\n * (and the focused one) are rendered; the rest are spacers of the same fixed height.\n */\nfunction RangeMonthList({\n state,\n styles,\n className,\n classNames,\n}: BodyProps & { state: RangeCalendarState }) {\n const confirm = useContext(PickerDialogContext);\n const ref = useRef<HTMLDivElement>(null);\n const listRef = useRef<HTMLDivElement>(null);\n const { calendarProps } = useRangeCalendar({}, state, ref);\n const { locale } = useLocale();\n const first = state.visibleRange.start;\n const count = monthsBetween(first, state.visibleRange.end) + 1;\n const focusedIndex = monthsBetween(first, state.focusedDate);\n const [view, setView] = useState(() => ({ top: focusedIndex * MONTH_HEIGHT, height: 0 }));\n const weekdays = useDateFormatter({ weekday: 'narrow' });\n const longWeekdays = useDateFormatter({ weekday: 'long' });\n const subhead = useDateFormatter({ month: 'long', year: 'numeric' });\n const onKeyDownCapture = usePickerKeys(state, {\n onConfirm: confirm?.requestConfirm,\n onMonthMenu: () => undefined,\n onYearMenu: () => undefined,\n });\n\n // Open on the focused month (the range's start, or today), then follow the scroll.\n const initialTop = useRef(view.top);\n useLayoutEffect(() => {\n const list = listRef.current;\n if (!list) return;\n // A list out of sight (`display: none` above it) can't scroll, so it scrolls to the focused\n // month once it shows; it used to open on the range's first month.\n let opened = list.getClientRects().length > 0;\n list.scrollTop = initialTop.current;\n const measure = () => {\n if (!opened && list.clientHeight > 0) {\n opened = true;\n list.scrollTop = initialTop.current;\n }\n setView({ top: list.scrollTop, height: list.clientHeight });\n };\n measure();\n const observer = typeof ResizeObserver === 'undefined' ? null : new ResizeObserver(measure);\n observer?.observe(list);\n list.addEventListener('scroll', measure, { passive: true });\n return () => {\n observer?.disconnect();\n list.removeEventListener('scroll', measure);\n };\n }, []);\n\n const height = view.height || MONTH_HEIGHT;\n let from = Math.max(0, Math.floor(view.top / MONTH_HEIGHT) - 1);\n let to = Math.min(count - 1, Math.floor((view.top + height) / MONTH_HEIGHT) + 1);\n if (state.isFocused) {\n from = Math.min(from, focusedIndex);\n to = Math.max(to, focusedIndex);\n }\n const weekStart = startOfWeek(today(getLocalTimeZone()), locale);\n\n return (\n <div\n {...mergeProps(calendarProps, { onKeyDownCapture })}\n ref={ref}\n className={styles.body({ class: cn('min-h-0 flex-1', className) })}\n >\n <div aria-hidden=\"true\" className={styles.weekdayRow()}>\n {Array.from({ length: 7 }, (_, index) => {\n const day = weekStart.add({ days: index }).toDate(getLocalTimeZone());\n return (\n <span\n key={index}\n title={longWeekdays.format(day)}\n className={styles.weekdayCell({ class: classNames?.weekday })}\n >\n {weekdays.format(day)}\n </span>\n );\n })}\n </div>\n <div ref={listRef} className={styles.months()}>\n <div style={{ height: from * MONTH_HEIGHT }} />\n {Array.from({ length: to - from + 1 }, (_, i) => {\n const month = first.add({ months: from + i });\n return (\n <div key={month.toString()} className=\"h-[336px]\">\n <div\n aria-hidden=\"true\"\n className={styles.monthSubhead({ class: classNames?.monthSubhead })}\n >\n {subhead.format(month.toDate(getLocalTimeZone()))}\n </div>\n <CalendarGrid state={state} styles={styles} month={month} classNames={classNames} />\n </div>\n );\n })}\n <div style={{ height: (count - 1 - to) * MONTH_HEIGHT }} />\n </div>\n </div>\n );\n}\n\n/** A month in the scrolling list: its 48px subhead and six 48px weeks. */\nconst MONTH_HEIGHT = 336;\n\nfunction YearList({\n state,\n styles,\n yearRange,\n className,\n label,\n autoFocus,\n exiting,\n exitProps,\n onPick,\n}: {\n state: CalendarState | RangeCalendarState;\n styles: ReturnType<typeof datePickerStyles>;\n yearRange: [number, number];\n className: string | undefined;\n label: string;\n autoFocus: boolean;\n /** Closing: drawn over the grid, out of the accessibility tree and taking no presses. */\n exiting: boolean;\n exitProps: { onTransitionEnd: (event: TransitionEvent<HTMLElement>) => void };\n onPick: () => void;\n}) {\n const current = today(getLocalTimeZone()).year;\n const focusedYear = state.focusedDate.year;\n const minYear = state.minValue?.year ?? -Infinity;\n const maxYear = state.maxValue?.year ?? Infinity;\n return (\n <div\n {...exitProps}\n role=\"radiogroup\"\n aria-label={label}\n aria-hidden={exiting || undefined}\n inert={exiting || undefined}\n data-exiting={exiting || undefined}\n className={styles.years()}\n ref={(element) => {\n if (exiting) return;\n // Open on the focused year, as Compose scrolls the year list to it.\n const selected = element?.querySelector<HTMLElement>('[aria-checked=\"true\"]');\n selected?.scrollIntoView?.({ block: 'center' });\n if (autoFocus) selected?.focus({ preventScroll: true });\n }}\n >\n {Array.from({ length: yearRange[1] - yearRange[0] + 1 }, (_, i) => yearRange[0] + i).map(\n (year) => (\n <ChoiceButton\n key={year}\n selected={year === focusedYear}\n disabled={year < minYear || year > maxYear}\n data-current={year === current || undefined}\n steps={YEAR_STEPS}\n className={styles.year({ class: className })}\n onPick={() => {\n state.setFocusedDate(state.focusedDate.set({ year }));\n onPick();\n }}\n >\n {year}\n </ChoiceButton>\n ),\n )}\n </div>\n );\n}\n\n/** Three years to a row. */\nconst YEAR_STEPS = { ArrowLeft: -1, ArrowRight: 1, ArrowUp: -3, ArrowDown: 3 };\n"],"mappings":"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"}
@@ -81,7 +81,10 @@ interface PickerDialogOwnProps extends Omit<RootDOMProps, 'title'> {
81
81
  * @default "any"
82
82
  */
83
83
  closedBy?: ClosedBy;
84
- /** Words the full-screen form shows and announces, with English defaults. */
84
+ /**
85
+ * Words the full-screen form shows and announces, with English defaults. A {@link LabelsProvider}
86
+ * sets them for the whole app.
87
+ */
85
88
  labels?: Partial<PickerDialogLabels>;
86
89
  /** The picker. */
87
90
  children: ReactNode | ((props: {
@@ -1,4 +1,5 @@
1
1
  "use client";
2
+ import { NO_DEFAULT_LABELS, useLabels } from "../labels/use-labels.js";
2
3
  import { TriggerContext } from "../../primitives/TriggerContext.js";
3
4
  import { mergeDataTokens } from "../../utils/merge-data-tokens.js";
4
5
  import { usePresence } from "../../primitives/use-presence.js";
@@ -48,7 +49,8 @@ function PickerDialog({ open, defaultOpen, onOpenChange, ...props }) {
48
49
  })
49
50
  });
50
51
  }
51
- function PickerDialogModal({ state, isExiting, exitProps, variant = "date", title, onConfirm, confirmButton, dismissButton, modeToggleButton, fullScreen = "never", closeIcon, closedBy = "any", transition = "reveal", labels = {}, children, className, style, ref, classNames, ...labelling }) {
52
+ function PickerDialogModal({ state, isExiting, exitProps, variant = "date", title, onConfirm, confirmButton, dismissButton, modeToggleButton, fullScreen = "never", closeIcon, closedBy = "any", transition = "reveal", labels: labelsProp, children, className, style, ref, classNames, ...labelling }) {
53
+ const labels = useLabels("PickerDialog", NO_DEFAULT_LABELS, labelsProp);
52
54
  const panelRef = useObjectRef(ref);
53
55
  const { modalProps, underlayProps } = useModalOverlay(closedByOverlayOptions(closedBy, isExiting), state, panelRef);
54
56
  const { root, rest: naming } = splitRootProps(labelling);
@@ -1 +1 @@
1
- {"version":3,"file":"PickerDialog.js","names":["Overlay"],"sources":["../../../src/components/date-picker/PickerDialog.tsx"],"sourcesContent":["'use client';\n\nimport {\n useLayoutEffect,\n useMemo,\n useRef,\n useState,\n type ReactElement,\n type ReactNode,\n type CSSProperties,\n type Ref,\n} from 'react';\nimport { mergeProps, useDialog, useModalOverlay, useObjectRef } from 'react-aria';\nimport { useOverlayTriggerState, type OverlayTriggerState } from 'react-stately';\nimport { Overlay } from '../../primitives/Overlay';\nimport { TriggerContext } from '../../primitives/TriggerContext';\nimport { usePresence } from '../../primitives/use-presence';\nimport { Button } from '../button/Button';\nimport { DIALOG_ROOT_STYLE, dialogStyles } from '../dialog/dialog-styles';\nimport type { DialogTransition } from '../dialog/Dialog';\nimport { IconButton } from '../icon-button/IconButton';\nimport { PickerDialogContext } from './picker-dialog-context';\nimport { pickerDialogStyles } from './picker-dialog-styles';\nimport { CloseIcon } from './picker-icons';\nimport { COMPACT_WINDOW, useMediaQuery } from './use-media-query';\nimport { closedByOverlayOptions, type ClosedBy } from '../../utils/closed-by';\nimport { mergeDataTokens } from '../../utils/merge-data-tokens';\nimport { splitRootProps, type RootDOMProps } from '../../utils/root-props';\n\ntype Naming =\n | {\n /** Accessible name of the dialog when there's no visible title. */\n 'aria-label': string;\n }\n | {\n /** Id of a visible element that names the dialog. */\n 'aria-labelledby': string;\n };\n\nexport interface PickerDialogClassNames {\n /** The dimmed layer behind the dialog. */\n scrim?: string;\n /** The dialog's surface: its colour, corners, padding and shadow. */\n panel?: string;\n /** The full-screen top row with the close and Save buttons. */\n header?: string;\n /** The full-screen close (x) icon button. */\n close?: string;\n /** The time picker dialog's `title` (\"Select time\"). */\n title?: string;\n /** The bottom row of actions: mode toggle, dismiss and confirm buttons. */\n actions?: string;\n}\n\n/** Words of a {@link PickerDialog}, for localisation. */\nexport interface PickerDialogLabels {\n /** The full-screen close (x) button. @default \"Close\" */\n close: string;\n /** The full-screen confirm button. @default \"Save\" */\n save: string;\n}\n\n/** The panel (the `dialog` element, where `ref` and `id` land) takes the DOM attributes. */\ninterface PickerDialogOwnProps extends Omit<RootDOMProps, 'title'> {\n /** Whether the dialog is open (controlled). */\n open?: boolean;\n /** Whether the dialog starts open when uncontrolled. @default false */\n defaultOpen?: boolean;\n /** Called when the dialog opens or closes. */\n onOpenChange?: (open: boolean) => void;\n /**\n * `date` holds a date picker edge to edge with the actions below (Compose's\n * `DatePickerDialog`); `time` pads the content 24px under a \"Select time\" style title\n * (Compose's `TimePickerDialog`). @default \"date\"\n */\n variant?: 'date' | 'time';\n /** Title for the time variant, e.g. \"Select time\". */\n title?: ReactNode;\n /**\n * Saves the picked value. With it, Enter on a day (or in a typed date) confirms and\n * closes the dialog (the M3 date picker keyboard table), and the full-screen form gets\n * its Save button. Called after the picker's latest value has rendered.\n */\n onConfirm?: () => void;\n /** The confirm button (last, at the end), e.g. `<Button variant=\"text\">OK</Button>`. */\n confirmButton: ReactNode;\n /** The dismiss button, before the confirm button. */\n dismissButton?: ReactNode;\n /** A control at the start of the actions row, e.g. the time picker's mode toggle. */\n modeToggleButton?: ReactNode;\n /**\n * Fill the window, with a close (x) icon button and a Save button at the top instead of\n * the actions (M3: a full-screen modal date picker is recommended on compact windows).\n * `compact` does so below 600px wide. @default \"never\"\n */\n fullScreen?: 'never' | 'always' | 'compact';\n /** Icon of the full-screen close button. */\n closeIcon?: ReactElement;\n /**\n * How the dialog enters and leaves, as `Dialog`'s `transition`: `reveal`, the M3 dialog\n * motion (it slides down while its container grows, then the picker and the actions fade\n * in), or `scale`, the original pop (a fade with a scale from 90%). Reduced motion keeps only\n * the fades. Ignored while the dialog is full screen.\n * @default \"reveal\"\n */\n transition?: DialogTransition;\n /**\n * How the user can close the dialog, as HTML's `<dialog closedby>`: `any` (Escape or a\n * press outside), `closerequest` (Escape only) or `none` (only its actions or the app).\n * @default \"any\"\n */\n closedBy?: ClosedBy;\n /** Words the full-screen form shows and announces, with English defaults. */\n labels?: Partial<PickerDialogLabels>;\n /** The picker. */\n children: ReactNode | ((props: { close: () => void }) => ReactNode);\n /**\n * Goes on the outermost element, a full-window layer whose inline placement it can't\n * move, so a layout class (`static`, `overflow-hidden`, a transform) never hides or clips\n * the dialog. Style the surface with `classNames.panel`.\n */\n className?: string;\n /** Inline styles for the outermost element, with `className`. */\n style?: CSSProperties;\n /** The dialog's id (on the panel, the `dialog` element). */\n id?: string;\n /** Ref to the panel, the `dialog` element. */\n ref?: Ref<HTMLDivElement>;\n /** Classes for each part, by slot. */\n classNames?: PickerDialogClassNames;\n}\n\nexport type PickerDialogProps = PickerDialogOwnProps & Naming;\n\n/**\n * The modal dialog for a date or time picker (Compose's `DatePickerDialog` /\n * `TimePickerDialog`): the picker on a `surface-container-high` panel with 28px corners at\n * level 3, and its actions; or, full screen, edge to edge with close and Save at the top.\n *\n * @example\n * <PickerDialog aria-label=\"Select date\" open={open} onOpenChange={setOpen}\n * onConfirm={() => setDate(draft)}\n * dismissButton={<Button variant=\"text\" onPress={() => setOpen(false)}>Cancel</Button>}\n * confirmButton={<Button variant=\"text\" onPress={confirm}>OK</Button>}>\n * <DatePicker value={draft} onChange={setDraft} />\n * </PickerDialog>\n */\nexport function PickerDialog({ open, defaultOpen, onOpenChange, ...props }: PickerDialogProps) {\n const state = useOverlayTriggerState({ isOpen: open, defaultOpen, onOpenChange });\n const { isPresent, isExiting, exitProps } = usePresence(state.isOpen);\n if (!isPresent) return null;\n return (\n <Overlay exiting={isExiting}>\n <PickerDialogModal {...props} state={state} isExiting={isExiting} exitProps={exitProps} />\n </Overlay>\n );\n}\n\nfunction PickerDialogModal({\n state,\n isExiting,\n exitProps,\n variant = 'date',\n title,\n onConfirm,\n confirmButton,\n dismissButton,\n modeToggleButton,\n fullScreen = 'never',\n closeIcon,\n closedBy = 'any',\n transition = 'reveal',\n labels = {},\n children,\n className,\n style,\n ref,\n classNames,\n ...labelling\n}: Omit<PickerDialogProps, 'open' | 'defaultOpen' | 'onOpenChange'> & {\n state: OverlayTriggerState;\n isExiting: boolean;\n exitProps: ReturnType<typeof usePresence>['exitProps'];\n}) {\n const panelRef = useObjectRef(ref);\n const { modalProps, underlayProps } = useModalOverlay(\n closedByOverlayOptions(closedBy, isExiting),\n state,\n panelRef,\n );\n const { root, rest: naming } = splitRootProps(labelling);\n const { dialogProps, titleProps } = useDialog(naming, panelRef);\n const compact = useMediaQuery(COMPACT_WINDOW);\n const full = fullScreen === 'always' || (fullScreen === 'compact' && compact);\n const shell = dialogStyles({ fullScreen: full ? 'always' : 'never', transition });\n const styles = pickerDialogStyles({ variant, fullScreen: full });\n const exiting = isExiting || undefined;\n\n // Enter on a day selects it first; confirm once the consumer has the new value, so the\n // latest `onConfirm` (reading that value) runs.\n const latest = useRef({ onConfirm, close: state.close });\n useLayoutEffect(() => {\n latest.current = { onConfirm, close: state.close };\n });\n const [requestConfirm] = useState(() => () => {\n setTimeout(() => {\n latest.current.onConfirm?.();\n latest.current.close();\n });\n });\n const canConfirm = onConfirm !== undefined;\n const context = useMemo(\n () => (canConfirm ? { requestConfirm } : null),\n [canConfirm, requestConfirm],\n );\n\n return (\n <>\n <div\n aria-hidden=\"true\"\n data-exiting={exiting}\n className={shell.scrim({ class: classNames?.scrim })}\n />\n <div style={{ ...style, ...DIALOG_ROOT_STYLE }} className={shell.root({ class: className })}>\n <div {...underlayProps} className={shell.positioner()}>\n <div\n {...exitProps}\n data-exiting={exiting}\n className={shell.motion({ class: styles.motion() })}\n >\n <div\n {...mergeProps(root, modalProps, dialogProps)}\n ref={panelRef}\n data-exiting={exiting}\n // The picker's component tokens (date-picker-tokens.ts, time-picker-tokens.ts)\n // paint the panel; `data-variant` is also a public styling hook.\n data-tokens={mergeDataTokens(\n variant === 'time' ? 'md-comp-time-picker' : 'md-comp-date-picker-modal',\n root,\n )}\n data-variant={variant}\n data-full-screen={full || undefined}\n className={styles.panel({\n class: [transition === 'reveal' && shell.parts(), classNames?.panel],\n })}\n >\n <TriggerContext value={null}>\n {full && (\n <div className={styles.header({ class: classNames?.header })}>\n <IconButton\n variant=\"standard\"\n density={0}\n icon={closeIcon ?? <CloseIcon />}\n aria-label={labels.close ?? 'Close'}\n onPress={state.close}\n className={styles.close({ class: classNames?.close })}\n />\n <div className={styles.buttons()}>\n {modeToggleButton}\n {onConfirm ? (\n <Button variant=\"text\" onPress={requestConfirm}>\n {labels.save ?? 'Save'}\n </Button>\n ) : (\n confirmButton\n )}\n </div>\n </div>\n )}\n {variant === 'time' && title != null && (\n <h2 {...titleProps} className={styles.title({ class: classNames?.title })}>\n {title}\n </h2>\n )}\n <PickerDialogContext value={context}>\n <div className={styles.content()}>\n {typeof children === 'function' ? children({ close: state.close }) : children}\n </div>\n </PickerDialogContext>\n {!full && (\n <div\n data-slot=\"actions\"\n className={styles.actions({ class: classNames?.actions })}\n >\n {modeToggleButton}\n <div className={styles.buttons()}>\n {dismissButton}\n {confirmButton}\n </div>\n </div>\n )}\n </TriggerContext>\n </div>\n </div>\n </div>\n </div>\n </>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"PickerDialog.js","names":["Overlay"],"sources":["../../../src/components/date-picker/PickerDialog.tsx"],"sourcesContent":["'use client';\n\nimport {\n useLayoutEffect,\n useMemo,\n useRef,\n useState,\n type ReactElement,\n type ReactNode,\n type CSSProperties,\n type Ref,\n} from 'react';\nimport { mergeProps, useDialog, useModalOverlay, useObjectRef } from 'react-aria';\nimport { useOverlayTriggerState, type OverlayTriggerState } from 'react-stately';\nimport { NO_DEFAULT_LABELS, useLabels } from '../labels/use-labels';\nimport { Overlay } from '../../primitives/Overlay';\nimport { TriggerContext } from '../../primitives/TriggerContext';\nimport { usePresence } from '../../primitives/use-presence';\nimport { Button } from '../button/Button';\nimport { DIALOG_ROOT_STYLE, dialogStyles } from '../dialog/dialog-styles';\nimport type { DialogTransition } from '../dialog/Dialog';\nimport { IconButton } from '../icon-button/IconButton';\nimport { PickerDialogContext } from './picker-dialog-context';\nimport { pickerDialogStyles } from './picker-dialog-styles';\nimport { CloseIcon } from './picker-icons';\nimport { COMPACT_WINDOW, useMediaQuery } from './use-media-query';\nimport { closedByOverlayOptions, type ClosedBy } from '../../utils/closed-by';\nimport { mergeDataTokens } from '../../utils/merge-data-tokens';\nimport { splitRootProps, type RootDOMProps } from '../../utils/root-props';\n\ntype Naming =\n | {\n /** Accessible name of the dialog when there's no visible title. */\n 'aria-label': string;\n }\n | {\n /** Id of a visible element that names the dialog. */\n 'aria-labelledby': string;\n };\n\nexport interface PickerDialogClassNames {\n /** The dimmed layer behind the dialog. */\n scrim?: string;\n /** The dialog's surface: its colour, corners, padding and shadow. */\n panel?: string;\n /** The full-screen top row with the close and Save buttons. */\n header?: string;\n /** The full-screen close (x) icon button. */\n close?: string;\n /** The time picker dialog's `title` (\"Select time\"). */\n title?: string;\n /** The bottom row of actions: mode toggle, dismiss and confirm buttons. */\n actions?: string;\n}\n\n/** Words of a {@link PickerDialog}, for localisation. */\nexport interface PickerDialogLabels {\n /** The full-screen close (x) button. @default \"Close\" */\n close: string;\n /** The full-screen confirm button. @default \"Save\" */\n save: string;\n}\n\n/** The panel (the `dialog` element, where `ref` and `id` land) takes the DOM attributes. */\ninterface PickerDialogOwnProps extends Omit<RootDOMProps, 'title'> {\n /** Whether the dialog is open (controlled). */\n open?: boolean;\n /** Whether the dialog starts open when uncontrolled. @default false */\n defaultOpen?: boolean;\n /** Called when the dialog opens or closes. */\n onOpenChange?: (open: boolean) => void;\n /**\n * `date` holds a date picker edge to edge with the actions below (Compose's\n * `DatePickerDialog`); `time` pads the content 24px under a \"Select time\" style title\n * (Compose's `TimePickerDialog`). @default \"date\"\n */\n variant?: 'date' | 'time';\n /** Title for the time variant, e.g. \"Select time\". */\n title?: ReactNode;\n /**\n * Saves the picked value. With it, Enter on a day (or in a typed date) confirms and\n * closes the dialog (the M3 date picker keyboard table), and the full-screen form gets\n * its Save button. Called after the picker's latest value has rendered.\n */\n onConfirm?: () => void;\n /** The confirm button (last, at the end), e.g. `<Button variant=\"text\">OK</Button>`. */\n confirmButton: ReactNode;\n /** The dismiss button, before the confirm button. */\n dismissButton?: ReactNode;\n /** A control at the start of the actions row, e.g. the time picker's mode toggle. */\n modeToggleButton?: ReactNode;\n /**\n * Fill the window, with a close (x) icon button and a Save button at the top instead of\n * the actions (M3: a full-screen modal date picker is recommended on compact windows).\n * `compact` does so below 600px wide. @default \"never\"\n */\n fullScreen?: 'never' | 'always' | 'compact';\n /** Icon of the full-screen close button. */\n closeIcon?: ReactElement;\n /**\n * How the dialog enters and leaves, as `Dialog`'s `transition`: `reveal`, the M3 dialog\n * motion (it slides down while its container grows, then the picker and the actions fade\n * in), or `scale`, the original pop (a fade with a scale from 90%). Reduced motion keeps only\n * the fades. Ignored while the dialog is full screen.\n * @default \"reveal\"\n */\n transition?: DialogTransition;\n /**\n * How the user can close the dialog, as HTML's `<dialog closedby>`: `any` (Escape or a\n * press outside), `closerequest` (Escape only) or `none` (only its actions or the app).\n * @default \"any\"\n */\n closedBy?: ClosedBy;\n /**\n * Words the full-screen form shows and announces, with English defaults. A {@link LabelsProvider}\n * sets them for the whole app.\n */\n labels?: Partial<PickerDialogLabels>;\n /** The picker. */\n children: ReactNode | ((props: { close: () => void }) => ReactNode);\n /**\n * Goes on the outermost element, a full-window layer whose inline placement it can't\n * move, so a layout class (`static`, `overflow-hidden`, a transform) never hides or clips\n * the dialog. Style the surface with `classNames.panel`.\n */\n className?: string;\n /** Inline styles for the outermost element, with `className`. */\n style?: CSSProperties;\n /** The dialog's id (on the panel, the `dialog` element). */\n id?: string;\n /** Ref to the panel, the `dialog` element. */\n ref?: Ref<HTMLDivElement>;\n /** Classes for each part, by slot. */\n classNames?: PickerDialogClassNames;\n}\n\nexport type PickerDialogProps = PickerDialogOwnProps & Naming;\n\n/**\n * The modal dialog for a date or time picker (Compose's `DatePickerDialog` /\n * `TimePickerDialog`): the picker on a `surface-container-high` panel with 28px corners at\n * level 3, and its actions; or, full screen, edge to edge with close and Save at the top.\n *\n * @example\n * <PickerDialog aria-label=\"Select date\" open={open} onOpenChange={setOpen}\n * onConfirm={() => setDate(draft)}\n * dismissButton={<Button variant=\"text\" onPress={() => setOpen(false)}>Cancel</Button>}\n * confirmButton={<Button variant=\"text\" onPress={confirm}>OK</Button>}>\n * <DatePicker value={draft} onChange={setDraft} />\n * </PickerDialog>\n */\nexport function PickerDialog({ open, defaultOpen, onOpenChange, ...props }: PickerDialogProps) {\n const state = useOverlayTriggerState({ isOpen: open, defaultOpen, onOpenChange });\n const { isPresent, isExiting, exitProps } = usePresence(state.isOpen);\n if (!isPresent) return null;\n return (\n <Overlay exiting={isExiting}>\n <PickerDialogModal {...props} state={state} isExiting={isExiting} exitProps={exitProps} />\n </Overlay>\n );\n}\n\nfunction PickerDialogModal({\n state,\n isExiting,\n exitProps,\n variant = 'date',\n title,\n onConfirm,\n confirmButton,\n dismissButton,\n modeToggleButton,\n fullScreen = 'never',\n closeIcon,\n closedBy = 'any',\n transition = 'reveal',\n labels: labelsProp,\n children,\n className,\n style,\n ref,\n classNames,\n ...labelling\n}: Omit<PickerDialogProps, 'open' | 'defaultOpen' | 'onOpenChange'> & {\n state: OverlayTriggerState;\n isExiting: boolean;\n exitProps: ReturnType<typeof usePresence>['exitProps'];\n}) {\n const labels = useLabels('PickerDialog', NO_DEFAULT_LABELS, labelsProp);\n const panelRef = useObjectRef(ref);\n const { modalProps, underlayProps } = useModalOverlay(\n closedByOverlayOptions(closedBy, isExiting),\n state,\n panelRef,\n );\n const { root, rest: naming } = splitRootProps(labelling);\n const { dialogProps, titleProps } = useDialog(naming, panelRef);\n const compact = useMediaQuery(COMPACT_WINDOW);\n const full = fullScreen === 'always' || (fullScreen === 'compact' && compact);\n const shell = dialogStyles({ fullScreen: full ? 'always' : 'never', transition });\n const styles = pickerDialogStyles({ variant, fullScreen: full });\n const exiting = isExiting || undefined;\n\n // Enter on a day selects it first; confirm once the consumer has the new value, so the\n // latest `onConfirm` (reading that value) runs.\n const latest = useRef({ onConfirm, close: state.close });\n useLayoutEffect(() => {\n latest.current = { onConfirm, close: state.close };\n });\n const [requestConfirm] = useState(() => () => {\n setTimeout(() => {\n latest.current.onConfirm?.();\n latest.current.close();\n });\n });\n const canConfirm = onConfirm !== undefined;\n const context = useMemo(\n () => (canConfirm ? { requestConfirm } : null),\n [canConfirm, requestConfirm],\n );\n\n return (\n <>\n <div\n aria-hidden=\"true\"\n data-exiting={exiting}\n className={shell.scrim({ class: classNames?.scrim })}\n />\n <div style={{ ...style, ...DIALOG_ROOT_STYLE }} className={shell.root({ class: className })}>\n <div {...underlayProps} className={shell.positioner()}>\n <div\n {...exitProps}\n data-exiting={exiting}\n className={shell.motion({ class: styles.motion() })}\n >\n <div\n {...mergeProps(root, modalProps, dialogProps)}\n ref={panelRef}\n data-exiting={exiting}\n // The picker's component tokens (date-picker-tokens.ts, time-picker-tokens.ts)\n // paint the panel; `data-variant` is also a public styling hook.\n data-tokens={mergeDataTokens(\n variant === 'time' ? 'md-comp-time-picker' : 'md-comp-date-picker-modal',\n root,\n )}\n data-variant={variant}\n data-full-screen={full || undefined}\n className={styles.panel({\n class: [transition === 'reveal' && shell.parts(), classNames?.panel],\n })}\n >\n <TriggerContext value={null}>\n {full && (\n <div className={styles.header({ class: classNames?.header })}>\n <IconButton\n variant=\"standard\"\n density={0}\n icon={closeIcon ?? <CloseIcon />}\n aria-label={labels.close ?? 'Close'}\n onPress={state.close}\n className={styles.close({ class: classNames?.close })}\n />\n <div className={styles.buttons()}>\n {modeToggleButton}\n {onConfirm ? (\n <Button variant=\"text\" onPress={requestConfirm}>\n {labels.save ?? 'Save'}\n </Button>\n ) : (\n confirmButton\n )}\n </div>\n </div>\n )}\n {variant === 'time' && title != null && (\n <h2 {...titleProps} className={styles.title({ class: classNames?.title })}>\n {title}\n </h2>\n )}\n <PickerDialogContext value={context}>\n <div className={styles.content()}>\n {typeof children === 'function' ? children({ close: state.close }) : children}\n </div>\n </PickerDialogContext>\n {!full && (\n <div\n data-slot=\"actions\"\n className={styles.actions({ class: classNames?.actions })}\n >\n {modeToggleButton}\n <div className={styles.buttons()}>\n {dismissButton}\n {confirmButton}\n </div>\n </div>\n )}\n </TriggerContext>\n </div>\n </div>\n </div>\n </div>\n </>\n );\n}\n"],"mappings":"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"}
@@ -156,15 +156,15 @@ export declare const datePickerStyles: import("tailwind-variants").TVReturnType<
156
156
  export declare const dockedDatePickerStyles: import("tailwind-variants").TVReturnType<{
157
157
  [key: string]: {
158
158
  [key: string]: import("tailwind-variants").ClassValue | {
159
- panel?: import("tailwind-variants").ClassValue;
160
- actions?: import("tailwind-variants").ClassValue;
161
159
  header?: import("tailwind-variants").ClassValue;
162
160
  view?: import("tailwind-variants").ClassValue;
161
+ menuIcon?: import("tailwind-variants").ClassValue;
162
+ group?: import("tailwind-variants").ClassValue;
163
163
  item?: import("tailwind-variants").ClassValue;
164
164
  check?: import("tailwind-variants").ClassValue;
165
+ actions?: import("tailwind-variants").ClassValue;
166
+ panel?: import("tailwind-variants").ClassValue;
165
167
  list?: import("tailwind-variants").ClassValue;
166
- menuIcon?: import("tailwind-variants").ClassValue;
167
- group?: import("tailwind-variants").ClassValue;
168
168
  calendar?: import("tailwind-variants").ClassValue;
169
169
  menuButton?: import("tailwind-variants").ClassValue;
170
170
  };
@@ -172,15 +172,15 @@ export declare const dockedDatePickerStyles: import("tailwind-variants").TVRetur
172
172
  } | {
173
173
  [x: string]: {
174
174
  [x: string]: import("tailwind-variants").ClassValue | {
175
- panel?: import("tailwind-variants").ClassValue;
176
- actions?: import("tailwind-variants").ClassValue;
177
175
  header?: import("tailwind-variants").ClassValue;
178
176
  view?: import("tailwind-variants").ClassValue;
177
+ menuIcon?: import("tailwind-variants").ClassValue;
178
+ group?: import("tailwind-variants").ClassValue;
179
179
  item?: import("tailwind-variants").ClassValue;
180
180
  check?: import("tailwind-variants").ClassValue;
181
+ actions?: import("tailwind-variants").ClassValue;
182
+ panel?: import("tailwind-variants").ClassValue;
181
183
  list?: import("tailwind-variants").ClassValue;
182
- menuIcon?: import("tailwind-variants").ClassValue;
183
- group?: import("tailwind-variants").ClassValue;
184
184
  calendar?: import("tailwind-variants").ClassValue;
185
185
  menuButton?: import("tailwind-variants").ClassValue;
186
186
  };
@@ -200,15 +200,15 @@ export declare const dockedDatePickerStyles: import("tailwind-variants").TVRetur
200
200
  }, undefined, {
201
201
  [key: string]: {
202
202
  [key: string]: import("tailwind-variants").ClassValue | {
203
- panel?: import("tailwind-variants").ClassValue;
204
- actions?: import("tailwind-variants").ClassValue;
205
203
  header?: import("tailwind-variants").ClassValue;
206
204
  view?: import("tailwind-variants").ClassValue;
205
+ menuIcon?: import("tailwind-variants").ClassValue;
206
+ group?: import("tailwind-variants").ClassValue;
207
207
  item?: import("tailwind-variants").ClassValue;
208
208
  check?: import("tailwind-variants").ClassValue;
209
+ actions?: import("tailwind-variants").ClassValue;
210
+ panel?: import("tailwind-variants").ClassValue;
209
211
  list?: import("tailwind-variants").ClassValue;
210
- menuIcon?: import("tailwind-variants").ClassValue;
211
- group?: import("tailwind-variants").ClassValue;
212
212
  calendar?: import("tailwind-variants").ClassValue;
213
213
  menuButton?: import("tailwind-variants").ClassValue;
214
214
  };
@@ -2,6 +2,6 @@ import { ComponentTokenSet } from "../../tokens/component.js";
2
2
  import "../../index.js";
3
3
  //#region src/components/date-picker/date-picker-tokens.d.ts
4
4
  /** The tokens of {@link DatePicker}, {@link DateRangePicker} and the date {@link PickerDialog}. */
5
- export declare const datePickerTokenSet: ComponentTokenSet<"container-color" | "container-shape" | "container-elevation" | "header-headline-color" | "date-selected-container-color" | "date-selected-label-text-color" | "date-today-container-outline-color" | "date-today-label-text-color" | "range-selection-active-indicator-container-color">;
5
+ export declare const datePickerTokenSet: ComponentTokenSet<"container-color" | "container-elevation" | "container-shape" | "header-headline-color" | "date-selected-container-color" | "date-selected-label-text-color" | "date-today-container-outline-color" | "date-today-label-text-color" | "range-selection-active-indicator-container-color">;
6
6
  //#endregion
7
7
  //# sourceMappingURL=date-picker-tokens.d.ts.map
@@ -201,7 +201,10 @@ export interface DialogHeaderLabels {
201
201
  export interface DialogHeaderProps extends Omit<ComponentPropsWithRef<'div'>, 'title'> {
202
202
  /** The headline; it names the dialog. */
203
203
  children: ReactNode;
204
- /** Words the header announces, with English defaults. */
204
+ /**
205
+ * Words the header announces, with English defaults. A {@link LabelsProvider} sets them for the
206
+ * whole app.
207
+ */
205
208
  labels?: Partial<DialogHeaderLabels>;
206
209
  /**
207
210
  * The confirming action, usually a text `Button` ("Save"). Shown in full screen only;
@@ -235,7 +238,7 @@ export interface DialogHeaderProps extends Omit<ComponentPropsWithRef<'div'>, 't
235
238
  * <DialogActions>…</DialogActions>
236
239
  * </Dialog>
237
240
  */
238
- export declare function DialogHeader({ children, labels, action, divider, closeDisabled, closeIcon, className, classNames, ...props }: DialogHeaderProps): import("react").JSX.Element;
241
+ export declare function DialogHeader({ children, labels: labelsProp, action, divider, closeDisabled, closeIcon, className, classNames, ...props }: DialogHeaderProps): import("react").JSX.Element;
239
242
  export interface DialogContentProps extends ComponentPropsWithRef<'div'> {
240
243
  /**
241
244
  * The basic dialog's optional dividers: 1px `outline-variant` lines across the panel
@@ -1,5 +1,6 @@
1
1
  "use client";
2
2
  import { cn } from "../../utils/cn.js";
3
+ import { useLabels } from "../labels/use-labels.js";
3
4
  import { TriggerContext, useTriggerProps } from "../../primitives/TriggerContext.js";
4
5
  import { mergeDataTokens } from "../../utils/merge-data-tokens.js";
5
6
  import { usePresence } from "../../primitives/use-presence.js";
@@ -325,7 +326,8 @@ const DEFAULT_HEADER_LABELS = { close: "Close" };
325
326
  * <DialogActions>…</DialogActions>
326
327
  * </Dialog>
327
328
  */
328
- function DialogHeader({ children, labels, action, divider = false, closeDisabled = false, closeIcon, className, classNames, ...props }) {
329
+ function DialogHeader({ children, labels: labelsProp, action, divider = false, closeDisabled = false, closeIcon, className, classNames, ...props }) {
330
+ const labels = useLabels("DialogHeader", DEFAULT_HEADER_LABELS, labelsProp);
329
331
  const { titleProps, hasIcon, fullScreen, close, setHeaderAction } = useContext(DialogPartsContext);
330
332
  const hasAction = action !== void 0;
331
333
  useLayoutEffect(() => {
@@ -345,7 +347,7 @@ function DialogHeader({ children, labels, action, divider = false, closeDisabled
345
347
  variant: "standard",
346
348
  density: 0,
347
349
  icon: closeIcon ?? /* @__PURE__ */ jsx(CloseIcon, {}),
348
- "aria-label": labels?.close ?? DEFAULT_HEADER_LABELS.close,
350
+ "aria-label": labels.close,
349
351
  disabled: closeDisabled,
350
352
  onPress: close,
351
353
  className: styles.headerButton({ class: cn(styles.close(), classNames?.close) })