@mortenbrudvik/waveui 0.9.0 → 0.10.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 (105) hide show
  1. package/README.md +425 -104
  2. package/dist/components/input/Calendar.cjs +2 -0
  3. package/dist/components/input/Calendar.cjs.map +1 -0
  4. package/dist/components/input/Calendar.mjs +352 -0
  5. package/dist/components/input/Calendar.mjs.map +1 -0
  6. package/dist/components/input/Calendar.views.cjs +2 -0
  7. package/dist/components/input/Calendar.views.cjs.map +1 -0
  8. package/dist/components/input/Calendar.views.mjs +194 -0
  9. package/dist/components/input/Calendar.views.mjs.map +1 -0
  10. package/dist/components/input/ColorArea.cjs +1 -1
  11. package/dist/components/input/ColorArea.cjs.map +1 -1
  12. package/dist/components/input/ColorArea.mjs +18 -18
  13. package/dist/components/input/ColorArea.mjs.map +1 -1
  14. package/dist/components/input/Combobox.cjs +1 -1
  15. package/dist/components/input/Combobox.cjs.map +1 -1
  16. package/dist/components/input/Combobox.mjs +232 -156
  17. package/dist/components/input/Combobox.mjs.map +1 -1
  18. package/dist/components/input/Combobox.text.cjs +2 -0
  19. package/dist/components/input/Combobox.text.cjs.map +1 -0
  20. package/dist/components/input/Combobox.text.mjs +24 -0
  21. package/dist/components/input/Combobox.text.mjs.map +1 -0
  22. package/dist/components/input/DatePicker.cjs +1 -1
  23. package/dist/components/input/DatePicker.cjs.map +1 -1
  24. package/dist/components/input/DatePicker.mjs +203 -288
  25. package/dist/components/input/DatePicker.mjs.map +1 -1
  26. package/dist/components/input/Dropdown.cjs +1 -1
  27. package/dist/components/input/Dropdown.cjs.map +1 -1
  28. package/dist/components/input/Dropdown.mjs +135 -109
  29. package/dist/components/input/Dropdown.mjs.map +1 -1
  30. package/dist/components/input/Listbox.cjs +2 -0
  31. package/dist/components/input/Listbox.cjs.map +1 -0
  32. package/dist/components/input/Listbox.mjs +134 -0
  33. package/dist/components/input/Listbox.mjs.map +1 -0
  34. package/dist/components/input/Option.cjs +1 -1
  35. package/dist/components/input/Option.cjs.map +1 -1
  36. package/dist/components/input/Option.mjs +158 -97
  37. package/dist/components/input/Option.mjs.map +1 -1
  38. package/dist/components/input/SwatchPicker.cjs +1 -1
  39. package/dist/components/input/SwatchPicker.cjs.map +1 -1
  40. package/dist/components/input/SwatchPicker.context.cjs +2 -0
  41. package/dist/components/input/SwatchPicker.context.cjs.map +1 -0
  42. package/dist/components/input/SwatchPicker.context.mjs +35 -0
  43. package/dist/components/input/SwatchPicker.context.mjs.map +1 -0
  44. package/dist/components/input/SwatchPicker.mjs +131 -103
  45. package/dist/components/input/SwatchPicker.mjs.map +1 -1
  46. package/dist/components/input/SwatchPicker.swatches.cjs +2 -0
  47. package/dist/components/input/SwatchPicker.swatches.cjs.map +1 -0
  48. package/dist/components/input/SwatchPicker.swatches.mjs +207 -0
  49. package/dist/components/input/SwatchPicker.swatches.mjs.map +1 -0
  50. package/dist/components/input/TagPicker.cjs +1 -1
  51. package/dist/components/input/TagPicker.cjs.map +1 -1
  52. package/dist/components/input/TagPicker.mjs +144 -139
  53. package/dist/components/input/TagPicker.mjs.map +1 -1
  54. package/dist/components/input/TimePicker.cjs +1 -1
  55. package/dist/components/input/TimePicker.cjs.map +1 -1
  56. package/dist/components/input/TimePicker.mjs +77 -77
  57. package/dist/components/input/TimePicker.mjs.map +1 -1
  58. package/dist/components/input/dateUtils.cjs +1 -1
  59. package/dist/components/input/dateUtils.cjs.map +1 -1
  60. package/dist/components/input/dateUtils.mjs +114 -96
  61. package/dist/components/input/dateUtils.mjs.map +1 -1
  62. package/dist/components/input/pickerLabels.cjs +2 -0
  63. package/dist/components/input/pickerLabels.cjs.map +1 -0
  64. package/dist/components/input/pickerLabels.mjs +16 -0
  65. package/dist/components/input/pickerLabels.mjs.map +1 -0
  66. package/dist/components/input/pickerValues.cjs +2 -0
  67. package/dist/components/input/pickerValues.cjs.map +1 -0
  68. package/dist/components/input/pickerValues.mjs +24 -0
  69. package/dist/components/input/pickerValues.mjs.map +1 -0
  70. package/dist/components/table/useGridNavigation.cjs +1 -1
  71. package/dist/components/table/useGridNavigation.cjs.map +1 -1
  72. package/dist/components/table/useGridNavigation.mjs +67 -70
  73. package/dist/components/table/useGridNavigation.mjs.map +1 -1
  74. package/dist/hooks/useActiveDescendant.cjs +2 -0
  75. package/dist/hooks/useActiveDescendant.cjs.map +1 -0
  76. package/dist/hooks/useActiveDescendant.mjs +56 -0
  77. package/dist/hooks/useActiveDescendant.mjs.map +1 -0
  78. package/dist/hooks/useListbox.cjs +1 -1
  79. package/dist/hooks/useListbox.cjs.map +1 -1
  80. package/dist/hooks/useListbox.mjs +250 -210
  81. package/dist/hooks/useListbox.mjs.map +1 -1
  82. package/dist/hooks/useRovingGrid.cjs +2 -0
  83. package/dist/hooks/useRovingGrid.cjs.map +1 -0
  84. package/dist/hooks/useRovingGrid.mjs +69 -0
  85. package/dist/hooks/useRovingGrid.mjs.map +1 -0
  86. package/dist/index.cjs +1 -1
  87. package/dist/index.d.cts +2147 -155
  88. package/dist/index.d.ts +2147 -155
  89. package/dist/index.mjs +107 -101
  90. package/dist/lib/classNames.cjs +1 -1
  91. package/dist/lib/classNames.cjs.map +1 -1
  92. package/dist/lib/classNames.mjs +84 -48
  93. package/dist/lib/classNames.mjs.map +1 -1
  94. package/dist/lib/date.cjs +2 -0
  95. package/dist/lib/date.cjs.map +1 -0
  96. package/dist/lib/date.mjs +44 -0
  97. package/dist/lib/date.mjs.map +1 -0
  98. package/dist/lib/focus.cjs +1 -1
  99. package/dist/lib/focus.cjs.map +1 -1
  100. package/dist/lib/focus.mjs +5 -2
  101. package/dist/lib/focus.mjs.map +1 -1
  102. package/dist/lib/layers.cjs.map +1 -1
  103. package/dist/lib/layers.mjs.map +1 -1
  104. package/dist/styles.css +1 -1
  105. package/package.json +1 -1
package/dist/index.d.ts CHANGED
@@ -199,6 +199,19 @@ export declare interface AccordionTriggerProps extends React_2.ButtonHTMLAttribu
199
199
  ref?: React_2.Ref<HTMLButtonElement>;
200
200
  }
201
201
 
202
+ /**
203
+ * `date` plus `amount` calendar days (negative to go back), at local midnight; the time of day is
204
+ * dropped.
205
+ */
206
+ export declare function addDays(date: Date, amount: number): Date;
207
+
208
+ /**
209
+ * `date` plus `amount` months (negative to go back), at local midnight; the time of day is dropped.
210
+ * The day is clamped to the length of the target month: January 31 plus one month is February 28
211
+ * (29 in a leap year), never a day of the following month.
212
+ */
213
+ export declare function addMonths(date: Date, amount: number): Date;
214
+
202
215
  /**
203
216
  * A slider for a color's opacity, drawn over a checkerboard, horizontal (mirrored in right-to-left
204
217
  * layouts) or vertical (bottom to top); `transparency` shows transparency instead. The arrow keys
@@ -765,6 +778,291 @@ export declare interface ButtonOwnProps {
765
778
  */
766
779
  export declare type ButtonProps<C extends React_2.ElementType = 'button'> = PolymorphicProps<C, ButtonOwnProps>;
767
780
 
781
+ /**
782
+ * A month calendar for picking one day, without a text input: the grid of DatePicker's dialog,
783
+ * placed in the page (APG date picker grid).
784
+ *
785
+ * - **Structure**: a `role="group"` root, named with `aria-label`/`aria-labelledby` or by a
786
+ * surrounding `Field`, around the previous-month button, the month text (a polite live region
787
+ * that labels the grid), the next-month button and a `role="grid"` table of six weeks, with an
788
+ * optional leading column of week numbers (`showWeekNumbers`, `firstWeekOfYear`) and an
789
+ * optional footer button, "Go to today" (`showGoToToday`), which shows today's month and focuses
790
+ * today without selecting it. The month text is no heading, since a component cannot know the
791
+ * page's heading levels.
792
+ * - **Month and year views** (`showMonthPicker`, on by default): the month text is a button
793
+ * (named by that text, its hint `labels.chooseMonth`) that shows the 12 months of the year; their
794
+ * heading, the year, is a button to the year view, a decade with the year before and after it
795
+ * (muted). The header buttons move by a year, then by a decade. A picked year shows its months
796
+ * and a picked month its days (the focused day keeps its day of the month, clamped); Escape
797
+ * goes back a level to the period shown before. Each view change moves focus into the new
798
+ * grid. Months and years wholly outside `minDate`/`maxDate` stay focusable, `aria-disabled`.
799
+ * - **Keyboard**: one tab stop in the grid, the focused day (the selected day of the shown month,
800
+ * else today, else the first day of the month in range, which may be unavailable). Arrow keys
801
+ * move by day and week (mirrored in RTL), PageUp/PageDown by month, Shift+PageUp/PageDown by
802
+ * year (the day is clamped to the month), Home/End to the start and end of the week; Enter,
803
+ * Space and a click pick the day. Unavailable days (`minDate`, `maxDate`, `disabledDates`) stay
804
+ * focusable and are `aria-disabled`. In the month and year views the arrows move by a cell and a
805
+ * row of four, Home/End to the row's ends, PageUp/PageDown by a year (months) or ten (years).
806
+ * - **Value**: `onValueChange` fires only when the day changes, with local midnight and `details`;
807
+ * picking the selected day again does nothing. A value that moves to another month shows that
808
+ * month. The selected day is `aria-selected` on its gridcell and `aria-pressed` on its button;
809
+ * today is `aria-current="date"`. With `selectionRange` a pick selects the day's week, work
810
+ * week (`workWeekDays`) or month: every available day of it is drawn and marked selected, the
811
+ * value is the picked day, and `details.range` lists the selected days in order.
812
+ * - **Marked days and custom content**: `markedDates` draws a dot in the text colour under the
813
+ * number, sets `data-marked` and says "marked" in the day's name; `renderDay` replaces the
814
+ * content of the day button (non-interactive content only) and `dayLabel` sets its name.
815
+ * - **Forms and Field**: `name`/`required` add a hidden input (ISO `yyyy-mm-dd`) that resets with
816
+ * its form (to `defaultValue`); a required calendar that the form reports missing focuses its
817
+ * tab stop. Inside a `Field` the group takes the label, the description and `aria-invalid`; it
818
+ * says "required" in its description (`labels.required`), since a group cannot carry
819
+ * `aria-required`.
820
+ * - **Server rendering**: pass `locale`, and `today`, `initialVisibleDate` or a value, so the
821
+ * server and the browser render the same month. Only `today` marks a day in the server HTML:
822
+ * without it the server HTML marks none and the browser marks today once hydrated. Without any
823
+ * of the three the month shown first comes from the server's clock (development warning).
824
+ *
825
+ * @example
826
+ * <Calendar aria-label="Due date" defaultValue={new Date(2025, 5, 12)} onValueChange={setDue} />
827
+ */
828
+ export declare const Calendar: {
829
+ ({ value: valueProp, defaultValue, onValueChange, minDate, maxDate, disabledDates, firstDayOfWeek, locale, today: todayProp, initialVisibleDate, showMonthPicker, showWeekNumbers, firstWeekOfYear, showGoToToday, markedDates, renderDay, dayLabel, selectionRange, workWeekDays, labels, name, form, required, id, "aria-label": ariaLabel, "aria-labelledby": ariaLabelledBy, "aria-describedby": ariaDescribedBy, "aria-invalid": ariaInvalid, "aria-required": ariaRequired, className, ref, ...rest }: CalendarProps): React_2.JSX.Element;
830
+ displayName: string;
831
+ };
832
+
833
+ /**
834
+ * Calendar: `root` on the `role="group"` element; `header` on the row of the navigation buttons
835
+ * and the heading; `previousButton` and `nextButton` on the navigation buttons (by a month, a
836
+ * year or a decade); `heading` on the month, year or decade text (a `<div>`, which labels the
837
+ * grid); `headingButton` on the heading's button to the month and year views; `grid` on the
838
+ * `role="grid"` element of every view; `weekday` on each weekday header cell; `weekNumberHeader`
839
+ * on the header cell of the week-number column and `weekNumber` on each week's row header
840
+ * (`showWeekNumbers`); `day`, `month` and `year` on each day, month and year button; `markedDot`
841
+ * on the dot inside a marked day's button; `footer` on the row of the footer buttons, with
842
+ * `todayButton` on "Go to today" (`showGoToToday`).
843
+ */
844
+ export declare const calendarClassNames: {
845
+ readonly root: "wave-calendar";
846
+ readonly header: "wave-calendar__header";
847
+ readonly previousButton: "wave-calendar__previous-button";
848
+ readonly heading: "wave-calendar__heading";
849
+ readonly headingButton: "wave-calendar__heading-button";
850
+ readonly nextButton: "wave-calendar__next-button";
851
+ readonly grid: "wave-calendar__grid";
852
+ readonly weekday: "wave-calendar__weekday";
853
+ readonly weekNumberHeader: "wave-calendar__week-number-header";
854
+ readonly weekNumber: "wave-calendar__week-number";
855
+ readonly day: "wave-calendar__day";
856
+ readonly markedDot: "wave-calendar__marked-dot";
857
+ readonly month: "wave-calendar__month";
858
+ readonly year: "wave-calendar__year";
859
+ readonly footer: "wave-calendar__footer";
860
+ readonly todayButton: "wave-calendar__today-button";
861
+ };
862
+
863
+ /**
864
+ * The built-in texts of the calendar, for localization: the names of the navigation buttons in
865
+ * the day, month and year views, the hints of the heading button, the "Go to today" button, the
866
+ * week-number column and the marked days, and (Calendar only) the required hint. Each member is
867
+ * optional and falls back to its English default. Month and weekday names and the day labels follow
868
+ * `locale`. DatePicker's labels extend this type.
869
+ */
870
+ export declare interface CalendarLabels {
871
+ /** Name of the previous-month button.
872
+ * @default 'Previous month'
873
+ */
874
+ previousMonth?: string;
875
+ /** Name of the next-month button.
876
+ * @default 'Next month'
877
+ */
878
+ nextMonth?: string;
879
+ /** Name of the previous-year button of the month view.
880
+ * @default 'Previous year'
881
+ */
882
+ previousYear?: string;
883
+ /** Name of the next-year button of the month view.
884
+ * @default 'Next year'
885
+ */
886
+ nextYear?: string;
887
+ /** Name of the previous-decade button of the year view.
888
+ * @default 'Previous decade'
889
+ */
890
+ previousDecade?: string;
891
+ /** Name of the next-decade button of the year view.
892
+ * @default 'Next decade'
893
+ */
894
+ nextDecade?: string;
895
+ /** Description of the heading button that shows the month view.
896
+ * @default 'Choose a month'
897
+ */
898
+ chooseMonth?: string;
899
+ /** Description of the heading button that shows the year view.
900
+ * @default 'Choose a year'
901
+ */
902
+ chooseYear?: string;
903
+ /** Name of the "Go to today" button.
904
+ * @default 'Go to today'
905
+ */
906
+ goToToday?: string;
907
+ /** Hidden text of the week-number column header.
908
+ * @default 'Week'
909
+ */
910
+ week?: string;
911
+ /** Name of a week-number row header.
912
+ * @default (week) => `Week ${week}`
913
+ */
914
+ weekNumber?: (week: number) => string;
915
+ /** Name of a marked day, built from its default name.
916
+ * @default (dayLabel) => `${dayLabel}, marked`
917
+ */
918
+ markedDay?: (dayLabel: string) => string;
919
+ /**
920
+ * Said in the calendar's description while it is required (`required`, a required Field, or a
921
+ * consumer `aria-required` alone), since its role cannot carry `aria-required`.
922
+ * @default 'Required'
923
+ */
924
+ required?: string;
925
+ }
926
+
927
+ /** Properties for the Calendar component. */
928
+ export declare interface CalendarProps extends Omit<React_2.HTMLAttributes<HTMLDivElement>, 'onChange' | 'defaultValue'> {
929
+ /** Controlled selected day (`null` for none). */
930
+ value?: Date | null;
931
+ /**
932
+ * Initial selected day for uncontrolled usage.
933
+ * @default null
934
+ */
935
+ defaultValue?: Date | null;
936
+ /**
937
+ * Called with the new day (local midnight) when the selected day changes: a pick of another day
938
+ * or a form reset (Fluent's `onSelectDate` fires on every pick). Picking the selected day again
939
+ * does nothing. WaveUI always passes `details`.
940
+ */
941
+ onValueChange?: (date: Date | null, details?: CalendarValueChangeDetails) => void;
942
+ /** Earliest available day (the whole day is included). */
943
+ minDate?: Date;
944
+ /** Latest available day (the whole day is included). */
945
+ maxDate?: Date;
946
+ /** Returns `true` for days that cannot be picked (called with local-midnight dates). */
947
+ disabledDates?: (date: Date) => boolean;
948
+ /**
949
+ * First day of the week (0 = Sunday, 1 = Monday, etc.).
950
+ * @default 0
951
+ */
952
+ firstDayOfWeek?: DayOfWeek;
953
+ /**
954
+ * BCP 47 locale of the month text, the weekday names and the day labels. Pass it when rendering
955
+ * on the server, so the server and the browser render the same text. The grid is Gregorian, as
956
+ * in DatePicker. A tag `Intl` rejects (the POSIX `de_DE`, a typo) falls back to the runtime
957
+ * default locale (development warning).
958
+ * @default the runtime default locale
959
+ */
960
+ locale?: string;
961
+ /**
962
+ * The day marked as today (`aria-current="date"`), and the tab stop when no day is selected in
963
+ * the shown month. Without it, the server HTML and the hydration render mark no day and the
964
+ * browser applies the current date once hydrated: pass it when rendering on the server, so the
965
+ * mark is in the HTML.
966
+ * @default the current date (applied after hydration when not passed)
967
+ */
968
+ today?: Date;
969
+ /**
970
+ * The month shown first when there is no value (Fluent's `initialPickerDate`), clamped into
971
+ * `minDate`/`maxDate` like the value's month and today's.
972
+ * @default today's month
973
+ */
974
+ initialVisibleDate?: Date;
975
+ /**
976
+ * Turns the month text into a button that shows the month view (the 12 months of the year),
977
+ * whose heading, the year, is a button to the year view (a decade with the year before and
978
+ * after it). A picked year shows its months and a picked month its days; Escape goes back a
979
+ * level to the period shown before. Fluent's `isMonthPickerVisible`, here as a drill-down in one
980
+ * pane.
981
+ * @default true
982
+ */
983
+ showMonthPicker?: boolean;
984
+ /**
985
+ * Adds a leading column of week numbers: a row header per week (`Week 23`, from
986
+ * `labels.weekNumber`) under a header cell named `labels.week`. The numbers follow
987
+ * `firstDayOfWeek` and `firstWeekOfYear`; the column is not focusable and the keys skip it.
988
+ * @default false
989
+ */
990
+ showWeekNumbers?: boolean;
991
+ /**
992
+ * Which week is week 1 of a year. ISO 8601 is `'first-four-day-week'` with `firstDayOfWeek={1}`.
993
+ * @default 'first-day'
994
+ */
995
+ firstWeekOfYear?: FirstWeekOfYear;
996
+ /**
997
+ * Adds a footer button that shows today's month in the day view and focuses today without
998
+ * selecting it. It is disabled while today is outside `minDate`/`maxDate`.
999
+ * @default false
1000
+ */
1001
+ showGoToToday?: boolean;
1002
+ /**
1003
+ * Days that draw a dot under the number (in the text colour of the day) and say "marked" in
1004
+ * their name (`labels.markedDay`); also `data-marked` on the day's button (Fluent's
1005
+ * `getMarkedDays`). Called with local-midnight dates.
1006
+ */
1007
+ markedDates?: (date: Date) => boolean;
1008
+ /**
1009
+ * Replaces the content inside a day's button, which keeps its role, state and keys;
1010
+ * `defaultContent` is the day number. The content must be non-interactive (no buttons or links),
1011
+ * and the button's name does not follow it: set the name with `dayLabel`. The marked-day dot is
1012
+ * drawn next to the content.
1013
+ */
1014
+ renderDay?: (date: Date, defaultContent: React_2.ReactNode) => React_2.ReactNode;
1015
+ /**
1016
+ * The accessible name of a day, from its default name (the date in words, `Monday, June 2,
1017
+ * 2025`, with `labels.markedDay` applied for a marked day). Use it to say what `renderDay` shows.
1018
+ */
1019
+ dayLabel?: (date: Date, defaultLabel: string) => string;
1020
+ /**
1021
+ * What a pick selects: the day, or its week, work week (`workWeekDays`) or month. The value is
1022
+ * the picked day, `details.range` the selected days, and every day of the range is
1023
+ * `aria-selected`, `aria-pressed` and `data-selected`. Days that are not available are left
1024
+ * out. Fluent's `dateRangeType`.
1025
+ * @default 'day'
1026
+ */
1027
+ selectionRange?: CalendarSelectionRange;
1028
+ /**
1029
+ * The days of `selectionRange="work-week"` (0 = Sunday), within the week that starts on
1030
+ * `firstDayOfWeek`.
1031
+ * @default [1, 2, 3, 4, 5]
1032
+ */
1033
+ workWeekDays?: readonly DayOfWeek[];
1034
+ /**
1035
+ * Names of the navigation buttons, the heading button's hints, the "Go to today" button, the
1036
+ * week-number column, the marked days and the required hint, for localization.
1037
+ */
1038
+ labels?: CalendarLabels;
1039
+ /** Form field name: the day is submitted as ISO `yyyy-mm-dd` (hidden input). */
1040
+ name?: string;
1041
+ /** Id of the `<form>` the value belongs to, when the calendar is outside it. */
1042
+ form?: string;
1043
+ /**
1044
+ * Blocks form submission while no day is selected; the form's report focuses the calendar's
1045
+ * tab stop. Said in the description (`labels.required`), as the group cannot carry
1046
+ * `aria-required`. A consumer `aria-required` alone also shows that hint (assistive technology
1047
+ * only: it does not block submission).
1048
+ */
1049
+ required?: boolean;
1050
+ /** Ref to the root element. */
1051
+ ref?: React_2.Ref<HTMLDivElement>;
1052
+ }
1053
+
1054
+ /** What a pick selects (the Calendar's `selectionRange`). */
1055
+ export declare type CalendarSelectionRange = 'day' | 'week' | 'work-week' | 'month';
1056
+
1057
+ /** Second argument of `Calendar`'s `onValueChange`. */
1058
+ export declare interface CalendarValueChangeDetails {
1059
+ /**
1060
+ * The selected days in order (local midnight): the picked day, or with `selectionRange` its
1061
+ * week, work week or month (the days that are not available left out); `[]` for `null`.
1062
+ */
1063
+ range: Date[];
1064
+ }
1065
+
768
1066
  /**
769
1067
  * A surface that groups related content, with `Card.Header`, `Card.Body` and `Card.Footer`.
770
1068
  *
@@ -1279,6 +1577,21 @@ export declare type CheckedValuesChangeHandler = (checkedValues: Record<string,
1279
1577
  */
