@mortenbrudvik/waveui 0.11.0 → 0.12.0

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 (116) hide show
  1. package/README.md +97 -2
  2. package/dist/components/button/Link.cjs +1 -1
  3. package/dist/components/button/Link.cjs.map +1 -1
  4. package/dist/components/button/Link.mjs +4 -4
  5. package/dist/components/data-display/AvatarGroup.cjs +1 -1
  6. package/dist/components/data-display/AvatarGroup.cjs.map +1 -1
  7. package/dist/components/data-display/AvatarGroup.mjs +10 -10
  8. package/dist/components/data-display/InfoButton.cjs +1 -1
  9. package/dist/components/data-display/InfoButton.cjs.map +1 -1
  10. package/dist/components/data-display/InfoButton.mjs +12 -12
  11. package/dist/components/feedback/Toaster.cjs +1 -1
  12. package/dist/components/feedback/Toaster.cjs.map +1 -1
  13. package/dist/components/feedback/Toaster.mjs +235 -235
  14. package/dist/components/feedback/Toaster.mjs.map +1 -1
  15. package/dist/components/input/Combobox.cjs +1 -1
  16. package/dist/components/input/Combobox.cjs.map +1 -1
  17. package/dist/components/input/Combobox.mjs +176 -175
  18. package/dist/components/input/Combobox.mjs.map +1 -1
  19. package/dist/components/input/DatePicker.cjs +1 -1
  20. package/dist/components/input/DatePicker.cjs.map +1 -1
  21. package/dist/components/input/DatePicker.mjs +188 -187
  22. package/dist/components/input/DatePicker.mjs.map +1 -1
  23. package/dist/components/input/Dropdown.cjs +1 -1
  24. package/dist/components/input/Dropdown.cjs.map +1 -1
  25. package/dist/components/input/Dropdown.mjs +41 -40
  26. package/dist/components/input/Dropdown.mjs.map +1 -1
  27. package/dist/components/input/Option.cjs +1 -1
  28. package/dist/components/input/Option.cjs.map +1 -1
  29. package/dist/components/input/Option.mjs +89 -87
  30. package/dist/components/input/Option.mjs.map +1 -1
  31. package/dist/components/input/TagPicker.root.cjs +1 -1
  32. package/dist/components/input/TagPicker.root.cjs.map +1 -1
  33. package/dist/components/input/TagPicker.root.mjs +136 -135
  34. package/dist/components/input/TagPicker.root.mjs.map +1 -1
  35. package/dist/components/input/TimePicker.cjs +1 -1
  36. package/dist/components/input/TimePicker.cjs.map +1 -1
  37. package/dist/components/input/TimePicker.mjs +156 -154
  38. package/dist/components/input/TimePicker.mjs.map +1 -1
  39. package/dist/components/navigation/Menu.popover.cjs +1 -1
  40. package/dist/components/navigation/Menu.popover.cjs.map +1 -1
  41. package/dist/components/navigation/Menu.popover.mjs +137 -127
  42. package/dist/components/navigation/Menu.popover.mjs.map +1 -1
  43. package/dist/components/navigation/Menu.root.cjs +1 -1
  44. package/dist/components/navigation/Menu.root.cjs.map +1 -1
  45. package/dist/components/navigation/Menu.root.mjs +4 -4
  46. package/dist/components/overlays/Dialog.cjs +1 -1
  47. package/dist/components/overlays/Dialog.cjs.map +1 -1
  48. package/dist/components/overlays/Dialog.mjs +123 -123
  49. package/dist/components/overlays/Dialog.mjs.map +1 -1
  50. package/dist/components/overlays/Drawer.panel.cjs +1 -1
  51. package/dist/components/overlays/Drawer.panel.cjs.map +1 -1
  52. package/dist/components/overlays/Drawer.panel.mjs +12 -12
  53. package/dist/components/overlays/Drawer.panel.mjs.map +1 -1
  54. package/dist/components/overlays/Popover.cjs +1 -1
  55. package/dist/components/overlays/Popover.cjs.map +1 -1
  56. package/dist/components/overlays/Popover.mjs +173 -162
  57. package/dist/components/overlays/Popover.mjs.map +1 -1
  58. package/dist/components/overlays/TeachingPopover.cjs +1 -1
  59. package/dist/components/overlays/TeachingPopover.cjs.map +1 -1
  60. package/dist/components/overlays/TeachingPopover.mjs +96 -91
  61. package/dist/components/overlays/TeachingPopover.mjs.map +1 -1
  62. package/dist/components/overlays/Tooltip.cjs +1 -1
  63. package/dist/components/overlays/Tooltip.cjs.map +1 -1
  64. package/dist/components/overlays/Tooltip.mjs +47 -47
  65. package/dist/components/overlays/Tooltip.mjs.map +1 -1
  66. package/dist/components/portal/Portal.cjs +1 -1
  67. package/dist/components/portal/Portal.cjs.map +1 -1
  68. package/dist/components/portal/Portal.mjs +5 -5
  69. package/dist/components/table/DataGrid.cjs +1 -1
  70. package/dist/components/table/DataGrid.cjs.map +1 -1
  71. package/dist/components/table/DataGrid.mjs +1 -1
  72. package/dist/hooks/useDismiss.cjs.map +1 -1
  73. package/dist/hooks/useDismiss.mjs.map +1 -1
  74. package/dist/hooks/useFocusTrap.cjs.map +1 -1
  75. package/dist/hooks/useFocusTrap.mjs.map +1 -1
  76. package/dist/hooks/useFocusVisible.cjs +2 -0
  77. package/dist/hooks/useFocusVisible.cjs.map +1 -0
  78. package/dist/hooks/useFocusVisible.mjs +49 -0
  79. package/dist/hooks/useFocusVisible.mjs.map +1 -0
  80. package/dist/hooks/useFocusableGroup.cjs +2 -0
  81. package/dist/hooks/useFocusableGroup.cjs.map +1 -0
  82. package/dist/hooks/useFocusableGroup.mjs +70 -0
  83. package/dist/hooks/useFocusableGroup.mjs.map +1 -0
  84. package/dist/hooks/useModalLayer.cjs +1 -1
  85. package/dist/hooks/useModalLayer.cjs.map +1 -1
  86. package/dist/hooks/useModalLayer.mjs +4 -4
  87. package/dist/hooks/useModalOpen.cjs +2 -0
  88. package/dist/hooks/useModalOpen.cjs.map +1 -0
  89. package/dist/hooks/useModalOpen.mjs +14 -0
  90. package/dist/hooks/useModalOpen.mjs.map +1 -0
  91. package/dist/hooks/usePopupPosition.cjs +1 -1
  92. package/dist/hooks/usePopupPosition.cjs.map +1 -1
  93. package/dist/hooks/usePopupPosition.mjs +82 -53
  94. package/dist/hooks/usePopupPosition.mjs.map +1 -1
  95. package/dist/hooks/useResolvedTarget.cjs +2 -0
  96. package/dist/hooks/useResolvedTarget.cjs.map +1 -0
  97. package/dist/hooks/useResolvedTarget.mjs +37 -0
  98. package/dist/hooks/useResolvedTarget.mjs.map +1 -0
  99. package/dist/hooks/useRovingGrid.cjs +1 -1
  100. package/dist/hooks/useRovingGrid.cjs.map +1 -1
  101. package/dist/hooks/useRovingGrid.mjs +8 -57
  102. package/dist/hooks/useRovingGrid.mjs.map +1 -1
  103. package/dist/hooks/useRovingTabIndex.cjs +1 -1
  104. package/dist/hooks/useRovingTabIndex.cjs.map +1 -1
  105. package/dist/hooks/useRovingTabIndex.mjs +142 -107
  106. package/dist/hooks/useRovingTabIndex.mjs.map +1 -1
  107. package/dist/index.cjs +1 -1
  108. package/dist/index.d.cts +814 -18
  109. package/dist/index.d.ts +814 -18
  110. package/dist/index.mjs +120 -108
  111. package/dist/lib/layers.cjs +1 -1
  112. package/dist/lib/layers.cjs.map +1 -1
  113. package/dist/lib/layers.mjs +112 -109
  114. package/dist/lib/layers.mjs.map +1 -1
  115. package/dist/styles.css +1 -1
  116. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"DatePicker.mjs","names":["formatLocaleDate","parseLocaleDate","useId","useId$1","React","defaultInvalidDateLabel","pattern","defaultOutOfRangeLabel","min","max","CALENDAR_PART_CLASS_NAMES","datePickerClassNames","DatePicker","valueProp","formatDateProp","parseDateProp","sizeProp","appearanceProp","openProp","ariaLabel","ariaLabelledBy","ariaDescribedBy","ariaInvalid","ariaRequired","ariaErrorMessage","ariaDetails","rest","props","onChange","warnDeprecated","useInputLook","hasCustomFormat","hasCustomParse","warnOnce","locale","isValidLocaleTag","selectedDate","setSelectedDate","useControllable","defaultValue","onValueChange","next","interactive","disabled","readOnly","openState","setOpen","defaultOpen","onOpenChange","isClient","useIsClient","isOpen","openControlled","format","date","formatDate","parse","text","parseDate","draft","setDraft","invalid","setInvalid","wasInteractive","setWasInteractive","selectedDay","formatISODate","seenDay","setSeenDay","commitDate","normalized","startOfDay","isSameDay","commitDraft","parsed","reason","isDateInRange","minDate","maxDate","disabledDates","rejected","onInvalidInput","openedFromInput","setOpenedFromInput","inputRef","toggleRef","surfaceRef","restoreTargetRef","surface","setSurface","inputRefs","useMergedRefs","controlRef","dialogId","headingId","errorId","close","restoreTo","useDismiss","target","event","FOCUSABLE_SELECTOR","usePopupPosition","surfaceRefs","setFloating","useFocusTrap","useRestoreFocus","field","useFieldContext","validates","required","showOwnError","fieldProps","useFieldControl","joinIds","invalidLook","isInvalidLook","form","showClear","clearable","handleInputChange","handleInputKeyDown","composeEventHandlers","onKeyDown","flushSync","handleInputBlur","onBlur","handleToggle","handleClear","handleClearMouseDown","selectDate","day","requestClose","handleDialogKeyDown","inputText","errorMessage","labels","getLocaleDateFormat","size","appearance","cn","className","setReference","inputHeightClasses","inputPaddingClasses","inputTextClasses","inputAppearanceClasses","inputFocus","disabledStyles","pickerEndPadding","pickerIconButtonClasses","pickerButtonOffset","DismissIcon","pickerGlyphSize","focusRing","CalendarIcon","HiddenInput","Portal","floatingProps","CalendarView","showCloseButton"],"sources":["../../../src/components/input/DatePicker.tsx"],"sourcesContent":["import * as React from 'react';\nimport { flushSync } from 'react-dom';\nimport { cn } from '../../lib/cn';\nimport { joinIds } from '../../lib/aria';\nimport { datePickerClassNames } from '../../lib/classNames';\nimport { composeEventHandlers } from '../../lib/composeEventHandlers';\nimport type { CoreSize, DayOfWeek, FirstWeekOfYear, InputAppearance } from '../../lib/types';\nimport { warnDeprecated, warnOnce } from '../../lib/dev';\nimport { FOCUSABLE_SELECTOR } from '../../lib/focus';\nimport { CalendarIcon, DismissIcon } from '../../lib/icons';\nimport {\n disabledStyles,\n focusRing,\n inputAppearanceClasses,\n inputFocus,\n inputHeightClasses,\n inputInvalid,\n inputPaddingClasses,\n inputTextClasses,\n} from '../../lib/styles';\nimport { useControllable } from '../../hooks/useControllable';\nimport { useDismiss } from '../../hooks/useDismiss';\nimport { useFieldContext, useFieldControl } from '../../hooks/useFieldControl';\nimport { useFocusTrap } from '../../hooks/useFocusTrap';\nimport { useFormReset } from '../../hooks/useFormReset';\nimport { useId } from '../../hooks/useId';\nimport { useIsClient } from '../../hooks/useIsClient';\nimport { useMergedRefs } from '../../hooks/useMergedRefs';\nimport { usePopupPosition } from '../../hooks/usePopupPosition';\nimport { useRestoreFocus } from '../../hooks/useRestoreFocus';\nimport { HiddenInput } from '../internal/HiddenInput';\nimport { Portal } from '../portal/Portal';\nimport { CalendarView, type CalendarLabels, type CalendarViewPartClassNames } from './Calendar';\nimport {\n formatDate as formatLocaleDate,\n formatISODate,\n getLocaleDateFormat,\n isDateInRange,\n isSameDay,\n isValidLocaleTag,\n parseDate as parseLocaleDate,\n startOfDay,\n} from './dateUtils';\nimport { useInputLook } from './inputLook';\nimport { isInvalidLook } from './Input';\nimport {\n pickerButtonOffset,\n pickerEndPadding,\n pickerGlyphSize,\n pickerIconButtonClasses,\n} from './pickerStyles';\nimport type { RoutedHandlers } from './routedHandlers';\n\n/** Why typed text was not accepted (see {@link DatePickerProps.onInvalidInput}). */\nexport type DatePickerInvalidReason = 'unparseable' | 'out-of-range' | 'disabled';\n\n/**\n * The DatePicker's built-in button names and error texts, for localization: its own (clear, open\n * calendar, the errors of typed text, Close) and those of the calendar in its dialog\n * ({@link CalendarLabels}: the navigation buttons, the heading button's hints, \"Go to today\", the\n * week-number column and the marked days; its `required` hint does not apply). Each member is\n * optional and falls back to its English default. Month and weekday names and the day labels\n * follow `locale`.\n */\nexport interface DatePickerLabels extends CalendarLabels {\n /** Name of the clear button.\n * @default 'Clear date'\n */\n clear?: string;\n /** Name of the button that opens the calendar.\n * @default 'Open calendar'\n */\n openCalendar?: string;\n /** Name of the footer button that closes the calendar (`showCloseButton`).\n * @default 'Close'\n */\n close?: string;\n /**\n * Error text for typed text that is not a date. `pattern` is the default format of `locale`\n * written with English field letters (`'MM/DD/YYYY'`, `'DD.MM.YYYY'`), or `undefined` with a\n * custom `parseDate` (its format is unknown to the picker).\n * @default (pattern) => pattern ? `Enter a date in the format ${pattern}.` : 'Enter a valid date.'\n */\n invalidDate?: (pattern: string | undefined) => string;\n /**\n * Error text for a typed date outside `minDate`/`maxDate`. The bounds are passed as the input\n * shows dates (`formatDate`); a bound that is not set is `undefined`.\n * @default (min, max) => `Enter a date between ${min} and ${max}.` (only `min`: `Enter a date on\n * or after ${min}.`; only `max`: `Enter a date on or before ${max}.`)\n */\n outOfRange?: (min: string | undefined, max: string | undefined) => string;\n /** Error text for a typed date that `disabledDates` excludes.\n * @default 'This date is not available.'\n */\n unavailableDate?: string;\n}\n\nconst defaultInvalidDateLabel = (pattern: string | undefined) =>\n pattern ? `Enter a date in the format ${pattern}.` : 'Enter a valid date.';\n\nconst defaultOutOfRangeLabel = (min: string | undefined, max: string | undefined) => {\n if (min !== undefined && max !== undefined) return `Enter a date between ${min} and ${max}.`;\n if (min !== undefined) return `Enter a date on or after ${min}.`;\n return `Enter a date on or before ${max}.`;\n};\n\n/** Properties for the DatePicker component. */\nexport interface DatePickerProps extends Omit<\n React.HTMLAttributes<HTMLDivElement>,\n 'onChange' | 'defaultValue' | 'placeholder' | RoutedHandlers\n> {\n /** Controlled selected date (`null` for none). Emitted dates are always local midnight. */\n value?: Date | null;\n /**\n * Initial date for uncontrolled usage.\n * @default null\n */\n defaultValue?: Date | null;\n /** Called with the new date (local midnight) or `null` whenever the selected day changes. */\n onValueChange?: (date: Date | null) => void;\n /**\n * @deprecated Use `onValueChange`. Still called with the new date (warns once in development).\n */\n onChange?: (date: Date | null) => void;\n /**\n * Formats the selected date for the input. Supply `parseDate` as its inverse: without it, typed\n * text is parsed with the default parser for `locale` (development warning).\n * @default Intl.DateTimeFormat(locale, { year: 'numeric', month: '2-digit', day: '2-digit' }),\n * in the Gregorian calendar when the locale's own has other months (see `locale`)\n */\n formatDate?: (date: Date) => string;\n /**\n * Parses typed text into a date (`null` when it is not one); the result is normalized to local\n * midnight. The default is the exact inverse of the default format for `locale` and also\n * accepts ISO `yyyy-mm-dd`.\n */\n parseDate?: (text: string) => Date | null;\n /**\n * BCP 47 locale of the default format/parse, the month and weekday names and the day labels\n * (runtime default when omitted). Pass it explicitly when rendering on the server, so the server\n * and the browser format the same text. The grid is Gregorian: a locale calendar with other\n * months or eras (the Persian default of `fa-IR`, `-u-ca-islamic`, `-u-ca-japanese`) is replaced\n * by the Gregorian one in the locale's language and digits; the Buddhist years of `th-TH` stay.\n * A tag `Intl` rejects (the POSIX `de_DE`, a typo) falls back to the runtime default locale\n * (development warning).\n */\n locale?: string;\n /** Earliest selectable day (the whole day is included). */\n minDate?: Date;\n /** Latest selectable day (the whole day is included). */\n maxDate?: Date;\n /** Returns `true` for days that cannot be selected (called with local-midnight dates). */\n disabledDates?: (date: Date) => boolean;\n /**\n * Placeholder text shown when no date is selected.\n * @default 'Select a date'\n */\n placeholder?: string;\n /**\n * Whether the date picker is disabled and non-interactive (the calendar is not shown).\n * @default false\n */\n disabled?: boolean;\n /**\n * Size of the field: `small` (24px tall), `medium` (32px) or `large` (40px). Default: the\n * surrounding Field's `size`, else `WaveProvider inputDefaults.size`, else `'medium'`. The\n * calendar keeps its size.\n */\n size?: CoreSize;\n /**\n * Look of the field: `outline` (a full border), `underline` (a bottom stroke only),\n * `filled-darker` or `filled-lighter` (a fill without a visible stroke: give the field a visible\n * label). Default: `WaveProvider inputDefaults.appearance`, else `'outline'`.\n */\n appearance?: InputAppearance;\n /**\n * Makes the input read-only: the calendar does not open and the value cannot change. Turning it\n * (or `disabled`) on while the user is typing drops the typed text.\n */\n readOnly?: boolean;\n /**\n * Whether to show a clear button when a date is selected (not shown while `readOnly`). Tab from\n * erased text clears the value before focus moves, so focus goes on to the calendar button, past\n * the clear button that disappears with it.\n * @default false\n */\n clearable?: boolean;\n /**\n * First day of the week (0 = Sunday, 1 = Monday, etc.).\n * @default 0\n */\n firstDayOfWeek?: DayOfWeek;\n /**\n * The day marked as today in the calendar (`aria-current=\"date\"`) and the start of its keys when\n * no day is selected. See `Calendar`'s `today`.\n * @default the current date\n */\n today?: Date;\n /**\n * The month the calendar shows first when there is no value, clamped into `minDate`/`maxDate`.\n * @default today's month\n */\n initialVisibleDate?: Date;\n /**\n * Turns the calendar's month text into a button that shows the month view, whose heading, the\n * year, is a button to the year view. Escape steps back from the year view to the month view\n * and from there to the days; it closes the calendar only from the day view.\n * @default true\n */\n showMonthPicker?: boolean;\n /**\n * Adds a leading column of week numbers to the calendar.\n * @default false\n */\n showWeekNumbers?: boolean;\n /**\n * Which week is week 1 of a year. ISO 8601 is `'first-four-day-week'` with `firstDayOfWeek={1}`.\n * @default 'first-day'\n */\n firstWeekOfYear?: FirstWeekOfYear;\n /**\n * Adds a \"Go to today\" button to the calendar's footer: it shows today's month and focuses\n * today without selecting it, and is disabled while today is outside `minDate`/`maxDate`.\n * @default false\n */\n showGoToToday?: boolean;\n /**\n * Adds a Close button to the calendar's footer; it closes the calendar as Escape does from the\n * day view (focus returns to the toggle, or to the input after Alt+ArrowDown).\n * @default false\n */\n showCloseButton?: boolean;\n /**\n * Days that draw a dot and say \"marked\" in their name in the calendar (`labels.markedDay`).\n * Called with local-midnight dates.\n */\n markedDates?: (date: Date) => boolean;\n /**\n * Replaces the content inside a calendar day's button; `defaultContent` is the day number. The\n * content must be non-interactive, and the button's name does not follow it: set the name with\n * `dayLabel`.\n */\n renderDay?: (date: Date, defaultContent: React.ReactNode) => React.ReactNode;\n /**\n * The accessible name of a calendar day, from its default name (the date in words, with\n * `labels.markedDay` applied for a marked day).\n */\n dayLabel?: (date: Date, defaultLabel: string) => string;\n /**\n * Controlled open state of the calendar. The calendar renders only in the browser: an open\n * picker is closed in the server HTML and opens once it has hydrated.\n */\n open?: boolean;\n /**\n * Initial open state for uncontrolled usage. A picker that starts disabled or read-only starts\n * closed. The calendar renders only in the browser: it is closed in the server HTML and opens\n * once the picker has hydrated.\n * @default false\n */\n defaultOpen?: boolean;\n /** Called when the calendar opens or closes (only when the state changes). */\n onOpenChange?: (open: boolean) => void;\n /**\n * Called when typed text is not accepted on Enter, Alt+ArrowDown or blur (once per edit): it\n * cannot be parsed (`'unparseable'`), lies outside `minDate`/`maxDate` (`'out-of-range'`) or is\n * excluded by `disabledDates` (`'disabled'`). The text stays in the input, which is marked\n * `aria-invalid` and described by an error message (left to the surrounding `Field` when it\n * shows an error). Enter reports it again when pressed again.\n */\n onInvalidInput?: (text: string, reason: DatePickerInvalidReason) => void;\n /**\n * Names of the clear, calendar and month buttons and the error texts of rejected typed text, for\n * localization. Unset members keep their English defaults.\n */\n labels?: DatePickerLabels;\n /** Form field name: the date is submitted as ISO `yyyy-mm-dd` (hidden input). */\n name?: string;\n /** Id of the `<form>` the value belongs to, when the picker is outside it. */\n form?: string;\n /**\n * Blocks form submission while no date is selected; sets `aria-required` on the input. Like a\n * native readonly input, a `readOnly` DatePicker does not block submission.\n */\n required?: boolean;\n /** Native `autocomplete` of the input. @default 'off' */\n autoComplete?: string;\n /** Focus handler of the text input (the root keeps the other handlers). */\n onFocus?: React.FocusEventHandler<HTMLInputElement>;\n /** Blur handler of the text input. */\n onBlur?: React.FocusEventHandler<HTMLInputElement>;\n /** Key handler of the text input; `preventDefault()` skips the picker's own keys. */\n onKeyDown?: React.KeyboardEventHandler<HTMLInputElement>;\n /** Key handler of the text input. */\n onKeyUp?: React.KeyboardEventHandler<HTMLInputElement>;\n /** Ref to the text input; `ref` stays on the root. */\n controlRef?: React.Ref<HTMLInputElement>;\n /** Ref to the root element. */\n ref?: React.Ref<HTMLDivElement>;\n}\n\n// The calendar's parts keep DatePicker's stable classes (0.8), on the same elements.\nconst CALENDAR_PART_CLASS_NAMES: CalendarViewPartClassNames = {\n header: datePickerClassNames.header,\n previousMonthButton: datePickerClassNames.previousMonthButton,\n heading: datePickerClassNames.heading,\n headingButton: datePickerClassNames.headingButton,\n nextMonthButton: datePickerClassNames.nextMonthButton,\n grid: datePickerClassNames.grid,\n weekday: datePickerClassNames.weekday,\n day: datePickerClassNames.day,\n month: datePickerClassNames.month,\n year: datePickerClassNames.year,\n weekNumberHeader: datePickerClassNames.weekNumberHeader,\n weekNumber: datePickerClassNames.weekNumber,\n markedDot: datePickerClassNames.markedDot,\n footer: datePickerClassNames.footer,\n todayButton: datePickerClassNames.todayButton,\n closeButton: datePickerClassNames.closeButton,\n};\n\n/**\n * A date input with a calendar dialog (APG date picker dialog).\n *\n * - **Typing**: the input accepts the default display format of `locale` (`Intl` numeric\n * year/month/day, e.g. `03/04/2025` for `en-GB`, `04/03/2025` for `en-US`) and ISO\n * `yyyy-mm-dd`. Text is committed on Enter, on Alt+ArrowDown (before the calendar opens) or when\n * the field loses focus — only when it was edited, and only when it names a different day. Text\n * that is not an available date is kept, the input is marked invalid and an error message\n * describes it (`onInvalidInput`, reported once per edit) until the text is edited or replaced\n * (a day picked in the calendar, the clear button, a form reset, a new day from the parent).\n * - **Calendar**: the toggle (`aria-haspopup=\"dialog\"`) or Alt+ArrowDown in the input opens a\n * modal dialog labelled by the month heading. Focus moves to the selected day (else today, else\n * the first available day of the month) and Tab stays inside. Arrow keys move by day/week\n * (mirrored in RTL), PageUp/PageDown by month, Shift+PageUp/PageDown by year (the day is clamped\n * to the month), Home/End to the start/end of the week, Enter/Space select. The month text is a\n * button (the heading button, `showMonthPicker`) that shows the month view, whose heading, the\n * year, leads to the year view; Escape steps back from the year view to the month view and from\n * there to the days, and closes only from the day view, returning focus to where the calendar\n * was opened from (the toggle, or the input after Alt+ArrowDown); a press outside closes it too.\n * `showCloseButton` adds a Close button that closes as Escape does from the day view, and\n * `showGoToToday` a button that shows today's month. `showWeekNumbers`, `markedDates`,\n * `renderDay` and `dayLabel` shape the day grid as in `Calendar`. Unavailable days stay focusable\n * (`aria-disabled`); a day focused by pointer becomes the starting point of the arrow keys. The\n * selected day is `aria-selected` on its gridcell and `aria-pressed` on its focusable button, so\n * the state is announced when focus lands on it; today is `aria-current=\"date\"`.\n * - The calendar closes when the picker becomes disabled or read-only (uncontrolled `open`: it\n * stays closed when the picker is enabled again), and the text typed until then is dropped.\n * - `clearable` shows a clear button while a date is selected (not while read-only). Tab from\n * erased text clears the value first, so focus moves on to the calendar button instead of to the\n * clear button that disappears.\n * - Every emitted date is local midnight. The calendar opens on the month of the selected date or\n * today, clamped into `minDate`/`maxDate`.\n * - **Size and appearance**: `size` resolves from its own prop, then the surrounding `Field`'s\n * `size`, then `WaveProvider inputDefaults.size`, else `'medium'`; `appearance` from its own\n * prop, then `WaveProvider inputDefaults.appearance`, else `'outline'`; both render as\n * `data-size` and `data-appearance` on the root `<div>`. The calendar keeps its size.\n * - The input (`controlRef`) receives `id`, `aria-label`, `aria-labelledby`, `aria-describedby`,\n * `aria-invalid`, `aria-required`, `aria-errormessage`, `aria-details`, `tabIndex`,\n * `autoFocus`, `onFocus`/`onBlur`/`onKeyDown`/`onKeyUp` and the text input attributes\n * `autoComplete`, `autoCapitalize`, `autoCorrect`, `inputMode`, `spellCheck` and\n * `enterKeyHint`. `ref`, `className`, `style`, other `aria-*` attributes and the remaining props\n * stay on the root `<div>`. Inside a `Field`, the input is labelled and described by it.\n * - `name`/`required` add a hidden input for native forms (ISO `yyyy-mm-dd`); the value resets\n * with its form.\n * - The built-in button names and error texts are English; `labels` localizes them.\n * - Pass `locale` explicitly when rendering on the server (see `locale`). The calendar renders only\n * in the browser: an open calendar (`defaultOpen`, `open`) is closed in the server HTML and opens\n * once the picker has hydrated.\n */\nexport const DatePicker = (props: DatePickerProps) => {\n const {\n value: valueProp,\n defaultValue,\n onValueChange,\n onChange,\n formatDate: formatDateProp,\n parseDate: parseDateProp,\n locale,\n minDate,\n maxDate,\n disabledDates,\n placeholder = 'Select a date',\n disabled = false,\n size: sizeProp,\n appearance: appearanceProp,\n readOnly,\n clearable = false,\n firstDayOfWeek = 0,\n today,\n initialVisibleDate,\n showMonthPicker,\n showWeekNumbers,\n firstWeekOfYear,\n showGoToToday,\n showCloseButton = false,\n markedDates,\n renderDay,\n dayLabel,\n open: openProp,\n defaultOpen,\n onOpenChange,\n onInvalidInput,\n labels,\n name,\n form,\n required,\n autoComplete = 'off',\n autoCapitalize,\n autoCorrect,\n enterKeyHint,\n inputMode,\n spellCheck,\n autoFocus,\n tabIndex,\n id,\n 'aria-label': ariaLabel,\n 'aria-labelledby': ariaLabelledBy,\n 'aria-describedby': ariaDescribedBy,\n 'aria-invalid': ariaInvalid,\n 'aria-required': ariaRequired,\n 'aria-errormessage': ariaErrorMessage,\n 'aria-details': ariaDetails,\n onFocus,\n onBlur,\n onKeyDown,\n onKeyUp,\n controlRef,\n className,\n ref,\n ...rest\n } = props;\n\n if (onChange !== undefined) warnDeprecated('DatePicker', 'onChange', 'onValueChange');\n\n const { size, appearance } = useInputLook(sizeProp, appearanceProp);\n\n const hasCustomFormat = formatDateProp !== undefined;\n const hasCustomParse = parseDateProp !== undefined;\n React.useEffect(() => {\n if (hasCustomFormat && !hasCustomParse) {\n warnOnce(\n 'DatePicker:formatDate-without-parseDate',\n 'DatePicker: `formatDate` is set without `parseDate`. Typed dates are parsed with the ' +\n 'default parser for `locale` (its numeric format or yyyy-mm-dd), which may not read ' +\n 'your format; pass `parseDate` as the inverse of `formatDate`.',\n );\n }\n }, [hasCustomFormat, hasCustomParse]);\n React.useEffect(() => {\n if (locale !== undefined && !isValidLocaleTag(locale)) {\n warnOnce(\n `DatePicker:invalid-locale:${locale}`,\n `DatePicker: \\`locale\\` \"${locale}\" is not a valid BCP 47 language tag (use hyphens, as ` +\n 'in \"en-US\"). The runtime default locale formats and parses the dates instead, so the ' +\n 'server and the browser may render different text.',\n );\n }\n }, [locale]);\n\n const [selectedDate, setSelectedDate] = useControllable<Date | null>(\n valueProp,\n defaultValue ?? null,\n (next) => {\n onValueChange?.(next);\n onChange?.(next);\n },\n );\n const interactive = !disabled && !readOnly;\n const [openState, setOpen] = useControllable<boolean>(\n openProp,\n // A picker that starts disabled or read-only never shows its calendar, so it starts closed\n // (no close to report later).\n (defaultOpen ?? false) && interactive,\n onOpenChange,\n );\n // The calendar lives in a portal, which renders only in the browser: until then (the server\n // HTML, hydration) the picker reports it closed, so no reference names a missing element.\n const isClient = useIsClient();\n const isOpen = openState && interactive && isClient;\n const openControlled = openProp !== undefined;\n\n // A calendar hidden because the picker became disabled or read-only is closed for good\n // (uncontrolled), so enabling the picker again does not bring it back and take focus.\n // onOpenChange(false) reports it; a controlled `open` stays the parent's.\n React.useEffect(() => {\n if (!interactive && openState && !openControlled) setOpen(false);\n }, [interactive, openState, openControlled, setOpen]);\n\n const format = (date: Date) =>\n formatDateProp ? formatDateProp(date) : formatLocaleDate(date, locale);\n const parse = (text: string) =>\n parseDateProp ? parseDateProp(text) : parseLocaleDate(text, locale);\n\n /* ---- draft text and validation ---------------------------------- */\n\n /** Typed text; `null` shows the formatted selected date (draft model). */\n const [draft, setDraft] = React.useState<string | null>(null);\n const [invalid, setInvalid] = React.useState<DatePickerInvalidReason | null>(null);\n\n // Adjusted during render (C-HOOKS). Locking the picker (readOnly/disabled) while the user types\n // drops the typed text and its error, so no later blur commits it (the value cannot change).\n const [wasInteractive, setWasInteractive] = React.useState(interactive);\n if (wasInteractive !== interactive) {\n setWasInteractive(interactive);\n if (!interactive) {\n setDraft(null);\n setInvalid(null);\n }\n }\n // A selected day the parent changes replaces rejected text (commits clear it themselves), so the\n // input never shows an error next to a valid value. Text the user is still typing stays.\n const selectedDay = selectedDate ? formatISODate(selectedDate) : '';\n const [seenDay, setSeenDay] = React.useState(selectedDay);\n if (seenDay !== selectedDay) {\n setSeenDay(selectedDay);\n if (invalid !== null) {\n setDraft(null);\n setInvalid(null);\n }\n }\n\n /** Commits a day (or `null`); nothing is emitted when it is the same day. */\n const commitDate = (next: Date | null) => {\n const normalized = next ? startOfDay(next) : null;\n const unchanged = normalized ? isSameDay(normalized, selectedDate) : selectedDate === null;\n if (!unchanged) setSelectedDate(normalized);\n setDraft(null);\n setInvalid(null);\n };\n\n /** Validates and commits the typed text; `false` when it was rejected (the text is kept). */\n const commitDraft = (text: string): boolean => {\n if (!text.trim()) {\n commitDate(null);\n return true;\n }\n const parsed = parse(text);\n let reason: DatePickerInvalidReason | null = null;\n if (!parsed || Number.isNaN(parsed.getTime())) reason = 'unparseable';\n else if (!isDateInRange(parsed, minDate, maxDate)) reason = 'out-of-range';\n else if (disabledDates?.(startOfDay(parsed))) reason = 'disabled';\n if (reason || !parsed) {\n const rejected = reason ?? 'unparseable';\n setInvalid(rejected);\n onInvalidInput?.(text, rejected);\n return false;\n }\n commitDate(parsed);\n return true;\n };\n\n /* ---- calendar --------------------------------------------------- */\n\n /** Opened with Alt+ArrowDown in the input: Escape returns focus there instead of the toggle. */\n const [openedFromInput, setOpenedFromInput] = React.useState(false);\n\n // A closed calendar forgets where it was opened from. This also drops an Alt+ArrowDown whose\n // opening a controlled parent declined (it renders in the same update, still closed), so a later\n // opening by the parent returns focus to the toggle, not the input.\n if (openedFromInput && !isOpen) setOpenedFromInput(false);\n\n /* ---- elements, popup primitives ---------------------------------- */\n\n const inputRef = React.useRef<HTMLInputElement | null>(null);\n const toggleRef = React.useRef<HTMLButtonElement | null>(null);\n const surfaceRef = React.useRef<HTMLDivElement | null>(null);\n /** Where focus goes when the calendar closes (`null`: back to the toggle). */\n const restoreTargetRef = React.useRef<HTMLElement | null>(null);\n const [surface, setSurface] = React.useState<HTMLDivElement | null>(null);\n const inputRefs = useMergedRefs<HTMLInputElement>(controlRef, inputRef);\n\n const dialogId = useId('datepicker-dialog');\n const headingId = useId('datepicker-heading');\n const errorId = useId('datepicker-error');\n\n const close = (restoreTo: HTMLElement | null) => {\n restoreTargetRef.current = restoreTo;\n setOpen(false);\n };\n\n const { layerId } = useDismiss({\n open: isOpen,\n onDismiss: (reason, event) => {\n // An outside press on another control hands focus to it (the trap held it until now);\n // otherwise focus returns to where the calendar was opened from.\n const target =\n reason === 'outside-press' && event.target instanceof Element\n ? event.target.closest<HTMLElement>(FOCUSABLE_SELECTOR)\n : null;\n close(target ?? (openedFromInput ? inputRef.current : null));\n },\n refs: [surfaceRef, toggleRef],\n anchorRef: toggleRef,\n kind: 'modal',\n });\n\n const { setReference, setFloating, floatingProps } = usePopupPosition({\n open: isOpen,\n side: 'bottom',\n align: 'start',\n });\n const surfaceRefs = useMergedRefs<HTMLDivElement>(surfaceRef, setSurface, setFloating);\n\n useFocusTrap(surface, {\n enabled: isOpen,\n layerId,\n // The calendar mounts with the dialog, so its grid's tab stop is in the surface already.\n initialFocus: () =>\n surfaceRef.current?.querySelector<HTMLElement>(\n '[data-wave-calendar-grid] button[tabindex=\"0\"]',\n ) ?? null,\n });\n\n useRestoreFocus({\n enabled: isOpen,\n container: surface,\n triggerRef: toggleRef,\n finalFocusRef: restoreTargetRef,\n onlyIfFocusInside: true,\n });\n\n // A new opening starts without a restore target (the toggle returns focus to itself, Escape to\n // where the calendar was opened from).\n React.useLayoutEffect(() => {\n if (isOpen) restoreTargetRef.current = null;\n }, [isOpen]);\n\n /* ---- forms and Field --------------------------------------------- */\n\n const field = useFieldContext();\n const isRequired = required ?? field?.required ?? false;\n // Like a native readonly input, a read-only picker is barred from constraint validation (the\n // user could not fix it); its value is still submitted.\n const validates = isRequired && !readOnly;\n const showOwnError = invalid !== null && !field?.hasErrorMessage;\n const fieldProps = useFieldControl({\n id,\n 'aria-label': ariaLabel,\n 'aria-labelledby': ariaLabelledBy,\n 'aria-describedby': joinIds(ariaDescribedBy, showOwnError ? errorId : undefined),\n 'aria-invalid': invalid !== null ? true : ariaInvalid,\n // An explicit `required={false}` wins over a required Field, so aria-required matches\n // `isRequired`.\n 'aria-required': ariaRequired ?? required,\n });\n const invalidLook = isInvalidLook(false, fieldProps['aria-invalid']);\n\n // Through the commit path: the default is emitted as local midnight, and only when it names\n // another day; the typed text and its error are dropped.\n useFormReset(inputRef, () => commitDate(defaultValue ?? null), form);\n\n // Read-only pickers offer no clear action (the value cannot change).\n const showClear = clearable && !readOnly && selectedDate !== null;\n\n /* ---- handlers ---------------------------------------------------- */\n\n const handleInputChange = (event: React.ChangeEvent<HTMLInputElement>) => {\n if (!interactive) return;\n setDraft(event.target.value);\n setInvalid(null);\n };\n\n const handleInputKeyDown = composeEventHandlers(\n onKeyDown,\n (event: React.KeyboardEvent<HTMLInputElement>) => {\n // Keys that belong to an IME composition (its confirming Enter) are left to the IME.\n if (!interactive || event.nativeEvent.isComposing) return;\n if (event.key === 'Enter' && draft !== null) {\n // An edit is committed instead of submitting the form; untouched text lets Enter submit.\n event.preventDefault();\n commitDraft(draft);\n } else if (\n event.key === 'Tab' &&\n !event.shiftKey &&\n showClear &&\n draft !== null &&\n !draft.trim()\n ) {\n // Erased text clears the value, and with it the clear button, the next tab stop. It is\n // settled before Tab moves focus (the blur would settle it while focus moves to that\n // button), so focus moves on to the calendar button instead of dropping to <body> with\n // the clear button (C-DISABLED).\n flushSync(() => commitDraft(draft));\n } else if (event.key === 'ArrowDown' && event.altKey && !isOpen) {\n event.preventDefault();\n // The edit is committed first, so the calendar opens on the typed month; rejected text is\n // kept and reported once (the blur that follows does not report it again).\n if (draft !== null && invalid === null) commitDraft(draft);\n setOpenedFromInput(true);\n setOpen(true);\n }\n },\n );\n\n const handleInputBlur = composeEventHandlers(onBlur, () => {\n // Text already rejected (Enter, Alt+ArrowDown) is kept without being reported again.\n if (interactive && draft !== null && invalid === null) commitDraft(draft);\n });\n\n const handleToggle = () => {\n if (!interactive) return;\n restoreTargetRef.current = null;\n setOpenedFromInput(false);\n setOpen(!isOpen);\n };\n\n const handleClear = () => {\n if (!interactive) return;\n commitDate(null);\n inputRef.current?.focus();\n };\n\n // The clear button keeps focus on the input: its blur would otherwise commit (or reject) the\n // edited text just before the clear, emitting twice for one click.\n const handleClearMouseDown = (event: React.MouseEvent<HTMLButtonElement>) => {\n event.preventDefault();\n };\n\n /** A day picked in the calendar (the calendar picks only available days). */\n const selectDate = (day: Date) => {\n if (!interactive) return;\n commitDate(day);\n close(inputRef.current);\n };\n\n /** Closes the calendar, as Escape does: focus returns to where it was opened from. */\n const requestClose = () => close(openedFromInput ? inputRef.current : null);\n\n const handleDialogKeyDown = (event: React.KeyboardEvent<HTMLDivElement>) => {\n if (event.key !== 'Escape' || event.defaultPrevented || event.nativeEvent.isComposing) return;\n // Consumed here, so enclosing layers (a Dialog around the picker) ignore it.\n event.preventDefault();\n requestClose();\n };\n\n /* ---- render ------------------------------------------------------ */\n\n const inputText = draft ?? (selectedDate ? format(selectedDate) : '');\n\n let errorMessage = '';\n if (invalid === 'unparseable') {\n errorMessage = (labels?.invalidDate ?? defaultInvalidDateLabel)(\n hasCustomParse ? undefined : getLocaleDateFormat(locale).pattern,\n );\n } else if (invalid === 'out-of-range' && (minDate || maxDate)) {\n errorMessage = (labels?.outOfRange ?? defaultOutOfRangeLabel)(\n minDate ? format(startOfDay(minDate)) : undefined,\n maxDate ? format(startOfDay(maxDate)) : undefined,\n );\n } else if (invalid === 'disabled') {\n errorMessage = labels?.unavailableDate ?? 'This date is not available.';\n }\n\n return (\n <div\n data-size={size}\n data-appearance={appearance}\n {...rest}\n ref={ref}\n className={cn(datePickerClassNames.root, 'relative inline-flex flex-col', className)}\n >\n <div ref={setReference} className=\"relative flex items-center\">\n <input\n ref={inputRefs}\n type=\"text\"\n {...fieldProps}\n aria-errormessage={ariaErrorMessage}\n aria-details={ariaDetails}\n value={inputText}\n onChange={handleInputChange}\n onFocus={onFocus}\n onBlur={handleInputBlur}\n onKeyDown={handleInputKeyDown}\n onKeyUp={onKeyUp}\n placeholder={placeholder}\n disabled={disabled}\n readOnly={readOnly}\n autoComplete={autoComplete}\n autoCapitalize={autoCapitalize}\n autoCorrect={autoCorrect}\n enterKeyHint={enterKeyHint}\n inputMode={inputMode}\n spellCheck={spellCheck}\n autoFocus={autoFocus}\n tabIndex={tabIndex}\n className={cn(\n datePickerClassNames.input,\n inputHeightClasses[size],\n 'w-full',\n inputPaddingClasses[size],\n inputTextClasses[size],\n inputAppearanceClasses[appearance],\n 'text-foreground placeholder:text-muted-foreground',\n inputFocus,\n disabledStyles,\n invalidLook && inputInvalid,\n pickerEndPadding(showClear ? 2 : 1, size),\n )}\n />\n {showClear && (\n <button\n type=\"button\"\n aria-label={labels?.clear ?? 'Clear date'}\n disabled={disabled}\n onMouseDown={handleClearMouseDown}\n onClick={handleClear}\n className={cn(\n datePickerClassNames.clearButton,\n pickerIconButtonClasses(size, appearance),\n pickerButtonOffset(size, 2),\n focusRing,\n disabledStyles,\n )}\n >\n <DismissIcon size={pickerGlyphSize(size, 'icon')} />\n </button>\n )}\n <button\n ref={toggleRef}\n type=\"button\"\n aria-label={labels?.openCalendar ?? 'Open calendar'}\n aria-haspopup=\"dialog\"\n aria-expanded={isOpen}\n aria-controls={isOpen ? dialogId : undefined}\n disabled={disabled || readOnly}\n onClick={handleToggle}\n className={cn(\n datePickerClassNames.openCalendarButton,\n pickerIconButtonClasses(size, appearance),\n pickerButtonOffset(size, 1),\n focusRing,\n disabledStyles,\n )}\n >\n <CalendarIcon size={pickerGlyphSize(size, 'icon')} />\n </button>\n </div>\n {showOwnError && (\n <p\n id={errorId}\n role=\"alert\"\n className={cn(datePickerClassNames.errorMessage, 'mt-1 text-caption-1 text-error')}\n >\n {errorMessage}\n </p>\n )}\n <HiddenInput\n name={name}\n form={form}\n disabled={disabled}\n value={selectedDate ? formatISODate(selectedDate) : ''}\n type=\"text\"\n required={validates}\n onInvalid={() => inputRef.current?.focus()}\n />\n {isOpen && (\n <Portal layerId={layerId}>\n <div\n ref={surfaceRefs}\n id={dialogId}\n role=\"dialog\"\n aria-modal=\"true\"\n aria-labelledby={headingId}\n {...floatingProps}\n data-state=\"open\"\n onKeyDown={handleDialogKeyDown}\n className={cn(\n datePickerClassNames.surface,\n 'rounded-md border border-border bg-background p-3 text-foreground shadow-16',\n )}\n >\n <CalendarView\n value={selectedDate}\n onPick={selectDate}\n minDate={minDate}\n maxDate={maxDate}\n disabledDates={disabledDates}\n firstDayOfWeek={firstDayOfWeek}\n locale={locale}\n today={today}\n initialVisibleDate={initialVisibleDate}\n showMonthPicker={showMonthPicker}\n showWeekNumbers={showWeekNumbers}\n firstWeekOfYear={firstWeekOfYear}\n showGoToToday={showGoToToday}\n markedDates={markedDates}\n renderDay={renderDay}\n dayLabel={dayLabel}\n onClose={showCloseButton ? requestClose : undefined}\n closeLabel={labels?.close}\n labels={labels}\n headingAs=\"h2\"\n headingId={headingId}\n partClassNames={CALENDAR_PART_CLASS_NAMES}\n />\n </div>\n </Portal>\n )}\n </div>\n );\n};\n\nDatePicker.displayName = 'DatePicker';\n"],"mappings":"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"}