1280
1578
  export declare function cn(...inputs: ClassValue[]): string;
1281
1579
 
1580
+ /**
1581
+ * Reads option labels from `children` during render (read-only), for display text before the
1582
+ * options have registered: on the server, in the first client render and during hydration
1583
+ * (layout effects have not run yet). Walks elements of components marked with
1584
+ * {@link markListboxElement}: `'option'` elements give `value → label` (`label` prop →
1585
+ * `textValue` → the text of their string/number children and host elements → `value` when they
1586
+ * have no children); `'group'` elements and Fragments are walked into. Other components are
1587
+ * opaque (their options resolve after registration). The first option of a value wins. A lazy
1588
+ * element type (an option or group written in a React Server Component) is unwrapped first.
1589
+ *
1590
+ * Display text = `listbox.getItem(value)?.label ?? collectOptionLabels(children).get(value)`
1591
+ * (`?? value` for freeform input only).
1592
+ */
1593
+ export declare function collectOptionLabels(children: React_2.ReactNode): Map<string, string>;
1594
+
1282
1595
  /**
1283
1596
  * A 2-D color field: saturation from left to right (mirrored in right-to-left layouts) and
1284
1597
  * brightness from bottom to top, at the value's hue. ArrowLeft and ArrowRight move saturation by
@@ -1772,6 +2085,71 @@ export declare interface ColorSliderProps extends Omit<React_2.HTMLAttributes<HT
1772
2085
  ref?: React_2.Ref<HTMLDivElement>;
1773
2086
  }
1774
2087
 
2088
+ /**
2089
+ * One color swatch of a `SwatchPicker`, read from `items` or rendered directly as a child.
2090
+ * Outside a `SwatchPicker` it throws in development and renders inertly in production.
2091
+ *
2092
+ * **Naming**: give it `aria-label`, or wrap it in a `Tooltip` with `relationship="label"` (its
2093
+ * `aria-labelledby` reaches this element, since every rest prop lands on the swatch's own
2094
+ * button). Without either it is named by its `color` value and a development warning is logged.
2095
+ *
2096
+ * **Disabled**: `disabled` is native (out of the arrow keys and the tab order, never selected);
2097
+ * the swatch is dimmed and crossed by a diagonal slash, so the state does not rely on its color.
2098
+ *
2099
+ * @example
2100
+ * <SwatchPicker aria-label="Accent color">
2101
+ * <ColorSwatch value="red" color="#d13438" aria-label="Red" />
2102
+ * </SwatchPicker>
2103
+ */
2104
+ export declare const ColorSwatch: {
2105
+ ({ color, borderColor, ...rest }: ColorSwatchProps): React_2.JSX.Element;
2106
+ displayName: string;
2107
+ };
2108
+
2109
+ /**
2110
+ * ColorSwatch (also the swatches of SwatchPicker's `items`; carries SwatchPicker's `swatch`):
2111
+ * `root` on the swatch `<button>`, where `className` lands in every layout; `icon` on the span of
2112
+ * your `icon`.
2113
+ */
2114
+ export declare const colorSwatchClassNames: {
2115
+ readonly root: "wave-color-swatch";
2116
+ readonly icon: "wave-color-swatch__icon";
2117
+ };
2118
+
2119
+ /** Properties for the ColorSwatch component. */
2120
+ export declare interface ColorSwatchProps extends Omit<React_2.ButtonHTMLAttributes<HTMLButtonElement>, 'value' | 'color'> {
2121
+ /** Unique identifier for the swatch (the value the picker selects and a form submits). */
2122
+ value: string;
2123
+ /** CSS color value (e.g., hex, rgb) used as the swatch background (a runtime user color). */
2124
+ color: string;
2125
+ /**
2126
+ * Decorative glyph (`aria-hidden`) shown while the swatch is not selected; the check replaces it
2127
+ * while selected. A `<button>` or `Button` passed here is not nested: its children become the
2128
+ * glyph and a one-time development warning is logged.
2129
+ */
2130
+ icon?: Slot<'span'>;
2131
+ /**
2132
+ * CSS color of the swatch's border, for a color close to the page background (set by hand, as
2133
+ * in Fluent). In forced colors the system border color replaces it.
2134
+ */
2135
+ borderColor?: string;
2136
+ /**
2137
+ * Size of the swatch (20, 24, 32 or 40px).
2138
+ * @default the picker's
2139
+ */
2140
+ size?: SwatchPickerSize;
2141
+ /**
2142
+ * Shape of the swatch.
2143
+ * @default the picker's
2144
+ */
2145
+ shape?: Shape;
2146
+ /**
2147
+ * Ref to the swatch button: `role="radio"` in the row layout, inside its cell in the grid
2148
+ * layout, a toggle button in tab mode.
2149
+ */
2150
+ ref?: React_2.Ref<HTMLButtonElement>;
2151
+ }
2152
+
1775
2153
  /**
1776
2154
  * An editable combobox: a text input with a filterable listbox of `Option`s (APG combobox with
1777
2155
  * list autocomplete). Typing filters the options; ArrowDown/ArrowUp move the highlight
@@ -1779,9 +2157,27 @@ export declare interface ColorSliderProps extends Omit<React_2.HTMLAttributes<HT
1779
2157
  * filter: its first match becomes active while typing, and the input shows the selected option's
1780
2158
  * label again when the listbox closes. With `freeform` the text itself is the value. Text that
1781
2159
  * matches no option shows "No matches" (`labels.noMatches`), announced through a status region.
1782
- * The expand button at the end of the input (a chevron, see `expandIcon`) opens and closes the
1783
- * list without taking focus from the input and is not a tab stop; `clearable` adds a clear button,
1784
- * a tab stop after the input. Both sit with the input in a wrapper `<div>` inside the root.
2160
+ * `filter` replaces the match (it may keep options that do not contain the text, for a server-side
2161
+ * search or a "Create …" entry), and `query`/`defaultQuery`/`onQueryChange` control the typed
2162
+ * text (not with `freeform`), which resets to `''` on a commit, a close, a blur, Escape, the clear
2163
+ * button and a form reset. The expand button at the end of the input (a chevron, see
2164
+ * `expandIcon`) opens and closes the list without taking focus from the input and is not a tab
2165
+ * stop; `clearable` adds a clear button, a tab stop after the input. Both sit with the input in a
2166
+ * wrapper `<div>` inside the root.
2167
+ *
2168
+ * `multiselect` turns the value into an array (Fluent's `selectedOptions`): options draw a
2169
+ * checkbox; Enter and a click toggle an option and keep the list open (Tab, Escape and
2170
+ * Alt+ArrowUp close without committing), and every toggle the user makes is announced
2171
+ * (`labels.added`/`labels.removed`, never for a controlled change, a clear or a form reset).
2172
+ * While no text is typed the input shows the selected labels in selection order
2173
+ * (`labels.selection`, values without an option left out) instead of the placeholder. Focusing
2174
+ * the input selects them, and so does their return to the focused input (a toggle, a close, a
2175
+ * form reset), so typing, pasting or composing text replaces them with a query that filters the
2176
+ * options; text inserted into them queries only what was inserted, an undo or a redo back to them
2177
+ * shows them again, and a toggle, a close or a blur clears the query. Backspace and Delete only
2178
+ * edit the text: the options, the clear button (which clears every value) and a form reset change
2179
+ * the value. `freeform` is not available with `multiselect`, and a non-literal
2180
+ * `multiselect={flag}` is a type error: render two elements, one for each mode.
1785
2181
  *
1786
2182
  * The `<input>` receives `id`, `aria-label`, `aria-labelledby`, `aria-describedby`,
1787
2183
  * `aria-invalid`, `aria-required`, `aria-errormessage`, `aria-details`, `tabIndex`, `autoFocus`,
@@ -1790,8 +2186,10 @@ export declare interface ColorSliderProps extends Omit<React_2.HTMLAttributes<HT
1790
2186
  * `ref`, `className`, `style`, other `aria-*` attributes and the remaining props stay on the root
1791
2187
  * `<div>`. Inside a `Field` the input is labelled and described by it. It shows the error look
1792
2188
  * whenever it ends up `aria-invalid` (its own `aria-invalid` or a `Field` error). With
1793
- * `name`/`required` the value takes part in form submission, validation and reset. The open
1794
- * listbox renders in a portal; while closed it stays in the DOM, hidden.
2189
+ * `name`/`required` the value takes part in form submission (one hidden input per value with
2190
+ * `multiselect`), validation and reset (a `multiselect` reset is compared by content, so restoring
2191
+ * the same values reports nothing). The open listbox renders in a portal; while closed it stays
2192
+ * in the DOM, hidden.
1795
2193
  *
1796
2194
  * **Size and appearance**: `size` resolves from its own prop, then the surrounding `Field`'s
1797
2195
  * `size`, then `WaveProvider inputDefaults.size`, else `'medium'`; `appearance` from its own prop,
@@ -1801,13 +2199,7 @@ export declare interface ColorSliderProps extends Omit<React_2.HTMLAttributes<HT
1801
2199
  * Sub-components: `Combobox.Option`, `Combobox.OptionGroup`. React Server Components import the
1802
2200
  * flat names `ComboboxOption` / `ComboboxOptionGroup` (dotted access needs a client file).
1803
2201
  */
1804
- export declare const Combobox: {
1805
- (props: ComboboxProps): React_2.JSX.Element;
1806
- displayName: string;
1807
- } & {
1808
- Option: React_2.NamedExoticComponent<OptionProps>;
1809
- OptionGroup: React_2.FC<OptionGroupProps>;
1810
- };
2202
+ export declare const Combobox: ComboboxComponent;
1811
2203
 
1812
2204
  /**
1813
2205
  * Combobox: `root` on the outer element; `input` on the `role="combobox"` input; `clearButton` on
@@ -1826,6 +2218,17 @@ export declare const comboboxClassNames: {
1826
2218
  readonly emptyMessage: "wave-combobox__empty-message";
1827
2219
  };
1828
2220
 
2221
+ /** The Combobox component's type: a multi-select signature, then the single-select one. */
2222
+ export declare interface ComboboxComponent {
2223
+ (props: ComboboxProps<true> & {
2224
+ multiselect: true;
2225
+ }): React_2.ReactNode;
2226
+ (props: ComboboxProps): React_2.ReactNode;
2227
+ displayName?: string;
2228
+ Option: typeof Option_2;
2229
+ OptionGroup: typeof OptionGroup;
2230
+ }
2231
+
1829
2232
  /**
1830
2233
  * The Combobox's built-in texts, for localization. Each member is optional and falls back to its
1831
2234
  * English default.
@@ -1843,6 +2246,24 @@ export declare interface ComboboxLabels {
1843
2246
  * @default 'Show options'
1844
2247
  */
1845
2248
  expand?: string;
2249
+ /**
2250
+ * The text of the selected labels the input shows with `multiselect` while no text is typed, in
2251
+ * selection order; values without an option are left out.
2252
+ * @default (labels) => labels.join(', ')
2253
+ */
2254
+ selection?: (labels: string[]) => string;
2255
+ /**
2256
+ * Announced when a `multiselect` toggle selects an option; `count` is the number of values
2257
+ * selected after the change.
2258
+ * @default (label, count) => `${label} added, ${count} selected`
2259
+ */
2260
+ added?: (label: string, count: number) => string;
2261
+ /**
2262
+ * Announced when a `multiselect` toggle deselects an option; `count` is the number of values
2263
+ * selected after the change.
2264
+ * @default (label, count) => `${label} removed, ${count} selected`
2265
+ */
2266
+ removed?: (label: string, count: number) => string;
1846
2267
  }
1847
2268
 
1848
2269
  /** Flat name of `Combobox.Option` for React Server Components. */
@@ -1852,22 +2273,38 @@ export declare const ComboboxOption: React_2.NamedExoticComponent<OptionProps>;
1852
2273
  export declare const ComboboxOptionGroup: React_2.FC<OptionGroupProps>;
1853
2274
 
1854
2275
  /** Properties for the Combobox component. */
1855
- export declare interface ComboboxProps extends Omit<React_2.HTMLAttributes<HTMLDivElement>, 'onChange' | 'defaultValue' | RoutedHandlers> {
1856
- /** Controlled selected value (`''` for none). */
1857
- value?: string;
2276
+ export declare interface ComboboxProps<M extends boolean = false> extends Omit<React_2.HTMLAttributes<HTMLDivElement>, 'onChange' | 'defaultValue' | RoutedHandlers> {
2277
+ /**
2278
+ * Several options can be selected (Fluent's `multiselect`): the value is an array, options show
2279
+ * a checkbox, Enter and a click toggle an option and keep the list open, and each toggle is
2280
+ * announced. While no text is typed the input shows the selected labels, selected whenever the
2281
+ * input gains focus or they return to it, so typing replaces them with text that filters the
2282
+ * options. Not available with `freeform`. A non-literal `multiselect={flag}` is a type error:
2283
+ * render two elements, one for each mode.
2284
+ * @default false
2285
+ */
2286
+ multiselect?: M;
2287
+ /**
2288
+ * Controlled selected value (`''` for none), or with `multiselect` the selected values (Fluent's
2289
+ * `selectedOptions`).
2290
+ */
2291
+ value?: M extends true ? readonly string[] : string;
1858
2292
  /**
1859
2293
  * Initial selected value for uncontrolled usage.
1860
- * @default ''
2294
+ * @default '' (`[]` with `multiselect`)
1861
2295
  */
1862
- defaultValue?: string;
2296
+ defaultValue?: M extends true ? readonly string[] : string;
1863
2297
  /**
1864
- * Called with the new value when it changes: an option is selected, or (with `freeform`) the
1865
- * text changes. Not called when the current option is selected again.
2298
+ * Called with the new value when it changes: an option is selected (toggled with `multiselect`,
2299
+ * which passes a new array), or (with `freeform`) the text changes. Without `multiselect` it is
2300
+ * not called when the current option is selected again; with it, activating a selected option
2301
+ * deselects it, which is a change. Fluent's `onOptionSelect`, under WaveUI's value/onValueChange
2302
+ * naming.
1866
2303
  */
1867
- onValueChange?: (value: string) => void;
2304
+ onValueChange?: M extends true ? (value: string[]) => void : (value: string) => void;
1868
2305
  /**
1869
- * Called on every option activation, also when the current option is selected again (and, with
1870
- * `freeform`, on every text change).
2306
+ * Called on every option activation, also when the current option is selected again (every
2307
+ * toggle with `multiselect`; with `freeform`, every text change).
1871
2308
  * @deprecated Use `onValueChange`.
1872
2309
  */
1873
2310
  onOptionSelect?: (value: string) => void;
@@ -1885,7 +2322,10 @@ export declare interface ComboboxProps extends Omit<React_2.HTMLAttributes<HTMLD
1885
2322
  defaultOpen?: boolean;
1886
2323
  /** Called when the listbox opens or closes. */
1887
2324
  onOpenChange?: (open: boolean) => void;
1888
- /** Placeholder text shown when no value is selected. */
2325
+ /**
2326
+ * Placeholder text shown when no value is selected; with `multiselect`, whenever the input shows
2327
+ * no selected labels (no value is selected, or no selected value has an option).
2328
+ */
1889
2329
  placeholder?: string;
1890
2330
  /**
1891
2331
  * Whether the combobox is disabled and non-interactive.
@@ -1909,11 +2349,64 @@ export declare interface ComboboxProps extends Omit<React_2.HTMLAttributes<HTMLD
1909
2349
  * first match becomes active, so Enter selects it) and the input shows the selected option's
1910
2350
  * label again when the listbox closes or loses focus. With it, the input shows typed text as
1911
2351
  * typed (also when it equals an option's value), a selected option's label, and a controlled
1912
- * `value` as soon as the parent sets it (a parent that normalizes or rejects the text).
2352
+ * `value` as soon as the parent sets it (a parent that normalizes or rejects the text). Not
2353
+ * available with `multiselect` (a type error there): free text cannot be one of several values.
2354
+ * @default false
2355
+ */
2356
+ freeform?: M extends true ? never : boolean;
2357
+ /**
2358
+ * Whether an option matches the typed text (the query, or with `freeform` the typed value).
2359
+ * Called with every option that is not hidden (its `value`, `label` and `textValue`) and the
2360
+ * text whenever the text is not empty; an option it returns `false` for is filtered out. It may
2361
+ * keep options that do not contain the text: `filter={() => true}` with `query` and
2362
+ * `onQueryChange` leaves the matching to you (a server-side search that replaces the options),
2363
+ * and a filter that always keeps an option of your own gives a "Create …" entry. With a
2364
+ * server-side search, keep the selected option among the children, `hidden` while the results
2365
+ * leave it out: a value without an option shows no label (the "Async search" story does this).
2366
+ * @default a case-insensitive substring match on the option's `textValue`, else its `label`
2367
+ */
2368
+ filter?: (option: ListboxItem, query: string) => boolean;
2369
+ /**
2370
+ * Controlled query: the text typed since the last commit, which filters the options. A
2371
+ * non-empty query shows in the input (hidden while `disabled` or `readOnly`); `''` shows the
2372
+ * selected option's label (the selected labels with `multiselect`), except while the user edits
2373
+ * the text, so erased text stays empty. Not used with `freeform`, where the typed text is the
2374
+ * value.
2375
+ */
2376
+ query?: string;
2377
+ /**
2378
+ * Initial query for uncontrolled usage. A Combobox that starts disabled or read-only starts
2379
+ * without it (as it starts closed). Not used with `freeform`.
2380
+ * @default ''
2381
+ */
2382
+ defaultQuery?: string;
2383
+ /**
2384
+ * Called with the new query when it changes: as the user types, and with `''` when it resets (a
2385
+ * commit, a close, a blur, Escape, the clear button, a form reset, or `disabled` or `readOnly`
2386
+ * turned on while text is typed). A Combobox that mounts disabled or read-only reports nothing:
2387
+ * it keeps a controlled query, which shows once it unlocks. Never called with `freeform`.
2388
+ */
2389
+ onQueryChange?: (query: string) => void;
2390
+ /**
2391
+ * Called after the active (highlighted) option changes — opening, arrow keys, the pointer, a
2392
+ * filter change that moves it — and with `null` when the list closes. It reports what
2393
+ * `aria-activedescendant` points at, from an effect once the change commits. Fluent's
2394
+ * `onActiveOptionChange` reports neither the pointer (its options have no hover highlight) nor
2395
+ * the close.
2396
+ */
2397
+ onActiveOptionChange?: (value: string | null) => void;
2398
+ /**
2399
+ * Keeps disabled options in the arrow-key order (the first match highlighted while typing may
2400
+ * then be a disabled one too); they still cannot be selected (Enter and a click do nothing and
2401
+ * the list stays open). Unlike Fluent, which always keeps disabled options reachable, WaveUI
2402
+ * skips them by default.
1913
2403
  * @default false
1914
2404
  */
1915
- freeform?: boolean;
1916
- /** Name of the value in form submissions (renders a hidden input). */
2405
+ disabledOptionsFocusable?: boolean;
2406
+ /**
2407
+ * Name of the value in form submissions (renders a hidden input; one per value with
2408
+ * `multiselect`).
2409
+ */
1917
2410
  name?: string;
1918
2411
  /** Id of the form the value belongs to, when the Combobox is outside it. */
1919
2412
  form?: string;
@@ -1928,7 +2421,11 @@ export declare interface ComboboxProps extends Omit<React_2.HTMLAttributes<HTMLD
1928
2421
  * @default 'off'
1929
2422
  */
1930
2423
  autoComplete?: string;
1931
- /** The maximum length of the typed text (`maxlength` of the `<input role="combobox">`). */
2424
+ /**
2425
+ * The maximum length of the typed text (`maxlength` of the `<input role="combobox">`). With
2426
+ * `multiselect` the input has no limit while it shows the selected labels, so the limit applies
2427
+ * to the typed query only.
2428
+ */
1932
2429
  maxLength?: number;
1933
2430
  /**
1934
2431
  * The value cannot be changed: the input is read-only and the listbox neither opens (click,
@@ -1939,8 +2436,8 @@ export declare interface ComboboxProps extends Omit<React_2.HTMLAttributes<HTMLD
1939
2436
  /**
1940
2437
  * Shows a clear button while a value is selected (not while `readOnly`; while `disabled` it is
1941
2438
  * shown disabled, as in DatePicker and TimePicker). It clears the value
1942
- * (`onValueChange('')`), drops typed text, closes the list and moves focus to the input. It is
1943
- * a tab stop after the input.
2439
+ * (`onValueChange('')`; every value with `multiselect`, `onValueChange([])`), drops typed text,
2440
+ * closes the list and moves focus to the input. It is a tab stop after the input.
1944
2441
  * @default false
1945
2442
  */
1946
2443
  clearable?: boolean;
@@ -1954,11 +2451,16 @@ export declare interface ComboboxProps extends Omit<React_2.HTMLAttributes<HTMLD
1954
2451
  */
1955
2452
  expandIcon?: Slot<'span'>;
1956
2453
  /**
1957
- * The built-in texts (the "No matches" status and the names of the clear and expand buttons),
1958
- * for localization. Unset members keep their English defaults.
2454
+ * The built-in texts (the "No matches" status, the names of the clear and expand buttons and,
2455
+ * with `multiselect`, the selected-labels text and the toggle announcements), for localization.
2456
+ * Unset members keep their English defaults.
1959
2457
  */
1960
2458
  labels?: ComboboxLabels;
1961
- /** Called when the `<input role="combobox">` receives focus (the root keeps other handlers). */
2459
+ /**
2460
+ * Called when the `<input role="combobox">` receives focus (the root keeps other handlers).
2461
+ * With `multiselect`, a focus while the input shows the selected labels then selects them;
2462
+ * `event.preventDefault()` skips that.
2463
+ */
1962
2464
  onFocus?: React_2.FocusEventHandler<HTMLInputElement>;
1963
2465
  /** Called when the `<input role="combobox">` loses focus. */
1964
2466
  onBlur?: React_2.FocusEventHandler<HTMLInputElement>;
@@ -2547,9 +3049,14 @@ export declare interface DataGridUncontrolledSortProps extends NoDeprecatedSortP
2547
3049
  * modal dialog labelled by the month heading. Focus moves to the selected day (else today, else
2548
3050
  * the first available day of the month) and Tab stays inside. Arrow keys move by day/week
2549
3051
  * (mirrored in RTL), PageUp/PageDown by month, Shift+PageUp/PageDown by year (the day is clamped
2550
- * to the month), Home/End to the start/end of the week, Enter/Space select. Escape closes and
2551
- * returns focus to where the calendar was opened from (the toggle, or the input after
2552
- * Alt+ArrowDown); a press outside closes it too. Unavailable days stay focusable
3052
+ * to the month), Home/End to the start/end of the week, Enter/Space select. The month text is a
3053
+ * button (the heading button, `showMonthPicker`) that shows the month view, whose heading, the
3054
+ * year, leads to the year view; Escape steps back from the year view to the month view and from
3055
+ * there to the days, and closes only from the day view, returning focus to where the calendar
3056
+ * was opened from (the toggle, or the input after Alt+ArrowDown); a press outside closes it too.
3057
+ * `showCloseButton` adds a Close button that closes as Escape does from the day view, and
3058
+ * `showGoToToday` a button that shows today's month. `showWeekNumbers`, `markedDates`,
3059
+ * `renderDay` and `dayLabel` shape the day grid as in `Calendar`. Unavailable days stay focusable
2553
3060
  * (`aria-disabled`); a day focused by pointer becomes the starting point of the arrow keys. The
2554
3061
  * selected day is `aria-selected` on its gridcell and `aria-pressed` on its focusable button, so
2555
3062
  * the state is announced when focus lands on it; today is `aria-current="date"`.
@@ -2586,9 +3093,15 @@ export declare const DatePicker: {
2586
3093
  * DatePicker: `root` on the outer element; `input` on the text input; `clearButton` on the clear
2587
3094
  * button; `openCalendarButton` on the calendar button; `errorMessage` on the `role="alert"`
2588
3095
  * message; `surface` on the portaled `role="dialog"` calendar; `header` on its month row;
2589
- * `previousMonthButton` and `nextMonthButton` on the month buttons; `heading` on the month
2590
- * `<h2>`; `grid` on the calendar's `role="grid"` element; `weekday` on each weekday header cell;
2591
- * `day` on each day button.
3096
+ * `previousMonthButton` and `nextMonthButton` on the navigation buttons (by a month, and in the
3097
+ * month and year views by a year and a decade); `heading` on the `<h2>` (the month, year or
3098
+ * decade); `headingButton` on its button to the month and year views; `grid` on the calendar's
3099
+ * `role="grid"` element of every view; `weekday` on each weekday header cell; `weekNumberHeader`
3100
+ * on the header cell of the week-number column and `weekNumber` on each week's row header
3101
+ * (`showWeekNumbers`); `day`, `month` and `year` on each day, month and year button; `markedDot`
3102
+ * on the dot inside a marked day's button; `footer` on the row of the footer buttons
3103
+ * (`showGoToToday`, `showCloseButton`), with `todayButton` on "Go to today" and `closeButton` on
3104
+ * "Close".
2592
3105
  */
2593
3106
  export declare const datePickerClassNames: {
2594
3107
  readonly root: "wave-date-picker";
@@ -2600,21 +3113,33 @@ export declare const datePickerClassNames: {
2600
3113
  readonly header: "wave-date-picker__header";
2601
3114
  readonly previousMonthButton: "wave-date-picker__previous-month-button";
2602
3115
  readonly heading: "wave-date-picker__heading";
3116
+ readonly headingButton: "wave-date-picker__heading-button";
2603
3117
  readonly nextMonthButton: "wave-date-picker__next-month-button";
2604
3118
  readonly grid: "wave-date-picker__grid";
2605
3119
  readonly weekday: "wave-date-picker__weekday";
3120
+ readonly weekNumberHeader: "wave-date-picker__week-number-header";
3121
+ readonly weekNumber: "wave-date-picker__week-number";
2606
3122
  readonly day: "wave-date-picker__day";
3123
+ readonly markedDot: "wave-date-picker__marked-dot";
3124
+ readonly month: "wave-date-picker__month";
3125
+ readonly year: "wave-date-picker__year";
3126
+ readonly footer: "wave-date-picker__footer";
3127
+ readonly todayButton: "wave-date-picker__today-button";
3128
+ readonly closeButton: "wave-date-picker__close-button";
2607
3129
  };
2608
3130
 
2609
3131
  /** Why typed text was not accepted (see {@link DatePickerProps.onInvalidInput}). */
2610
3132
  export declare type DatePickerInvalidReason = 'unparseable' | 'out-of-range' | 'disabled';
2611
3133
 
2612
3134
  /**
2613
- * The DatePicker's built-in button names and error texts, for localization. Each member is
3135
+ * The DatePicker's built-in button names and error texts, for localization: its own (clear, open
3136
+ * calendar, the errors of typed text, Close) and those of the calendar in its dialog
3137
+ * ({@link CalendarLabels}: the navigation buttons, the heading button's hints, "Go to today", the
3138
+ * week-number column and the marked days; its `required` hint does not apply). Each member is
2614
3139
  * optional and falls back to its English default. Month and weekday names and the day labels
2615
3140
  * follow `locale`.
2616
3141
  */
2617
- export declare interface DatePickerLabels {
3142
+ export declare interface DatePickerLabels extends CalendarLabels {
2618
3143
  /** Name of the clear button.
2619
3144
  * @default 'Clear date'
2620
3145
  */
@@ -2623,14 +3148,10 @@ export declare interface DatePickerLabels {
2623
3148
  * @default 'Open calendar'
2624
3149
  */
2625
3150
  openCalendar?: string;
2626
- /** Name of the calendar's previous-month button.
2627
- * @default 'Previous month'
2628
- */
2629
- previousMonth?: string;
2630
- /** Name of the calendar's next-month button.
2631
- * @default 'Next month'
3151
+ /** Name of the footer button that closes the calendar (`showCloseButton`).
3152
+ * @default 'Close'
2632
3153
  */
2633
- nextMonth?: string;
3154
+ close?: string;
2634
3155
  /**
2635
3156
  * Error text for typed text that is not a date. `pattern` is the default format of `locale`
2636
3157
  * written with English field letters (`'MM/DD/YYYY'`, `'DD.MM.YYYY'`), or `undefined` with a
@@ -2733,7 +3254,63 @@ export declare interface DatePickerProps extends Omit<React_2.HTMLAttributes<HTM
2733
3254
  * First day of the week (0 = Sunday, 1 = Monday, etc.).
2734
3255
  * @default 0
2735
3256
  */
2736
- firstDayOfWeek?: 0 | 1 | 2 | 3 | 4 | 5 | 6;
3257
+ firstDayOfWeek?: DayOfWeek;
3258
+ /**
3259
+ * The day marked as today in the calendar (`aria-current="date"`) and the start of its keys when
3260
+ * no day is selected. See `Calendar`'s `today`.
3261
+ * @default the current date
3262
+ */
3263
+ today?: Date;
3264
+ /**
3265
+ * The month the calendar shows first when there is no value, clamped into `minDate`/`maxDate`.
3266
+ * @default today's month
3267
+ */
3268
+ initialVisibleDate?: Date;
3269
+ /**
3270
+ * Turns the calendar's month text into a button that shows the month view, whose heading, the
3271
+ * year, is a button to the year view. Escape steps back from the year view to the month view
3272
+ * and from there to the days; it closes the calendar only from the day view.
3273
+ * @default true
3274
+ */
3275
+ showMonthPicker?: boolean;
3276
+ /**
3277
+ * Adds a leading column of week numbers to the calendar.
3278
+ * @default false
3279
+ */
3280
+ showWeekNumbers?: boolean;
3281
+ /**
3282
+ * Which week is week 1 of a year. ISO 8601 is `'first-four-day-week'` with `firstDayOfWeek={1}`.
3283
+ * @default 'first-day'
3284
+ */
3285
+ firstWeekOfYear?: FirstWeekOfYear;
3286
+ /**
3287
+ * Adds a "Go to today" button to the calendar's footer: it shows today's month and focuses
3288
+ * today without selecting it, and is disabled while today is outside `minDate`/`maxDate`.
3289
+ * @default false
3290
+ */
3291
+ showGoToToday?: boolean;
3292
+ /**
3293
+ * Adds a Close button to the calendar's footer; it closes the calendar as Escape does from the
3294
+ * day view (focus returns to the toggle, or to the input after Alt+ArrowDown).
3295
+ * @default false
3296
+ */
3297
+ showCloseButton?: boolean;
3298
+ /**
3299
+ * Days that draw a dot and say "marked" in their name in the calendar (`labels.markedDay`).
3300
+ * Called with local-midnight dates.
3301
+ */
3302
+ markedDates?: (date: Date) => boolean;
3303
+ /**
3304
+ * Replaces the content inside a calendar day's button; `defaultContent` is the day number. The
3305
+ * content must be non-interactive, and the button's name does not follow it: set the name with
3306
+ * `dayLabel`.
3307
+ */
3308
+ renderDay?: (date: Date, defaultContent: React_2.ReactNode) => React_2.ReactNode;
3309
+ /**
3310
+ * The accessible name of a calendar day, from its default name (the date in words, with
3311
+ * `labels.markedDay` applied for a marked day).
3312
+ */
3313
+ dayLabel?: (date: Date, defaultLabel: string) => string;
2737
3314
  /**
2738
3315
  * Controlled open state of the calendar. The calendar renders only in the browser: an open
2739
3316
  * picker is closed in the server HTML and opens once it has hydrated.
@@ -2786,6 +3363,9 @@ export declare interface DatePickerProps extends Omit<React_2.HTMLAttributes<HTM
2786
3363
  ref?: React_2.Ref<HTMLDivElement>;
2787
3364
  }
2788
3365
 
3366
+ /** A day of the week, as `Date.prototype.getDay()` numbers them: 0 is Sunday, 6 is Saturday. */
3367
+ export declare type DayOfWeek = 0 | 1 | 2 | 3 | 4 | 5 | 6;
3368
+
2789
3369
  /**
2790
3370
  * A modal dialog (Fluent UI v2 style): `Dialog` holds the open state; `Dialog.Trigger` opens it and
2791
3371
  * `Dialog.Content` renders the surface in a portal while open.
@@ -3092,6 +3672,9 @@ export declare interface DialogTriggerRenderProps extends React_2.HTMLAttributes
3092
3672
  ref: React_2.RefCallback<HTMLElement>;
3093
3673
  }
3094
3674
 
3675
+ /** Why a popup layer is dismissed: Escape, a press outside it, or focus moving outside it. */
3676
+ export declare type DismissReason = 'escape' | 'outside-press' | 'focus-outside';
3677
+
3095
3678
  /**
3096
3679
  * A line that separates content, horizontally or vertically, optionally with a label in the middle.
3097
3680
  *
@@ -3402,8 +3985,18 @@ export declare interface DrawerTriggerRenderProps extends React_2.HTMLAttributes
3402
3985
  * A select-only combobox (APG): a button that opens a listbox of `Option`s. Enter, Space,
3403
3986
  * ArrowDown/ArrowUp, Home/End and typing a character open it and move the highlight
3404
3987
  * (`aria-activedescendant`); Enter/Space select, Tab selects the highlighted option and moves on,
3405
- * Escape closes. `clearable` adds a clear button, a tab stop after the combobox button; both sit
3406
- * in a wrapper `<div>` inside the root.
3988
+ * Escape closes. The button's chevron (see `expandIcon`) turns while the list is open, and
3989
+ * `renderValue` replaces its content while a value is selected. `clearable` adds a clear button,
3990
+ * a tab stop after the combobox button; both sit in a wrapper `<div>` inside the root.
3991
+ *
3992
+ * `multiselect` turns the value into an array (Fluent's `selectedOptions`): options draw a
3993
+ * checkbox; Enter and Space toggle the highlighted option, a click toggles the clicked option, and
3994
+ * the list stays open (Tab, Escape and Alt+ArrowUp close without committing); the button shows the
3995
+ * selected labels in selection order (`labels.selection`, replacing the placeholder while any are
3996
+ * selected, values without an option left out) and every toggle the user makes is announced
3997
+ * (`labels.added`/`labels.removed`, never for a controlled change, a clear or a form reset).
3998
+ * `clearable` then clears every value. A non-literal `multiselect={flag}` is a type error: render
3999
+ * two elements, one for each mode.
3407
4000
  *
3408
4001
  * The `<button>` receives `id`, `aria-label`, `aria-labelledby`, `aria-describedby`,
3409
4002
  * `aria-invalid`, `aria-required`, `aria-errormessage`, `aria-details`, `tabIndex`, `autoFocus`
@@ -3411,8 +4004,10 @@ export declare interface DrawerTriggerRenderProps extends React_2.HTMLAttributes
3411
4004
  * attributes and the remaining props stay on the root `<div>`. Inside a `Field` the button is
3412
4005
  * labelled and described by it — otherwise give it an `aria-label`. It shows the error look
3413
4006
  * whenever it ends up `aria-invalid` (its own `aria-invalid` or a `Field` error). With
3414
- * `name`/`required` the value takes part in form submission, validation and reset. The open
3415
- * listbox renders in a portal; while closed it stays in the DOM, hidden.
4007
+ * `name`/`required` the value takes part in form submission (one hidden input per value with
4008
+ * `multiselect`), validation and reset (a `multiselect` reset is compared by content, so restoring
4009
+ * the same values reports nothing). The open listbox renders in a portal; while closed it stays
4010
+ * in the DOM, hidden.
3416
4011
  *
3417
4012
  * **Size and appearance**: `size` resolves from its own prop, then the surrounding `Field`'s
3418
4013
  * `size`, then `WaveProvider inputDefaults.size`, else `'medium'`; `appearance` from its own prop,
@@ -3422,13 +4017,7 @@ export declare interface DrawerTriggerRenderProps extends React_2.HTMLAttributes
3422
4017
  * Sub-components: `Dropdown.Option`, `Dropdown.OptionGroup`. React Server Components import the
3423
4018
  * flat names `DropdownOption` / `DropdownOptionGroup` (dotted access needs a client file).
3424
4019
  */
3425
- export declare const Dropdown: {
3426
- (props: DropdownProps): React_2.JSX.Element;
3427
- displayName: string;
3428
- } & {
3429
- Option: React_2.NamedExoticComponent<OptionProps>;
3430
- OptionGroup: React_2.FC<OptionGroupProps>;
3431
- };
4020
+ export declare const Dropdown: DropdownComponent;
3432
4021
 
3433
4022
  /**
3434
4023
  * Dropdown: `root` on the outer element; `button` on the `role="combobox"` button; `value` on the
@@ -3445,6 +4034,17 @@ export declare const dropdownClassNames: {
3445
4034
  readonly surface: "wave-dropdown__surface";
3446
4035
  };
3447
4036
 
4037
+ /** The Dropdown component's type: a multi-select signature, then the single-select one. */
4038
+ export declare interface DropdownComponent {
4039
+ (props: DropdownProps<true> & {
4040
+ multiselect: true;
4041
+ }): React_2.ReactNode;
4042
+ (props: DropdownProps): React_2.ReactNode;
4043
+ displayName?: string;
4044
+ Option: typeof Option_2;
4045
+ OptionGroup: typeof OptionGroup;
4046
+ }
4047
+
3448
4048
  /**
3449
4049
  * The Dropdown's built-in texts, for localization. Each member is optional and falls back to its
3450
4050
  * English default.
@@ -3454,6 +4054,24 @@ export declare interface DropdownLabels {
3454
4054
  * @default 'Clear selection'
3455
4055
  */
3456
4056
  clear?: string;
4057
+ /**
4058
+ * The text of the selected labels shown in the combobox with `multiselect`, in selection order;
4059
+ * values without an option are left out. Replaces the button's joined value text.
4060
+ * @default (labels) => labels.join(', ')
4061
+ */
4062
+ selection?: (labels: string[]) => string;
4063
+ /**
4064
+ * Announced when a `multiselect` toggle selects an option; `count` is the number of values
4065
+ * selected after the change.
4066
+ * @default (label, count) => `${label} added, ${count} selected`
4067
+ */
4068
+ added?: (label: string, count: number) => string;
4069
+ /**
4070
+ * Announced when a `multiselect` toggle deselects an option; `count` is the number of values
4071
+ * selected after the change.
4072
+ * @default (label, count) => `${label} removed, ${count} selected`
4073
+ */
4074
+ removed?: (label: string, count: number) => string;
3457
4075
  }
3458
4076
 
3459
4077
  /** Flat name of `Dropdown.Option` for React Server Components. */
@@ -3463,18 +4081,33 @@ export declare const DropdownOption: React_2.NamedExoticComponent<OptionProps>;
3463
4081
  export declare const DropdownOptionGroup: React_2.FC<OptionGroupProps>;
3464
4082
 
3465
4083
  /** Properties for the Dropdown component. */
3466
- export declare interface DropdownProps extends Omit<React_2.HTMLAttributes<HTMLDivElement>, 'onChange' | 'defaultValue' | RoutedHandlers> {
3467
- /** Controlled selected value (`''` for none). */
3468
- value?: string;
4084
+ export declare interface DropdownProps<M extends boolean = false> extends Omit<React_2.HTMLAttributes<HTMLDivElement>, 'onChange' | 'defaultValue' | RoutedHandlers> {
4085
+ /**
4086
+ * Several options can be selected (Fluent's `multiselect`): the value is an array, options show
4087
+ * a checkbox, Enter and Space toggle the highlighted option, a click toggles the clicked
4088
+ * option, the list stays open, and each toggle is announced. A non-literal `multiselect={flag}`
4089
+ * is a type error: render two elements, one for each mode.
4090
+ * @default false
4091
+ */
4092
+ multiselect?: M;
4093
+ /**
4094
+ * Controlled selected value (`''` for none), or with `multiselect` the selected values (Fluent's
4095
+ * `selectedOptions`).
4096
+ */
4097
+ value?: M extends true ? readonly string[] : string;
3469
4098
  /**
3470
4099
  * Initial selected value for uncontrolled usage.
3471
- * @default ''
4100
+ * @default '' (`[]` with `multiselect`)
3472
4101
  */
3473
- defaultValue?: string;
3474
- /** Called with the new value when a different option is selected. */
3475
- onValueChange?: (value: string) => void;
4102
+ defaultValue?: M extends true ? readonly string[] : string;
4103
+ /**
4104
+ * Called with the new value when it changes (a new array with `multiselect`; Fluent's
4105
+ * `onOptionSelect`, under WaveUI's value/onValueChange naming).
4106
+ */
4107
+ onValueChange?: M extends true ? (value: string[]) => void : (value: string) => void;
3476
4108
  /**
3477
- * Called on every option activation, also when the current option is selected again.
4109
+ * Called on every option activation, also when the current option is selected again (every
4110
+ * toggle with `multiselect`).
3478
4111
  * @deprecated Use `onValueChange`.
3479
4112
  */
3480
4113
  onOptionSelect?: (value: string) => void;
@@ -3492,12 +4125,36 @@ export declare interface DropdownProps extends Omit<React_2.HTMLAttributes<HTMLD
3492
4125
  defaultOpen?: boolean;
3493
4126
  /** Called when the listbox opens or closes. */
3494
4127
  onOpenChange?: (open: boolean) => void;
4128
+ /**
4129
+ * Called after the active (highlighted) option changes — opening, arrow keys, typeahead, the
4130
+ * pointer — and with `null` when the list closes. It reports what `aria-activedescendant` points
4131
+ * at, from an effect once the change commits. Fluent's `onActiveOptionChange` reports neither the
4132
+ * pointer (its options have no hover highlight) nor the close.
4133
+ */
4134
+ onActiveOptionChange?: (value: string | null) => void;
4135
+ /**
4136
+ * Keeps disabled options in the arrow-key, Home/End, PageUp/PageDown and typeahead order (the
4137
+ * highlighted-by-default option may then be a disabled one too); they still cannot be selected
4138
+ * (Enter, Space and a click do nothing and the list stays open), and in single-select mode,
4139
+ * reaching one with Tab or Alt+ArrowUp closes the list without selecting it. Unlike Fluent,
4140
+ * which always keeps disabled options reachable, WaveUI skips them by default.
4141
+ * @default false
4142
+ */
4143
+ disabledOptionsFocusable?: boolean;
3495
4144
  /**
3496
4145
  * Placeholder text shown when no value is selected. It is not an accessible name: label the
3497
4146
  * Dropdown with a `Field`, `aria-label` or `aria-labelledby`.
3498
4147
  * @default 'Select an option'
3499
4148
  */
3500
4149
  placeholder?: string;
4150
+ /**
4151
+ * Renders the button's content while a value is selected (the placeholder shows otherwise), in
4152
+ * place of the selected label (`labels.selection` with `multiselect`). It receives the raw
4153
+ * value(s), never a label; the content must be non-interactive, and its text is the combobox's
4154
+ * value, so image-only content leaves the value empty.
4155
+ * @default the selected label (`labels.selection` with `multiselect`)
4156
+ */
4157
+ renderValue?: M extends true ? (value: string[]) => React_2.ReactNode : (value: string) => React_2.ReactNode;
3501
4158
  /**
3502
4159
  * Whether the dropdown is disabled and non-interactive. Turning it on while the listbox is open
3503
4160
  * closes it (`onOpenChange(false)`).
@@ -3507,7 +4164,7 @@ export declare interface DropdownProps extends Omit<React_2.HTMLAttributes<HTMLD
3507
4164
  /**
3508
4165
  * Size of the field: `small` (24px tall), `medium` (32px) or `large` (40px). Default: the
3509
4166
  * surrounding Field's `size`, else `WaveProvider inputDefaults.size`, else `'medium'`. The
3510
- * listbox keeps its size.
4167
+ * listbox keeps its size; the multi-select value text and clear button follow it.
3511
4168
  */
3512
4169
  size?: CoreSize;
3513
4170
  /**
@@ -3516,7 +4173,10 @@ export declare interface DropdownProps extends Omit<React_2.HTMLAttributes<HTMLD
3516
4173
  * label). Default: `WaveProvider inputDefaults.appearance`, else `'outline'`.
3517
4174
  */
3518
4175
  appearance?: InputAppearance;
3519
- /** Name of the value in form submissions (renders a hidden input). */
4176
+ /**
4177
+ * Name of the value in form submissions (renders a hidden input; one per value with
4178
+ * `multiselect`).
4179
+ */
3520
4180
  name?: string;
3521
4181
  /** Id of the form the value belongs to, when the Dropdown is outside it. */
3522
4182
  form?: string;
@@ -3524,11 +4184,23 @@ export declare interface DropdownProps extends Omit<React_2.HTMLAttributes<HTMLD
3524
4184
  required?: boolean;
3525
4185
  /**
3526
4186
  * Shows a clear button while a value is selected (shown disabled while `disabled`). It clears
3527
- * the value, closes the list and moves focus to the combobox button. It is a tab stop after it.
4187
+ * the value (every value with `multiselect`), closes the list and moves focus to the combobox
4188
+ * button. It is a tab stop after it.
3528
4189
  * @default false
3529
4190
  */
3530
4191
  clearable?: boolean;
3531
- /** The name of the clear button, for localization. Unset members keep their English defaults. */
4192
+ /**
4193
+ * The glyph at the end of the button (default: a chevron). `null` or `undefined` keep it;
4194
+ * `false`, or a value that renders nothing, hides it (the button's end padding follows,
4195
+ * together with `clearable`). The default chevron's size and the glyph's offset follow
4196
+ * `size`. Decorative content rendered inside the button: a `<button>` or `Button` passed
4197
+ * here is not nested (its children become the glyph, with a development warning).
4198
+ */
4199
+ expandIcon?: Slot<'span'>;
4200
+ /**
4201
+ * The clear button's name and, with `multiselect`, the selected-labels text and the toggle
4202
+ * announcements, for localization. Unset members keep their English defaults.
4203
+ */
3532
4204
  labels?: DropdownLabels;
3533
4205
  /** Called when the `<button role="combobox">` receives focus (the root keeps other handlers). */
3534
4206
  onFocus?: React_2.FocusEventHandler<HTMLButtonElement>;
@@ -3547,6 +4219,60 @@ export declare interface DropdownProps extends Omit<React_2.HTMLAttributes<HTMLD
3547
4219
  ref?: React_2.Ref<HTMLDivElement>;
3548
4220
  }
3549
4221
 
4222
+ /**
4223
+ * An "add" button inside a `SwatchPicker` (for example to open a color dialog): it has no value
4224
+ * and is never selected. In the row layout it is a plain button with its own tab stop, outside
4225
+ * the radio group's arrow order, and arrow keys pressed on it do nothing. In the grid layout it
4226
+ * is a cell like the others, in the arrow order (without `aria-selected`). Outside a
4227
+ * `SwatchPicker` it throws in development and renders inertly in production.
4228
+ *
4229
+ * @example
4230
+ * <SwatchPicker aria-label="Accent color" items={items}>
4231
+ * <EmptySwatch onClick={openColorDialog} />
4232
+ * </SwatchPicker>
4233
+ */
4234
+ export declare const EmptySwatch: {
4235
+ ({ icon, size: sizeProp, shape: shapeProp, className, "aria-label": ariaLabel, "aria-labelledby": ariaLabelledBy, ref, ...rest }: EmptySwatchProps): React_2.JSX.Element;
4236
+ displayName: string;
4237
+ };
4238
+
4239
+ /**
4240
+ * EmptySwatch (carries SwatchPicker's `swatch`): `root` on the `<button>`; `icon` on the span of
4241
+ * its glyph (the plus, or your `icon`).
4242
+ */
4243
+ export declare const emptySwatchClassNames: {
4244
+ readonly root: "wave-empty-swatch";
4245
+ readonly icon: "wave-empty-swatch__icon";
4246
+ };
4247
+
4248
+ /** Properties for the EmptySwatch component. */
4249
+ export declare interface EmptySwatchProps extends React_2.ButtonHTMLAttributes<HTMLButtonElement> {
4250
+ /**
4251
+ * Accessible name of the button.
4252
+ * @default 'Add color'
4253
+ */
4254
+ 'aria-label'?: string;
4255
+ /**
4256
+ * Decorative glyph (`aria-hidden`). `null` and `undefined` keep the plus glyph; `false` or
4257
+ * anything that renders nothing shows none. A `<button>` or `Button` passed here is not nested:
4258
+ * its children become the glyph and a one-time development warning is logged.
4259
+ * @default a plus glyph
4260
+ */
4261
+ icon?: Slot<'span'>;
4262
+ /**
4263
+ * Size of the swatch (20, 24, 32 or 40px).
4264
+ * @default the picker's
4265
+ */
4266
+ size?: SwatchPickerSize;
4267
+ /**
4268
+ * Shape of the swatch.
4269
+ * @default the picker's
4270
+ */
4271
+ shape?: Shape;
4272
+ /** Ref to the button. */
4273
+ ref?: React_2.Ref<HTMLButtonElement>;
4274
+ }
4275
+
3550
4276
  /**
3551
4277
  * Lays out a form control with a label, a validation message, a hint and a required indicator,
3552
4278
  * and wires them to the control.
@@ -3864,6 +4590,13 @@ export declare interface FieldProps extends React_2.HTMLAttributes<HTMLDivElemen
3864
4590
  ref?: React_2.Ref<HTMLDivElement>;
3865
4591
  }
3866
4592
 
4593
+ /**
4594
+ * Which week is week 1 of a year: the week of January 1 (`'first-day'`), the first week that lies
4595
+ * wholly in the year (`'first-full-week'`), or the first week with at least four days in the year
4596
+ * (`'first-four-day-week'`, ISO 8601 when weeks start on Monday).
4597
+ */
4598
+ export declare type FirstWeekOfYear = 'first-day' | 'first-full-week' | 'first-four-day-week';
4599
+
3867
4600
  /**
3868
4601
  * A flexbox layout container with token-based gaps.
3869
4602
  *
@@ -3936,6 +4669,30 @@ export declare type FlexProps<C extends React_2.ElementType = 'div'> = Polymorph
3936
4669
  */
3937
4670
  export declare function getThemeClassName(theme: WaveTheme): string;
3938
4671
 
4672
+ /**
4673
+ * The week number (1–53) of `date`'s calendar day (time of day ignored): days before a year's week
4674
+ * 1 belong to the previous year's last week, and days in the next year's week 1 are week 1. ISO 8601
4675
+ * is `{ firstDayOfWeek: 1, firstWeekOfYear: 'first-four-day-week' }`.
4676
+ *
4677
+ * @param options Defaults to Sunday weeks, week 1 being the week of January 1.
4678
+ * @default `{ firstDayOfWeek: 0, firstWeekOfYear: 'first-day' }`
4679
+ */
4680
+ export declare function getWeekNumber(date: Date, options?: GetWeekNumberOptions): number;
4681
+
4682
+ /** Options of {@link getWeekNumber}. */
4683
+ export declare interface GetWeekNumberOptions {
4684
+ /**
4685
+ * The weekday weeks start on (0 is Sunday).
4686
+ * @default 0
4687
+ */
4688
+ firstDayOfWeek?: DayOfWeek;
4689
+ /**
4690
+ * Which week is week 1 of a year.
4691
+ * @default 'first-day'
4692
+ */
4693
+ firstWeekOfYear?: FirstWeekOfYear;
4694
+ }
4695
+
3939
4696
  /**
3940
4697
  * A CSS grid layout with a fixed column count and token gaps.
3941
4698
  *
@@ -4092,6 +4849,55 @@ export declare interface ImageProps extends React_2.ImgHTMLAttributes<HTMLImageE
4092
4849
  /** Shape of the image corners (the shared {@link Shape} vocabulary). */
4093
4850
  export declare type ImageShape = Shape;
4094
4851
 
4852
+ /**
4853
+ * One image swatch of a `SwatchPicker`: a pattern or texture drawn as a covering background
4854
+ * image. Outside a `SwatchPicker` it throws in development and renders inertly in production.
4855
+ *
4856
+ * **Naming**: give it `aria-label`, or wrap it in a `Tooltip` with `relationship="label"`.
4857
+ * Without either it is named by its `value` and a development warning is logged.
4858
+ *
4859
+ * **Selected and disabled**: an image has no single luminance, so the check and the disabled slash
4860
+ * are the theme's foreground glyph over a background halo. Unlike `ColorSwatch` it does not opt
4861
+ * out of forced colors (a background image stays).
4862
+ *
4863
+ * @example
4864
+ * <SwatchPicker aria-label="Pattern">
4865
+ * <ImageSwatch value="dots" src="/dots.png" aria-label="Dots" />
4866
+ * </SwatchPicker>
4867
+ */
4868
+ export declare const ImageSwatch: {
4869
+ ({ src, ...rest }: ImageSwatchProps): React_2.JSX.Element;
4870
+ displayName: string;
4871
+ };
4872
+
4873
+ /** ImageSwatch (carries SwatchPicker's `swatch`): `root` on the swatch `<button>`. */
4874
+ export declare const imageSwatchClassNames: {
4875
+ readonly root: "wave-image-swatch";
4876
+ };
4877
+
4878
+ /** Properties for the ImageSwatch component. */
4879
+ export declare interface ImageSwatchProps extends Omit<React_2.ButtonHTMLAttributes<HTMLButtonElement>, 'value'> {
4880
+ /** Unique identifier for the swatch (the value the picker selects and a form submits). */
4881
+ value: string;
4882
+ /** URL of the image (drawn as a covering background image). */
4883
+ src: string;
4884
+ /**
4885
+ * Size of the swatch (20, 24, 32 or 40px).
4886
+ * @default the picker's
4887
+ */
4888
+ size?: SwatchPickerSize;
4889
+ /**
4890
+ * Shape of the swatch.
4891
+ * @default the picker's
4892
+ */
4893
+ shape?: Shape;
4894
+ /**
4895
+ * Ref to the swatch button: `role="radio"` in the row layout, inside its cell in the grid
4896
+ * layout, a toggle button in tab mode.
4897
+ */
4898
+ ref?: React_2.Ref<HTMLButtonElement>;
4899
+ }
4900
+
4095
4901
  /**
4096
4902
  * A button with the info glyph that shows `info` in a note next to it: text, links or other rich
4097
4903
  * content, placed above the button with a beak (a toggletip).
@@ -4376,6 +5182,9 @@ export declare interface InputProps extends Omit<React_2.InputHTMLAttributes<HTM
4376
5182
  ref?: React_2.Ref<HTMLInputElement>;
4377
5183
  }
4378
5184
 
5185
+ /** Whether both dates are on the same calendar day (time of day ignored); `false` when either is missing. */
5186
+ export declare function isSameDay(a: Date | null | undefined, b: Date | null | undefined): boolean;
5187
+
4379
5188
  /**
4380
5189
  * A text label for a form control (`htmlFor`), on the Fluent type ramp. The optional required
4381
5190
  * indicator is decorative (`aria-hidden`). `Field` renders its own label; use `Label` for custom
@@ -4496,60 +5305,529 @@ export declare interface LinkOwnProps {
4496
5305
  }
4497
5306
 
4498
5307
  /**
4499
- * Props of {@link Link} rendered as `C` (default `'a'`). `LinkProps` without a type argument is
4500
- * the 0.4 name: the props of a Link rendered as an `<a>`, including `ref`.
5308
+ * Props of {@link Link} rendered as `C` (default `'a'`). `LinkProps` without a type argument is
5309
+ * the 0.4 name: the props of a Link rendered as an `<a>`, including `ref`.
5310
+ */
5311
+ export declare type LinkProps<C extends React_2.ElementType = 'a'> = PolymorphicProps<C, LinkOwnProps>;
5312
+
5313
+ /** @deprecated Use {@link LinkAppearance}. */
5314
+ export declare type LinkVariant = LinkAppearance;
5315
+
5316
+ /**
5317
+ * A vertical list of items, optionally selectable.
5318
+ *
5319
+ * - **Plain** (`selectable` false): `role="list"` with `listitem`s; item actions stay in the
5320
+ * normal Tab order.
5321
+ * - **Selectable** (APG Listbox): `role="listbox"` with `option`s and one Tab stop (the first
5322
+ * selected option, else the first option). ArrowUp/Down move focus (wrapping), Home/End jump to
5323
+ * the ends, typeahead is on for more than 7 items, Enter/Space and clicks toggle selection (a
5324
+ * Space typed within 500 ms of a typeahead character continues the search instead; with Ctrl,
5325
+ * Alt or Meta, Enter and Space are left to the page).
5326
+ * - **Selectable with item actions** (APG Grid): `role="grid"` with `row`s (carrying
5327
+ * `aria-selected`) and `gridcell`s for the content and the action. One Tab stop; Up/Down move
5328
+ * between rows, Right/Left (mirrored in RTL) move into and out of the actions. A cell that holds
5329
+ * a text-entry widget takes focus itself: Enter/F2 enter the widget, Escape returns to the cell.
5330
+ * Clicks and keys that start inside an action, or inside a popup it opens (a Popover, a Menu),
5331
+ * never toggle selection.
5332
+ * - **Switching semantics remounts the items.** Listbox/list and grid use different elements
5333
+ * (`ul`/`li` and `div`), so when a selectable list gains its first item action, loses its last
5334
+ * one, or `selectable` changes while items have actions, React remounts the items and their
5335
+ * content: state inside them (an inline rename input's draft, an uncontrolled checkbox) is reset.
5336
+ * Focus that is on an item or inside it when the list switches moves to the same item (by
5337
+ * `value`, else by position; the next item when the focused one was removed), so the switch
5338
+ * never drops it to `<body>`. This includes focus inside the last action when that action
5339
+ * removes itself (an inline rename input that unmounts on Enter). An action that removes itself
5340
+ * while focused without causing a switch drops focus, like any removed element. When the list
5341
+ * may switch, keep such state in the parent (or keep an action on at least one item).
5342
+ * - Selection: `selectionMode` `'single'` (default) or `'multiple'`; controlled with
5343
+ * `selectedItems` (or `selectedItem` in single mode) or uncontrolled with the `default*` props.
5344
+ * Values of items that are no longer rendered are dropped from the reported selection.
5345
+ * - Sub-component: `List.Item` (also exported as `ListItem` for React Server Components).
5346
+ *
5347
+ * @example
5348
+ * <List selectable selectionMode="multiple" aria-label="Fruits" onSelectionChange={setFruits}>
5349
+ * <List.Item value="apple">Apple</List.Item>
5350
+ * <List.Item value="banana">Banana</List.Item>
5351
+ * </List>
5352
+ */
5353
+ export declare const List: {
5354
+ <M extends ListSelectionMode = "single">(props: ListProps<M>): React_2.ReactNode;
5355
+ displayName: string;
5356
+ } & {
5357
+ Item: {
5358
+ ({ value, action, className, children, onClick, onKeyDown, ref, ...rest }: ListItemProps): React_2.JSX.Element;
5359
+ displayName: string;
5360
+ };
5361
+ };
5362
+
5363
+ /**
5364
+ * A list of options that holds focus itself (APG listbox): one `<ul role="listbox">` of
5365
+ * `Option`s, whose `aria-activedescendant` points at the active option while the list has focus.
5366
+ * It is the picker option model shown in the page — typeahead, groups, disabled options and the
5367
+ * option look of Dropdown and Combobox. Use `List` with `selectable` (`selectionMode`) instead
5368
+ * when each item needs real focus, actions of its own or interactive content.
5369
+ *
5370
+ * - **Focus.** One tab stop. The active option exists only while the list has focus, and a
5371
+ * switch to another window keeps it: the selected option (with `multiselect`, the first
5372
+ * selected one in list order), else the first. While no option can be active (an empty list,
5373
+ * every option hidden, or every option disabled without `disabledOptionsFocusable`), and while
5374
+ * the active option is scrolled out of the list's view, the list draws its own focus ring. A
5375
+ * press on an option with the primary button focuses the list and makes that option active
5376
+ * without scrolling, so the click selects it even while the selected option is scrolled out of
5377
+ * view; a right or middle press is left to the browser. `autoFocus` focuses the list when it
5378
+ * mounts.
5379
+ * - **Keys.** ArrowDown and ArrowUp move without wrapping, Home and End go to the first and last
5380
+ * option, PageUp and PageDown move ten options, and typing moves to the matching option
5381
+ * (typeahead). Space and Enter select the active option: the selection does not follow the
5382
+ * active option. Tab, Escape and Alt+Arrow keys are left to the page, so an enclosing Dialog
5383
+ * closes on Escape.
5384
+ * - **Selection.** `value`, `defaultValue` and `onValueChange` are Fluent's `selectedOptions`,
5385
+ * `defaultSelectedOptions` and `onOptionSelect` under WaveUI's value naming. A single-select
5386
+ * Listbox keeps the selected option when it is selected again (no deselection). `multiselect`
5387
+ * turns the value into an array: options draw a checkbox, Space, Enter and a click toggle an
5388
+ * option, the value keeps selection order, and every toggle the user makes is announced
5389
+ * (`labels.added`/`labels.removed`; never a controlled change or a form reset). A non-literal
5390
+ * `multiselect={flag}` is a type error: render two elements, one for each mode.
5391
+ * - **Disabled.** `disabled` takes the list out of the tab order (a click does not focus it
5392
+ * either), dims it, takes pointer input off its options, selects nothing and submits nothing.
5393
+ * Disabled options are skipped by the keys unless `disabledOptionsFocusable`, and are never
5394
+ * selected.
5395
+ * - **Forms and Field.** With `name` the value is submitted with its form (one entry, or one per
5396
+ * value with `multiselect`), and `required` needs a value (native validation; a missing value
5397
+ * moves focus to the list). A reset of its form restores `defaultValue`, with or without a
5398
+ * `name` (a `multiselect` reset is compared by content, so restoring the same values reports
5399
+ * nothing). Inside a `Field` the list is labelled by its label, described by its message and
5400
+ * hint, and takes its invalid and required state; otherwise name it with `aria-label` or
5401
+ * `aria-labelledby` (development warns once when it has no name).
5402
+ * - It has no built-in height: give it one through `className` and it scrolls.
5403
+ *
5404
+ * Every prop, the `ref` and the handlers go to the `<ul>`. Sub-components: `Listbox.Option`,
5405
+ * `Listbox.OptionGroup`. React Server Components import the flat names `ListboxOption` /
5406
+ * `ListboxOptionGroup` (dotted access needs a client file).
5407
+ *
5408
+ * @example
5409
+ * <Listbox aria-label="Fruit" name="fruit" defaultValue="banana">
5410
+ * <Listbox.Option value="apple">Apple</Listbox.Option>
5411
+ * <Listbox.Option value="banana">Banana</Listbox.Option>
5412
+ * </Listbox>
5413
+ */
5414
+ export declare const Listbox: ListboxComponent;
5415
+
5416
+ /** Listbox: `root` on the `role="listbox"` list (its options carry Option's classes). */
5417
+ export declare const listboxClassNames: {
5418
+ readonly root: "wave-listbox";
5419
+ };
5420
+
5421
+ /** Props for the combobox element (spread them; see {@link UseListboxResult.getComboboxProps}). */
5422
+ export declare interface ListboxComboboxProps {
5423
+ role: 'combobox';
5424
+ /** {@link UseListboxOptions.open}. */
5425
+ 'aria-expanded': boolean;
5426
+ /** The listbox's id ({@link UseListboxResult.listboxId}). */
5427
+ 'aria-controls': string;
5428
+ /** The active option's id, while the listbox is open and an option is active. */
5429
+ 'aria-activedescendant'?: string;
5430
+ 'aria-haspopup': 'listbox';
5431
+ /** Editable mode: typing filters the options. */
5432
+ 'aria-autocomplete'?: 'list';
5433
+ }
5434
+
5435
+ /** The Listbox component's type: a multi-select signature, then the single-select one. */
5436
+ export declare interface ListboxComponent {
5437
+ (props: ListboxProps<true> & {
5438
+ multiselect: true;
5439
+ }): React_2.ReactNode;
5440
+ (props: ListboxProps): React_2.ReactNode;
5441
+ displayName?: string;
5442
+ Option: typeof Option_2;
5443
+ OptionGroup: typeof OptionGroup;
5444
+ }
5445
+
5446
+ /**
5447
+ * The context a listbox provides to its options (`useListbox(...).context`; pass it to
5448
+ * `ListboxProvider` for a list rendered without `ListboxSurface`).
5449
+ */
5450
+ export declare interface ListboxContextValue {
5451
+ /** The listbox element's id, which the option ids start with. */
5452
+ listboxId: string;
5453
+ /** The per-option state and the registration of the options. */
5454
+ store: ListboxStore;
5455
+ /** Whether the listbox is {@link UseListboxOptions.multiselect}. */
5456
+ multiselect: boolean;
5457
+ /** The listbox's {@link UseListboxOptions.mode}: standalone options add the pointer press. */
5458
+ mode: 'editable' | 'select-only' | 'standalone';
5459
+ /**
5460
+ * Commits `value` (an option click): `item` stands for the option while it has not registered
5461
+ * yet, and `event` is the click behind the commit. A disabled option is never committed.
5462
+ */
5463
+ select(value: string, item: ListboxItem, event: Event): void;
5464
+ /** Highlights `value` (pointer movement); not scrolled into view, so the list stays put. */
5465
+ highlight(value: string): void;
5466
+ /**
5467
+ * Standalone mode: a pointer press on option `value` (its `mousedown`, whose default the option
5468
+ * prevents). Focuses the list without scrolling and makes the option active without scrolling
5469
+ * it into view, in one update, so the click that follows commits the pressed option even when
5470
+ * focus would have scrolled another option into view. A press on an option that cannot be
5471
+ * active (a disabled one, unless {@link UseListboxOptions.disabledOptionsFocusable}) keeps a
5472
+ * focused list's active option, and an unfocused list starts on its `autoHighlight` option,
5473
+ * not scrolled into view either. Development warns once when the list element is unknown
5474
+ * (the `ref` of {@link UseListboxResult.getListboxProps} was not passed on).
5475
+ */
5476
+ press(value: string): void;
5477
+ }
5478
+
5479
+ /**
5480
+ * What {@link collectOptionLabels} does with the elements of a component marked by
5481
+ * {@link markListboxElement}: `'option'` reads a value and its label, `'group'` walks the children.
5482
+ */
5483
+ export declare type ListboxElementKind = 'option' | 'group';
5484
+
5485
+ /**
5486
+ * One option of a listbox: an entry of {@link UseListboxOptions.items} (data mode), or what an
5487
+ * option registers (registration mode, {@link useListboxOption}).
5488
+ */
5489
+ export declare interface ListboxItem {
5490
+ /** Unique value within the listbox. */
5491
+ value: string;
5492
+ /** Display label (Combobox input text, Dropdown trigger text). */
5493
+ label: string;
5494
+ /** Text matched by typeahead and filters instead of `label`. */
5495
+ textValue?: string;
5496
+ /**
5497
+ * Disabled options are rendered but skipped by navigation, unless
5498
+ * {@link UseListboxOptions.disabledOptionsFocusable}, and never committed.
5499
+ * @default false
5500
+ */
5501
+ disabled?: boolean;
5502
+ /**
5503
+ * Hidden options are left out of navigation and rendering like filtered-out ones: never
5504
+ * highlighted, reached by typeahead or committed with the keyboard (registered options render
5505
+ * `hidden`). Their label stays known ({@link UseListboxResult.getItem}). In data mode (`items`)
5506
+ * it is the item's own flag; a registered option is hidden by its own `hidden` attribute or by a
5507
+ * hidden group around it.
5508
+ * @default false
5509
+ */
5510
+ hidden?: boolean;
5511
+ }
5512
+
5513
+ /**
5514
+ * The Listbox's built-in texts, for localization: the announcements of a `multiselect` toggle.
5515
+ * Each member is optional and falls back to its English default.
5516
+ */
5517
+ export declare interface ListboxLabels {
5518
+ /**
5519
+ * Announced when a `multiselect` toggle selects an option; `count` is the number of values
5520
+ * selected after the change.
5521
+ * @default (label, count) => `${label} added, ${count} selected`
5522
+ */
5523
+ added?: (label: string, count: number) => string;
5524
+ /**
5525
+ * Announced when a `multiselect` toggle deselects an option; `count` is the number of values
5526
+ * selected after the change.
5527
+ * @default (label, count) => `${label} removed, ${count} selected`
5528
+ */
5529
+ removed?: (label: string, count: number) => string;
5530
+ }
5531
+
5532
+ /** Props for the listbox element (see {@link UseListboxResult.getListboxProps}). */
5533
+ export declare interface ListboxListProps {
5534
+ /** {@link UseListboxResult.listboxId}. */
5535
+ id: string;
5536
+ role: 'listbox';
5537
+ /** With {@link UseListboxOptions.multiselect}. */
5538
+ 'aria-multiselectable'?: true;
5539
+ /** `-1` in the combobox modes (focus stays on the combobox); `0` in standalone mode. */
5540
+ tabIndex: 0 | -1;
5541
+ /** The combobox modes: keeps focus on the combobox while options are clicked. */
5542
+ onMouseDown?(event: React_2.MouseEvent): void;
5543
+ /** Standalone mode: the active option's id while the list has focus and an option is active. */
5544
+ 'aria-activedescendant'?: string;
5545
+ /**
5546
+ * Standalone mode: the list element, which a pointer press on an option focuses. Merge it with
5547
+ * your own ref (a press warns in development when it was dropped).
5548
+ */
5549
+ ref?: React_2.RefCallback<HTMLElement>;
5550
+ }
5551
+
5552
+ /**
5553
+ * Why {@link UseListboxOptions.onOpenChange} was called: `'keyboard'` (a key opens the listbox, or
5554
+ * closes it without a commit), `'select'` (a commit closes it), `'escape'` or `'tab'` (Tab closes
5555
+ * it, after committing the active option in single-select select-only mode).
5556
+ */
5557
+ export declare type ListboxOpenChangeReason = 'keyboard' | 'select' | 'escape' | 'tab';
5558
+
5559
+ /** Flat name of `Listbox.Option` for React Server Components. */
5560
+ export declare const ListboxOption: React_2.NamedExoticComponent<OptionProps>;
5561
+
5562
+ /**
5563
+ * Props for an option element (spread them onto the `<li>`; compose `onClick`, and `onMouseDown`
5564
+ * in standalone mode, with yours).
5565
+ */
5566
+ export declare interface ListboxOptionElementProps<E extends HTMLElement = HTMLElement> {
5567
+ /**
5568
+ * The option's stable id ({@link UseListboxResult.getOptionId}), which `aria-activedescendant`
5569
+ * points at while the option is active.
5570
+ */
5571
+ id: string;
5572
+ role: 'option';
5573
+ 'aria-selected': boolean;
5574
+ /** While disabled. */
5575
+ 'aria-disabled'?: true;
5576
+ /** While filtered out or hidden. */
5577
+ hidden?: boolean;
5578
+ /** While the option is active, for styling. */
5579
+ 'data-active'?: '';
5580
+ /** While selected, for styling. */
5581
+ 'data-selected'?: '';
5582
+ /** While disabled, for styling. */
5583
+ 'data-disabled'?: '';
5584
+ /** Commits the option (a disabled one does nothing). */
5585
+ onClick(event: React_2.MouseEvent<E>): void;
5586
+ /** Makes the option under the pointer active (not a disabled one), without scrolling the list. */
5587
+ onPointerMove(event: React_2.PointerEvent<E>): void;
5588
+ /** Standalone mode only: the pointer press ({@link ListboxContextValue.press}). */
5589
+ onMouseDown?(event: React_2.MouseEvent<E>): void;
5590
+ /** Registers the element; it also sets the `ref` passed to {@link useListboxOption}. */
5591
+ ref: React_2.RefCallback<E>;
5592
+ }
5593
+
5594
+ /** Flat name of `Listbox.OptionGroup` for React Server Components. */
5595
+ export declare const ListboxOptionGroup: React_2.FC<OptionGroupProps>;
5596
+
5597
+ /** Properties for the Listbox component. */
5598
+ export declare interface ListboxProps<M extends boolean = false> extends Omit<React_2.HTMLAttributes<HTMLUListElement>, 'onChange' | 'defaultValue'> {
5599
+ /**
5600
+ * Several options can be selected (Fluent's `multiselect`; List's `selectionMode="multiple"` is
5601
+ * the other widget): the value is an array, options draw a checkbox, Space, Enter and a click
5602
+ * toggle an option, and each toggle is announced. A non-literal `multiselect={flag}` is a type
5603
+ * error: render two elements, one for each mode.
5604
+ * @default false
5605
+ */
5606
+ multiselect?: M;
5607
+ /**
5608
+ * Controlled selected value (`''` for none), or with `multiselect` the selected values in
5609
+ * selection order (Fluent's `selectedOptions`).
5610
+ */
5611
+ value?: M extends true ? readonly string[] : string;
5612
+ /**
5613
+ * Initial selected value for uncontrolled usage, which a form reset restores.
5614
+ * @default '' (`[]` with `multiselect`)
5615
+ */
5616
+ defaultValue?: M extends true ? readonly string[] : string;
5617
+ /**
5618
+ * Called with the new value when it changes (a new array with `multiselect`; Fluent's
5619
+ * `onOptionSelect`, under WaveUI's value/onValueChange naming). In single-select mode, selecting
5620
+ * the selected option again changes nothing: the Listbox never deselects it.
5621
+ */
5622
+ onValueChange?: M extends true ? (value: string[]) => void : (value: string) => void;
5623
+ /**
5624
+ * Called after the active (highlighted) option changes — focus, arrow keys, typeahead, the
5625
+ * pointer — and with `null` when focus leaves the list (a switch to another window keeps the
5626
+ * active option). It reports what `aria-activedescendant` points at, from an effect once the
5627
+ * change commits. Fluent's `onActiveOptionChange` reports neither the pointer (its options have
5628
+ * no hover highlight) nor the loss of focus.
5629
+ */
5630
+ onActiveOptionChange?: (value: string | null) => void;
5631
+ /**
5632
+ * Takes the list out of the tab order (a click does not focus it either, as a disabled native
5633
+ * `<select>`) and dims it: its options take no pointer input, nothing can be selected, and
5634
+ * nothing is submitted or validated. Renders `aria-disabled` and `data-disabled`. An
5635
+ * `aria-disabled` of your own without `disabled` is passed through as it is: the list stays
5636
+ * interactive.
5637
+ * @default false
5638
+ */
5639
+ disabled?: boolean;
5640
+ /**
5641
+ * Focuses the list when it mounts in the browser (React focuses only form controls itself), not
5642
+ * while `disabled`. Server-rendered HTML carries the `autofocus` attribute for the browser's own
5643
+ * autofocus, so a hydrating list takes no focus, as React leaves a hydrated form control alone.
5644
+ * @default false
5645
+ */
5646
+ autoFocus?: boolean;
5647
+ /**
5648
+ * Keeps disabled options in the arrow-key, Home/End, PageUp/PageDown and typeahead order (the
5649
+ * option that is active on focus may then be a disabled one too); they still cannot be
5650
+ * selected (Space, Enter and a click do nothing). Unlike Fluent, which always keeps disabled
5651
+ * options reachable, WaveUI skips them by default.
5652
+ * @default false
5653
+ */
5654
+ disabledOptionsFocusable?: boolean;
5655
+ /** The `multiselect` toggle announcements, for localization. Unset members keep their English defaults. */
5656
+ labels?: ListboxLabels;
5657
+ /**
5658
+ * Name of the value in form submissions (renders a hidden input inside the list; one per value
5659
+ * with `multiselect`).
5660
+ */
5661
+ name?: string;
5662
+ /** Id of the form the value belongs to, when the Listbox is outside it. */
5663
+ form?: string;
5664
+ /**
5665
+ * A value is required to submit the form (native constraint validation); when validation finds
5666
+ * it empty, focus moves to the list.
5667
+ */
5668
+ required?: boolean;
5669
+ /**
5670
+ * Called on a key press on the list, before the built-in keys; `event.preventDefault()` skips
5671
+ * them.
5672
+ */
5673
+ onKeyDown?: React_2.KeyboardEventHandler<HTMLUListElement>;
5674
+ /** Ref to the `<ul role="listbox">`. */
5675
+ ref?: React_2.Ref<HTMLUListElement>;
5676
+ }
5677
+
5678
+ /**
5679
+ * Provides a listbox's context to its options, for a custom picker that renders its list without
5680
+ * `ListboxSurface`: `<ListboxProvider value={listbox.context}><ul {...listbox.getListboxProps()}>…</ul></ListboxProvider>`.
5681
+ */
5682
+ export declare function ListboxProvider({ value, children }: ListboxProviderProps): React_2.JSX.Element;
5683
+
5684
+ export declare namespace ListboxProvider {
5685
+ var displayName: string;
5686
+ }
5687
+
5688
+ /** Props of {@link ListboxProvider}. */
5689
+ export declare interface ListboxProviderProps {
5690
+ /** The context of a listbox: `useListbox(...).context`. */
5691
+ value: ListboxContextValue;
5692
+ /** The options (`Option`, `OptionGroup` or options of your own on `useListboxOption`). */
5693
+ children?: React_2.ReactNode;
5694
+ }
5695
+
5696
+ /**
5697
+ * Second argument of {@link UseListboxOptions.onSelect}: the committed option and the event behind
5698
+ * the commit.
5699
+ */
5700
+ export declare interface ListboxSelectDetails {
5701
+ /** The committed option. */
5702
+ item: ListboxItem;
5703
+ /** The key or click event behind the commit. */
5704
+ event: Event;
5705
+ }
5706
+
5707
+ /**
5708
+ * The per-option state of a listbox ({@link ListboxContextValue.store}) and the contract of option
5709
+ * components: {@link useListboxOption} is built on it, and so can an option component of your own
5710
+ * be. `register` adds an option, `getIndex` gives its stable id, and the flags say how to draw it:
5711
+ * subscribe with `useSyncExternalStore` and read one value (`() => store.isActive(value)`), so only
5712
+ * the options whose answer changed re-render.
5713
+ */
5714
+ export declare interface ListboxStore {
5715
+ /** Calls `listener` after a flag of any option changed. Returns the unsubscribe function. */
5716
+ subscribe(listener: () => void): () => void;
5717
+ /** Whether `value` is the active option, the one `aria-activedescendant` points at. */
5718
+ isActive(value: string): boolean;
5719
+ /** Whether `value` is selected. */
5720
+ isSelected(value: string): boolean;
5721
+ /** Whether `value` is filtered out or hidden: render its option `hidden`. */
5722
+ isHidden(value: string): boolean;
5723
+ /**
5724
+ * The stable per-listbox index of `value`, assigned the first time the value is seen: the
5725
+ * option's id is `${listboxId}-opt-${getIndex(value)}` ({@link UseListboxResult.getOptionId}),
5726
+ * the same across filtering and remounts.
5727
+ */
5728
+ getIndex(value: string): number;
5729
+ /**
5730
+ * Registers an option and its element (registration mode): call it from a layout effect, as
5731
+ * {@link useListboxOption} does, and call the returned function to unregister, when the option
5732
+ * unmounts or before it registers a changed item. The options are ordered by their elements'
5733
+ * DOM position. The registrations of a commit are published once from the listbox's layout
5734
+ * effect (later ones once per microtask).
5735
+ */
5736
+ register(item: ListboxItem, element: React_2.RefObject<HTMLElement | null>): () => void;
5737
+ }
5738
+
5739
+ /**
5740
+ * The option list of a custom picker and the popup it opens in: a `<ul role="listbox">` with the
5741
+ * options (spread from `listbox.getListboxProps()`), rendered `hidden` in place inside your
5742
+ * picker while the list is not shown, so the options register and their ids exist from the first
5743
+ * render, and in a portaled surface placed by {@link useListboxPopup} while it is, never in both.
5744
+ * While the listbox is open with nothing to show, the surface shows `emptyContent` instead, if
5745
+ * any. A press on the surface keeps focus on your combobox. It provides the listbox's context to
5746
+ * the options, so it needs no {@link ListboxProvider}.
5747
+ *
5748
+ * @example
5749
+ * <ListboxSurface
5750
+ * listbox={listbox}
5751
+ * layerId={layerId}
5752
+ * surfaceRef={surfaceRef}
5753
+ * floatingProps={floatingProps}
5754
+ * open={open}
5755
+ * expanded={expanded}
5756
+ * aria-labelledby={labelId}
5757
+ * >
5758
+ * <Option value="georgia">Georgia</Option>
5759
+ * </ListboxSurface>
5760
+ */
5761
+ export declare function ListboxSurface(props: ListboxSurfaceProps): React_2.JSX.Element;
5762
+
5763
+ export declare namespace ListboxSurface {
5764
+ var displayName: string;
5765
+ }
5766
+
5767
+ /**
5768
+ * ListboxSurface: `root` on the portaled popup around the list, while it shows the list or the
5769
+ * empty content; `list` on the `role="listbox"` list, also while it renders in place inside your
5770
+ * picker. In Combobox, Dropdown and TagPicker these elements also carry the picker's own
5771
+ * `surface` and `listbox` classes.
4501
5772
  */
4502
- export declare type LinkProps<C extends React_2.ElementType = 'a'> = PolymorphicProps<C, LinkOwnProps>;
4503
-
4504
- /** @deprecated Use {@link LinkAppearance}. */
4505
- export declare type LinkVariant = LinkAppearance;
5773
+ export declare const listboxSurfaceClassNames: {
5774
+ readonly root: "wave-listbox-surface";
5775
+ readonly list: "wave-listbox-surface__list";
5776
+ };
4506
5777
 
4507
5778
  /**
4508
- * A vertical list of items, optionally selectable.
4509
- *
4510
- * - **Plain** (`selectable` false): `role="list"` with `listitem`s; item actions stay in the
4511
- * normal Tab order.
4512
- * - **Selectable** (APG Listbox): `role="listbox"` with `option`s and one Tab stop (the first
4513
- * selected option, else the first option). ArrowUp/Down move focus (wrapping), Home/End jump to
4514
- * the ends, typeahead is on for more than 7 items, Enter/Space and clicks toggle selection (a
4515
- * Space typed within 500 ms of a typeahead character continues the search instead; with Ctrl,
4516
- * Alt or Meta, Enter and Space are left to the page).
4517
- * - **Selectable with item actions** (APG Grid): `role="grid"` with `row`s (carrying
4518
- * `aria-selected`) and `gridcell`s for the content and the action. One Tab stop; Up/Down move
4519
- * between rows, Right/Left (mirrored in RTL) move into and out of the actions. A cell that holds
4520
- * a text-entry widget takes focus itself: Enter/F2 enter the widget, Escape returns to the cell.
4521
- * Clicks and keys that start inside an action, or inside a popup it opens (a Popover, a Menu),
4522
- * never toggle selection.
4523
- * - **Switching semantics remounts the items.** Listbox/list and grid use different elements
4524
- * (`ul`/`li` and `div`), so when a selectable list gains its first item action, loses its last
4525
- * one, or `selectable` changes while items have actions, React remounts the items and their
4526
- * content: state inside them (an inline rename input's draft, an uncontrolled checkbox) is reset.
4527
- * Focus that is on an item or inside it when the list switches moves to the same item (by
4528
- * `value`, else by position; the next item when the focused one was removed), so the switch
4529
- * never drops it to `<body>`. This includes focus inside the last action when that action
4530
- * removes itself (an inline rename input that unmounts on Enter). An action that removes itself
4531
- * while focused without causing a switch drops focus, like any removed element. When the list
4532
- * may switch, keep such state in the parent (or keep an action on at least one item).
4533
- * - Selection: `selectionMode` `'single'` (default) or `'multiple'`; controlled with
4534
- * `selectedItems` (or `selectedItem` in single mode) or uncontrolled with the `default*` props.
4535
- * Values of items that are no longer rendered are dropped from the reported selection.
4536
- * - Sub-component: `List.Item` (also exported as `ListItem` for React Server Components).
4537
- *
4538
- * @example
4539
- * <List selectable selectionMode="multiple" aria-label="Fruits" onSelectionChange={setFruits}>
4540
- * <List.Item value="apple">Apple</List.Item>
4541
- * <List.Item value="banana">Banana</List.Item>
4542
- * </List>
5779
+ * Props of {@link ListboxSurface}. The options of one listbox live in one list at a time, and this
5780
+ * surface renders that list: render every option of the listbox inside it, never in a second list
5781
+ * of your own, not even for an exit animation.
4543
5782
  */
4544
- export declare const List: {
4545
- <M extends ListSelectionMode = "single">(props: ListProps<M>): React_2.ReactNode;
4546
- displayName: string;
4547
- } & {
4548
- Item: {
4549
- ({ value, action, className, children, onClick, onKeyDown, ref, ...rest }: ListItemProps): React_2.JSX.Element;
4550
- displayName: string;
4551
- };
4552
- };
5783
+ export declare interface ListboxSurfaceProps {
5784
+ /** The listbox: the result of `useListbox` in select-only or editable mode. */
5785
+ listbox: UseListboxResult;
5786
+ /** `layerId` from {@link useListboxPopup}: the surface joins the popup's dismiss layer. */
5787
+ layerId: string;
5788
+ /** `surfaceRef` from {@link useListboxPopup}. */
5789
+ surfaceRef: React_2.RefCallback<HTMLElement>;
5790
+ /** `floatingProps` from {@link useListboxPopup}: the surface's placement. */
5791
+ floatingProps: UseListboxPopupResult['floatingProps'];
5792
+ /** The listbox is open (your open state). `emptyContent` shows only while it is. */
5793
+ open: boolean;
5794
+ /**
5795
+ * The list is shown: the listbox is open and has options to show (`open &&
5796
+ * listbox.items.length > 0`). The list then renders in the surface, and otherwise `hidden`, in
5797
+ * place inside your picker. Set your combobox's `aria-expanded` to this value after spreading
5798
+ * `getComboboxProps()`, which reports `open`, so the combobox is not announced as expanded while
5799
+ * nothing is shown.
5800
+ */
5801
+ expanded: boolean;
5802
+ /**
5803
+ * Shown in the surface while the listbox is open but not expanded, such as a "No matches"
5804
+ * message. `undefined` and `null` show no surface; any other value shows one, so `false` and
5805
+ * `''` show an empty surface.
5806
+ */
5807
+ emptyContent?: React_2.ReactNode;
5808
+ /** Names the list. Name it with this or `aria-labelledby`, usually your picker's label. */
5809
+ 'aria-label'?: string;
5810
+ /** Ids of the elements that name the list, usually your picker's label. */
5811
+ 'aria-labelledby'?: string;
5812
+ /**
5813
+ * Options draw a check while selected (in a multi-select list, a checkbox square). Turn it off
5814
+ * for a list that never shows selected options, such as the suggestions of a tag picker.
5815
+ * @default true
5816
+ */
5817
+ showCheck?: boolean;
5818
+ /**
5819
+ * Classes merged last onto the list: they replace the list's own classes they conflict with,
5820
+ * its maximum height included.
5821
+ */
5822
+ listClassName?: string;
5823
+ /**
5824
+ * Classes merged last onto the surface, the popup around the list: they replace its own
5825
+ * classes they conflict with.
5826
+ */
5827
+ surfaceClassName?: string;
5828
+ /** The options (`Option`, `OptionGroup` or options of your own on `useListboxOption`). */
5829
+ children?: React_2.ReactNode;
5830
+ }
4553
5831
 
4554
5832
  /** List: `root` on the `<ul>` (the `role="grid"` element of a selectable list with actions). */
4555
5833
  export declare const listClassNames: {
@@ -4648,6 +5926,22 @@ export declare interface ListProps<M extends ListSelectionMode = ListSelectionMo
4648
5926
  /** Selection modes of {@link List}: the shared `SelectionMode` plus the deprecated `'multi'`. */
4649
5927
  export declare type ListSelectionMode = SelectionMode_2 | 'multi';
4650
5928
 
5929
+ /**
5930
+ * Marks a component so {@link collectOptionLabels} recognises its elements: `'option'` (reads its
5931
+ * `value` prop and its label: the `label` prop, else `textValue`, else its text children, as
5932
+ * `Option`'s) or `'group'` (walks its `children`). Returns the component (function, `memo` or
5933
+ * `forwardRef` components). Mark every option or group component of your own that is rendered in
5934
+ * a listbox (`Option` and `OptionGroup` are marked): unmarked components are opaque to
5935
+ * {@link collectOptionLabels}, so their labels are unknown on the server and in the first client
5936
+ * render.
5937
+ *
5938
+ * @example
5939
+ * // Option components of your own, built on useListboxOption:
5940
+ * export const ColorOption = markListboxElement(ColorOptionImpl, 'option');
5941
+ * export const ColorGroup = markListboxElement(ColorGroupImpl, 'group');
5942
+ */
5943
+ export declare function markListboxElement<C extends object>(component: C, kind: ListboxElementKind): C;
5944
+
4651
5945
  /**
4652
5946
  * A menu of actions (`role="menu"`), in one of two forms:
4653
5947
  *
@@ -6060,9 +7354,12 @@ export declare interface OpenChangeDetails<R extends string = string> {
6060
7354
  }
6061
7355
 
6062
7356
  /**
6063
- * An option of a `Combobox`, `Dropdown` (and `TagPicker`'s generated list). Renders
6064
- * `<li role="option">` with a stable id (`aria-activedescendant` target), `aria-selected`, a check
6065
- * mark while selected and `data-active`/`data-selected`/`data-disabled` attributes for styling.
7357
+ * An option of a listbox: a `Listbox`, `Combobox` or `Dropdown` (and `TagPicker`'s generated
7358
+ * list), or a custom picker's list, rendered through `ListboxSurface` or under a
7359
+ * `ListboxProvider`. Renders `<li role="option">` with a stable id (`aria-activedescendant`
7360
+ * target), `aria-selected`, a check mark while selected (`checkIcon` replaces it; in a
7361
+ * multi-select list it sits in a checkbox square) and `data-active`/`data-selected`/
7362
+ * `data-disabled` attributes for styling.
6066
7363
  *
6067
7364
  * Options register with the surrounding listbox (in DOM order, groups included), so they can be
6068
7365
  * wrapped, grouped or rendered conditionally. The option is memoized: moving the highlight
@@ -6073,31 +7370,37 @@ export declare interface OpenChangeDetails<R extends string = string> {
6073
7370
  * use its data variant (`data-[active]:bg-…`, `data-[selected]:bg-…`). The active option keeps
6074
7371
  * its focus outline.
6075
7372
  *
6076
- * Use it inside a `Combobox` or `Dropdown` only; it throws in development elsewhere.
7373
+ * Use it inside a listbox only; it throws in development elsewhere.
6077
7374
  */
6078
7375
  declare const Option_2: React_2.NamedExoticComponent<OptionProps>;
6079
7376
  export { Option_2 as Option }
6080
7377
 
6081
7378
  /**
6082
- * Option (also Combobox.Option and Dropdown.Option): `root` on the `role="option"` element;
6083
- * `checkIcon` on the check `<svg>`; `content` on the content span.
7379
+ * Option (also Combobox.Option, Dropdown.Option and Listbox.Option): `root` on the `role="option"`
7380
+ * element; `indicator` on the checkbox square of a multi-select list; `checkIcon` on the check
7381
+ * `<svg>`, or on the span of your `checkIcon` (inside the square in a multi-select list);
7382
+ * `content` on the content span.
6084
7383
  */
6085
7384
  export declare const optionClassNames: {
6086
7385
  readonly root: "wave-option";
7386
+ readonly indicator: "wave-option__indicator";
6087
7387
  readonly checkIcon: "wave-option__check-icon";
6088
7388
  readonly content: "wave-option__content";
6089
7389
  };
6090
7390
 
6091
7391
  /**
6092
- * Groups options under a heading: `<li role="presentation">` with the heading and a
6093
- * `<ul role="group" aria-labelledby>` of the options. Hidden while a filter (or their own `hidden`)
6094
- * hides all its options, also options wrapped in a component or in nested groups.
7392
+ * Groups options under an optional heading: `<li role="presentation">` with the heading and a
7393
+ * `<ul role="group">` of the options, named by the heading (`label`) or by your `aria-label` or
7394
+ * `aria-labelledby`, which win over it. Hidden while a filter (or their own `hidden`) hides all
7395
+ * its options, also options wrapped in a component or in nested groups. Use it inside a listbox,
7396
+ * as `Option`.
6095
7397
  */
6096
7398
  export declare const OptionGroup: React_2.FC<OptionGroupProps>;
6097
7399
 
6098
7400
  /**
6099
- * OptionGroup (also Combobox.OptionGroup and Dropdown.OptionGroup): `root` on the group's entry
6100
- * in the list; `label` on its heading; `list` on the `role="group"` list of its options.
7401
+ * OptionGroup (also Combobox.OptionGroup, Dropdown.OptionGroup and Listbox.OptionGroup): `root`
7402
+ * on the group's entry in the list; `label` on its heading (rendered only for a `label`); `list`
7403
+ * on the `role="group"` list of its options.
6101
7404
  */
6102
7405
  export declare const optionGroupClassNames: {
6103
7406
  readonly root: "wave-option-group";
@@ -6105,10 +7408,28 @@ export declare const optionGroupClassNames: {
6105
7408
  readonly list: "wave-option-group__list";
6106
7409
  };
6107
7410
 
6108
- /** Properties for the OptionGroup component used to group options. */
7411
+ /**
7412
+ * Props of {@link OptionGroup}. `aria-label` and `aria-labelledby` go to the group's
7413
+ * `role="group"` list; the other props go to its `<li role="presentation">` item.
7414
+ */
6109
7415
  export declare interface OptionGroupProps extends React_2.LiHTMLAttributes<HTMLLIElement> {
6110
- /** Heading label for the option group (names the group). */
6111
- label: string;
7416
+ /**
7417
+ * The group's heading, which names the group. Keep it text (an icon next to the text is fine): a
7418
+ * label cannot be interactive, since nothing in it is reachable inside a listbox. Without a
7419
+ * label no heading renders; name the group with `aria-label` or `aria-labelledby` then. A group
7420
+ * without a name logs a development warning.
7421
+ */
7422
+ label?: React_2.ReactNode;
7423
+ /**
7424
+ * Names the group's list in place of the label (the heading still shows). A prop that holds
7425
+ * `undefined`, as from a wrapper that forwards it, leaves the label in charge.
7426
+ */
7427
+ 'aria-label'?: string;
7428
+ /**
7429
+ * Ids of the elements that name the group's list, in place of the label (the heading still
7430
+ * shows). A prop that holds `undefined` leaves the label in charge.
7431
+ */
7432
+ 'aria-labelledby'?: string;
6112
7433
  /**
6113
7434
  * Hides the group and every option in it (see `Option`'s `hidden`): keyboard navigation and
6114
7435
  * typeahead skip its options.
@@ -6119,7 +7440,10 @@ export declare interface OptionGroupProps extends React_2.LiHTMLAttributes<HTMLL
6119
7440
  ref?: React_2.Ref<HTMLLIElement>;
6120
7441
  }
6121
7442
 
6122
- /** Properties for the Option component used within Combobox and Dropdown. */
7443
+ /**
7444
+ * Props of {@link Option}, an option of a listbox (Listbox, Combobox, Dropdown or a custom
7445
+ * picker's list).
7446
+ */
6123
7447
  export declare interface OptionProps extends Omit<React_2.LiHTMLAttributes<HTMLLIElement>, 'value'> {
6124
7448
  /** Value associated with this option. Unique within its listbox. */
6125
7449
  value: string;
@@ -6132,11 +7456,25 @@ export declare interface OptionProps extends Omit<React_2.LiHTMLAttributes<HTMLL
6132
7456
  /** Text matched by typeahead and filtering instead of the label. */
6133
7457
  textValue?: string;
6134
7458
  /**
6135
- * Whether the option is disabled: it stays visible but is skipped by keyboard navigation and
6136
- * cannot be selected.
7459
+ * Whether the option is disabled: it stays in the list but can never be selected (a click, Enter
7460
+ * and Space do nothing). Keyboard navigation and typeahead skip it, unless the listbox keeps
7461
+ * disabled options focusable (`disabledOptionsFocusable`), where they reach it. It is drawn in
7462
+ * the muted text colour, its check included: in a multi-select list the checkbox square takes
7463
+ * that colour instead of the brand colour, checked or not.
6137
7464
  * @default false
6138
7465
  */
6139
7466
  disabled?: boolean;
7467
+ /**
7468
+ * Replaces the check glyph that marks the option while it is selected (decorative,
7469
+ * `aria-hidden`); in a multi-select list the glyph is drawn inside the option's 16px checkbox
7470
+ * square. The check is a required indicator, the sign of the selection that does not rely on
7471
+ * colour: `null` and `undefined` keep the default glyph, and so does a value that renders
7472
+ * nothing (`false`, `''`, an empty array), which also logs a development warning. Unlike
7473
+ * `Combobox.expandIcon`, a value that renders nothing does not hide the indicator (Fluent's
7474
+ * `checkIcon={null}` removes it).
7475
+ * @default a check mark
7476
+ */
7477
+ checkIcon?: Slot<'span'>;
6140
7478
  /**
6141
7479
  * Hides the option, like a native `<option hidden>`: it is not shown, keyboard navigation and
6142
7480
  * typeahead skip it, and it never becomes the active option. Its label stays known, so a
@@ -8444,6 +9782,14 @@ export declare interface StackOwnProps {
8444
9782
  */
8445
9783
  export declare type StackProps<C extends React_2.ElementType = 'div'> = PolymorphicProps<C, StackOwnProps>;
8446
9784
 
9785
+ /**
9786
+ * The first day of `date`'s week, at local midnight; the time of day is dropped.
9787
+ *
9788
+ * @param firstDayOfWeek The weekday weeks start on (0 is Sunday).
9789
+ * @default 0
9790
+ */
9791
+ export declare function startOfWeek(date: Date, firstDayOfWeek?: DayOfWeek): Date;
9792
+
8447
9793
  /** Semantic status used for alerts, messages, and status indicators. */
8448
9794
  export declare type Status = 'success' | 'warning' | 'error' | 'info';
8449
9795
 
@@ -8608,37 +9954,87 @@ export declare interface SwatchItem {
8608
9954
  }
8609
9955
 
8610
9956
  /**
8611
- * A single-select grid of color swatches (`role="radiogroup"` of `role="radio"` buttons).
9957
+ * A single-select set of color swatches: a radio group (the default row layout) or a grid of rows
9958
+ * (`layout="grid"`).
8612
9959
  *
8613
- * - **Keyboard** (APG radio group): one tab stop — the selected swatch, else the first. All four
8614
- * arrow keys move focus and select (Left/Right mirrored under `dir="rtl"`), wrapping at the
8615
- * ends; Home/End jump to the first/last swatch.
9960
+ * - **Row layout** (APG radio group, `role="radiogroup"` of `role="radio"` buttons): one tab stop,
9961
+ * the selected swatch, else the first. All four arrow keys move focus and select (Left/Right
9962
+ * mirrored under `dir="rtl"`), wrapping at the ends; Home/End jump to the first/last swatch.
9963
+ * - **Grid layout** (APG grid, `role="grid"` of `SwatchPicker.Row` rows whose cells hold the
9964
+ * swatch buttons, the selected one `aria-selected` and pressed): the arrow keys move focus only.
9965
+ * Left/Right go through the cells in reading order across rows (mirrored under `dir="rtl"`) and
9966
+ * stop at the grid's first and last cell; Up/Down go to the nearest enabled cell of the
9967
+ * previous/next row; Home/End to the first/last cell of the row, Ctrl+Home/End of the grid.
9968
+ * Space, Enter and a click select. One tab stop: the last focused cell, starting at the
9969
+ * selected swatch, else the first. `items`, and every run of children that are not rows, render
9970
+ * in a row of their own; rows do not wrap.
8616
9971
  * - **Selected indicator**: an offset ring in the foreground color (drawn on the page background,
8617
9972
  * not on the swatch) plus a check glyph whose color is picked by the swatch's luminance, so the
8618
9973
  * selection never relies on color alone.
8619
- * - **Naming**: give the group a name with `aria-label`/`aria-labelledby` or render it inside a
9974
+ * - **Naming**: give the picker a name with `aria-label`/`aria-labelledby` or render it inside a
8620
9975
  * `Field`, and give every item a `label`; both are reported in development when missing.
8621
9976
  * - **Forms**: with `name` (or `required`) it takes part in native forms; a form reset restores
8622
- * `defaultValue`.
9977
+ * `defaultValue`. A required grid says so in its description (`labels.required`), since its
9978
+ * role does not allow `aria-required`.
9979
+ * - **Composition**: `items` render as `ColorSwatch` elements before `children`. A `ColorSwatch`,
9980
+ * `ImageSwatch` or `EmptySwatch` rendered directly as a child lets you wrap it, for example in
9981
+ * a `Tooltip` with `relationship="label"` to name and describe it. A swatch rendered outside any
9982
+ * `SwatchPicker` throws in development. React Server Components use the flat `SwatchPickerRow`
9983
+ * name for `SwatchPicker.Row`.
8623
9984
  *
8624
9985
  * @example
8625
9986
  * <SwatchPicker aria-label="Accent color" items={[{ value: 'red', color: '#d13438', label: 'Red' }]} />
9987
+ *
9988
+ * @example
9989
+ * <SwatchPicker layout="grid" aria-label="Accent color">
9990
+ * <SwatchPicker.Row>
9991
+ * <ColorSwatch value="red" color="#d13438" aria-label="Red" />
9992
+ * <ColorSwatch value="blue" color="#0f6cbd" aria-label="Blue" />
9993
+ * </SwatchPicker.Row>
9994
+ * <SwatchPicker.Row>
9995
+ * <ColorSwatch value="green" color="#107c10" aria-label="Green" />
9996
+ * <EmptySwatch onClick={openColorDialog} />
9997
+ * </SwatchPicker.Row>
9998
+ * </SwatchPicker>
8626
9999
  */
8627
10000
  export declare const SwatchPicker: {
8628
- ({ items, value: valueProp, defaultValue, onValueChange, onChange, size, shape, name, required, form, className, id, "aria-label": ariaLabel, "aria-labelledby": ariaLabelledBy, "aria-describedby": ariaDescribedBy, "aria-invalid": ariaInvalid, "aria-required": ariaRequired, onKeyDown, onFocus, ref, ...rest }: SwatchPickerProps): React_2.JSX.Element;
10001
+ ({ items, value: valueProp, defaultValue, onValueChange, onChange, children, layout, focusMode, labels, size, shape, spacing, name, required, form, className, id, "aria-label": ariaLabel, "aria-labelledby": ariaLabelledBy, "aria-describedby": ariaDescribedBy, "aria-invalid": ariaInvalid, "aria-required": ariaRequired, onKeyDown, onFocus, ref, ...rest }: SwatchPickerProps): React_2.JSX.Element;
8629
10002
  displayName: string;
10003
+ } & {
10004
+ Row: {
10005
+ ({ className, ref, ...rest }: SwatchPickerRowProps): React_2.JSX.Element;
10006
+ displayName: string;
10007
+ };
8630
10008
  };
8631
10009
 
8632
- /** SwatchPicker: `root` on the `role="radiogroup"` element; `swatch` on each `role="radio"` button. */
10010
+ /**
10011
+ * SwatchPicker: `root` on the picker element (`role="radiogroup"`, or `role="grid"` in the grid
10012
+ * layout); `swatch` on the button of every swatch in it (`items`, and the `ColorSwatch`,
10013
+ * `ImageSwatch` and `EmptySwatch` children, next to their own classes).
10014
+ */
8633
10015
  export declare const swatchPickerClassNames: {
8634
10016
  readonly root: "wave-swatch-picker";
8635
10017
  readonly swatch: "wave-swatch-picker__swatch";
8636
10018
  };
8637
10019
 
10020
+ /** Built-in strings of the SwatchPicker component (C-NAMING). */
10021
+ export declare interface SwatchPickerLabels {
10022
+ /**
10023
+ * Said where the picker's role cannot carry `aria-required` (the grid layout, and the group of
10024
+ * `focusMode="tab"`): a hidden text
10025
+ * joined into the picker's description while it is required.
10026
+ * @default 'Required'
10027
+ */
10028
+ required?: string;
10029
+ }
10030
+
8638
10031
  /** Properties for the SwatchPicker component. */
8639
10032
  export declare interface SwatchPickerProps extends Omit<React_2.HTMLAttributes<HTMLDivElement>, 'onChange' | 'defaultValue'> {
8640
- /** The swatches to display, in order (a readonly array is accepted; it is never modified). */
8641
- items: readonly SwatchItem[];
10033
+ /**
10034
+ * The swatches to display, in order (a readonly array is accepted; it is never modified):
10035
+ * rendered as `ColorSwatch` elements, before `children`.
10036
+ */
10037
+ items?: readonly SwatchItem[];
8642
10038
  /** Controlled selected swatch value (`''` = nothing selected). */
8643
10039
  value?: string;
8644
10040
  /** Initial selected value for uncontrolled usage (also what a form reset restores).
@@ -8652,11 +10048,46 @@ export declare interface SwatchPickerProps extends Omit<React_2.HTMLAttributes<H
8652
10048
  * @deprecated Use `onValueChange`.
8653
10049
  */
8654
10050
  onChange?: (value: string) => void;
8655
- /** Size of each swatch button (24, 32 or 40px).
10051
+ /**
10052
+ * Swatches rendered directly, in order, after `items` (e.g. `ColorSwatch`): read the picker's
10053
+ * context, so they may be wrapped in a `Tooltip` or another element that forwards its own props.
10054
+ * `SwatchPicker.Row` elements start rows; in the grid layout every run of other children (and
10055
+ * `items`, with the children that follow them) renders in a row of its own. A `SwatchPicker.Row`
10056
+ * must be a direct child or inside a Fragment: a wrapper component around a Row lands in an
10057
+ * implicit row, and nested rows are reported in development.
10058
+ */
10059
+ children?: React_2.ReactNode;
10060
+ /**
10061
+ * `'row'`: a radio group whose arrow keys select (and wrap). `'grid'`: rows of cells
10062
+ * (`SwatchPicker.Row`) whose arrow keys move focus in two dimensions without selecting; Space,
10063
+ * Enter and a click select. Changing it while mounted remounts the swatches, so focus falls
10064
+ * back to the page.
10065
+ * @default 'row'
10066
+ */
10067
+ layout?: 'row' | 'grid';
10068
+ /**
10069
+ * `'arrow'`: one tab stop and arrow keys, with the radio group (row layout) or grid (grid
10070
+ * layout) semantics. `'tab'`: every enabled swatch is its own tab stop and the arrow keys do
10071
+ * nothing, so the picker is a `role="group"` of toggle buttons (`aria-pressed`, the selected
10072
+ * one pressed) in both layouts; rows have no role, and Space, Enter and a click select
10073
+ * (pressing the selected swatch again keeps it selected). The required hint (`labels.required`)
10074
+ * applies, as the group cannot carry `aria-required`.
10075
+ * @default 'arrow'
10076
+ */
10077
+ focusMode?: 'arrow' | 'tab';
10078
+ /** Built-in strings, for localization. */
10079
+ labels?: SwatchPickerLabels;
10080
+ /** Size of each swatch button (20, 24, 32 or 40px). A 20px swatch passes the target-size bar
10081
+ * through its spacing; a swatch's own `size` overrides this.
8656
10082
  * @default 'medium'
8657
10083
  */
8658
10084
  size?: SwatchPickerSize;
8659
- /** Shape of each swatch button.
10085
+ /** Gap between swatches (and between rows): 4px or 8px. At `'small'` the focus outline's offset shrinks from 4px to
10086
+ * 2px, so it does not cover the neighbour.
10087
+ * @default 'medium'
10088
+ */
10089
+ spacing?: 'small' | 'medium';
10090
+ /** Shape of each swatch button (a swatch's own `shape` overrides this).
8660
10091
  * @default 'circular'
8661
10092
  */
8662
10093
  shape?: Shape;
@@ -8665,16 +10096,61 @@ export declare interface SwatchPickerProps extends Omit<React_2.HTMLAttributes<H
8665
10096
  * (nothing while no swatch is selected).
8666
10097
  */
8667
10098
  name?: string;
8668
- /** A swatch must be selected before the form can be submitted (native validation). */
10099
+ /**
10100
+ * A swatch must be selected before the form can be submitted (native validation). The row
10101
+ * layout says so with `aria-required`; the grid layout and tab mode, whose roles do not allow
10102
+ * it, with the hidden `labels.required` text in the description (which a consumer
10103
+ * `aria-required` alone also shows).
10104
+ */
8669
10105
  required?: boolean;
8670
10106
  /** Id of the form the picker belongs to, when it is rendered outside that form. */
8671
10107
  form?: string;
8672
- /** Ref to the `role="radiogroup"` element. */
10108
+ /**
10109
+ * Ref to the root element: `role="radiogroup"`, `role="grid"` in the grid layout, or
10110
+ * `role="group"` in tab mode.
10111
+ */
10112
+ ref?: React_2.Ref<HTMLDivElement>;
10113
+ }
10114
+
10115
+ /**
10116
+ * One row of swatches in a `SwatchPicker` (also exported as the flat `SwatchPickerRow`, for React
10117
+ * Server Components). In the grid layout it is a `role="row"` element whose swatches are its
10118
+ * cells; Up and Down move between rows, and the row does not wrap (a wrapped swatch would sit
10119
+ * where Up and Down do not reach it): size it yourself. In the row layout and in tab mode
10120
+ * (`focusMode="tab"`) it is a full-width line without a role, and its swatches stay radios of the
10121
+ * one group (row layout) or toggle buttons. Place it as a direct child of the `SwatchPicker` or
10122
+ * inside a Fragment: a wrapper component around a Row lands in an implicit row, and a Row inside
10123
+ * a Row is reported in development. Outside a `SwatchPicker` it throws in development.
10124
+ *
10125
+ * @example
10126
+ * <SwatchPicker layout="grid" aria-label="Accent color">
10127
+ * <SwatchPicker.Row>
10128
+ * <ColorSwatch value="red" color="#d13438" aria-label="Red" />
10129
+ * <ColorSwatch value="blue" color="#0f6cbd" aria-label="Blue" />
10130
+ * </SwatchPicker.Row>
10131
+ * </SwatchPicker>
10132
+ */
10133
+ export declare const SwatchPickerRow: {
10134
+ ({ className, ref, ...rest }: SwatchPickerRowProps): React_2.JSX.Element;
10135
+ displayName: string;
10136
+ };
10137
+
10138
+ /**
10139
+ * SwatchPicker.Row: `root` on the row element (`role="row"` in the grid layout), also on the rows
10140
+ * the picker adds around `items` and loose swatches.
10141
+ */
10142
+ export declare const swatchPickerRowClassNames: {
10143
+ readonly root: "wave-swatch-picker-row";
10144
+ };
10145
+
10146
+ /** Properties for the SwatchPicker.Row component. */
10147
+ export declare interface SwatchPickerRowProps extends React_2.HTMLAttributes<HTMLDivElement> {
10148
+ /** Ref to the row element. */
8673
10149
  ref?: React_2.Ref<HTMLDivElement>;
8674
10150
  }
8675
10151
 
8676
- /** Size of the swatches. */
8677
- export declare type SwatchPickerSize = Extract<Size, 'small' | 'medium' | 'large'>;
10152
+ /** Size of the swatches: 20, 24, 32 or 40px. */
10153
+ export declare type SwatchPickerSize = Extract<Size, 'extra-small' | 'small' | 'medium' | 'large'>;
8678
10154
 
8679
10155
  /**
8680
10156
  * An on/off toggle drawn as a `role="switch"` button inside a `<label>`.
@@ -9257,7 +10733,10 @@ export declare interface TagOwnProps {
9257
10733
  * surrounding form), Escape closes the list (and then clears the typed text). Backspace in the
9258
10734
  * empty input moves focus to the last tag; Backspace or Delete there removes it. Additions and
9259
10735
  * removals are announced ("Cherry removed, 2 selected"), and so is "No matches" for text that
9260
- * matches no option.
10736
+ * matches no option. `filter` replaces the match (it may keep options that do not contain the
10737
+ * text, for a server-side search or a "Create …" entry), and `query`/`defaultQuery`/
10738
+ * `onQueryChange` control the typed text, which resets to `''` when a tag is added, on Escape and
10739
+ * on a form reset, and stays on a blur.
9261
10740
  *
9262
10741
  * The tags form a list named "Selected"; the input is described by a summary of the selected
9263
10742
  * labels ("Selected: Apple, Banana"). These built-in texts are English; `labels` localizes them.
@@ -9384,6 +10863,36 @@ export declare interface TagPickerProps extends Omit<React_2.HTMLAttributes<HTML
9384
10863
  * @default 'Select...'
9385
10864
  */
9386
10865
  placeholder?: string;
10866
+ /**
10867
+ * Whether an option matches the typed text (the query). Called with every listed option (its
10868
+ * `value` and `label`; selected options are not listed) and the text whenever the text is not
10869
+ * empty; an option it returns `false` for is filtered out. It may keep options that do not
10870
+ * contain the text: `filter={() => true}` with `query` and `onQueryChange` leaves the matching
10871
+ * to you (a server-side search that replaces `options`), and a filter that always keeps an
10872
+ * option of your own gives a "Create …" entry. With a server-side search, keep the selected
10873
+ * options in `options` (they are never listed): a selected value without an option shows its raw
10874
+ * value as the tag label, with a development warning (the "Async search" story does this).
10875
+ * @default a case-insensitive substring match on the option's `label`
10876
+ */
10877
+ filter?: (option: ListboxItem, query: string) => boolean;
10878
+ /**
10879
+ * Controlled query: the text typed since the last tag was added, which filters the options and
10880
+ * shows in the input (hidden while `disabled` or `readOnly`).
10881
+ */
10882
+ query?: string;
10883
+ /**
10884
+ * Initial query for uncontrolled usage. A TagPicker that starts disabled or read-only starts
10885
+ * without it (as it starts closed).
10886
+ * @default ''
10887
+ */
10888
+ defaultQuery?: string;
10889
+ /**
10890
+ * Called with the new query when it changes: as the user types, and with `''` when it resets (a
10891
+ * tag added, Escape on the closed list, a form reset, or `disabled` or `readOnly` turned on
10892
+ * while text is typed). A blur or a close keeps the text. A TagPicker that mounts disabled or
10893
+ * read-only reports nothing: it keeps a controlled query, which shows once it unlocks.
10894
+ */
10895
+ onQueryChange?: (query: string) => void;
9387
10896
  /**
9388
10897
  * Whether the tag picker is disabled: nothing can be added or removed, and the remove buttons
9389
10898
  * leave the tab order.
@@ -11172,6 +12681,94 @@ export declare interface TreeProps extends React_2.HTMLAttributes<HTMLDivElement
11172
12681
  /** Typography scale variant mapping to Fluent UI type ramp tokens. */
11173
12682
  export declare type TypographyVariant = 'caption-2' | 'caption-1' | 'body-1' | 'body-2' | 'subtitle-2' | 'subtitle-1' | 'title-3' | 'title-2' | 'title-1' | 'large-title' | 'display';
11174
12683
 
12684
+ /**
12685
+ * The active (virtually focused) item of a composite that keeps DOM focus on one element and points
12686
+ * `aria-activedescendant` at the active item: a combobox, a listbox that holds focus, a command
12687
+ * palette. The state is React state, so the active id is derived during render (server HTML
12688
+ * included) and nothing reads the DOM during render.
12689
+ *
12690
+ * - The moved-to item is dropped when it leaves `items` or while `enabled` is `false`, and does not
12691
+ * come back without a user action; `fallback` is active while nothing was moved to.
12692
+ * - Keyboard and programmatic moves are scrolled into view (`{ block: 'nearest' }`); pointer moves
12693
+ * (`highlight`) and `setActiveValue(value, { scroll: false })` are not.
12694
+ * - `onActiveValueChange` reports every change after the commit, once (StrictMode included).
12695
+ *
12696
+ * `useListbox` is built on it; use it directly for composites that are not listboxes.
12697
+ *
12698
+ * @example
12699
+ * const ad = useActiveDescendant({ items: results.map((r) => r.id), getId: (id) => `cmd-${id}`, enabled: open });
12700
+ * <input aria-activedescendant={ad.activeDescendantId} onKeyDown={(e) => { if (e.key === 'ArrowDown') ad.next(); }} />
12701
+ */
12702
+ export declare function useActiveDescendant(options: UseActiveDescendantOptions): UseActiveDescendantResult;
12703
+
12704
+ /** Options of {@link useActiveDescendant}. */
12705
+ export declare interface UseActiveDescendantOptions {
12706
+ /** The values that can become active, in navigation order. */
12707
+ items: readonly string[];
12708
+ /** The DOM id of an item's element: the `aria-activedescendant` target. */
12709
+ getId: (value: string) => string;
12710
+ /**
12711
+ * While `false`, no item is active and the moved-to item is forgotten (a closed popup, an
12712
+ * unfocused list). A move made in the same update that enables the hook is kept.
12713
+ * @default true
12714
+ */
12715
+ enabled?: boolean;
12716
+ /**
12717
+ * The active item while none was moved to, or after the moved-to item left `items` (the
12718
+ * selected option, for example). Ignored when it is not in `items`.
12719
+ * @default null
12720
+ */
12721
+ fallback?: string | null;
12722
+ /** `next()` and `prev()` wrap at the ends. @default false */
12723
+ loop?: boolean;
12724
+ /**
12725
+ * Whenever `items` changes while the hook is enabled (compared by content), its first item
12726
+ * becomes active — also when the change comes with enabling (the keystroke that opens a
12727
+ * filtered list). Enabling with unchanged items keeps the fallback. It wins over a move made in
12728
+ * the same update.
12729
+ * @default false
12730
+ */
12731
+ activateFirstOnChange?: boolean;
12732
+ /** The element of an item, for scrolling it into view. @default document.getElementById(getId(value)) */
12733
+ getElement?: (value: string) => HTMLElement | null;
12734
+ /** Called after the active item changed (from an effect), `null` included. */
12735
+ onActiveValueChange?: (value: string | null) => void;
12736
+ }
12737
+
12738
+ /** Result of {@link useActiveDescendant}. The methods have stable identities. */
12739
+ export declare interface UseActiveDescendantResult {
12740
+ /** The moved-to item, else the fallback; `null` while disabled. Derived during render. */
12741
+ activeValue: string | null;
12742
+ /** `getId(activeValue)`, or `undefined`: spread as `aria-activedescendant`. */
12743
+ activeDescendantId: string | undefined;
12744
+ /**
12745
+ * Moves to `value`, or back to the fallback with `null`. The value is kept as it is; the next
12746
+ * render drops it when it is not in that render's `items` or the hook is disabled, clearing any
12747
+ * earlier move. Scrolled into view unless `scroll` is `false`.
12748
+ */
12749
+ setActiveValue: (value: string | null, options?: {
12750
+ scroll?: boolean;
12751
+ }) => void;
12752
+ /**
12753
+ * Moves to `value` for pointer movement, not scrolled into view; ignored while disabled, when
12754
+ * `value` is not in `items` or is already active.
12755
+ */
12756
+ highlight: (value: string) => void;
12757
+ /** Moves to the first item. */
12758
+ first: () => void;
12759
+ /** Moves to the last item. */
12760
+ last: () => void;
12761
+ /** The item after the active one (the first when none is active); wraps with `loop`. */
12762
+ next: () => void;
12763
+ /** The item before the active one (the last when none is active); wraps with `loop`. */
12764
+ prev: () => void;
12765
+ /**
12766
+ * Moves `delta` items (PageDown: `move(10)`), clamped at the ends, never wrapping; from no active
12767
+ * item, a positive delta goes to the first item and a negative one to the last.
12768
+ */
12769
+ move: (delta: number) => void;
12770
+ }
12771
+
11175
12772
  /**
11176
12773
  * Returns {@link announce} and keeps the shared live regions alive while the caller is mounted
11177
12774
  * (they are created on mount and removed when the last caller unmounts).
@@ -11345,6 +12942,401 @@ export declare function useIsOverflowing(target: React_2.RefObject<HTMLElement |
11345
12942
  */
11346
12943
  export declare function useIsOverflowItemVisible(itemId: string): boolean;
11347
12944
 
12945
+ /**
12946
+ * The listbox behaviour of Listbox, Combobox, Dropdown, TagPicker and TimePicker, and the base of a
12947
+ * custom picker: one navigable option list drives the highlight, `aria-activedescendant` and the
12948
+ * commit, so the highlighted option is always the one Enter selects. The highlight is
12949
+ * {@link useActiveDescendant}'s.
12950
+ *
12951
+ * - **Items.** Data mode (`items`) or registration mode: `Option`s, or option components of your
12952
+ * own on {@link useListboxOption}, register inside the listbox's context (`context`, which
12953
+ * `ListboxSurface` and `ListboxProvider` provide) in DOM order, `OptionGroup`s included. The
12954
+ * registrations of one commit are published once from this hook's layout effect (which runs
12955
+ * after the options'); later additions/removals are published once per microtask. A keyed
12956
+ * reorder of the same options re-sorts them: the DOM order is re-checked after a commit of this
12957
+ * hook's component that moved option elements (a highlight move moves none, so it costs O(1))
12958
+ * and, while it is mounted, whenever option elements move (a `MutationObserver` on their
12959
+ * common ancestor) — so memoized options or hoisted elements that a wrapper component inside
12960
+ * the listbox reorders are re-sorted too, although neither the options nor this component
12961
+ * render. Options register even when filtered out or hidden (they render `hidden` and are not
12962
+ * navigable), so labels are always known — use {@link collectOptionLabels} for the display text
12963
+ * before registration (SSR/first render). `filter` is the navigability predicate, which a
12964
+ * picker builds from its query.
12965
+ * - **Active option** is derived during render: the highlighted value, else the `autoHighlight`
12966
+ * fallback. The highlight is reset on close and after a single-select commit that closes the
12967
+ * listbox, and dropped once it is not navigable any more (filtered out, hidden, removed by an
12968
+ * update, or disabled without `disabledOptionsFocusable`), so it does not come back without a
12969
+ * user action when the option returns. With
12970
+ * `highlightOnFilter` the first option becomes active whenever the options change while open
12971
+ * (`useActiveDescendant`'s `activateFirstOnChange`). Editable: a text-editing key (printable
12972
+ * characters, Backspace/Delete, cut/paste/undo/redo) clears the highlight — visual focus
12973
+ * returns to the textbox (APG) — so Enter after typing never commits an option highlighted
12974
+ * before the edit; with `highlightOnFilter` the key makes the first option active instead.
12975
+ * - **Ids** `${listboxId}-opt-${n}` are stable per value (across filtering and remounts between
12976
+ * an inline closed list and a portaled open list).
12977
+ * - **Store.** Options read their active/selected/hidden flags through a store, so moving the
12978
+ * highlight re-renders only the old and the new option.
12979
+ * - **Keys (APG).** Editable: ArrowDown/ArrowUp open (selected, else first/last) and move;
12980
+ * Alt+ArrowDown opens without moving; Alt+ArrowUp closes; Enter commits the active option (with
12981
+ * the listbox closed Enter is not prevented, so forms submit); Escape closes (closed + text:
12982
+ * `onClearDraft`); Tab closes; Home/End/printable keys stay with the input (text-editing keys
12983
+ * clear the highlight, see above). Select-only:
12984
+ * ArrowDown/ArrowUp/Home/End/typeahead open and position (a closed typeahead starts from the
12985
+ * selected option; characters typed with AltGr, i.e. Ctrl+Alt on Windows, count); PageUp/PageDown
12986
+ * jump 10; Enter/Space open or commit (always prevented on keydown, Space also on keyup, so a
12987
+ * `<button>` combobox is not clicked again; a Space typed within 500 ms of a typeahead character
12988
+ * continues the search instead); Alt+ArrowUp and Tab commit and close in single-select mode
12989
+ * (with `multiselect` they only close; Tab is not prevented); Escape closes. Standalone (the
12990
+ * list has focus; nothing opens or closes): ArrowDown/ArrowUp move (from no active option to
12991
+ * the first/last), Home/End, PageUp/PageDown (10) and typeahead move; Enter and Space commit
12992
+ * and keep the committed option active (a Space typed within 500 ms of a typeahead character
12993
+ * continues the search instead); Tab, Escape and Alt+Arrow keys are not handled and not
12994
+ * prevented, so the page and enclosing layers get them.
12995
+ * "Selected" means the first selected navigable option in list order. Disabled options are
12996
+ * skipped unless `disabledOptionsFocusable`, and never committed; hidden options are not
12997
+ * navigable at all.
12998
+ * - The active option is scrolled into view (`{ block: 'nearest' }`) in a layout effect, except
12999
+ * after a pointer highlight or a pointer press (the list would scroll under the pointer).
13000
+ *
13001
+ * **Consumer contract** (Listbox, Combobox, Dropdown, TagPicker, TimePicker and custom pickers):
13002
+ * - All options of a listbox live in a single container at a time (inline only while closed,
13003
+ * portaled only while open — never both, not even for an exit animation; `ListboxSurface` does
13004
+ * this). Options split over two containers are watched from `<body>` and registered twice
13005
+ * (development warns).
13006
+ * - Spread `getComboboxProps()` onto the combobox element and attach **both** `onKeyDown` and
13007
+ * `onKeyUp` to it (compose them with your own handlers). `onKeyUp` is required for a
13008
+ * `<button>` combobox (select-only): without it the button's native click on Space keyup
13009
+ * toggles the listbox again after a keydown commit.
13010
+ * - Registration mode: mark option and group components of your own with
13011
+ * {@link markListboxElement} (`Option` and `OptionGroup` are marked; memo components can be
13012
+ * marked too). {@link collectOptionLabels} walks only marked components, so without the marks
13013
+ * the server render and the first client render have no display text.
13014
+ * - Display text: `getItem(value)?.label ?? collectOptionLabels(children).get(value)` (`?? value`
13015
+ * for freeform input only). Editable pickers pass `onClearDraft` for Escape on a closed list.
13016
+ * - A popup list renders in `ListboxSurface`, placed and dismissed by `useListboxPopup`; a list
13017
+ * rendered without it gets the options' context from `ListboxProvider`.
13018
+ * - Standalone mode (a listbox that holds focus): spread `getListboxProps()` onto the list and
13019
+ * merge its `ref` with yours (a pointer press on an option focuses the list through it), attach
13020
+ * `onKeyDown` to the list and pass the list's focus state as `open`. `getComboboxProps()` is not
13021
+ * used.
13022
+ */
13023
+ export declare function useListbox(options: UseListboxOptions): UseListboxResult;
13024
+
13025
+ /**
13026
+ * An option of the surrounding listbox, for option components of your own: the listbox's context
13027
+ * comes from `ListboxSurface` or `ListboxProvider` ({@link UseListboxResult.context}). Registers
13028
+ * the option (registration mode) and its element, and reads its flags from the listbox store, so
13029
+ * it re-renders only when its own active/selected/hidden state changes. Spread `optionProps` onto
13030
+ * the `<li>` (`id`, `role="option"`, `aria-selected`, `aria-disabled`, `hidden`, and
13031
+ * `data-active`/`data-selected`/`data-disabled` for styling) and compose its `onClick` — and in
13032
+ * standalone mode its `onMouseDown`, the pointer press — with your own handlers. Mark the
13033
+ * component with {@link markListboxElement}, so its label is known before it registers.
13034
+ *
13035
+ * Throws in development when used outside a listbox; in production it logs the error once and
13036
+ * renders an inert option.
13037
+ *
13038
+ * @typeParam E The option element type (`HTMLLIElement` for an `<li>`), so `ref` needs no cast.
13039
+ */
13040
+ export declare function useListboxOption<E extends HTMLElement = HTMLElement>(props: UseListboxOptionProps, ref?: React_2.Ref<E>): UseListboxOptionResult<E>;
13041
+
13042
+ /**
13043
+ * Props of {@link useListboxOption}. The option's position in the listbox follows its element's
13044
+ * DOM position, also when the option is memoized and only moved (see {@link useListbox}).
13045
+ */
13046
+ export declare interface UseListboxOptionProps {
13047
+ /** The option's value, unique within the listbox. */
13048
+ value: string;
13049
+ /**
13050
+ * Display label; falls back to `textValue`, then the element's text content, then `value`. The
13051
+ * text content is re-read after every render of the option. Text that a child component changes
13052
+ * from its own state (without the option re-rendering) is not seen; pass `label` or `textValue`
13053
+ * for such options.
13054
+ */
13055
+ label?: string;
13056
+ /** Text matched by typeahead and filters instead of the label. */
13057
+ textValue?: string;
13058
+ /**
13059
+ * The option can never be committed; the keys skip it unless the listbox has
13060
+ * {@link UseListboxOptions.disabledOptionsFocusable}.
13061
+ * @default false
13062
+ */
13063
+ disabled?: boolean;
13064
+ /**
13065
+ * The option is hidden (its own `hidden` attribute, or a hidden group around it): it registers
13066
+ * as a hidden item ({@link ListboxItem.hidden}), so it is not navigable, and
13067
+ * `optionProps.hidden` is set from the first render (server included).
13068
+ * @default false
13069
+ */
13070
+ hidden?: boolean;
13071
+ }
13072
+
13073
+ /** Result of {@link useListboxOption}. */
13074
+ export declare interface UseListboxOptionResult<E extends HTMLElement = HTMLElement> {
13075
+ /** The option's stable id. */
13076
+ id: string;
13077
+ /** Whether the option is selected. */
13078
+ selected: boolean;
13079
+ /** Whether the option is active (keyboard or pointer highlight). */
13080
+ active: boolean;
13081
+ /** Whether the option is disabled. */
13082
+ disabled: boolean;
13083
+ /** Filtered out, or hidden by its own props ({@link UseListboxOptionProps.hidden}). */
13084
+ hidden: boolean;
13085
+ /** Whether the surrounding listbox is {@link UseListboxOptions.multiselect}. */
13086
+ multiselect: boolean;
13087
+ /** Spread onto the option element (see {@link ListboxOptionElementProps}). */
13088
+ optionProps: ListboxOptionElementProps<E>;
13089
+ }
13090
+
13091
+ /** Options of {@link useListbox}. */
13092
+ export declare interface UseListboxOptions {
13093
+ /**
13094
+ * Whether the listbox is shown. You own the open state: `onOpenChange` asks you to change it.
13095
+ * Standalone mode: whether the list has focus — an option is active only while it does.
13096
+ */
13097
+ open: boolean;
13098
+ /**
13099
+ * Called when a key (or a commit) wants to open or close the listbox. `details.reason` says why
13100
+ * (`'keyboard'`, `'select'` — a commit that closes the list —, `'escape'` or `'tab'`) and
13101
+ * `details.event` is the key or click event behind it. WaveUI always passes `details`; it is
13102
+ * typed optional until 1.0 so that code which calls this prop itself keeps compiling. Never
13103
+ * called in standalone mode.
13104
+ */
13105
+ onOpenChange?: (open: boolean, details?: OpenChangeDetails<ListboxOpenChangeReason>) => void;
13106
+ /**
13107
+ * `'editable'`: a text input combobox (Combobox, TagPicker, TimePicker).
13108
+ * `'select-only'`: a button/div combobox without text entry (Dropdown).
13109
+ * `'standalone'`: a listbox that holds focus itself (Listbox), with nothing to open or close:
13110
+ * `open` is its focus state, the keys move and commit (a commit keeps the committed option
13111
+ * active), Tab, Escape and Alt+Arrow keys are left to the page, `onOpenChange` is never called,
13112
+ * and a pointer press on an option focuses the list and activates the option without scrolling
13113
+ * (see {@link UseListboxResult.getListboxProps}).
13114
+ */
13115
+ mode: 'editable' | 'select-only' | 'standalone';
13116
+ /**
13117
+ * Several values can be selected: the list gets `aria-multiselectable`, and a commit keeps the
13118
+ * listbox open on the committed option (your `onSelect` adds or removes the value).
13119
+ * @default false
13120
+ */
13121
+ multiselect?: boolean;
13122
+ /** The selected values (`[]` when nothing is selected). */
13123
+ selectedValues: readonly string[];
13124
+ /**
13125
+ * Called when an option is committed: click, Enter/Space, and in single-select select-only mode
13126
+ * also Tab and Alt+ArrowUp (with `multiselect` they close without committing). `details.item` is
13127
+ * the committed option and `details.event` the key or click event behind the commit. WaveUI
13128
+ * always passes `details`; it is typed optional until 1.0 so that code which calls this prop
13129
+ * itself keeps compiling.
13130
+ */
13131
+ onSelect: (value: string, details?: ListboxSelectDetails) => void;
13132
+ /**
13133
+ * Data mode: the options, in list order. Omit it for registration mode, where the options
13134
+ * register themselves in DOM order: `Option`s, or option components of your own on
13135
+ * {@link useListboxOption}, rendered inside the listbox's context
13136
+ * ({@link UseListboxResult.context}, which `ListboxSurface` and `ListboxProvider` provide).
13137
+ */
13138
+ items?: readonly ListboxItem[];
13139
+ /**
13140
+ * The navigability predicate: an item it returns `false` for is filtered out — left out of the
13141
+ * keys, typeahead and {@link UseListboxResult.items}, never active, and rendered `hidden` as a
13142
+ * registered option (its label stays known). It is never called for a hidden item, which stays
13143
+ * out anyway. A picker builds it from its query, the text typed so far: by default, Combobox
13144
+ * keeps the options whose `textValue ?? label` contains it, ignoring case, and a component with
13145
+ * a `filter(option, query)` prop builds this predicate by binding its current query to it.
13146
+ * Without it, every item that is not hidden is navigable.
13147
+ */
13148
+ filter?: (item: ListboxItem) => boolean;
13149
+ /** Arrow keys wrap around at the ends. @default false */
13150
+ loop?: boolean;
13151
+ /**
13152
+ * Printable characters move to the matching option (on by default in select-only and standalone
13153
+ * mode).
13154
+ * @default mode !== 'editable'
13155
+ */
13156
+ typeahead?: boolean;
13157
+ /**
13158
+ * Keeps disabled options in the arrow-key, Home/End, PageUp/PageDown and typeahead order: they
13159
+ * still cannot be committed (Enter, Space and a click do nothing and the list stays open), and
13160
+ * while one is active, Tab and Alt+ArrowUp in single-select select-only mode close the listbox
13161
+ * without a commit. The `autoHighlight` fallback may then be a disabled option too.
13162
+ * @default false
13163
+ */
13164
+ disabledOptionsFocusable?: boolean;
13165
+ /**
13166
+ * The option that is active while no option is highlighted: `'selected'` — the first selected
13167
+ * navigable option in list order (not in `selectedValues` order), else the first option;
13168
+ * `'first'` — the first option; `false` — none. A highlighted option that leaves the navigable
13169
+ * set is dropped (the fallback takes over, also when the option returns); in editable mode a
13170
+ * text-editing key clears the highlight.
13171
+ * @default 'selected'
13172
+ */
13173
+ autoHighlight?: 'selected' | 'first' | false;
13174
+ /**
13175
+ * Whenever the options the keys reach (the navigable ones, the disabled ones only with
13176
+ * `disabledOptionsFocusable`) change while open, compared by content — as when typing filters
13177
+ * them — the first of them becomes active, also when the update that opens the listbox changes
13178
+ * them (compared with those before opening, as the keystroke that opens a filtered list does).
13179
+ * Opening with unchanged options keeps the `autoHighlight` start. It sets
13180
+ * {@link useActiveDescendant}'s `activateFirstOnChange`. In editable mode every text-editing key
13181
+ * while open makes the first option active as well, also when the options stay the same.
13182
+ * @default false
13183
+ */
13184
+ highlightOnFilter?: boolean;
13185
+ /**
13186
+ * Called after the active (highlighted) option changes — arrow keys, typeahead, the pointer, a
13187
+ * filter change, opening — and with `null` when the listbox closes. Passed straight through to
13188
+ * {@link useActiveDescendant}'s `onActiveValueChange`.
13189
+ */
13190
+ onActiveValueChange?: (value: string | null) => void;
13191
+ /** Prefix of the generated listbox id. @default 'listbox' */
13192
+ idPrefix?: string;
13193
+ /**
13194
+ * Editable: Escape with the listbox closed and text in the input calls this (and prevents the
13195
+ * default), so you can clear the typed text. Not handled when omitted.
13196
+ */
13197
+ onClearDraft?: () => void;
13198
+ }
13199
+
13200
+ /**
13201
+ * Dismissal and positioning of a custom picker's listbox popup, for {@link ListboxSurface}. The
13202
+ * popup is dismissed by Escape, by a press outside your picker and its surface, and by focus
13203
+ * leaving them (`onDismiss` says which). The surface opens below the anchor and as wide as it,
13204
+ * flips above it when there is no room below, and is limited to the space available; its
13205
+ * `data-side` and `data-align` attributes give the final placement.
13206
+ *
13207
+ * While the listbox is open with nothing to show (`surfaceOpen` is `false`), Escape is left to an
13208
+ * enclosing layer, such as a Dialog around the picker. Let your combobox's key handler leave it
13209
+ * too: on such an Escape, set your open state to `false` without calling `listbox.onKeyDown`,
13210
+ * which handles Escape (and prevents its default) whenever the listbox is open. Do so only when
13211
+ * `!event.nativeEvent.isComposing`, as Dropdown, Combobox and TagPicker do: an Escape that only
13212
+ * cancels an IME composition must not close the listbox, and `listbox.onKeyDown` ignores such
13213
+ * keys too.
13214
+ *
13215
+ * @example
13216
+ * const expanded = open && listbox.items.length > 0;
13217
+ * const { layerId, setReference, surfaceRef, floatingProps } = useListboxPopup({
13218
+ * open,
13219
+ * surfaceOpen: expanded,
13220
+ * onDismiss: () => setOpen(false),
13221
+ * rootRef,
13222
+ * anchorRef: buttonRef,
13223
+ * });
13224
+ * const buttonMergedRef = useMergedRefs(buttonRef, setReference);
13225
+ */
13226
+ export declare function useListboxPopup(options: UseListboxPopupOptions): UseListboxPopupResult;
13227
+
13228
+ /** Options of {@link useListboxPopup}. */
13229
+ export declare interface UseListboxPopupOptions {
13230
+ /**
13231
+ * The listbox is open (your open state). While it is, a press outside your picker and its
13232
+ * surface, and focus leaving them, dismiss it.
13233
+ */
13234
+ open: boolean;
13235
+ /**
13236
+ * The surface is shown (the list, or the empty content of {@link ListboxSurface}): it is
13237
+ * positioned, and Escape dismisses it. While the listbox is open with nothing shown (no options
13238
+ * to show), Escape is left to an enclosing layer, such as a Dialog around the picker.
13239
+ */
13240
+ surfaceOpen: boolean;
13241
+ /**
13242
+ * Called when the popup should close: set your open state to `false`. `reason` is `'escape'`,
13243
+ * `'outside-press'` or `'focus-outside'`.
13244
+ */
13245
+ onDismiss: (reason: DismissReason) => void;
13246
+ /** Your picker's root element: presses and focus inside it are not outside the popup. */
13247
+ rootRef: React_2.RefObject<HTMLElement | null>;
13248
+ /**
13249
+ * The combobox element, which anchors the popup's dismiss layer. Pass the element to
13250
+ * `setReference` too (merged into its ref), which places the surface against it.
13251
+ */
13252
+ anchorRef: React_2.RefObject<HTMLElement | null>;
13253
+ }
13254
+
13255
+ /**
13256
+ * Result of {@link useListboxPopup}. Destructure it: `eslint-plugin-react-hooks` treats an object
13257
+ * with a member passed to a `ref` prop as a ref, and rejects reading its other members during
13258
+ * render (`react-hooks/refs`).
13259
+ */
13260
+ export declare interface UseListboxPopupResult {
13261
+ /** The popup's dismiss layer: pass it to {@link ListboxSurface}. */
13262
+ layerId: string;
13263
+ /**
13264
+ * Ref callback for the element the surface is placed against: merge it into your combobox's ref.
13265
+ */
13266
+ setReference: (el: HTMLElement | null) => void;
13267
+ /** Ref callback for the surface: pass it to {@link ListboxSurface}. */
13268
+ surfaceRef: React_2.RefCallback<HTMLElement>;
13269
+ /** The surface's `data-side`, `data-align` and position style: pass them to {@link ListboxSurface}. */
13270
+ floatingProps: {
13271
+ 'data-side': string;
13272
+ 'data-align': string;
13273
+ style: React_2.CSSProperties;
13274
+ };
13275
+ }
13276
+
13277
+ /** Result of {@link useListbox}. */
13278
+ export declare interface UseListboxResult {
13279
+ /** Id of the listbox element. */
13280
+ listboxId: string;
13281
+ /**
13282
+ * The active (highlighted) option, derived during render; `null` while closed (in standalone
13283
+ * mode, while the list does not have focus).
13284
+ */
13285
+ activeValue: string | null;
13286
+ /** `getOptionId(activeValue)` while open and an option is active. */
13287
+ activeDescendantId: string | undefined;
13288
+ /**
13289
+ * The navigable items in DOM/data order: without filtered-out and hidden items; disabled ones
13290
+ * are included (navigation skips them, unless
13291
+ * {@link UseListboxOptions.disabledOptionsFocusable}).
13292
+ */
13293
+ items: ListboxItem[];
13294
+ /** Unfiltered lookup (registered options or `items`), e.g. for the selected option's label. */
13295
+ getItem(value: string): ListboxItem | undefined;
13296
+ /** `${listboxId}-opt-${n}`; `n` is assigned the first time a value is seen and never changes. */
13297
+ getOptionId(value: string): string;
13298
+ /**
13299
+ * Highlights `value` while open, scrolled into view like a keyboard highlight; `null` returns the
13300
+ * highlight to the `autoHighlight` option. The value is checked in the next render: if it is not
13301
+ * navigable then (disabled options count as not navigable unless
13302
+ * {@link UseListboxOptions.disabledOptionsFocusable}), it is dropped like `null`, and the
13303
+ * highlight returns to the `autoHighlight` option, or to none. A kept value is dropped when it
13304
+ * leaves the navigable set later. A value set while closed survives only when the same update
13305
+ * opens the listbox.
13306
+ */
13307
+ setActiveValue(value: string | null): void;
13308
+ /**
13309
+ * Attach to the combobox element (to the list in standalone mode). Ignores key events a handler
13310
+ * of yours already prevented (compose yours first).
13311
+ */
13312
+ onKeyDown(event: React_2.KeyboardEvent): void;
13313
+ /**
13314
+ * Attach to the combobox element next to `onKeyDown`. Required for a `<button>` combobox
13315
+ * (select-only): it prevents the Space keyup, so the native click does not toggle the listbox
13316
+ * again after the keydown opened or committed.
13317
+ */
13318
+ onKeyUp(event: React_2.KeyboardEvent): void;
13319
+ /**
13320
+ * Props for the combobox element (spread them): its role, `aria-expanded`, `aria-controls`,
13321
+ * `aria-haspopup`, `aria-activedescendant` while an option is active and, in editable mode,
13322
+ * `aria-autocomplete`. Not used in standalone mode, where the list itself has focus.
13323
+ */
13324
+ getComboboxProps(): ListboxComboboxProps;
13325
+ /**
13326
+ * Props for the listbox element (spread them). The combobox modes: `tabIndex: -1` and an
13327
+ * `onMouseDown` that keeps focus on the combobox while options are clicked. Standalone mode:
13328
+ * `tabIndex: 0`, `aria-activedescendant` while an option is active, and a `ref` (merge it with
13329
+ * yours: a pointer press on an option focuses the list through it), without `onMouseDown`.
13330
+ * Both: `aria-multiselectable` with `multiselect`.
13331
+ */
13332
+ getListboxProps(): ListboxListProps;
13333
+ /**
13334
+ * The context of the listbox's options: `ListboxSurface` provides it; for a list you render
13335
+ * yourself, pass it to `ListboxProvider` around the options.
13336
+ */
13337
+ context: ListboxContextValue;
13338
+ }
13339
+
11348
13340
  /**
11349
13341
  * Merges several refs into one callback ref whose identity never changes (React 19 cleanup-aware,
11350
13342
  * like {@link mergeRefs}, which merges refs without a hook).