1
+ {"version":3,"file":"DatePicker.mjs","names":["formatLocaleDate","parseLocaleDate","useId","useId$1","React","defaultInvalidDateLabel","pattern","defaultOutOfRangeLabel","min","max","CALENDAR_PART_CLASS_NAMES","datePickerClassNames","DatePicker","valueProp","formatDateProp","parseDateProp","sizeProp","appearanceProp","openProp","ariaLabel","ariaLabelledBy","ariaDescribedBy","ariaInvalid","ariaRequired","ariaErrorMessage","ariaDetails","rest","props","onChange","warnDeprecated","useInputLook","hasCustomFormat","hasCustomParse","warnOnce","locale","isValidLocaleTag","selectedDate","setSelectedDate","useControllable","defaultValue","onValueChange","next","interactive","disabled","readOnly","openState","setOpen","defaultOpen","onOpenChange","isClient","useIsClient","isOpen","openControlled","format","date","formatDate","parse","text","parseDate","draft","setDraft","invalid","setInvalid","wasInteractive","setWasInteractive","selectedDay","formatISODate","seenDay","setSeenDay","commitDate","normalized","startOfDay","isSameDay","commitDraft","parsed","reason","isDateInRange","minDate","maxDate","disabledDates","rejected","onInvalidInput","openedFromInput","setOpenedFromInput","inputRef","toggleRef","surfaceRef","restoreTargetRef","surface","setSurface","inputRefs","useMergedRefs","controlRef","dialogId","headingId","errorId","close","restoreTo","useDismiss","target","event","FOCUSABLE_SELECTOR","usePopupPosition","resolvePositioning","positioning","surfaceRefs","setFloating","useFocusTrap","useRestoreFocus","field","useFieldContext","validates","required","showOwnError","fieldProps","useFieldControl","joinIds","invalidLook","isInvalidLook","form","showClear","clearable","handleInputChange","handleInputKeyDown","composeEventHandlers","onKeyDown","flushSync","handleInputBlur","onBlur","handleToggle","handleClear","handleClearMouseDown","selectDate","day","requestClose","handleDialogKeyDown","inputText","errorMessage","labels","getLocaleDateFormat","size","appearance","cn","className","setReference","inputHeightClasses","inputPaddingClasses","inputTextClasses","inputAppearanceClasses","inputFocus","disabledStyles","pickerEndPadding","pickerIconButtonClasses","pickerButtonOffset","DismissIcon","pickerGlyphSize","focusRing","CalendarIcon","HiddenInput","Portal","floatingProps","CalendarView","showCloseButton"],"sources":["../../../src/components/input/DatePicker.tsx"],"sourcesContent":["import * as React from 'react';\nimport { flushSync } from 'react-dom';\nimport { cn } from '../../lib/cn';\nimport { joinIds } from '../../lib/aria';\nimport { datePickerClassNames } from '../../lib/classNames';\nimport { composeEventHandlers } from '../../lib/composeEventHandlers';\nimport type {\n CoreSize,\n DayOfWeek,\n FirstWeekOfYear,\n InputAppearance,\n PopupPositioningOptions,\n} from '../../lib/types';\nimport { warnDeprecated, warnOnce } from '../../lib/dev';\nimport { FOCUSABLE_SELECTOR } from '../../lib/focus';\nimport { CalendarIcon, DismissIcon } from '../../lib/icons';\nimport {\n disabledStyles,\n focusRing,\n inputAppearanceClasses,\n inputFocus,\n inputHeightClasses,\n inputInvalid,\n inputPaddingClasses,\n inputTextClasses,\n} from '../../lib/styles';\nimport { useControllable } from '../../hooks/useControllable';\nimport { useDismiss } from '../../hooks/useDismiss';\nimport { useFieldContext, useFieldControl } from '../../hooks/useFieldControl';\nimport { useFocusTrap } from '../../hooks/useFocusTrap';\nimport { useFormReset } from '../../hooks/useFormReset';\nimport { useId } from '../../hooks/useId';\nimport { useIsClient } from '../../hooks/useIsClient';\nimport { useMergedRefs } from '../../hooks/useMergedRefs';\nimport { resolvePositioning, usePopupPosition } from '../../hooks/usePopupPosition';\nimport { useRestoreFocus } from '../../hooks/useRestoreFocus';\nimport { HiddenInput } from '../internal/HiddenInput';\nimport { Portal } from '../portal/Portal';\nimport { CalendarView, type CalendarLabels, type CalendarViewPartClassNames } from './Calendar';\nimport {\n formatDate as formatLocaleDate,\n formatISODate,\n getLocaleDateFormat,\n isDateInRange,\n isSameDay,\n isValidLocaleTag,\n parseDate as parseLocaleDate,\n startOfDay,\n} from './dateUtils';\nimport { useInputLook } from './inputLook';\nimport { isInvalidLook } from './Input';\nimport {\n pickerButtonOffset,\n pickerEndPadding,\n pickerGlyphSize,\n pickerIconButtonClasses,\n} from './pickerStyles';\nimport type { RoutedHandlers } from './routedHandlers';\n\n/** Why typed text was not accepted (see {@link DatePickerProps.onInvalidInput}). */\nexport type DatePickerInvalidReason = 'unparseable' | 'out-of-range' | 'disabled';\n\n/**\n * The DatePicker's built-in button names and error texts, for localization: its own (clear, open\n * calendar, the errors of typed text, Close) and those of the calendar in its dialog\n * ({@link CalendarLabels}: the navigation buttons, the heading button's hints, \"Go to today\", the\n * week-number column and the marked days; its `required` hint does not apply). Each member is\n * optional and falls back to its English default. Month and weekday names and the day labels\n * follow `locale`.\n */\nexport interface DatePickerLabels extends CalendarLabels {\n /** Name of the clear button.\n * @default 'Clear date'\n */\n clear?: string;\n /** Name of the button that opens the calendar.\n * @default 'Open calendar'\n */\n openCalendar?: string;\n /** Name of the footer button that closes the calendar (`showCloseButton`).\n * @default 'Close'\n */\n close?: string;\n /**\n * Error text for typed text that is not a date. `pattern` is the default format of `locale`\n * written with English field letters (`'MM/DD/YYYY'`, `'DD.MM.YYYY'`), or `undefined` with a\n * custom `parseDate` (its format is unknown to the picker).\n * @default (pattern) => pattern ? `Enter a date in the format ${pattern}.` : 'Enter a valid date.'\n */\n invalidDate?: (pattern: string | undefined) => string;\n /**\n * Error text for a typed date outside `minDate`/`maxDate`. The bounds are passed as the input\n * shows dates (`formatDate`); a bound that is not set is `undefined`.\n * @default (min, max) => `Enter a date between ${min} and ${max}.` (only `min`: `Enter a date on\n * or after ${min}.`; only `max`: `Enter a date on or before ${max}.`)\n */\n outOfRange?: (min: string | undefined, max: string | undefined) => string;\n /** Error text for a typed date that `disabledDates` excludes.\n * @default 'This date is not available.'\n */\n unavailableDate?: string;\n}\n\nconst defaultInvalidDateLabel = (pattern: string | undefined) =>\n pattern ? `Enter a date in the format ${pattern}.` : 'Enter a valid date.';\n\nconst defaultOutOfRangeLabel = (min: string | undefined, max: string | undefined) => {\n if (min !== undefined && max !== undefined) return `Enter a date between ${min} and ${max}.`;\n if (min !== undefined) return `Enter a date on or after ${min}.`;\n return `Enter a date on or before ${max}.`;\n};\n\n/** Properties for the DatePicker component. */\nexport interface DatePickerProps extends Omit<\n React.HTMLAttributes<HTMLDivElement>,\n 'onChange' | 'defaultValue' | 'placeholder' | RoutedHandlers\n> {\n /** Controlled selected date (`null` for none). Emitted dates are always local midnight. */\n value?: Date | null;\n /**\n * Initial date for uncontrolled usage.\n * @default null\n */\n defaultValue?: Date | null;\n /** Called with the new date (local midnight) or `null` whenever the selected day changes. */\n onValueChange?: (date: Date | null) => void;\n /**\n * @deprecated Use `onValueChange`. Still called with the new date (warns once in development).\n */\n onChange?: (date: Date | null) => void;\n /**\n * Formats the selected date for the input. Supply `parseDate` as its inverse: without it, typed\n * text is parsed with the default parser for `locale` (development warning).\n * @default Intl.DateTimeFormat(locale, { year: 'numeric', month: '2-digit', day: '2-digit' }),\n * in the Gregorian calendar when the locale's own has other months (see `locale`)\n */\n formatDate?: (date: Date) => string;\n /**\n * Parses typed text into a date (`null` when it is not one); the result is normalized to local\n * midnight. The default is the exact inverse of the default format for `locale` and also\n * accepts ISO `yyyy-mm-dd`.\n */\n parseDate?: (text: string) => Date | null;\n /**\n * BCP 47 locale of the default format/parse, the month and weekday names and the day labels\n * (runtime default when omitted). Pass it explicitly when rendering on the server, so the server\n * and the browser format the same text. The grid is Gregorian: a locale calendar with other\n * months or eras (the Persian default of `fa-IR`, `-u-ca-islamic`, `-u-ca-japanese`) is replaced\n * by the Gregorian one in the locale's language and digits; the Buddhist years of `th-TH` stay.\n * A tag `Intl` rejects (the POSIX `de_DE`, a typo) falls back to the runtime default locale\n * (development warning).\n */\n locale?: string;\n /** Earliest selectable day (the whole day is included). */\n minDate?: Date;\n /** Latest selectable day (the whole day is included). */\n maxDate?: Date;\n /** Returns `true` for days that cannot be selected (called with local-midnight dates). */\n disabledDates?: (date: Date) => boolean;\n /**\n * Placeholder text shown when no date is selected.\n * @default 'Select a date'\n */\n placeholder?: string;\n /**\n * Whether the date picker is disabled and non-interactive (the calendar is not shown).\n * @default false\n */\n disabled?: boolean;\n /**\n * Size of the field: `small` (24px tall), `medium` (32px) or `large` (40px). Default: the\n * surrounding Field's `size`, else `WaveProvider inputDefaults.size`, else `'medium'`. The\n * calendar keeps its size.\n */\n size?: CoreSize;\n /**\n * Advanced positioning of the popup (Fluent's `positioning`): `offset`, `fitViewport`,\n * `matchReferenceWidth` and `fallbackPlacements` (tried in order when the requested side has no\n * room). The popup opens below the field.\n * @default `{}`: the calendar opens 4px below the field\n */\n positioning?: PopupPositioningOptions;\n /**\n * Look of the field: `outline` (a full border), `underline` (a bottom stroke only),\n * `filled-darker` or `filled-lighter` (a fill without a visible stroke: give the field a visible\n * label). Default: `WaveProvider inputDefaults.appearance`, else `'outline'`.\n */\n appearance?: InputAppearance;\n /**\n * Makes the input read-only: the calendar does not open and the value cannot change. Turning it\n * (or `disabled`) on while the user is typing drops the typed text.\n */\n readOnly?: boolean;\n /**\n * Whether to show a clear button when a date is selected (not shown while `readOnly`). Tab from\n * erased text clears the value before focus moves, so focus goes on to the calendar button, past\n * the clear button that disappears with it.\n * @default false\n */\n clearable?: boolean;\n /**\n * First day of the week (0 = Sunday, 1 = Monday, etc.).\n * @default 0\n */\n firstDayOfWeek?: DayOfWeek;\n /**\n * The day marked as today in the calendar (`aria-current=\"date\"`) and the start of its keys when\n * no day is selected. See `Calendar`'s `today`.\n * @default the current date\n */\n today?: Date;\n /**\n * The month the calendar shows first when there is no value, clamped into `minDate`/`maxDate`.\n * @default today's month\n */\n initialVisibleDate?: Date;\n /**\n * Turns the calendar's month text into a button that shows the month view, whose heading, the\n * year, is a button to the year view. Escape steps back from the year view to the month view\n * and from there to the days; it closes the calendar only from the day view.\n * @default true\n */\n showMonthPicker?: boolean;\n /**\n * Adds a leading column of week numbers to the calendar.\n * @default false\n */\n showWeekNumbers?: boolean;\n /**\n * Which week is week 1 of a year. ISO 8601 is `'first-four-day-week'` with `firstDayOfWeek={1}`.\n * @default 'first-day'\n */\n firstWeekOfYear?: FirstWeekOfYear;\n /**\n * Adds a \"Go to today\" button to the calendar's footer: it shows today's month and focuses\n * today without selecting it, and is disabled while today is outside `minDate`/`maxDate`.\n * @default false\n */\n showGoToToday?: boolean;\n /**\n * Adds a Close button to the calendar's footer; it closes the calendar as Escape does from the\n * day view (focus returns to the toggle, or to the input after Alt+ArrowDown).\n * @default false\n */\n showCloseButton?: boolean;\n /**\n * Days that draw a dot and say \"marked\" in their name in the calendar (`labels.markedDay`).\n * Called with local-midnight dates.\n */\n markedDates?: (date: Date) => boolean;\n /**\n * Replaces the content inside a calendar day's button; `defaultContent` is the day number. The\n * content must be non-interactive, and the button's name does not follow it: set the name with\n * `dayLabel`.\n */\n renderDay?: (date: Date, defaultContent: React.ReactNode) => React.ReactNode;\n /**\n * The accessible name of a calendar day, from its default name (the date in words, with\n * `labels.markedDay` applied for a marked day).\n */\n dayLabel?: (date: Date, defaultLabel: string) => string;\n /**\n * Controlled open state of the calendar. The calendar renders only in the browser: an open\n * picker is closed in the server HTML and opens once it has hydrated.\n */\n open?: boolean;\n /**\n * Initial open state for uncontrolled usage. A picker that starts disabled or read-only starts\n * closed. The calendar renders only in the browser: it is closed in the server HTML and opens\n * once the picker has hydrated.\n * @default false\n */\n defaultOpen?: boolean;\n /** Called when the calendar opens or closes (only when the state changes). */\n onOpenChange?: (open: boolean) => void;\n /**\n * Called when typed text is not accepted on Enter, Alt+ArrowDown or blur (once per edit): it\n * cannot be parsed (`'unparseable'`), lies outside `minDate`/`maxDate` (`'out-of-range'`) or is\n * excluded by `disabledDates` (`'disabled'`). The text stays in the input, which is marked\n * `aria-invalid` and described by an error message (left to the surrounding `Field` when it\n * shows an error). Enter reports it again when pressed again.\n */\n onInvalidInput?: (text: string, reason: DatePickerInvalidReason) => void;\n /**\n * Names of the clear, calendar and month buttons and the error texts of rejected typed text, for\n * localization. Unset members keep their English defaults.\n */\n labels?: DatePickerLabels;\n /** Form field name: the date is submitted as ISO `yyyy-mm-dd` (hidden input). */\n name?: string;\n /** Id of the `<form>` the value belongs to, when the picker is outside it. */\n form?: string;\n /**\n * Blocks form submission while no date is selected; sets `aria-required` on the input. Like a\n * native readonly input, a `readOnly` DatePicker does not block submission.\n */\n required?: boolean;\n /** Native `autocomplete` of the input. @default 'off' */\n autoComplete?: string;\n /** Focus handler of the text input (the root keeps the other handlers). */\n onFocus?: React.FocusEventHandler<HTMLInputElement>;\n /** Blur handler of the text input. */\n onBlur?: React.FocusEventHandler<HTMLInputElement>;\n /** Key handler of the text input; `preventDefault()` skips the picker's own keys. */\n onKeyDown?: React.KeyboardEventHandler<HTMLInputElement>;\n /** Key handler of the text input. */\n onKeyUp?: React.KeyboardEventHandler<HTMLInputElement>;\n /** Ref to the text input; `ref` stays on the root. */\n controlRef?: React.Ref<HTMLInputElement>;\n /** Ref to the root element. */\n ref?: React.Ref<HTMLDivElement>;\n}\n\n// The calendar's parts keep DatePicker's stable classes (0.8), on the same elements.\nconst CALENDAR_PART_CLASS_NAMES: CalendarViewPartClassNames = {\n header: datePickerClassNames.header,\n previousMonthButton: datePickerClassNames.previousMonthButton,\n heading: datePickerClassNames.heading,\n headingButton: datePickerClassNames.headingButton,\n nextMonthButton: datePickerClassNames.nextMonthButton,\n grid: datePickerClassNames.grid,\n weekday: datePickerClassNames.weekday,\n day: datePickerClassNames.day,\n month: datePickerClassNames.month,\n year: datePickerClassNames.year,\n weekNumberHeader: datePickerClassNames.weekNumberHeader,\n weekNumber: datePickerClassNames.weekNumber,\n markedDot: datePickerClassNames.markedDot,\n footer: datePickerClassNames.footer,\n todayButton: datePickerClassNames.todayButton,\n closeButton: datePickerClassNames.closeButton,\n};\n\n/**\n * A date input with a calendar dialog (APG date picker dialog).\n *\n * - **Typing**: the input accepts the default display format of `locale` (`Intl` numeric\n * year/month/day, e.g. `03/04/2025` for `en-GB`, `04/03/2025` for `en-US`) and ISO\n * `yyyy-mm-dd`. Text is committed on Enter, on Alt+ArrowDown (before the calendar opens) or when\n * the field loses focus — only when it was edited, and only when it names a different day. Text\n * that is not an available date is kept, the input is marked invalid and an error message\n * describes it (`onInvalidInput`, reported once per edit) until the text is edited or replaced\n * (a day picked in the calendar, the clear button, a form reset, a new day from the parent).\n * - **Calendar**: the toggle (`aria-haspopup=\"dialog\"`) or Alt+ArrowDown in the input opens a\n * modal dialog labelled by the month heading. Focus moves to the selected day (else today, else\n * the first available day of the month) and Tab stays inside. Arrow keys move by day/week\n * (mirrored in RTL), PageUp/PageDown by month, Shift+PageUp/PageDown by year (the day is clamped\n * to the month), Home/End to the start/end of the week, Enter/Space select. The month text is a\n * button (the heading button, `showMonthPicker`) that shows the month view, whose heading, the\n * year, leads to the year view; Escape steps back from the year view to the month view and from\n * there to the days, and closes only from the day view, returning focus to where the calendar\n * was opened from (the toggle, or the input after Alt+ArrowDown); a press outside closes it too.\n * `showCloseButton` adds a Close button that closes as Escape does from the day view, and\n * `showGoToToday` a button that shows today's month. `showWeekNumbers`, `markedDates`,\n * `renderDay` and `dayLabel` shape the day grid as in `Calendar`. Unavailable days stay focusable\n * (`aria-disabled`); a day focused by pointer becomes the starting point of the arrow keys. The\n * selected day is `aria-selected` on its gridcell and `aria-pressed` on its focusable button, so\n * the state is announced when focus lands on it; today is `aria-current=\"date\"`.\n * - The calendar closes when the picker becomes disabled or read-only (uncontrolled `open`: it\n * stays closed when the picker is enabled again), and the text typed until then is dropped.\n * - `clearable` shows a clear button while a date is selected (not while read-only). Tab from\n * erased text clears the value first, so focus moves on to the calendar button instead of to the\n * clear button that disappears.\n * - Every emitted date is local midnight. The calendar opens on the month of the selected date or\n * today, clamped into `minDate`/`maxDate`.\n * - **Size and appearance**: `size` resolves from its own prop, then the surrounding `Field`'s\n * `size`, then `WaveProvider inputDefaults.size`, else `'medium'`; `appearance` from its own\n * prop, then `WaveProvider inputDefaults.appearance`, else `'outline'`; both render as\n * `data-size` and `data-appearance` on the root `<div>`. The calendar keeps its size.\n * - The input (`controlRef`) receives `id`, `aria-label`, `aria-labelledby`, `aria-describedby`,\n * `aria-invalid`, `aria-required`, `aria-errormessage`, `aria-details`, `tabIndex`,\n * `autoFocus`, `onFocus`/`onBlur`/`onKeyDown`/`onKeyUp` and the text input attributes\n * `autoComplete`, `autoCapitalize`, `autoCorrect`, `inputMode`, `spellCheck` and\n * `enterKeyHint`. `ref`, `className`, `style`, other `aria-*` attributes and the remaining props\n * stay on the root `<div>`. Inside a `Field`, the input is labelled and described by it.\n * - `name`/`required` add a hidden input for native forms (ISO `yyyy-mm-dd`); the value resets\n * with its form.\n * - The built-in button names and error texts are English; `labels` localizes them.\n * - Pass `locale` explicitly when rendering on the server (see `locale`). The calendar renders only\n * in the browser: an open calendar (`defaultOpen`, `open`) is closed in the server HTML and opens\n * once the picker has hydrated.\n */\nexport const DatePicker = (props: DatePickerProps) => {\n const {\n value: valueProp,\n defaultValue,\n onValueChange,\n onChange,\n formatDate: formatDateProp,\n parseDate: parseDateProp,\n locale,\n minDate,\n maxDate,\n disabledDates,\n placeholder = 'Select a date',\n disabled = false,\n size: sizeProp,\n positioning,\n appearance: appearanceProp,\n readOnly,\n clearable = false,\n firstDayOfWeek = 0,\n today,\n initialVisibleDate,\n showMonthPicker,\n showWeekNumbers,\n firstWeekOfYear,\n showGoToToday,\n showCloseButton = false,\n markedDates,\n renderDay,\n dayLabel,\n open: openProp,\n defaultOpen,\n onOpenChange,\n onInvalidInput,\n labels,\n name,\n form,\n required,\n autoComplete = 'off',\n autoCapitalize,\n autoCorrect,\n enterKeyHint,\n inputMode,\n spellCheck,\n autoFocus,\n tabIndex,\n id,\n 'aria-label': ariaLabel,\n 'aria-labelledby': ariaLabelledBy,\n 'aria-describedby': ariaDescribedBy,\n 'aria-invalid': ariaInvalid,\n 'aria-required': ariaRequired,\n 'aria-errormessage': ariaErrorMessage,\n 'aria-details': ariaDetails,\n onFocus,\n onBlur,\n onKeyDown,\n onKeyUp,\n controlRef,\n className,\n ref,\n ...rest\n } = props;\n\n if (onChange !== undefined) warnDeprecated('DatePicker', 'onChange', 'onValueChange');\n\n const { size, appearance } = useInputLook(sizeProp, appearanceProp);\n\n const hasCustomFormat = formatDateProp !== undefined;\n const hasCustomParse = parseDateProp !== undefined;\n React.useEffect(() => {\n if (hasCustomFormat && !hasCustomParse) {\n warnOnce(\n 'DatePicker:formatDate-without-parseDate',\n 'DatePicker: `formatDate` is set without `parseDate`. Typed dates are parsed with the ' +\n 'default parser for `locale` (its numeric format or yyyy-mm-dd), which may not read ' +\n 'your format; pass `parseDate` as the inverse of `formatDate`.',\n );\n }\n }, [hasCustomFormat, hasCustomParse]);\n React.useEffect(() => {\n if (locale !== undefined && !isValidLocaleTag(locale)) {\n warnOnce(\n `DatePicker:invalid-locale:${locale}`,\n `DatePicker: \\`locale\\` \"${locale}\" is not a valid BCP 47 language tag (use hyphens, as ` +\n 'in \"en-US\"). The runtime default locale formats and parses the dates instead, so the ' +\n 'server and the browser may render different text.',\n );\n }\n }, [locale]);\n\n const [selectedDate, setSelectedDate] = useControllable<Date | null>(\n valueProp,\n defaultValue ?? null,\n (next) => {\n onValueChange?.(next);\n onChange?.(next);\n },\n );\n const interactive = !disabled && !readOnly;\n const [openState, setOpen] = useControllable<boolean>(\n openProp,\n // A picker that starts disabled or read-only never shows its calendar, so it starts closed\n // (no close to report later).\n (defaultOpen ?? false) && interactive,\n onOpenChange,\n );\n // The calendar lives in a portal, which renders only in the browser: until then (the server\n // HTML, hydration) the picker reports it closed, so no reference names a missing element.\n const isClient = useIsClient();\n const isOpen = openState && interactive && isClient;\n const openControlled = openProp !== undefined;\n\n // A calendar hidden because the picker became disabled or read-only is closed for good\n // (uncontrolled), so enabling the picker again does not bring it back and take focus.\n // onOpenChange(false) reports it; a controlled `open` stays the parent's.\n React.useEffect(() => {\n if (!interactive && openState && !openControlled) setOpen(false);\n }, [interactive, openState, openControlled, setOpen]);\n\n const format = (date: Date) =>\n formatDateProp ? formatDateProp(date) : formatLocaleDate(date, locale);\n const parse = (text: string) =>\n parseDateProp ? parseDateProp(text) : parseLocaleDate(text, locale);\n\n /* ---- draft text and validation ---------------------------------- */\n\n /** Typed text; `null` shows the formatted selected date (draft model). */\n const [draft, setDraft] = React.useState<string | null>(null);\n const [invalid, setInvalid] = React.useState<DatePickerInvalidReason | null>(null);\n\n // Adjusted during render (C-HOOKS). Locking the picker (readOnly/disabled) while the user types\n // drops the typed text and its error, so no later blur commits it (the value cannot change).\n const [wasInteractive, setWasInteractive] = React.useState(interactive);\n if (wasInteractive !== interactive) {\n setWasInteractive(interactive);\n if (!interactive) {\n setDraft(null);\n setInvalid(null);\n }\n }\n // A selected day the parent changes replaces rejected text (commits clear it themselves), so the\n // input never shows an error next to a valid value. Text the user is still typing stays.\n const selectedDay = selectedDate ? formatISODate(selectedDate) : '';\n const [seenDay, setSeenDay] = React.useState(selectedDay);\n if (seenDay !== selectedDay) {\n setSeenDay(selectedDay);\n if (invalid !== null) {\n setDraft(null);\n setInvalid(null);\n }\n }\n\n /** Commits a day (or `null`); nothing is emitted when it is the same day. */\n const commitDate = (next: Date | null) => {\n const normalized = next ? startOfDay(next) : null;\n const unchanged = normalized ? isSameDay(normalized, selectedDate) : selectedDate === null;\n if (!unchanged) setSelectedDate(normalized);\n setDraft(null);\n setInvalid(null);\n };\n\n /** Validates and commits the typed text; `false` when it was rejected (the text is kept). */\n const commitDraft = (text: string): boolean => {\n if (!text.trim()) {\n commitDate(null);\n return true;\n }\n const parsed = parse(text);\n let reason: DatePickerInvalidReason | null = null;\n if (!parsed || Number.isNaN(parsed.getTime())) reason = 'unparseable';\n else if (!isDateInRange(parsed, minDate, maxDate)) reason = 'out-of-range';\n else if (disabledDates?.(startOfDay(parsed))) reason = 'disabled';\n if (reason || !parsed) {\n const rejected = reason ?? 'unparseable';\n setInvalid(rejected);\n onInvalidInput?.(text, rejected);\n return false;\n }\n commitDate(parsed);\n return true;\n };\n\n /* ---- calendar --------------------------------------------------- */\n\n /** Opened with Alt+ArrowDown in the input: Escape returns focus there instead of the toggle. */\n const [openedFromInput, setOpenedFromInput] = React.useState(false);\n\n // A closed calendar forgets where it was opened from. This also drops an Alt+ArrowDown whose\n // opening a controlled parent declined (it renders in the same update, still closed), so a later\n // opening by the parent returns focus to the toggle, not the input.\n if (openedFromInput && !isOpen) setOpenedFromInput(false);\n\n /* ---- elements, popup primitives ---------------------------------- */\n\n const inputRef = React.useRef<HTMLInputElement | null>(null);\n const toggleRef = React.useRef<HTMLButtonElement | null>(null);\n const surfaceRef = React.useRef<HTMLDivElement | null>(null);\n /** Where focus goes when the calendar closes (`null`: back to the toggle). */\n const restoreTargetRef = React.useRef<HTMLElement | null>(null);\n const [surface, setSurface] = React.useState<HTMLDivElement | null>(null);\n const inputRefs = useMergedRefs<HTMLInputElement>(controlRef, inputRef);\n\n const dialogId = useId('datepicker-dialog');\n const headingId = useId('datepicker-heading');\n const errorId = useId('datepicker-error');\n\n const close = (restoreTo: HTMLElement | null) => {\n restoreTargetRef.current = restoreTo;\n setOpen(false);\n };\n\n const { layerId } = useDismiss({\n open: isOpen,\n onDismiss: (reason, event) => {\n // An outside press on another control hands focus to it (the trap held it until now);\n // otherwise focus returns to where the calendar was opened from.\n const target =\n reason === 'outside-press' && event.target instanceof Element\n ? event.target.closest<HTMLElement>(FOCUSABLE_SELECTOR)\n : null;\n close(target ?? (openedFromInput ? inputRef.current : null));\n },\n refs: [surfaceRef, toggleRef],\n anchorRef: toggleRef,\n kind: 'modal',\n });\n\n const { setReference, setFloating, floatingProps } = usePopupPosition({\n open: isOpen,\n side: 'bottom',\n align: 'start',\n ...resolvePositioning(positioning, {}),\n });\n const surfaceRefs = useMergedRefs<HTMLDivElement>(surfaceRef, setSurface, setFloating);\n\n useFocusTrap(surface, {\n enabled: isOpen,\n layerId,\n // The calendar mounts with the dialog, so its grid's tab stop is in the surface already.\n initialFocus: () =>\n surfaceRef.current?.querySelector<HTMLElement>(\n '[data-wave-calendar-grid] button[tabindex=\"0\"]',\n ) ?? null,\n });\n\n useRestoreFocus({\n enabled: isOpen,\n container: surface,\n triggerRef: toggleRef,\n finalFocusRef: restoreTargetRef,\n onlyIfFocusInside: true,\n });\n\n // A new opening starts without a restore target (the toggle returns focus to itself, Escape to\n // where the calendar was opened from).\n React.useLayoutEffect(() => {\n if (isOpen) restoreTargetRef.current = null;\n }, [isOpen]);\n\n /* ---- forms and Field --------------------------------------------- */\n\n const field = useFieldContext();\n const isRequired = required ?? field?.required ?? false;\n // Like a native readonly input, a read-only picker is barred from constraint validation (the\n // user could not fix it); its value is still submitted.\n const validates = isRequired && !readOnly;\n const showOwnError = invalid !== null && !field?.hasErrorMessage;\n const fieldProps = useFieldControl({\n id,\n 'aria-label': ariaLabel,\n 'aria-labelledby': ariaLabelledBy,\n 'aria-describedby': joinIds(ariaDescribedBy, showOwnError ? errorId : undefined),\n 'aria-invalid': invalid !== null ? true : ariaInvalid,\n // An explicit `required={false}` wins over a required Field, so aria-required matches\n // `isRequired`.\n 'aria-required': ariaRequired ?? required,\n });\n const invalidLook = isInvalidLook(false, fieldProps['aria-invalid']);\n\n // Through the commit path: the default is emitted as local midnight, and only when it names\n // another day; the typed text and its error are dropped.\n useFormReset(inputRef, () => commitDate(defaultValue ?? null), form);\n\n // Read-only pickers offer no clear action (the value cannot change).\n const showClear = clearable && !readOnly && selectedDate !== null;\n\n /* ---- handlers ---------------------------------------------------- */\n\n const handleInputChange = (event: React.ChangeEvent<HTMLInputElement>) => {\n if (!interactive) return;\n setDraft(event.target.value);\n setInvalid(null);\n };\n\n const handleInputKeyDown = composeEventHandlers(\n onKeyDown,\n (event: React.KeyboardEvent<HTMLInputElement>) => {\n // Keys that belong to an IME composition (its confirming Enter) are left to the IME.\n if (!interactive || event.nativeEvent.isComposing) return;\n if (event.key === 'Enter' && draft !== null) {\n // An edit is committed instead of submitting the form; untouched text lets Enter submit.\n event.preventDefault();\n commitDraft(draft);\n } else if (\n event.key === 'Tab' &&\n !event.shiftKey &&\n showClear &&\n draft !== null &&\n !draft.trim()\n ) {\n // Erased text clears the value, and with it the clear button, the next tab stop. It is\n // settled before Tab moves focus (the blur would settle it while focus moves to that\n // button), so focus moves on to the calendar button instead of dropping to <body> with\n // the clear button (C-DISABLED).\n flushSync(() => commitDraft(draft));\n } else if (event.key === 'ArrowDown' && event.altKey && !isOpen) {\n event.preventDefault();\n // The edit is committed first, so the calendar opens on the typed month; rejected text is\n // kept and reported once (the blur that follows does not report it again).\n if (draft !== null && invalid === null) commitDraft(draft);\n setOpenedFromInput(true);\n setOpen(true);\n }\n },\n );\n\n const handleInputBlur = composeEventHandlers(onBlur, () => {\n // Text already rejected (Enter, Alt+ArrowDown) is kept without being reported again.\n if (interactive && draft !== null && invalid === null) commitDraft(draft);\n });\n\n const handleToggle = () => {\n if (!interactive) return;\n restoreTargetRef.current = null;\n setOpenedFromInput(false);\n setOpen(!isOpen);\n };\n\n const handleClear = () => {\n if (!interactive) return;\n commitDate(null);\n inputRef.current?.focus();\n };\n\n // The clear button keeps focus on the input: its blur would otherwise commit (or reject) the\n // edited text just before the clear, emitting twice for one click.\n const handleClearMouseDown = (event: React.MouseEvent<HTMLButtonElement>) => {\n event.preventDefault();\n };\n\n /** A day picked in the calendar (the calendar picks only available days). */\n const selectDate = (day: Date) => {\n if (!interactive) return;\n commitDate(day);\n close(inputRef.current);\n };\n\n /** Closes the calendar, as Escape does: focus returns to where it was opened from. */\n const requestClose = () => close(openedFromInput ? inputRef.current : null);\n\n const handleDialogKeyDown = (event: React.KeyboardEvent<HTMLDivElement>) => {\n if (event.key !== 'Escape' || event.defaultPrevented || event.nativeEvent.isComposing) return;\n // Consumed here, so enclosing layers (a Dialog around the picker) ignore it.\n event.preventDefault();\n requestClose();\n };\n\n /* ---- render ------------------------------------------------------ */\n\n const inputText = draft ?? (selectedDate ? format(selectedDate) : '');\n\n let errorMessage = '';\n if (invalid === 'unparseable') {\n errorMessage = (labels?.invalidDate ?? defaultInvalidDateLabel)(\n hasCustomParse ? undefined : getLocaleDateFormat(locale).pattern,\n );\n } else if (invalid === 'out-of-range' && (minDate || maxDate)) {\n errorMessage = (labels?.outOfRange ?? defaultOutOfRangeLabel)(\n minDate ? format(startOfDay(minDate)) : undefined,\n maxDate ? format(startOfDay(maxDate)) : undefined,\n );\n } else if (invalid === 'disabled') {\n errorMessage = labels?.unavailableDate ?? 'This date is not available.';\n }\n\n return (\n <div\n data-size={size}\n data-appearance={appearance}\n {...rest}\n ref={ref}\n className={cn(datePickerClassNames.root, 'relative inline-flex flex-col', className)}\n >\n <div ref={setReference} className=\"relative flex items-center\">\n <input\n ref={inputRefs}\n type=\"text\"\n {...fieldProps}\n aria-errormessage={ariaErrorMessage}\n aria-details={ariaDetails}\n value={inputText}\n onChange={handleInputChange}\n onFocus={onFocus}\n onBlur={handleInputBlur}\n onKeyDown={handleInputKeyDown}\n onKeyUp={onKeyUp}\n placeholder={placeholder}\n disabled={disabled}\n readOnly={readOnly}\n autoComplete={autoComplete}\n autoCapitalize={autoCapitalize}\n autoCorrect={autoCorrect}\n enterKeyHint={enterKeyHint}\n inputMode={inputMode}\n spellCheck={spellCheck}\n autoFocus={autoFocus}\n tabIndex={tabIndex}\n className={cn(\n datePickerClassNames.input,\n inputHeightClasses[size],\n 'w-full',\n inputPaddingClasses[size],\n inputTextClasses[size],\n inputAppearanceClasses[appearance],\n 'text-foreground placeholder:text-muted-foreground',\n inputFocus,\n disabledStyles,\n invalidLook && inputInvalid,\n pickerEndPadding(showClear ? 2 : 1, size),\n )}\n />\n {showClear && (\n <button\n type=\"button\"\n aria-label={labels?.clear ?? 'Clear date'}\n disabled={disabled}\n onMouseDown={handleClearMouseDown}\n onClick={handleClear}\n className={cn(\n datePickerClassNames.clearButton,\n pickerIconButtonClasses(size, appearance),\n pickerButtonOffset(size, 2),\n focusRing,\n disabledStyles,\n )}\n >\n <DismissIcon size={pickerGlyphSize(size, 'icon')} />\n </button>\n )}\n <button\n ref={toggleRef}\n type=\"button\"\n aria-label={labels?.openCalendar ?? 'Open calendar'}\n aria-haspopup=\"dialog\"\n aria-expanded={isOpen}\n aria-controls={isOpen ? dialogId : undefined}\n disabled={disabled || readOnly}\n onClick={handleToggle}\n className={cn(\n datePickerClassNames.openCalendarButton,\n pickerIconButtonClasses(size, appearance),\n pickerButtonOffset(size, 1),\n focusRing,\n disabledStyles,\n )}\n >\n <CalendarIcon size={pickerGlyphSize(size, 'icon')} />\n </button>\n </div>\n {showOwnError && (\n <p\n id={errorId}\n role=\"alert\"\n className={cn(datePickerClassNames.errorMessage, 'mt-1 text-caption-1 text-error')}\n >\n {errorMessage}\n </p>\n )}\n <HiddenInput\n name={name}\n form={form}\n disabled={disabled}\n value={selectedDate ? formatISODate(selectedDate) : ''}\n type=\"text\"\n required={validates}\n onInvalid={() => inputRef.current?.focus()}\n />\n {isOpen && (\n <Portal layerId={layerId}>\n <div\n ref={surfaceRefs}\n id={dialogId}\n role=\"dialog\"\n aria-modal=\"true\"\n aria-labelledby={headingId}\n {...floatingProps}\n data-state=\"open\"\n onKeyDown={handleDialogKeyDown}\n className={cn(\n datePickerClassNames.surface,\n 'rounded-md border border-border bg-background p-3 text-foreground shadow-16',\n )}\n >\n <CalendarView\n value={selectedDate}\n onPick={selectDate}\n minDate={minDate}\n maxDate={maxDate}\n disabledDates={disabledDates}\n firstDayOfWeek={firstDayOfWeek}\n locale={locale}\n today={today}\n initialVisibleDate={initialVisibleDate}\n showMonthPicker={showMonthPicker}\n showWeekNumbers={showWeekNumbers}\n firstWeekOfYear={firstWeekOfYear}\n showGoToToday={showGoToToday}\n markedDates={markedDates}\n renderDay={renderDay}\n dayLabel={dayLabel}\n onClose={showCloseButton ? requestClose : undefined}\n closeLabel={labels?.close}\n labels={labels}\n headingAs=\"h2\"\n headingId={headingId}\n partClassNames={CALENDAR_PART_CLASS_NAMES}\n />\n </div>\n </Portal>\n )}\n </div>\n );\n};\n\nDatePicker.displayName = 'DatePicker';\n"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- "use client";const e=require("../../_virtual/_rolldown/runtime.cjs"),t=require("../../lib/cn.cjs"),n=require("../../lib/dev.cjs"),r=require("../../lib/slot.cjs"),i=require("../../lib/composeEventHandlers.cjs"),a=require("../../lib/classNames.cjs"),o=require("../../hooks/useControllable.cjs"),s=require("../../hooks/useMergedRefs.cjs"),c=require("../../hooks/useFieldControl.cjs"),l=require("../../hooks/useListbox.cjs"),u=require("../../lib/styles.cjs"),ee=require("../button/Button.slots.cjs"),d=require("../../lib/icons.cjs"),te=require("./inputLook.cjs"),ne=require("./Input.cjs"),re=require("../../hooks/useFormReset.cjs"),ie=require("../internal/HiddenInput.cjs"),f=require("./pickerStyles.cjs"),ae=require("./Combobox.expand.cjs"),p=require("./Option.cjs"),m=require("./pickerLabels.cjs"),h=require("./pickerValues.cjs");let g=require("react");g=e.__toESM(g,1);let _=require("react/jsx-runtime");var v=e=>{let{multiselect:v=!1,value:y,defaultValue:b,onValueChange:x,onOptionSelect:S,open:oe,defaultOpen:se,onOpenChange:ce,onActiveOptionChange:le,disabledOptionsFocusable:ue=!1,placeholder:de=`Select an option`,renderValue:C,disabled:w=!1,size:fe,appearance:pe,name:me,form:T,required:E,clearable:he=!1,expandIcon:D,labels:O,autoFocus:ge,tabIndex:_e,id:ve,"aria-label":ye,"aria-labelledby":be,"aria-describedby":xe,"aria-invalid":Se,"aria-required":Ce,"aria-errormessage":we,"aria-details":Te,onFocus:Ee,onBlur:De,onKeyDown:Oe,onKeyUp:ke,controlRef:Ae,className:je,children:k,ref:Me,...Ne}=e;S!==void 0&&n.warnDeprecated(`Dropdown`,`onOptionSelect`,`onValueChange`);let A=c.useFieldContext(),Pe=E??A?.required??!1,j=c.useFieldControl({id:ve,"aria-label":ye,"aria-labelledby":be,"aria-describedby":xe,"aria-invalid":Se,"aria-required":Ce??E}),Fe=ne.isInvalidLook(!1,j[`aria-invalid`]),{size:M,appearance:N}=te.useInputLook(fe,pe),[Ie,P]=o.useControllable(y,b??(v?h.EMPTY_VALUES:``),e=>{x?.(typeof e==`string`?e:[...e])}),F=h.toValues(Ie),[I,L]=o.useControllable(oe,(se??!1)&&!w,ce),R=I&&!w,z=w&&I;g.useEffect(()=>{z&&L(!1)},[z,L]);let B=g.useRef(null),V=g.useRef(null),H=g.useMemo(()=>l.collectOptionLabels(k),[k]),U=l.useListbox({open:R,onOpenChange:e=>L(e),mode:`select-only`,multiselect:v,disabledOptionsFocusable:ue,selectedValues:F,onSelect:(e,t)=>{if(!v){P(e),S?.(e);return}let{values:n,added:r}=h.toggleValue(F,e);P(n),S?.(e),m.announceToggle(O,t?.item.label??H.get(e)??e,r,n.length)},onActiveValueChange:le,idPrefix:`dropdown-listbox`}),W=R&&U.items.length>0,{layerId:Le,setReference:Re,surfaceRef:ze,floatingProps:Be}=p.useListboxPopup({open:R,surfaceOpen:W,onDismiss:()=>L(!1),rootRef:B,anchorRef:V}),Ve=s.useMergedRefs(B,Me),He=s.useMergedRefs(V,Ae,Re);re.useFormReset(V,()=>{if(!v){P(b??``);return}P(e=>h.resetValues(e,b))},T);let G=F.map(e=>U.getItem(e)?.label??H.get(e)).filter(e=>e!==void 0),K=v?G.length>0?(O?.selection??m.defaultSelectionLabel)(G):``:G[0]??``,q=ae.showsExpandButton(D),{glyph:J,button:Y}=ee.unwrapButtonGlyph(D);g.useEffect(()=>{Y&&n.warnOnce(`Dropdown:expandIcon-button`,`Dropdown: \`expandIcon\` received ${Y}; its children render as the glyph of the combobox button and its props were dropped (buttons cannot be nested). Pass icon content instead, e.g. \`expandIcon={<MyIcon />}\`.`)},[Y]);let X=F.length>0,Z=C?X:K!==``,Ue=X?C?C(v?[...F]:F[0]??``):K:void 0,We=e=>{if(e.key===`Escape`&&R&&!W&&!e.nativeEvent.isComposing){L(!1);return}U.onKeyDown(e)},Ge=()=>{P(v?h.EMPTY_VALUES:``),L(!1),V.current?.focus()},Q=he&&X,$=M===`small`?`end-2`:`end-3`,Ke=j[`aria-label`]===void 0?j[`aria-labelledby`]??A?.labelId:j[`aria-labelledby`];return(0,_.jsxs)(`div`,{"data-size":M,"data-appearance":N,...Ne,ref:Ve,className:t.cn(a.dropdownClassNames.root,`relative inline-flex flex-col`,je),children:[v&&(0,_.jsx)(m.PickerAnnouncer,{}),(0,_.jsxs)(`div`,{className:`relative flex items-center`,children:[(0,_.jsxs)(`button`,{type:`button`,...j,...U.getComboboxProps(),"aria-expanded":W,"aria-errormessage":we,"aria-details":Te,ref:He,disabled:w,autoFocus:ge,tabIndex:_e,onClick:()=>L(e=>!e),onKeyDown:i.composeEventHandlers(Oe,We),onKeyUp:i.composeEventHandlers(ke,U.onKeyUp),onFocus:Ee,onBlur:De,className:t.cn(a.dropdownClassNames.button,`relative flex w-full items-center justify-between py-0 text-start`,u.inputHeightClasses[M],u.inputPaddingClasses[M],u.inputTextClasses[M],u.inputAppearanceClasses[N],`text-foreground`,f.pickerEndPadding(Number(Q)+Number(q),M),u.inputFocus,u.disabledStyles,Fe&&`border-destructive`),children:[(0,_.jsx)(`span`,{className:t.cn(a.dropdownClassNames.value,`truncate`,!Z&&`text-muted-foreground`),children:Z?Ue:de}),q&&(J!=null&&r.slotRendersContent(J)?r.renderSlot(J,`span`,t.cn(a.dropdownClassNames.expandIcon,`absolute inline-flex transition-transform motion-reduce:transition-none`,$,W&&`rotate-180`),{"aria-hidden":!0}):(0,_.jsx)(d.ChevronDownIcon,{size:f.pickerGlyphSize(M,`chevron`),className:t.cn(a.dropdownClassNames.expandIcon,`absolute transition-transform motion-reduce:transition-none`,$,W&&`rotate-180`)}))]}),Q&&(0,_.jsx)(`button`,{type:`button`,"aria-label":O?.clear??`Clear selection`,disabled:w,onMouseDown:e=>e.preventDefault(),onClick:Ge,className:t.cn(a.dropdownClassNames.clearButton,f.pickerIconButtonClasses(M,N),f.pickerButtonOffset(M,q?2:1),`focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring`,`disabled:cursor-not-allowed disabled:opacity-50 aria-disabled:cursor-not-allowed aria-disabled:opacity-50 aria-disabled:focus-visible:opacity-100`),children:(0,_.jsx)(d.DismissIcon,{size:f.pickerGlyphSize(M,`icon`)})})]}),(0,_.jsx)(p.ListboxSurface,{listbox:U,layerId:Le,surfaceRef:ze,floatingProps:Be,open:R,expanded:W,listClassName:a.dropdownClassNames.listbox,surfaceClassName:a.dropdownClassNames.surface,"aria-label":j[`aria-label`],"aria-labelledby":Ke,children:k}),(0,_.jsx)(ie.HiddenInput,{name:me,form:T,disabled:w,value:v?F:F[0]??``,type:`text`,required:Pe,onInvalid:()=>V.current?.focus()})]})};v.displayName=`Dropdown`;var y=p.Option,b=p.OptionGroup,x=Object.assign(v,{Option:p.Option,OptionGroup:p.OptionGroup});exports.Dropdown=x,exports.DropdownOption=y,exports.DropdownOptionGroup=b;
1
+ "use client";const e=require("../../_virtual/_rolldown/runtime.cjs"),t=require("../../lib/cn.cjs"),n=require("../../lib/dev.cjs"),r=require("../../lib/slot.cjs"),i=require("../../lib/composeEventHandlers.cjs"),a=require("../../lib/classNames.cjs"),o=require("../../hooks/useControllable.cjs"),s=require("../../hooks/useMergedRefs.cjs"),c=require("../../hooks/useFieldControl.cjs"),l=require("../../hooks/useListbox.cjs"),u=require("../../lib/styles.cjs"),ee=require("../button/Button.slots.cjs"),d=require("../../lib/icons.cjs"),te=require("./inputLook.cjs"),ne=require("./Input.cjs"),re=require("../../hooks/useFormReset.cjs"),ie=require("../internal/HiddenInput.cjs"),f=require("./pickerStyles.cjs"),ae=require("./Combobox.expand.cjs"),p=require("./Option.cjs"),m=require("./pickerLabels.cjs"),h=require("./pickerValues.cjs");let g=require("react");g=e.__toESM(g,1);let _=require("react/jsx-runtime");var v=e=>{let{multiselect:v=!1,value:y,defaultValue:b,onValueChange:x,onOptionSelect:S,open:oe,defaultOpen:se,onOpenChange:ce,onActiveOptionChange:le,disabledOptionsFocusable:ue=!1,placeholder:de=`Select an option`,renderValue:C,disabled:w=!1,size:fe,positioning:pe,appearance:me,name:he,form:T,required:E,clearable:ge=!1,expandIcon:D,labels:O,autoFocus:_e,tabIndex:ve,id:ye,"aria-label":be,"aria-labelledby":xe,"aria-describedby":Se,"aria-invalid":Ce,"aria-required":we,"aria-errormessage":Te,"aria-details":Ee,onFocus:De,onBlur:Oe,onKeyDown:ke,onKeyUp:Ae,controlRef:je,className:Me,children:k,ref:Ne,...Pe}=e;S!==void 0&&n.warnDeprecated(`Dropdown`,`onOptionSelect`,`onValueChange`);let A=c.useFieldContext(),Fe=E??A?.required??!1,j=c.useFieldControl({id:ye,"aria-label":be,"aria-labelledby":xe,"aria-describedby":Se,"aria-invalid":Ce,"aria-required":we??E}),Ie=ne.isInvalidLook(!1,j[`aria-invalid`]),{size:M,appearance:N}=te.useInputLook(fe,me),[Le,P]=o.useControllable(y,b??(v?h.EMPTY_VALUES:``),e=>{x?.(typeof e==`string`?e:[...e])}),F=h.toValues(Le),[I,L]=o.useControllable(oe,(se??!1)&&!w,ce),R=I&&!w,z=w&&I;g.useEffect(()=>{z&&L(!1)},[z,L]);let B=g.useRef(null),V=g.useRef(null),H=g.useMemo(()=>l.collectOptionLabels(k),[k]),U=l.useListbox({open:R,onOpenChange:e=>L(e),mode:`select-only`,multiselect:v,disabledOptionsFocusable:ue,selectedValues:F,onSelect:(e,t)=>{if(!v){P(e),S?.(e);return}let{values:n,added:r}=h.toggleValue(F,e);P(n),S?.(e),m.announceToggle(O,t?.item.label??H.get(e)??e,r,n.length)},onActiveValueChange:le,idPrefix:`dropdown-listbox`}),W=R&&U.items.length>0,{layerId:Re,setReference:ze,surfaceRef:Be,floatingProps:Ve}=p.useListboxPopup({positioning:pe,open:R,surfaceOpen:W,onDismiss:()=>L(!1),rootRef:B,anchorRef:V}),He=s.useMergedRefs(B,Ne),Ue=s.useMergedRefs(V,je,ze);re.useFormReset(V,()=>{if(!v){P(b??``);return}P(e=>h.resetValues(e,b))},T);let G=F.map(e=>U.getItem(e)?.label??H.get(e)).filter(e=>e!==void 0),K=v?G.length>0?(O?.selection??m.defaultSelectionLabel)(G):``:G[0]??``,q=ae.showsExpandButton(D),{glyph:J,button:Y}=ee.unwrapButtonGlyph(D);g.useEffect(()=>{Y&&n.warnOnce(`Dropdown:expandIcon-button`,`Dropdown: \`expandIcon\` received ${Y}; its children render as the glyph of the combobox button and its props were dropped (buttons cannot be nested). Pass icon content instead, e.g. \`expandIcon={<MyIcon />}\`.`)},[Y]);let X=F.length>0,Z=C?X:K!==``,We=X?C?C(v?[...F]:F[0]??``):K:void 0,Ge=e=>{if(e.key===`Escape`&&R&&!W&&!e.nativeEvent.isComposing){L(!1);return}U.onKeyDown(e)},Ke=()=>{P(v?h.EMPTY_VALUES:``),L(!1),V.current?.focus()},Q=ge&&X,$=M===`small`?`end-2`:`end-3`,qe=j[`aria-label`]===void 0?j[`aria-labelledby`]??A?.labelId:j[`aria-labelledby`];return(0,_.jsxs)(`div`,{"data-size":M,"data-appearance":N,...Pe,ref:He,className:t.cn(a.dropdownClassNames.root,`relative inline-flex flex-col`,Me),children:[v&&(0,_.jsx)(m.PickerAnnouncer,{}),(0,_.jsxs)(`div`,{className:`relative flex items-center`,children:[(0,_.jsxs)(`button`,{type:`button`,...j,...U.getComboboxProps(),"aria-expanded":W,"aria-errormessage":Te,"aria-details":Ee,ref:Ue,disabled:w,autoFocus:_e,tabIndex:ve,onClick:()=>L(e=>!e),onKeyDown:i.composeEventHandlers(ke,Ge),onKeyUp:i.composeEventHandlers(Ae,U.onKeyUp),onFocus:De,onBlur:Oe,className:t.cn(a.dropdownClassNames.button,`relative flex w-full items-center justify-between py-0 text-start`,u.inputHeightClasses[M],u.inputPaddingClasses[M],u.inputTextClasses[M],u.inputAppearanceClasses[N],`text-foreground`,f.pickerEndPadding(Number(Q)+Number(q),M),u.inputFocus,u.disabledStyles,Ie&&`border-destructive`),children:[(0,_.jsx)(`span`,{className:t.cn(a.dropdownClassNames.value,`truncate`,!Z&&`text-muted-foreground`),children:Z?We:de}),q&&(J!=null&&r.slotRendersContent(J)?r.renderSlot(J,`span`,t.cn(a.dropdownClassNames.expandIcon,`absolute inline-flex transition-transform motion-reduce:transition-none`,$,W&&`rotate-180`),{"aria-hidden":!0}):(0,_.jsx)(d.ChevronDownIcon,{size:f.pickerGlyphSize(M,`chevron`),className:t.cn(a.dropdownClassNames.expandIcon,`absolute transition-transform motion-reduce:transition-none`,$,W&&`rotate-180`)}))]}),Q&&(0,_.jsx)(`button`,{type:`button`,"aria-label":O?.clear??`Clear selection`,disabled:w,onMouseDown:e=>e.preventDefault(),onClick:Ke,className:t.cn(a.dropdownClassNames.clearButton,f.pickerIconButtonClasses(M,N),f.pickerButtonOffset(M,q?2:1),`focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring`,`disabled:cursor-not-allowed disabled:opacity-50 aria-disabled:cursor-not-allowed aria-disabled:opacity-50 aria-disabled:focus-visible:opacity-100`),children:(0,_.jsx)(d.DismissIcon,{size:f.pickerGlyphSize(M,`icon`)})})]}),(0,_.jsx)(p.ListboxSurface,{listbox:U,layerId:Re,surfaceRef:Be,floatingProps:Ve,open:R,expanded:W,listClassName:a.dropdownClassNames.listbox,surfaceClassName:a.dropdownClassNames.surface,"aria-label":j[`aria-label`],"aria-labelledby":qe,children:k}),(0,_.jsx)(ie.HiddenInput,{name:he,form:T,disabled:w,value:v?F:F[0]??``,type:`text`,required:Fe,onInvalid:()=>V.current?.focus()})]})};v.displayName=`Dropdown`;var y=p.Option,b=p.OptionGroup,x=Object.assign(v,{Option:p.Option,OptionGroup:p.OptionGroup});exports.Dropdown=x,exports.DropdownOption=y,exports.DropdownOptionGroup=b;
2
2
  //# sourceMappingURL=Dropdown.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"Dropdown.cjs","names":["useFieldContext","useFieldControl","isInvalidLook","useInputLook","useControllable","EMPTY_VALUES","toValues","React","collectOptionLabels","useListbox","toggleValue","useListboxPopup","useMergedRefs","resetValues","defaultSelectionLabel","showsExpandButton","unwrapButtonGlyph","cn","dropdownClassNames","PickerAnnouncer","composeEventHandlers","inputHeightClasses","inputPaddingClasses","inputTextClasses","inputAppearanceClasses","pickerEndPadding","inputFocus","disabledStyles","slotRendersContent","renderSlot","ChevronDownIcon","pickerGlyphSize","pickerIconButtonClasses","pickerButtonOffset","DismissIcon","ListboxSurface","HiddenInput","Option","OptionGroup","require_runtime","require_cn","require_dev","require_slot","require_composeEventHandlers","require_classNames","require_useControllable","require_useMergedRefs","require_useFieldControl","require_useListbox","require_styles","require_Button_slots","require_icons","require_inputLook","require_Input","require_useFormReset","require_HiddenInput","require_pickerStyles","require_Combobox_expand","require_Option","require_pickerLabels","require_pickerValues","react","react_jsx_runtime","DropdownRoot","valueProp","openProp","sizeProp","appearanceProp","ariaLabel","ariaLabelledBy","ariaDescribedBy","ariaInvalid","ariaRequired","ariaErrorMessage","ariaDetails","rest","props","onOptionSelect","field","isRequired","required","fieldProps","invalidLook","value","setValue","defaultValue","multiselect","onValueChange","next","values","openState","setOpen","defaultOpen","disabled","onOpenChange","open","lockedOpen","rootRef","buttonRef","optionLabels","children","listbox","updated","labels","details","added","onActiveOptionChange","expanded","rootMergedRef","ref","buttonMergedRef","controlRef","setReference","current","form","shownLabels","v","label","displayText","showExpand","expandIcon","expandGlyph","expandIconButton","hasValue","showValue","renderValue","valueNode","handleKeyDown","event","handleClear","showClear","clearable","expandOffset","size","listLabelledBy","appearance","className","onKeyDown","onKeyUp","placeholder","DropdownOption","DropdownOptionGroup","Dropdown"],"sources":["../../../src/components/input/Dropdown.tsx"],"sourcesContent":["import * as React from 'react';\nimport { dropdownClassNames } from '../../lib/classNames';\nimport { cn } from '../../lib/cn';\nimport { composeEventHandlers } from '../../lib/composeEventHandlers';\nimport { warnDeprecated, warnOnce } from '../../lib/dev';\nimport { ChevronDownIcon, DismissIcon } from '../../lib/icons';\nimport { renderSlot, slotRendersContent } from '../../lib/slot';\nimport type { Slot } from '../../lib/slot';\nimport {\n disabledStyles,\n focusRing,\n inputAppearanceClasses,\n inputFocus,\n inputHeightClasses,\n inputInvalid,\n inputPaddingClasses,\n inputTextClasses,\n} from '../../lib/styles';\nimport type { CoreSize, InputAppearance } from '../../lib/types';\nimport { useControllable } from '../../hooks/useControllable';\nimport { useFieldContext, useFieldControl } from '../../hooks/useFieldControl';\nimport { useFormReset } from '../../hooks/useFormReset';\nimport { collectOptionLabels, useListbox } from '../../hooks/useListbox';\nimport { useMergedRefs } from '../../hooks/useMergedRefs';\nimport { unwrapButtonGlyph } from '../button/Button.slots';\nimport { HiddenInput } from '../internal/HiddenInput';\nimport { showsExpandButton } from './Combobox.expand';\nimport { useInputLook } from './inputLook';\nimport { isInvalidLook } from './Input';\nimport { ListboxSurface, Option, OptionGroup, useListboxPopup } from './Option';\nimport { announceToggle, defaultSelectionLabel, PickerAnnouncer } from './pickerLabels';\nimport {\n pickerButtonOffset,\n pickerEndPadding,\n pickerGlyphSize,\n pickerIconButtonClasses,\n} from './pickerStyles';\nimport { EMPTY_VALUES, resetValues, toggleValue, toValues } from './pickerValues';\nimport type { RoutedHandlers } from './routedHandlers';\n\n/* ------------------------------------------------------------------ */\n/* Dropdown */\n/* ------------------------------------------------------------------ */\n\n/**\n * The Dropdown's built-in texts, for localization. Each member is optional and falls back to its\n * English default.\n */\nexport interface DropdownLabels {\n /** Name of the clear button (`clearable`).\n * @default 'Clear selection'\n */\n clear?: string;\n /**\n * The text of the selected labels shown in the combobox with `multiselect`, in selection order;\n * values without an option are left out. Replaces the button's joined value text.\n * @default (labels) => labels.join(', ')\n */\n selection?: (labels: string[]) => string;\n /**\n * Announced when a `multiselect` toggle selects an option; `count` is the number of values\n * selected after the change.\n * @default (label, count) => `${label} added, ${count} selected`\n */\n added?: (label: string, count: number) => string;\n /**\n * Announced when a `multiselect` toggle deselects an option; `count` is the number of values\n * selected after the change.\n * @default (label, count) => `${label} removed, ${count} selected`\n */\n removed?: (label: string, count: number) => string;\n}\n\n/** Properties for the Dropdown component. */\nexport interface DropdownProps<M extends boolean = false> extends Omit<\n React.HTMLAttributes<HTMLDivElement>,\n 'onChange' | 'defaultValue' | RoutedHandlers\n> {\n /**\n * Several options can be selected (Fluent's `multiselect`): the value is an array, options show\n * a checkbox, Enter and Space toggle the highlighted option, a click toggles the clicked\n * option, the list stays open, and each toggle is announced. A non-literal `multiselect={flag}`\n * is a type error: render two elements, one for each mode.\n * @default false\n */\n multiselect?: M;\n /**\n * Controlled selected value (`''` for none), or with `multiselect` the selected values (Fluent's\n * `selectedOptions`).\n */\n value?: M extends true ? readonly string[] : string;\n /**\n * Initial selected value for uncontrolled usage.\n * @default '' (`[]` with `multiselect`)\n */\n defaultValue?: M extends true ? readonly string[] : string;\n /**\n * Called with the new value when it changes (a new array with `multiselect`; Fluent's\n * `onOptionSelect`, under WaveUI's value/onValueChange naming).\n */\n onValueChange?: M extends true ? (value: string[]) => void : (value: string) => void;\n /**\n * Called on every option activation, also when the current option is selected again (every\n * toggle with `multiselect`).\n * @deprecated Use `onValueChange`.\n */\n onOptionSelect?: (value: string) => void;\n /**\n * Controlled open state of the listbox. The list renders only in the browser: an open dropdown\n * is closed in the server HTML and opens once it has hydrated.\n */\n open?: boolean;\n /**\n * Initial open state for uncontrolled usage. A dropdown that starts disabled starts closed. The\n * list renders only in the browser: it is closed in the server HTML and opens once the dropdown\n * has hydrated.\n * @default false\n */\n defaultOpen?: boolean;\n /** Called when the listbox opens or closes. */\n onOpenChange?: (open: boolean) => void;\n /**\n * Called after the active (highlighted) option changes — opening, arrow keys, typeahead, the\n * pointer — and with `null` when the list closes. It reports what `aria-activedescendant` points\n * at, from an effect once the change commits. Fluent's `onActiveOptionChange` reports neither the\n * pointer (its options have no hover highlight) nor the close.\n */\n onActiveOptionChange?: (value: string | null) => void;\n /**\n * Keeps disabled options in the arrow-key, Home/End, PageUp/PageDown and typeahead order (the\n * highlighted-by-default option may then be a disabled one too); they still cannot be selected\n * (Enter, Space and a click do nothing and the list stays open), and in single-select mode,\n * reaching one with Tab or Alt+ArrowUp closes the list without selecting it. Unlike Fluent,\n * which always keeps disabled options reachable, WaveUI skips them by default.\n * @default false\n */\n disabledOptionsFocusable?: boolean;\n /**\n * Placeholder text shown when no value is selected. It is not an accessible name: label the\n * Dropdown with a `Field`, `aria-label` or `aria-labelledby`.\n * @default 'Select an option'\n */\n placeholder?: string;\n /**\n * Renders the button's content while a value is selected (the placeholder shows otherwise), in\n * place of the selected label (`labels.selection` with `multiselect`). It receives the raw\n * value(s), never a label; the content must be non-interactive, and its text is the combobox's\n * value, so image-only content leaves the value empty.\n * @default the selected label (`labels.selection` with `multiselect`)\n */\n renderValue?: M extends true\n ? (value: string[]) => React.ReactNode\n : (value: string) => React.ReactNode;\n /**\n * Whether the dropdown is disabled and non-interactive. Turning it on while the listbox is open\n * closes it (`onOpenChange(false)`).\n * @default false\n */\n disabled?: boolean;\n /**\n * Size of the field: `small` (24px tall), `medium` (32px) or `large` (40px). Default: the\n * surrounding Field's `size`, else `WaveProvider inputDefaults.size`, else `'medium'`. The\n * listbox keeps its size; the multi-select value text and clear button follow it.\n */\n size?: CoreSize;\n /**\n * Look of the field: `outline` (a full border), `underline` (a bottom stroke only),\n * `filled-darker` or `filled-lighter` (a fill without a visible stroke: give the field a visible\n * label). Default: `WaveProvider inputDefaults.appearance`, else `'outline'`.\n */\n appearance?: InputAppearance;\n /**\n * Name of the value in form submissions (renders a hidden input; one per value with\n * `multiselect`).\n */\n name?: string;\n /** Id of the form the value belongs to, when the Dropdown is outside it. */\n form?: string;\n /** A value is required to submit the form (native constraint validation). */\n required?: boolean;\n /**\n * Shows a clear button while a value is selected (shown disabled while `disabled`). It clears\n * the value (every value with `multiselect`), closes the list and moves focus to the combobox\n * button. It is a tab stop after it.\n * @default false\n */\n clearable?: boolean;\n /**\n * The glyph at the end of the button (default: a chevron). `null` or `undefined` keep it;\n * `false`, or a value that renders nothing, hides it (the button's end padding follows,\n * together with `clearable`). The default chevron's size and the glyph's offset follow\n * `size`. Decorative content rendered inside the button: a `<button>` or `Button` passed\n * here is not nested (its children become the glyph, with a development warning).\n */\n expandIcon?: Slot<'span'>;\n /**\n * The clear button's name and, with `multiselect`, the selected-labels text and the toggle\n * announcements, for localization. Unset members keep their English defaults.\n */\n labels?: DropdownLabels;\n /** Called when the `<button role=\"combobox\">` receives focus (the root keeps other handlers). */\n onFocus?: React.FocusEventHandler<HTMLButtonElement>;\n /** Called when the `<button role=\"combobox\">` loses focus. */\n onBlur?: React.FocusEventHandler<HTMLButtonElement>;\n /**\n * Called on a key press on the `<button role=\"combobox\">`, before the built-in listbox keys;\n * `event.preventDefault()` skips them.\n */\n onKeyDown?: React.KeyboardEventHandler<HTMLButtonElement>;\n /** Called when a key is released on the `<button role=\"combobox\">`. */\n onKeyUp?: React.KeyboardEventHandler<HTMLButtonElement>;\n /** Ref to the `<button role=\"combobox\">` (the focusable element). */\n controlRef?: React.Ref<HTMLButtonElement>;\n /** Ref to the root `<div>`. */\n ref?: React.Ref<HTMLDivElement>;\n}\n\n/** The Dropdown component's type: a multi-select signature, then the single-select one. */\nexport interface DropdownComponent {\n (props: DropdownProps<true> & { multiselect: true }): React.ReactNode;\n (props: DropdownProps): React.ReactNode;\n displayName?: string;\n Option: typeof Option;\n OptionGroup: typeof OptionGroup;\n}\n\nconst DropdownRoot = (props: DropdownProps<boolean>) => {\n const {\n multiselect = false,\n value: valueProp,\n defaultValue,\n onValueChange,\n onOptionSelect,\n open: openProp,\n defaultOpen,\n onOpenChange,\n onActiveOptionChange,\n disabledOptionsFocusable = false,\n placeholder = 'Select an option',\n renderValue,\n disabled = false,\n size: sizeProp,\n appearance: appearanceProp,\n name,\n form,\n required,\n clearable = false,\n expandIcon,\n labels,\n autoFocus,\n tabIndex,\n id,\n 'aria-label': ariaLabel,\n 'aria-labelledby': ariaLabelledBy,\n 'aria-describedby': ariaDescribedBy,\n 'aria-invalid': ariaInvalid,\n 'aria-required': ariaRequired,\n 'aria-errormessage': ariaErrorMessage,\n 'aria-details': ariaDetails,\n onFocus,\n onBlur,\n onKeyDown,\n onKeyUp,\n controlRef,\n className,\n children,\n ref,\n ...rest\n } = props;\n\n if (onOptionSelect !== undefined) warnDeprecated('Dropdown', 'onOptionSelect', 'onValueChange');\n\n const field = useFieldContext();\n const isRequired = required ?? field?.required ?? false;\n const fieldProps = useFieldControl({\n id,\n 'aria-label': ariaLabel,\n 'aria-labelledby': ariaLabelledBy,\n 'aria-describedby': ariaDescribedBy,\n 'aria-invalid': ariaInvalid,\n // An explicit `required={false}` wins over a required Field, so aria-required matches\n // `isRequired`.\n 'aria-required': ariaRequired ?? required,\n });\n // The error look follows the resolved state: the consumer's `aria-invalid` or the Field's.\n const invalidLook = isInvalidLook(false, fieldProps['aria-invalid']);\n const { size, appearance } = useInputLook(sizeProp, appearanceProp);\n\n const [value, setValue] = useControllable<string | readonly string[]>(\n valueProp,\n defaultValue ?? (multiselect ? EMPTY_VALUES : ''),\n (next) => {\n // The two call signatures make `onValueChange` a union of incompatible functions from here:\n // the root itself is written against the wider, internal shape (D9).\n (onValueChange as ((value: string | string[]) => void) | undefined)?.(\n typeof next === 'string' ? next : [...next],\n );\n },\n );\n // Normalised for the listbox, the display text and the clear/reset logic: a single value is its\n // own one-element array, and a `value` passed as `null`/`undefined` from JavaScript (bypassing\n // the type system) is none rather than a crash, as 0.7 did for the single-select string.\n const values = toValues(value);\n\n // A dropdown that starts disabled never shows its list, so it starts closed (no close to report\n // later).\n const [openState, setOpen] = useControllable(\n openProp,\n (defaultOpen ?? false) && !disabled,\n onOpenChange,\n );\n const open = openState && !disabled;\n // Disabling also closes the list itself, not only the derived `open`, so enabling it again does\n // not reopen it without a user action. The close is reported through onOpenChange (a consumer\n // callback from an effect, C-HOOKS); a controlled `open` that stays true is not shown meanwhile.\n const lockedOpen = disabled && openState;\n React.useEffect(() => {\n if (lockedOpen) setOpen(false);\n }, [lockedOpen, setOpen]);\n\n const rootRef = React.useRef<HTMLDivElement | null>(null);\n const buttonRef = React.useRef<HTMLButtonElement | null>(null);\n\n const optionLabels = React.useMemo(() => collectOptionLabels(children), [children]);\n\n const listbox = useListbox({\n open,\n onOpenChange: (next) => setOpen(next),\n mode: 'select-only',\n multiselect,\n disabledOptionsFocusable,\n selectedValues: values,\n onSelect: (next, details) => {\n if (!multiselect) {\n // 0.7 order: the value callback first, the deprecated one after.\n setValue(next);\n onOptionSelect?.(next);\n return;\n }\n const { values: updated, added } = toggleValue(values, next);\n setValue(updated);\n onOptionSelect?.(next);\n // The committed option's label: the item useListbox passed in `details` (its own result,\n // `listbox`, cannot be read from inside the options object passed to it), else the label\n // read from `children` before the option registered, else the raw value. Announces a\n // toggle the user made (D41): never a controlled change, a clear or a form reset, none of\n // which reach this callback.\n announceToggle(\n labels,\n details?.item.label ?? optionLabels.get(next) ?? next,\n added,\n updated.length,\n );\n },\n onActiveValueChange: onActiveOptionChange,\n idPrefix: 'dropdown-listbox',\n });\n\n const expanded = open && listbox.items.length > 0;\n const { layerId, setReference, surfaceRef, floatingProps } = useListboxPopup({\n open,\n surfaceOpen: expanded,\n onDismiss: () => setOpen(false),\n rootRef,\n anchorRef: buttonRef,\n });\n\n const rootMergedRef = useMergedRefs<HTMLDivElement>(rootRef, ref);\n const buttonMergedRef = useMergedRefs<HTMLButtonElement>(buttonRef, controlRef, setReference);\n\n useFormReset(\n buttonRef,\n () => {\n if (!multiselect) {\n setValue(defaultValue ?? '');\n return;\n }\n // Compared by content (C-FORMS), so a reset that keeps the same values reports nothing.\n setValue((current) => resetValues(current, defaultValue));\n },\n form,\n );\n\n const labelOf = (v: string) => listbox.getItem(v)?.label ?? optionLabels.get(v);\n const shownLabels = values.map(labelOf).filter((label): label is string => label !== undefined);\n const displayText = multiselect\n ? shownLabels.length > 0\n ? (labels?.selection ?? defaultSelectionLabel)(shownLabels)\n : ''\n : (shownLabels[0] ?? '');\n\n // D15: the optional-indicator rule (Phase 1 D21) shared with Combobox's expand button, and the\n // glyph slot rule shared with SplitButton, MenuButton `menuIcon` and Combobox/TimePicker\n // `expandIcon` (C-SLOTS).\n const showExpand = showsExpandButton(expandIcon);\n const { glyph: expandGlyph, button: expandIconButton } = unwrapButtonGlyph(expandIcon);\n React.useEffect(() => {\n if (expandIconButton) {\n warnOnce(\n 'Dropdown:expandIcon-button',\n `Dropdown: \\`expandIcon\\` received ${expandIconButton}; its children render as the ` +\n 'glyph of the combobox button and its props were dropped (buttons cannot be nested). ' +\n 'Pass icon content instead, e.g. `expandIcon={<MyIcon />}`.',\n );\n }\n }, [expandIconButton]);\n\n // D15: `renderValue` replaces the button's content while a value is selected, given the raw\n // value(s) — never a label — so it is called only while `values` holds any (never for `''`/\n // `[]`); without it, the selected label(s) computed above show as in 0.7.\n const hasValue = values.length > 0;\n const showValue = renderValue ? hasValue : displayText !== '';\n const valueNode = !hasValue\n ? undefined\n : renderValue\n ? (renderValue as (value: string | string[]) => React.ReactNode)(\n multiselect ? [...values] : (values[0] ?? ''),\n )\n : displayText;\n\n const handleKeyDown = (event: React.KeyboardEvent<HTMLButtonElement>) => {\n if (event.key === 'Escape' && open && !expanded && !event.nativeEvent.isComposing) {\n // Open with nothing shown (no options): close, but leave Escape to an enclosing layer\n // (overlays#1) instead of consuming it for an invisible list.\n setOpen(false);\n return;\n }\n listbox.onKeyDown(event);\n };\n\n // The button disappears with the value, so focus moves to the combobox explicitly (C-DISABLED).\n const handleClear = () => {\n setValue(multiselect ? EMPTY_VALUES : '');\n setOpen(false);\n buttonRef.current?.focus();\n };\n\n const showClear = clearable && hasValue;\n // The expand glyph's inline-end offset per size (P4-01), shared by the chevron and a consumer\n // glyph.\n const expandOffset = size === 'small' ? 'end-2' : 'end-3';\n\n const listLabelledBy =\n fieldProps['aria-label'] === undefined\n ? (fieldProps['aria-labelledby'] ?? field?.labelId)\n : fieldProps['aria-labelledby'];\n\n return (\n <div\n data-size={size}\n data-appearance={appearance}\n {...rest}\n ref={rootMergedRef}\n className={cn(dropdownClassNames.root, 'relative inline-flex flex-col', className)}\n >\n {multiselect && <PickerAnnouncer />}\n <div className=\"relative flex items-center\">\n <button\n type=\"button\"\n {...fieldProps}\n {...listbox.getComboboxProps()}\n aria-expanded={expanded}\n aria-errormessage={ariaErrorMessage}\n aria-details={ariaDetails}\n ref={buttonMergedRef}\n disabled={disabled}\n autoFocus={autoFocus}\n tabIndex={tabIndex}\n onClick={() => setOpen((current) => !current)}\n onKeyDown={composeEventHandlers(onKeyDown, handleKeyDown)}\n onKeyUp={composeEventHandlers(onKeyUp, listbox.onKeyUp)}\n onFocus={onFocus}\n onBlur={onBlur}\n className={cn(\n dropdownClassNames.button,\n // Every padding is set here (C-NATIVE), not left to an app-wide `button` rule. The end\n // padding keeps the text clear of the chevron (and of the clear button while it shows).\n 'relative flex w-full items-center justify-between py-0 text-start',\n inputHeightClasses[size],\n inputPaddingClasses[size],\n inputTextClasses[size],\n inputAppearanceClasses[appearance],\n 'text-foreground',\n pickerEndPadding(Number(showClear) + Number(showExpand), size),\n inputFocus,\n disabledStyles,\n invalidLook && inputInvalid,\n )}\n >\n <span\n className={cn(\n dropdownClassNames.value,\n 'truncate',\n !showValue && 'text-muted-foreground',\n )}\n >\n {showValue ? valueNode : placeholder}\n </span>\n {showExpand &&\n (expandGlyph != null && slotRendersContent(expandGlyph) ? (\n renderSlot(\n expandGlyph,\n 'span',\n cn(\n dropdownClassNames.expandIcon,\n 'absolute inline-flex transition-transform motion-reduce:transition-none',\n expandOffset,\n expanded && 'rotate-180',\n ),\n { 'aria-hidden': true },\n )\n ) : (\n <ChevronDownIcon\n size={pickerGlyphSize(size, 'chevron')}\n className={cn(\n dropdownClassNames.expandIcon,\n 'absolute transition-transform motion-reduce:transition-none',\n expandOffset,\n expanded && 'rotate-180',\n )}\n />\n ))}\n </button>\n {showClear && (\n <button\n type=\"button\"\n aria-label={labels?.clear ?? 'Clear selection'}\n disabled={disabled}\n // Keeps focus on the combobox while the pointer clears it.\n onMouseDown={(event) => event.preventDefault()}\n onClick={handleClear}\n className={cn(\n dropdownClassNames.clearButton,\n pickerIconButtonClasses(size, appearance),\n // Before the chevron while it shows, else at the end.\n pickerButtonOffset(size, showExpand ? 2 : 1),\n focusRing,\n disabledStyles,\n )}\n >\n <DismissIcon size={pickerGlyphSize(size, 'icon')} />\n </button>\n )}\n </div>\n <ListboxSurface\n listbox={listbox}\n layerId={layerId}\n surfaceRef={surfaceRef}\n floatingProps={floatingProps}\n open={open}\n expanded={expanded}\n listClassName={dropdownClassNames.listbox}\n surfaceClassName={dropdownClassNames.surface}\n aria-label={fieldProps['aria-label']}\n aria-labelledby={listLabelledBy}\n >\n {children}\n </ListboxSurface>\n <HiddenInput\n name={name}\n form={form}\n disabled={disabled}\n value={multiselect ? values : (values[0] ?? '')}\n type=\"text\"\n required={isRequired}\n onInvalid={() => buttonRef.current?.focus()}\n />\n </div>\n );\n};\nDropdownRoot.displayName = 'Dropdown';\n\n/** Flat name of `Dropdown.Option` for React Server Components. */\nexport const DropdownOption = Option;\n/** Flat name of `Dropdown.OptionGroup` for React Server Components. */\nexport const DropdownOptionGroup = OptionGroup;\n\n/**\n * A select-only combobox (APG): a button that opens a listbox of `Option`s. Enter, Space,\n * ArrowDown/ArrowUp, Home/End and typing a character open it and move the highlight\n * (`aria-activedescendant`); Enter/Space select, Tab selects the highlighted option and moves on,\n * Escape closes. The button's chevron (see `expandIcon`) turns while the list is open, and\n * `renderValue` replaces its content while a value is selected. `clearable` adds a clear button,\n * a tab stop after the combobox button; both sit in a wrapper `<div>` inside the root.\n *\n * `multiselect` turns the value into an array (Fluent's `selectedOptions`): options draw a\n * checkbox; Enter and Space toggle the highlighted option, a click toggles the clicked option, and\n * the list stays open (Tab, Escape and Alt+ArrowUp close without committing); the button shows the\n * selected labels in selection order (`labels.selection`, replacing the placeholder while any are\n * selected, values without an option left out) and every toggle the user makes is announced\n * (`labels.added`/`labels.removed`, never for a controlled change, a clear or a form reset).\n * `clearable` then clears every value. A non-literal `multiselect={flag}` is a type error: render\n * two elements, one for each mode.\n *\n * The `<button>` receives `id`, `aria-label`, `aria-labelledby`, `aria-describedby`,\n * `aria-invalid`, `aria-required`, `aria-errormessage`, `aria-details`, `tabIndex`, `autoFocus`\n * and `onFocus`/`onBlur`/`onKeyDown`/`onKeyUp`. `ref`, `className`, `style`, other `aria-*`\n * attributes and the remaining props stay on the root `<div>`. Inside a `Field` the button is\n * labelled and described by it — otherwise give it an `aria-label`. It shows the error look\n * whenever it ends up `aria-invalid` (its own `aria-invalid` or a `Field` error). With\n * `name`/`required` the value takes part in form submission (one hidden input per value with\n * `multiselect`), validation and reset (a `multiselect` reset is compared by content, so restoring\n * the same values reports nothing). The open listbox renders in a portal; while closed it stays\n * in the DOM, hidden.\n *\n * **Size and appearance**: `size` resolves from its own prop, then the surrounding `Field`'s\n * `size`, then `WaveProvider inputDefaults.size`, else `'medium'`; `appearance` from its own prop,\n * then `WaveProvider inputDefaults.appearance`, else `'outline'`; both render as `data-size` and\n * `data-appearance` on the root `<div>`. The listbox keeps its size.\n *\n * Sub-components: `Dropdown.Option`, `Dropdown.OptionGroup`. React Server Components import the\n * flat names `DropdownOption` / `DropdownOptionGroup` (dotted access needs a client file).\n */\nexport const Dropdown = /* @__PURE__ */ Object.assign(DropdownRoot, {\n Option,\n OptionGroup,\n}) as DropdownComponent;\n"],"mappings":"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"}
1
+ {"version":3,"file":"Dropdown.cjs","names":["useFieldContext","useFieldControl","isInvalidLook","useInputLook","useControllable","EMPTY_VALUES","toValues","React","collectOptionLabels","useListbox","toggleValue","useListboxPopup","useMergedRefs","resetValues","defaultSelectionLabel","showsExpandButton","unwrapButtonGlyph","cn","dropdownClassNames","PickerAnnouncer","composeEventHandlers","inputHeightClasses","inputPaddingClasses","inputTextClasses","inputAppearanceClasses","pickerEndPadding","inputFocus","disabledStyles","slotRendersContent","renderSlot","ChevronDownIcon","pickerGlyphSize","pickerIconButtonClasses","pickerButtonOffset","DismissIcon","ListboxSurface","HiddenInput","Option","OptionGroup","require_runtime","require_cn","require_dev","require_slot","require_composeEventHandlers","require_classNames","require_useControllable","require_useMergedRefs","require_useFieldControl","require_useListbox","require_styles","require_Button_slots","require_icons","require_inputLook","require_Input","require_useFormReset","require_HiddenInput","require_pickerStyles","require_Combobox_expand","require_Option","require_pickerLabels","require_pickerValues","react","react_jsx_runtime","DropdownRoot","valueProp","openProp","sizeProp","appearanceProp","ariaLabel","ariaLabelledBy","ariaDescribedBy","ariaInvalid","ariaRequired","ariaErrorMessage","ariaDetails","rest","props","onOptionSelect","field","isRequired","required","fieldProps","invalidLook","value","setValue","defaultValue","multiselect","onValueChange","next","values","openState","setOpen","defaultOpen","disabled","onOpenChange","open","lockedOpen","rootRef","buttonRef","optionLabels","children","listbox","updated","labels","details","added","onActiveOptionChange","expanded","rootMergedRef","ref","buttonMergedRef","controlRef","setReference","current","form","shownLabels","v","label","displayText","showExpand","expandIcon","expandGlyph","expandIconButton","hasValue","showValue","renderValue","valueNode","handleKeyDown","event","handleClear","showClear","clearable","expandOffset","size","listLabelledBy","appearance","className","onKeyDown","onKeyUp","placeholder","DropdownOption","DropdownOptionGroup","Dropdown"],"sources":["../../../src/components/input/Dropdown.tsx"],"sourcesContent":["import * as React from 'react';\nimport { dropdownClassNames } from '../../lib/classNames';\nimport { cn } from '../../lib/cn';\nimport { composeEventHandlers } from '../../lib/composeEventHandlers';\nimport { warnDeprecated, warnOnce } from '../../lib/dev';\nimport { ChevronDownIcon, DismissIcon } from '../../lib/icons';\nimport { renderSlot, slotRendersContent } from '../../lib/slot';\nimport type { Slot } from '../../lib/slot';\nimport {\n disabledStyles,\n focusRing,\n inputAppearanceClasses,\n inputFocus,\n inputHeightClasses,\n inputInvalid,\n inputPaddingClasses,\n inputTextClasses,\n} from '../../lib/styles';\nimport type { CoreSize, InputAppearance, PopupPositioningOptions } from '../../lib/types';\nimport { useControllable } from '../../hooks/useControllable';\nimport { useFieldContext, useFieldControl } from '../../hooks/useFieldControl';\nimport { useFormReset } from '../../hooks/useFormReset';\nimport { collectOptionLabels, useListbox } from '../../hooks/useListbox';\nimport { useMergedRefs } from '../../hooks/useMergedRefs';\nimport { unwrapButtonGlyph } from '../button/Button.slots';\nimport { HiddenInput } from '../internal/HiddenInput';\nimport { showsExpandButton } from './Combobox.expand';\nimport { useInputLook } from './inputLook';\nimport { isInvalidLook } from './Input';\nimport { ListboxSurface, Option, OptionGroup, useListboxPopup } from './Option';\nimport { announceToggle, defaultSelectionLabel, PickerAnnouncer } from './pickerLabels';\nimport {\n pickerButtonOffset,\n pickerEndPadding,\n pickerGlyphSize,\n pickerIconButtonClasses,\n} from './pickerStyles';\nimport { EMPTY_VALUES, resetValues, toggleValue, toValues } from './pickerValues';\nimport type { RoutedHandlers } from './routedHandlers';\n\n/* ------------------------------------------------------------------ */\n/* Dropdown */\n/* ------------------------------------------------------------------ */\n\n/**\n * The Dropdown's built-in texts, for localization. Each member is optional and falls back to its\n * English default.\n */\nexport interface DropdownLabels {\n /** Name of the clear button (`clearable`).\n * @default 'Clear selection'\n */\n clear?: string;\n /**\n * The text of the selected labels shown in the combobox with `multiselect`, in selection order;\n * values without an option are left out. Replaces the button's joined value text.\n * @default (labels) => labels.join(', ')\n */\n selection?: (labels: string[]) => string;\n /**\n * Announced when a `multiselect` toggle selects an option; `count` is the number of values\n * selected after the change.\n * @default (label, count) => `${label} added, ${count} selected`\n */\n added?: (label: string, count: number) => string;\n /**\n * Announced when a `multiselect` toggle deselects an option; `count` is the number of values\n * selected after the change.\n * @default (label, count) => `${label} removed, ${count} selected`\n */\n removed?: (label: string, count: number) => string;\n}\n\n/** Properties for the Dropdown component. */\nexport interface DropdownProps<M extends boolean = false> extends Omit<\n React.HTMLAttributes<HTMLDivElement>,\n 'onChange' | 'defaultValue' | RoutedHandlers\n> {\n /**\n * Several options can be selected (Fluent's `multiselect`): the value is an array, options show\n * a checkbox, Enter and Space toggle the highlighted option, a click toggles the clicked\n * option, the list stays open, and each toggle is announced. A non-literal `multiselect={flag}`\n * is a type error: render two elements, one for each mode.\n * @default false\n */\n multiselect?: M;\n /**\n * Controlled selected value (`''` for none), or with `multiselect` the selected values (Fluent's\n * `selectedOptions`).\n */\n value?: M extends true ? readonly string[] : string;\n /**\n * Initial selected value for uncontrolled usage.\n * @default '' (`[]` with `multiselect`)\n */\n defaultValue?: M extends true ? readonly string[] : string;\n /**\n * Called with the new value when it changes (a new array with `multiselect`; Fluent's\n * `onOptionSelect`, under WaveUI's value/onValueChange naming).\n */\n onValueChange?: M extends true ? (value: string[]) => void : (value: string) => void;\n /**\n * Called on every option activation, also when the current option is selected again (every\n * toggle with `multiselect`).\n * @deprecated Use `onValueChange`.\n */\n onOptionSelect?: (value: string) => void;\n /**\n * Controlled open state of the listbox. The list renders only in the browser: an open dropdown\n * is closed in the server HTML and opens once it has hydrated.\n */\n open?: boolean;\n /**\n * Initial open state for uncontrolled usage. A dropdown that starts disabled starts closed. The\n * list renders only in the browser: it is closed in the server HTML and opens once the dropdown\n * has hydrated.\n * @default false\n */\n defaultOpen?: boolean;\n /** Called when the listbox opens or closes. */\n onOpenChange?: (open: boolean) => void;\n /**\n * Called after the active (highlighted) option changes — opening, arrow keys, typeahead, the\n * pointer — and with `null` when the list closes. It reports what `aria-activedescendant` points\n * at, from an effect once the change commits. Fluent's `onActiveOptionChange` reports neither the\n * pointer (its options have no hover highlight) nor the close.\n */\n onActiveOptionChange?: (value: string | null) => void;\n /**\n * Keeps disabled options in the arrow-key, Home/End, PageUp/PageDown and typeahead order (the\n * highlighted-by-default option may then be a disabled one too); they still cannot be selected\n * (Enter, Space and a click do nothing and the list stays open), and in single-select mode,\n * reaching one with Tab or Alt+ArrowUp closes the list without selecting it. Unlike Fluent,\n * which always keeps disabled options reachable, WaveUI skips them by default.\n * @default false\n */\n disabledOptionsFocusable?: boolean;\n /**\n * Placeholder text shown when no value is selected. It is not an accessible name: label the\n * Dropdown with a `Field`, `aria-label` or `aria-labelledby`.\n * @default 'Select an option'\n */\n placeholder?: string;\n /**\n * Renders the button's content while a value is selected (the placeholder shows otherwise), in\n * place of the selected label (`labels.selection` with `multiselect`). It receives the raw\n * value(s), never a label; the content must be non-interactive, and its text is the combobox's\n * value, so image-only content leaves the value empty.\n * @default the selected label (`labels.selection` with `multiselect`)\n */\n renderValue?: M extends true\n ? (value: string[]) => React.ReactNode\n : (value: string) => React.ReactNode;\n /**\n * Whether the dropdown is disabled and non-interactive. Turning it on while the listbox is open\n * closes it (`onOpenChange(false)`).\n * @default false\n */\n disabled?: boolean;\n /**\n * Size of the field: `small` (24px tall), `medium` (32px) or `large` (40px). Default: the\n * surrounding Field's `size`, else `WaveProvider inputDefaults.size`, else `'medium'`. The\n * listbox keeps its size; the multi-select value text and clear button follow it.\n */\n size?: CoreSize;\n /**\n * Advanced positioning of the popup (Fluent's `positioning`): `offset`, `fitViewport`,\n * `matchReferenceWidth` and `fallbackPlacements` (tried in order when the requested side has no\n * room). The popup opens below the field.\n * @default `{ matchReferenceWidth: true, fitViewport: true }`\n */\n positioning?: PopupPositioningOptions;\n /**\n * Look of the field: `outline` (a full border), `underline` (a bottom stroke only),\n * `filled-darker` or `filled-lighter` (a fill without a visible stroke: give the field a visible\n * label). Default: `WaveProvider inputDefaults.appearance`, else `'outline'`.\n */\n appearance?: InputAppearance;\n /**\n * Name of the value in form submissions (renders a hidden input; one per value with\n * `multiselect`).\n */\n name?: string;\n /** Id of the form the value belongs to, when the Dropdown is outside it. */\n form?: string;\n /** A value is required to submit the form (native constraint validation). */\n required?: boolean;\n /**\n * Shows a clear button while a value is selected (shown disabled while `disabled`). It clears\n * the value (every value with `multiselect`), closes the list and moves focus to the combobox\n * button. It is a tab stop after it.\n * @default false\n */\n clearable?: boolean;\n /**\n * The glyph at the end of the button (default: a chevron). `null` or `undefined` keep it;\n * `false`, or a value that renders nothing, hides it (the button's end padding follows,\n * together with `clearable`). The default chevron's size and the glyph's offset follow\n * `size`. Decorative content rendered inside the button: a `<button>` or `Button` passed\n * here is not nested (its children become the glyph, with a development warning).\n */\n expandIcon?: Slot<'span'>;\n /**\n * The clear button's name and, with `multiselect`, the selected-labels text and the toggle\n * announcements, for localization. Unset members keep their English defaults.\n */\n labels?: DropdownLabels;\n /** Called when the `<button role=\"combobox\">` receives focus (the root keeps other handlers). */\n onFocus?: React.FocusEventHandler<HTMLButtonElement>;\n /** Called when the `<button role=\"combobox\">` loses focus. */\n onBlur?: React.FocusEventHandler<HTMLButtonElement>;\n /**\n * Called on a key press on the `<button role=\"combobox\">`, before the built-in listbox keys;\n * `event.preventDefault()` skips them.\n */\n onKeyDown?: React.KeyboardEventHandler<HTMLButtonElement>;\n /** Called when a key is released on the `<button role=\"combobox\">`. */\n onKeyUp?: React.KeyboardEventHandler<HTMLButtonElement>;\n /** Ref to the `<button role=\"combobox\">` (the focusable element). */\n controlRef?: React.Ref<HTMLButtonElement>;\n /** Ref to the root `<div>`. */\n ref?: React.Ref<HTMLDivElement>;\n}\n\n/** The Dropdown component's type: a multi-select signature, then the single-select one. */\nexport interface DropdownComponent {\n (props: DropdownProps<true> & { multiselect: true }): React.ReactNode;\n (props: DropdownProps): React.ReactNode;\n displayName?: string;\n Option: typeof Option;\n OptionGroup: typeof OptionGroup;\n}\n\nconst DropdownRoot = (props: DropdownProps<boolean>) => {\n const {\n multiselect = false,\n value: valueProp,\n defaultValue,\n onValueChange,\n onOptionSelect,\n open: openProp,\n defaultOpen,\n onOpenChange,\n onActiveOptionChange,\n disabledOptionsFocusable = false,\n placeholder = 'Select an option',\n renderValue,\n disabled = false,\n size: sizeProp,\n positioning,\n appearance: appearanceProp,\n name,\n form,\n required,\n clearable = false,\n expandIcon,\n labels,\n autoFocus,\n tabIndex,\n id,\n 'aria-label': ariaLabel,\n 'aria-labelledby': ariaLabelledBy,\n 'aria-describedby': ariaDescribedBy,\n 'aria-invalid': ariaInvalid,\n 'aria-required': ariaRequired,\n 'aria-errormessage': ariaErrorMessage,\n 'aria-details': ariaDetails,\n onFocus,\n onBlur,\n onKeyDown,\n onKeyUp,\n controlRef,\n className,\n children,\n ref,\n ...rest\n } = props;\n\n if (onOptionSelect !== undefined) warnDeprecated('Dropdown', 'onOptionSelect', 'onValueChange');\n\n const field = useFieldContext();\n const isRequired = required ?? field?.required ?? false;\n const fieldProps = useFieldControl({\n id,\n 'aria-label': ariaLabel,\n 'aria-labelledby': ariaLabelledBy,\n 'aria-describedby': ariaDescribedBy,\n 'aria-invalid': ariaInvalid,\n // An explicit `required={false}` wins over a required Field, so aria-required matches\n // `isRequired`.\n 'aria-required': ariaRequired ?? required,\n });\n // The error look follows the resolved state: the consumer's `aria-invalid` or the Field's.\n const invalidLook = isInvalidLook(false, fieldProps['aria-invalid']);\n const { size, appearance } = useInputLook(sizeProp, appearanceProp);\n\n const [value, setValue] = useControllable<string | readonly string[]>(\n valueProp,\n defaultValue ?? (multiselect ? EMPTY_VALUES : ''),\n (next) => {\n // The two call signatures make `onValueChange` a union of incompatible functions from here:\n // the root itself is written against the wider, internal shape (D9).\n (onValueChange as ((value: string | string[]) => void) | undefined)?.(\n typeof next === 'string' ? next : [...next],\n );\n },\n );\n // Normalised for the listbox, the display text and the clear/reset logic: a single value is its\n // own one-element array, and a `value` passed as `null`/`undefined` from JavaScript (bypassing\n // the type system) is none rather than a crash, as 0.7 did for the single-select string.\n const values = toValues(value);\n\n // A dropdown that starts disabled never shows its list, so it starts closed (no close to report\n // later).\n const [openState, setOpen] = useControllable(\n openProp,\n (defaultOpen ?? false) && !disabled,\n onOpenChange,\n );\n const open = openState && !disabled;\n // Disabling also closes the list itself, not only the derived `open`, so enabling it again does\n // not reopen it without a user action. The close is reported through onOpenChange (a consumer\n // callback from an effect, C-HOOKS); a controlled `open` that stays true is not shown meanwhile.\n const lockedOpen = disabled && openState;\n React.useEffect(() => {\n if (lockedOpen) setOpen(false);\n }, [lockedOpen, setOpen]);\n\n const rootRef = React.useRef<HTMLDivElement | null>(null);\n const buttonRef = React.useRef<HTMLButtonElement | null>(null);\n\n const optionLabels = React.useMemo(() => collectOptionLabels(children), [children]);\n\n const listbox = useListbox({\n open,\n onOpenChange: (next) => setOpen(next),\n mode: 'select-only',\n multiselect,\n disabledOptionsFocusable,\n selectedValues: values,\n onSelect: (next, details) => {\n if (!multiselect) {\n // 0.7 order: the value callback first, the deprecated one after.\n setValue(next);\n onOptionSelect?.(next);\n return;\n }\n const { values: updated, added } = toggleValue(values, next);\n setValue(updated);\n onOptionSelect?.(next);\n // The committed option's label: the item useListbox passed in `details` (its own result,\n // `listbox`, cannot be read from inside the options object passed to it), else the label\n // read from `children` before the option registered, else the raw value. Announces a\n // toggle the user made (D41): never a controlled change, a clear or a form reset, none of\n // which reach this callback.\n announceToggle(\n labels,\n details?.item.label ?? optionLabels.get(next) ?? next,\n added,\n updated.length,\n );\n },\n onActiveValueChange: onActiveOptionChange,\n idPrefix: 'dropdown-listbox',\n });\n\n const expanded = open && listbox.items.length > 0;\n const { layerId, setReference, surfaceRef, floatingProps } = useListboxPopup({\n positioning,\n open,\n surfaceOpen: expanded,\n onDismiss: () => setOpen(false),\n rootRef,\n anchorRef: buttonRef,\n });\n\n const rootMergedRef = useMergedRefs<HTMLDivElement>(rootRef, ref);\n const buttonMergedRef = useMergedRefs<HTMLButtonElement>(buttonRef, controlRef, setReference);\n\n useFormReset(\n buttonRef,\n () => {\n if (!multiselect) {\n setValue(defaultValue ?? '');\n return;\n }\n // Compared by content (C-FORMS), so a reset that keeps the same values reports nothing.\n setValue((current) => resetValues(current, defaultValue));\n },\n form,\n );\n\n const labelOf = (v: string) => listbox.getItem(v)?.label ?? optionLabels.get(v);\n const shownLabels = values.map(labelOf).filter((label): label is string => label !== undefined);\n const displayText = multiselect\n ? shownLabels.length > 0\n ? (labels?.selection ?? defaultSelectionLabel)(shownLabels)\n : ''\n : (shownLabels[0] ?? '');\n\n // D15: the optional-indicator rule (Phase 1 D21) shared with Combobox's expand button, and the\n // glyph slot rule shared with SplitButton, MenuButton `menuIcon` and Combobox/TimePicker\n // `expandIcon` (C-SLOTS).\n const showExpand = showsExpandButton(expandIcon);\n const { glyph: expandGlyph, button: expandIconButton } = unwrapButtonGlyph(expandIcon);\n React.useEffect(() => {\n if (expandIconButton) {\n warnOnce(\n 'Dropdown:expandIcon-button',\n `Dropdown: \\`expandIcon\\` received ${expandIconButton}; its children render as the ` +\n 'glyph of the combobox button and its props were dropped (buttons cannot be nested). ' +\n 'Pass icon content instead, e.g. `expandIcon={<MyIcon />}`.',\n );\n }\n }, [expandIconButton]);\n\n // D15: `renderValue` replaces the button's content while a value is selected, given the raw\n // value(s) — never a label — so it is called only while `values` holds any (never for `''`/\n // `[]`); without it, the selected label(s) computed above show as in 0.7.\n const hasValue = values.length > 0;\n const showValue = renderValue ? hasValue : displayText !== '';\n const valueNode = !hasValue\n ? undefined\n : renderValue\n ? (renderValue as (value: string | string[]) => React.ReactNode)(\n multiselect ? [...values] : (values[0] ?? ''),\n )\n : displayText;\n\n const handleKeyDown = (event: React.KeyboardEvent<HTMLButtonElement>) => {\n if (event.key === 'Escape' && open && !expanded && !event.nativeEvent.isComposing) {\n // Open with nothing shown (no options): close, but leave Escape to an enclosing layer\n // (overlays#1) instead of consuming it for an invisible list.\n setOpen(false);\n return;\n }\n listbox.onKeyDown(event);\n };\n\n // The button disappears with the value, so focus moves to the combobox explicitly (C-DISABLED).\n const handleClear = () => {\n setValue(multiselect ? EMPTY_VALUES : '');\n setOpen(false);\n buttonRef.current?.focus();\n };\n\n const showClear = clearable && hasValue;\n // The expand glyph's inline-end offset per size (P4-01), shared by the chevron and a consumer\n // glyph.\n const expandOffset = size === 'small' ? 'end-2' : 'end-3';\n\n const listLabelledBy =\n fieldProps['aria-label'] === undefined\n ? (fieldProps['aria-labelledby'] ?? field?.labelId)\n : fieldProps['aria-labelledby'];\n\n return (\n <div\n data-size={size}\n data-appearance={appearance}\n {...rest}\n ref={rootMergedRef}\n className={cn(dropdownClassNames.root, 'relative inline-flex flex-col', className)}\n >\n {multiselect && <PickerAnnouncer />}\n <div className=\"relative flex items-center\">\n <button\n type=\"button\"\n {...fieldProps}\n {...listbox.getComboboxProps()}\n aria-expanded={expanded}\n aria-errormessage={ariaErrorMessage}\n aria-details={ariaDetails}\n ref={buttonMergedRef}\n disabled={disabled}\n autoFocus={autoFocus}\n tabIndex={tabIndex}\n onClick={() => setOpen((current) => !current)}\n onKeyDown={composeEventHandlers(onKeyDown, handleKeyDown)}\n onKeyUp={composeEventHandlers(onKeyUp, listbox.onKeyUp)}\n onFocus={onFocus}\n onBlur={onBlur}\n className={cn(\n dropdownClassNames.button,\n // Every padding is set here (C-NATIVE), not left to an app-wide `button` rule. The end\n // padding keeps the text clear of the chevron (and of the clear button while it shows).\n 'relative flex w-full items-center justify-between py-0 text-start',\n inputHeightClasses[size],\n inputPaddingClasses[size],\n inputTextClasses[size],\n inputAppearanceClasses[appearance],\n 'text-foreground',\n pickerEndPadding(Number(showClear) + Number(showExpand), size),\n inputFocus,\n disabledStyles,\n invalidLook && inputInvalid,\n )}\n >\n <span\n className={cn(\n dropdownClassNames.value,\n 'truncate',\n !showValue && 'text-muted-foreground',\n )}\n >\n {showValue ? valueNode : placeholder}\n </span>\n {showExpand &&\n (expandGlyph != null && slotRendersContent(expandGlyph) ? (\n renderSlot(\n expandGlyph,\n 'span',\n cn(\n dropdownClassNames.expandIcon,\n 'absolute inline-flex transition-transform motion-reduce:transition-none',\n expandOffset,\n expanded && 'rotate-180',\n ),\n { 'aria-hidden': true },\n )\n ) : (\n <ChevronDownIcon\n size={pickerGlyphSize(size, 'chevron')}\n className={cn(\n dropdownClassNames.expandIcon,\n 'absolute transition-transform motion-reduce:transition-none',\n expandOffset,\n expanded && 'rotate-180',\n )}\n />\n ))}\n </button>\n {showClear && (\n <button\n type=\"button\"\n aria-label={labels?.clear ?? 'Clear selection'}\n disabled={disabled}\n // Keeps focus on the combobox while the pointer clears it.\n onMouseDown={(event) => event.preventDefault()}\n onClick={handleClear}\n className={cn(\n dropdownClassNames.clearButton,\n pickerIconButtonClasses(size, appearance),\n // Before the chevron while it shows, else at the end.\n pickerButtonOffset(size, showExpand ? 2 : 1),\n focusRing,\n disabledStyles,\n )}\n >\n <DismissIcon size={pickerGlyphSize(size, 'icon')} />\n </button>\n )}\n </div>\n <ListboxSurface\n listbox={listbox}\n layerId={layerId}\n surfaceRef={surfaceRef}\n floatingProps={floatingProps}\n open={open}\n expanded={expanded}\n listClassName={dropdownClassNames.listbox}\n surfaceClassName={dropdownClassNames.surface}\n aria-label={fieldProps['aria-label']}\n aria-labelledby={listLabelledBy}\n >\n {children}\n </ListboxSurface>\n <HiddenInput\n name={name}\n form={form}\n disabled={disabled}\n value={multiselect ? values : (values[0] ?? '')}\n type=\"text\"\n required={isRequired}\n onInvalid={() => buttonRef.current?.focus()}\n />\n </div>\n );\n};\nDropdownRoot.displayName = 'Dropdown';\n\n/** Flat name of `Dropdown.Option` for React Server Components. */\nexport const DropdownOption = Option;\n/** Flat name of `Dropdown.OptionGroup` for React Server Components. */\nexport const DropdownOptionGroup = OptionGroup;\n\n/**\n * A select-only combobox (APG): a button that opens a listbox of `Option`s. Enter, Space,\n * ArrowDown/ArrowUp, Home/End and typing a character open it and move the highlight\n * (`aria-activedescendant`); Enter/Space select, Tab selects the highlighted option and moves on,\n * Escape closes. The button's chevron (see `expandIcon`) turns while the list is open, and\n * `renderValue` replaces its content while a value is selected. `clearable` adds a clear button,\n * a tab stop after the combobox button; both sit in a wrapper `<div>` inside the root.\n *\n * `multiselect` turns the value into an array (Fluent's `selectedOptions`): options draw a\n * checkbox; Enter and Space toggle the highlighted option, a click toggles the clicked option, and\n * the list stays open (Tab, Escape and Alt+ArrowUp close without committing); the button shows the\n * selected labels in selection order (`labels.selection`, replacing the placeholder while any are\n * selected, values without an option left out) and every toggle the user makes is announced\n * (`labels.added`/`labels.removed`, never for a controlled change, a clear or a form reset).\n * `clearable` then clears every value. A non-literal `multiselect={flag}` is a type error: render\n * two elements, one for each mode.\n *\n * The `<button>` receives `id`, `aria-label`, `aria-labelledby`, `aria-describedby`,\n * `aria-invalid`, `aria-required`, `aria-errormessage`, `aria-details`, `tabIndex`, `autoFocus`\n * and `onFocus`/`onBlur`/`onKeyDown`/`onKeyUp`. `ref`, `className`, `style`, other `aria-*`\n * attributes and the remaining props stay on the root `<div>`. Inside a `Field` the button is\n * labelled and described by it — otherwise give it an `aria-label`. It shows the error look\n * whenever it ends up `aria-invalid` (its own `aria-invalid` or a `Field` error). With\n * `name`/`required` the value takes part in form submission (one hidden input per value with\n * `multiselect`), validation and reset (a `multiselect` reset is compared by content, so restoring\n * the same values reports nothing). The open listbox renders in a portal; while closed it stays\n * in the DOM, hidden.\n *\n * **Size and appearance**: `size` resolves from its own prop, then the surrounding `Field`'s\n * `size`, then `WaveProvider inputDefaults.size`, else `'medium'`; `appearance` from its own prop,\n * then `WaveProvider inputDefaults.appearance`, else `'outline'`; both render as `data-size` and\n * `data-appearance` on the root `<div>`. The listbox keeps its size.\n *\n * Sub-components: `Dropdown.Option`, `Dropdown.OptionGroup`. React Server Components import the\n * flat names `DropdownOption` / `DropdownOptionGroup` (dotted access needs a client file).\n */\nexport const Dropdown = /* @__PURE__ */ Object.assign(DropdownRoot, {\n Option,\n OptionGroup,\n}) as DropdownComponent;\n"],"mappings":"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"}