@godxjp/ui 21.0.0 → 23.0.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 (154) hide show
  1. package/README.md +4 -4
  2. package/dist/app/app-provider.js +2 -1
  3. package/dist/components/data-display/badge.d.ts +28 -1
  4. package/dist/components/data-display/badge.js +2 -0
  5. package/dist/components/data-display/data-table.d.ts +18 -2
  6. package/dist/components/data-display/data-table.js +4 -0
  7. package/dist/components/data-display/index.d.ts +1 -1
  8. package/dist/components/data-display/popover.d.ts +19 -1
  9. package/dist/components/data-display/popover.js +9 -1
  10. package/dist/components/data-display/progress.d.ts +37 -0
  11. package/dist/components/data-display/progress.js +57 -5
  12. package/dist/components/data-display/scroll-area.d.ts +24 -4
  13. package/dist/components/data-display/scroll-area.js +34 -72
  14. package/dist/components/data-entry/cascader.js +8 -6
  15. package/dist/components/data-entry/checkbox.js +2 -0
  16. package/dist/components/data-entry/choice-hit-target.d.ts +24 -0
  17. package/dist/components/data-entry/choice-hit-target.js +12 -0
  18. package/dist/components/data-entry/control-surface.d.ts +8 -0
  19. package/dist/components/data-entry/control-surface.js +10 -1
  20. package/dist/components/data-entry/date-picker.d.ts +10 -3
  21. package/dist/components/data-entry/date-picker.js +503 -238
  22. package/dist/components/data-entry/form-field.d.ts +1 -1
  23. package/dist/components/data-entry/form-field.js +7 -3
  24. package/dist/components/data-entry/form.js +10 -1
  25. package/dist/components/data-entry/index.d.ts +0 -6
  26. package/dist/components/data-entry/index.js +0 -6
  27. package/dist/components/data-entry/label.d.ts +14 -1
  28. package/dist/components/data-entry/label.js +6 -1
  29. package/dist/components/data-entry/radio.d.ts +27 -6
  30. package/dist/components/data-entry/radio.js +89 -43
  31. package/dist/components/data-entry/search-select.js +226 -89
  32. package/dist/components/data-entry/select.d.ts +76 -14
  33. package/dist/components/data-entry/select.js +497 -163
  34. package/dist/components/data-entry/slider.d.ts +3 -11
  35. package/dist/components/data-entry/slider.js +582 -93
  36. package/dist/components/data-entry/switch.d.ts +6 -3
  37. package/dist/components/data-entry/switch.js +36 -11
  38. package/dist/components/layout/mobile-shell.d.ts +1 -1
  39. package/dist/components/layout/mobile-shell.js +2 -0
  40. package/dist/components/navigation/dropdown-menu.d.ts +11 -3
  41. package/dist/components/navigation/dropdown-menu.js +190 -15
  42. package/dist/components/navigation/index.d.ts +0 -3
  43. package/dist/components/navigation/index.js +0 -78
  44. package/dist/components/navigation/steps.d.ts +1 -1
  45. package/dist/components/navigation/steps.js +3 -1
  46. package/dist/components/navigation/tabs-scroll.d.ts +27 -0
  47. package/dist/components/navigation/tabs-scroll.js +52 -1
  48. package/dist/components/navigation/tabs.d.ts +2 -2
  49. package/dist/components/navigation/tabs.js +88 -23
  50. package/dist/components/ui/index.d.ts +0 -4
  51. package/dist/components/ui/index.js +0 -4
  52. package/dist/components/ui/input-otp.d.ts +1 -1
  53. package/dist/components/ui/segmented.d.ts +15 -1
  54. package/dist/components/ui/segmented.js +15 -6
  55. package/dist/components/ui/tag-input.js +3 -5
  56. package/dist/i18n/messages/en.json +3 -2
  57. package/dist/i18n/messages/ja.json +3 -2
  58. package/dist/i18n/messages/vi.json +3 -2
  59. package/dist/lib/datetime/picker-format.d.ts +18 -0
  60. package/dist/lib/datetime/picker-format.js +35 -1
  61. package/dist/lib/field-a11y.d.ts +12 -0
  62. package/dist/lib/field-a11y.js +14 -1
  63. package/dist/lib/select-options.d.ts +21 -0
  64. package/dist/lib/select-options.js +46 -0
  65. package/dist/props/components/data-display.prop.d.ts +16 -6
  66. package/dist/props/components/data-entry.prop.d.ts +503 -129
  67. package/dist/props/components/index.d.ts +2 -2
  68. package/dist/props/components/layout.prop.d.ts +12 -1
  69. package/dist/props/components/navigation.prop.d.ts +93 -1
  70. package/dist/props/registry.d.ts +79 -16
  71. package/dist/props/registry.js +85 -15
  72. package/dist/props/vocabulary/data.prop.d.ts +12 -0
  73. package/dist/props/vocabulary/index.d.ts +2 -2
  74. package/dist/props/vocabulary/layout.prop.d.ts +11 -0
  75. package/dist/styles/badge-layout.css +4 -0
  76. package/dist/styles/card-layout.css +6 -6
  77. package/dist/styles/control.css +220 -29
  78. package/dist/styles/data-display-layout.css +94 -23
  79. package/dist/styles/focus-ring.css +6 -4
  80. package/dist/styles/fonts.css +88 -4
  81. package/dist/styles/navigation-layout.css +36 -236
  82. package/dist/styles/shell-layout.css +149 -139
  83. package/dist/styles/table-layout.css +41 -3
  84. package/dist/tokens/components/control.css +4 -0
  85. package/dist/tokens/components/data-display.css +9 -5
  86. package/dist/tokens/components/navigation.css +9 -5
  87. package/dist/tokens/components/scroll-area.css +7 -0
  88. package/dist/tokens/components/segmented.css +0 -2
  89. package/dist/tokens/components/shell.css +2 -0
  90. package/dist/tokens/components/table.css +3 -0
  91. package/dist/tokens/foundation.css +7 -0
  92. package/docs/COMPONENTS.md +14 -14
  93. package/docs/CONSUMER-RULES.md +24 -1
  94. package/docs/CUSTOMER-THEMING.md +7 -1
  95. package/docs/FRAME-COVERAGE-REPORT.md +5 -11
  96. package/docs/TOKENS.md +65 -0
  97. package/docs/data-display/badge.tsx +37 -0
  98. package/docs/data-display/data-table/index.tsx +45 -1
  99. package/docs/data-display/popover.tsx +43 -5
  100. package/docs/data-display/progress.tsx +28 -0
  101. package/docs/data-display/scroll-area.tsx +51 -45
  102. package/docs/data-entry/calendar.tsx +2 -2
  103. package/docs/data-entry/date-picker.tsx +144 -5
  104. package/docs/data-entry/form/examples/invoice-form.tsx +2 -2
  105. package/docs/data-entry/form-field/examples/a11y-contract.tsx +3 -5
  106. package/docs/data-entry/form.tsx +4 -4
  107. package/docs/data-entry/input-otp.tsx +5 -2
  108. package/docs/data-entry/number-input.tsx +31 -0
  109. package/docs/data-entry/segmented.tsx +143 -2
  110. package/docs/data-entry/select-matrix.tsx +1 -2
  111. package/docs/data-entry/select.tsx +108 -3
  112. package/docs/data-entry/slider.tsx +125 -47
  113. package/docs/feedback/dialog.tsx +1 -2
  114. package/docs/feedback/sheet.tsx +1 -2
  115. package/docs/layout/app-shell-states.tsx +143 -0
  116. package/docs/layout/mobile-shell.tsx +5 -0
  117. package/docs/navigation/dropdown-menu.tsx +75 -4
  118. package/docs/navigation/tabs.tsx +149 -0
  119. package/docs/roadmap/antd-parity.md +35 -34
  120. package/docs/roadmap/parity-audit-data-entry.md +196 -172
  121. package/docs/roadmap/parity-audit-layout-navigation-general.md +304 -310
  122. package/docs/roadmap/parity-backlog.md +8 -10
  123. package/docs/showcase/acme-portal.tsx +7 -0
  124. package/package.json +28 -64
  125. package/scripts/ui-audit.mjs +18 -5
  126. package/scripts/visual-audit-rules.mjs +0 -7
  127. package/scripts/visual-audit.mjs +6 -27
  128. package/dist/components/data-entry/date-range-picker.d.ts +0 -11
  129. package/dist/components/data-entry/date-range-picker.js +0 -349
  130. package/dist/components/data-entry/month-picker.d.ts +0 -10
  131. package/dist/components/data-entry/month-picker.js +0 -241
  132. package/dist/components/data-entry/month-range-picker.d.ts +0 -10
  133. package/dist/components/data-entry/month-range-picker.js +0 -301
  134. package/dist/components/navigation/context-menu.d.ts +0 -21
  135. package/dist/components/navigation/context-menu.js +0 -149
  136. package/dist/components/navigation/menubar.d.ts +0 -21
  137. package/dist/components/navigation/menubar.js +0 -136
  138. package/dist/components/navigation/navigation-menu.d.ts +0 -10
  139. package/dist/components/navigation/navigation-menu.js +0 -91
  140. package/dist/components/ui/context-menu.d.ts +0 -1
  141. package/dist/components/ui/context-menu.js +0 -2
  142. package/dist/components/ui/date-range-picker.d.ts +0 -1
  143. package/dist/components/ui/date-range-picker.js +0 -2
  144. package/dist/components/ui/menubar.d.ts +0 -1
  145. package/dist/components/ui/menubar.js +0 -2
  146. package/dist/components/ui/navigation-menu.d.ts +0 -1
  147. package/dist/components/ui/navigation-menu.js +0 -2
  148. package/docs/FRAME-A11Y-CI.md +0 -349
  149. package/docs/data-entry/date-range-picker.tsx +0 -175
  150. package/docs/data-entry/month-picker.tsx +0 -101
  151. package/docs/data-entry/month-range-picker.tsx +0 -115
  152. package/docs/navigation/context-menu.tsx +0 -128
  153. package/docs/navigation/menubar.tsx +0 -141
  154. package/docs/navigation/navigation-menu.tsx +0 -158
@@ -1,8 +1,4 @@
1
1
  /** Data Entry component prop types — @see docs/COMPONENTS.md#data-entry */
2
- import type * as CheckboxPrimitive from "@radix-ui/react-checkbox";
3
- import type * as RadioGroupPrimitive from "@radix-ui/react-radio-group";
4
- import type * as SliderPrimitive from "@radix-ui/react-slider";
5
- import type * as SwitchPrimitive from "@radix-ui/react-switch";
6
2
  import type { RenderProps as InputOTPRenderProps } from "input-otp";
7
3
  import type { DayPickerProps } from "react-day-picker";
8
4
  import type { DateRange } from "react-day-picker";
@@ -39,8 +35,15 @@ export type InputOTPMaskProp = boolean | string;
39
35
  * The value is ALWAYS driven from here (`value` controlled, or `defaultValue` + internal state), so
40
36
  * `formatter` and `readOnly` hold for typing AND for paste — `input-otp` writes its own internal
41
37
  * state on paste, which a wrapper that only intercepted `onChange` could not undo.
38
+ *
39
+ * `style` is OMITTED because it cannot be honoured: `input-otp` owns both elements it could land
40
+ * on and writes their geometry itself — the field's own style object replaces anything passed in
41
+ * (measured: `style={{ color: "red" }}` left the input at the library's `color: transparent`) and
42
+ * the container's is hard-coded too. A type that accepts a prop the render can never deliver is
43
+ * the defect gh#477 reported for `id`; `id` is real and forwarded, this one was not. The paint of
44
+ * the field is reached through `className` / `containerClassName` and the `--otp-*` tokens.
42
45
  */
43
- export type InputOTPProp = Omit<React.InputHTMLAttributes<HTMLInputElement>, "value" | "defaultValue" | "onChange" | "size" | "children"> & {
46
+ export type InputOTPProp = Omit<React.InputHTMLAttributes<HTMLInputElement>, "value" | "defaultValue" | "onChange" | "size" | "children" | "style"> & {
44
47
  /** Number of slots — antd `length`. Required by `input-otp`. */
45
48
  maxLength: number;
46
49
  value?: string;
@@ -285,6 +288,22 @@ export type FormFieldProp = {
285
288
  label: LabelProp;
286
289
  required?: RequiredProp;
287
290
  helper?: HelperProp;
291
+ /**
292
+ * Which side of the control the helper line sits on — `after` (default, under the input) or
293
+ * `before` (between the label and the input).
294
+ *
295
+ * `before` is for a helper the reader needs BEFORE they answer rather than after: the
296
+ * secondary language of a bilingual form, a unit or format note, a pick-one-of-these
297
+ * preamble. `labelAddon` cannot carry that — it is an inline row beside the label with no
298
+ * wrap, sized for a chip or a help button, so a full sentence squeezes the label instead of
299
+ * taking its own line. Putting the second line inside `label` does work, but costs the
300
+ * string-label fallbacks (`aria-label`, `FieldNameContext`), which fire only when `label` is
301
+ * a plain string.
302
+ *
303
+ * Paint only: the helper keeps its id and stays on the control's `aria-describedby`, so this
304
+ * never changes what a screen reader reads or the order it reads it in.
305
+ */
306
+ helperPlacement?: "before" | "after";
288
307
  error?: ErrorProp;
289
308
  validateStatus?: "success" | "warning" | "error" | "validating";
290
309
  hasFeedback?: boolean;
@@ -316,6 +335,22 @@ export type FormFieldProp = {
316
335
  label: LabelProp;
317
336
  required?: RequiredProp;
318
337
  helper?: HelperProp;
338
+ /**
339
+ * Which side of the control the helper line sits on — `after` (default, under the input) or
340
+ * `before` (between the label and the input).
341
+ *
342
+ * `before` is for a helper the reader needs BEFORE they answer rather than after: the
343
+ * secondary language of a bilingual form, a unit or format note, a pick-one-of-these
344
+ * preamble. `labelAddon` cannot carry that — it is an inline row beside the label with no
345
+ * wrap, sized for a chip or a help button, so a full sentence squeezes the label instead of
346
+ * taking its own line. Putting the second line inside `label` does work, but costs the
347
+ * string-label fallbacks (`aria-label`, `FieldNameContext`), which fire only when `label` is
348
+ * a plain string.
349
+ *
350
+ * Paint only: the helper keeps its id and stays on the control's `aria-describedby`, so this
351
+ * never changes what a screen reader reads or the order it reads it in.
352
+ */
353
+ helperPlacement?: "before" | "after";
319
354
  error?: ErrorProp;
320
355
  validateStatus?: "success" | "warning" | "error" | "validating";
321
356
  hasFeedback?: boolean;
@@ -386,8 +421,20 @@ export type SearchInputProp = FieldA11yProps & {
386
421
  /** Chrome level — antd `variant`. Default `outlined`. */
387
422
  variant?: ControlVariantProp;
388
423
  };
389
- /** @see Checkbox — extends Radix checkbox root props. */
390
- export type CheckboxProp = React.ComponentPropsWithoutRef<typeof CheckboxPrimitive.Root> & {
424
+ /**
425
+ * @see Checkbox
426
+ *
427
+ * Public shape unchanged from the @radix-ui/react-checkbox era — `checked` / `defaultChecked` take
428
+ * the tri-state `"indeterminate"`, `onCheckedChange` reports it back, and `disabled` / `required`
429
+ * keep their HTML spelling. checkbox.tsx translates all of it to react-aria's `isSelected` /
430
+ * `isIndeterminate` / `onChange` / `isDisabled`; none of those names reach a consumer. Written out
431
+ * here rather than derived from a primitive that the component no longer uses.
432
+ */
433
+ export type CheckboxProp = Omit<React.ComponentPropsWithoutRef<"button">, "checked" | "defaultChecked" | "onChange"> & {
434
+ checked?: boolean | "indeterminate";
435
+ defaultChecked?: boolean | "indeterminate";
436
+ onCheckedChange?: (checked: boolean | "indeterminate") => void;
437
+ required?: boolean;
391
438
  /**
392
439
  * antd `indeterminate` — paint the PARTIAL mark (a dash) without changing `checked`. Radix
393
440
  * spells the same state as `checked="indeterminate"`; this is the antd spelling of it, and the
@@ -442,10 +489,30 @@ export type RadioGroupProp = FieldA11yProps & {
442
489
  export type RadioOptionTypeProp = "default" | "button";
443
490
  /** antd `RadioGroupButtonStyle` — the selected button is outlined, or filled with the brand. */
444
491
  export type RadioButtonStyleProp = "outline" | "solid";
445
- /** @see Radio.Item — Radix radio group item. */
446
- export type RadioProp = React.ComponentPropsWithoutRef<typeof RadioGroupPrimitive.Item>;
447
- /** @see Switch — extends Radix switch root props. */
448
- export type SwitchProp = React.ComponentPropsWithoutRef<typeof SwitchPrimitive.Root> & {
492
+ /**
493
+ * @see Radio.Item
494
+ *
495
+ * Public shape unchanged from the @radix-ui/react-radio-group era — `value` / `disabled` keep
496
+ * their HTML spelling; react-aria's `isDisabled` never reaches a consumer.
497
+ */
498
+ export type RadioProp = Omit<React.ComponentPropsWithoutRef<"button">, "value"> & {
499
+ value: string;
500
+ };
501
+ /**
502
+ * @see Switch
503
+ *
504
+ * The PUBLIC shape is unchanged from the @radix-ui/react-switch era — `checked` /
505
+ * `defaultChecked` / `onCheckedChange` / `disabled` / `required` keep their HTML spelling.
506
+ * react-aria-components spells the same five `isSelected` / `defaultSelected` / `onChange` /
507
+ * `isDisabled`, and that translation happens inside `switch.tsx`; none of those names reach a
508
+ * consumer. Written out here rather than derived from a primitive so the surface stops moving
509
+ * whenever the base does.
510
+ */
511
+ export type SwitchProp = Omit<React.ComponentPropsWithoutRef<"button">, "checked" | "defaultChecked" | "onChange" | "value"> & {
512
+ checked?: boolean;
513
+ defaultChecked?: boolean;
514
+ onCheckedChange?: (checked: boolean) => void;
515
+ required?: boolean;
449
516
  size?: "sm" | "md";
450
517
  /**
451
518
  * antd `loading` — the toggle is mid-flight: a spinner replaces the thumb glyph and the control
@@ -467,43 +534,157 @@ export type FieldProp = {
467
534
  children: React.ReactNode;
468
535
  };
469
536
  /**
470
- * Tick marks on a slider rail — antd `SliderMarks`. Keyed by the value the mark sits on; the
471
- * value is the label. `null` renders the tick with no label.
537
+ * One tick on a slider rail — antd's two spellings: the label itself, or `{ label, style }` where
538
+ * the object also carries a per-mark inline style. `null` renders the tick with no label.
472
539
  */
473
- export type SliderMarksProp = Record<number, React.ReactNode>;
540
+ export type SliderMarkProp = React.ReactNode | {
541
+ label?: React.ReactNode;
542
+ /** antd's per-mark style. Prefer styling the `label` node — it is already a ReactNode. */
543
+ style?: React.CSSProperties;
544
+ };
474
545
  /**
475
- * antd `tooltip` the value bubble over a dragging thumb. `false` switches it off, `true` uses
476
- * the raw value, and the object form formats it (a unit, a currency, a 全角 label).
546
+ * Tick marks on a slider rail antd `SliderMarks`. Keyed by the value the mark sits on. With
547
+ * `step={null}` the marks (plus `min` and `max`) are the ONLY values the slider can take.
548
+ */
549
+ export type SliderMarksProp = Record<number, SliderMarkProp>;
550
+ /**
551
+ * antd `tooltip` — the value bubble over a thumb. `false` switches it off, `true` uses the raw
552
+ * value, and the object form formats and places it.
477
553
  */
478
554
  export type SliderTooltipProp = boolean | {
479
- /** Force the bubble on/off instead of following hover/drag. */
555
+ /**
556
+ * `true` keeps the bubble visible; `false` keeps it hidden even while dragging or hovering —
557
+ * both exactly as antd. Unset, it follows hover, keyboard focus and drag.
558
+ */
480
559
  open?: boolean;
481
- /** Render the bubble's content. `null` switches the bubble off, exactly as antd's does. */
560
+ /**
561
+ * Which side of the thumb. `left` / `right` are the INLINE sides and mirror under RTL like
562
+ * the rest of the slider. Defaults to `top`, or `right` on a vertical slider (antd's default).
563
+ */
564
+ placement?: "top" | "bottom" | "left" | "right";
565
+ /** Flip to the opposite side when the bubble would leave the viewport. Default `true`. */
566
+ autoAdjustOverflow?: boolean;
567
+ /**
568
+ * Render the bubble's content. `null` switches the bubble off, exactly as antd's does. A
569
+ * string or number result is ALSO the thumb's `aria-valuetext`, so a `¥50,000` slider is
570
+ * announced as ¥50,000 and not as a bare 50000.
571
+ */
482
572
  formatter?: ((value: number) => React.ReactNode) | null;
483
573
  };
484
- /** @see Slider — numeric range (Radix Slider). */
485
- export type SliderProp = React.ComponentPropsWithoutRef<typeof SliderPrimitive.Root> & {
574
+ /**
575
+ * antd's range object — `range={{ editable, minCount, maxCount, draggableTrack }}`. Any object is
576
+ * a range, exactly like `range={true}`.
577
+ */
578
+ export type SliderRangeConfigProp = {
579
+ /**
580
+ * Thumbs can be added and removed: a press on the rail ADDS one there, and Delete / Backspace on
581
+ * a focused thumb removes it. Ignored while any thumb is disabled, and wins over `draggableTrack`
582
+ * — both exactly as antd.
583
+ */
584
+ editable?: boolean;
585
+ /** Fewest thumbs `editable` may leave. Default 0. */
586
+ minCount?: number;
587
+ /** Most thumbs `editable` may create. Default unlimited. */
588
+ maxCount?: number;
589
+ /** Drag the painted span to move every thumb at once, keeping their distance. */
590
+ draggableTrack?: boolean;
591
+ };
592
+ /**
593
+ * @see Slider — numeric slider on react-aria-components, antd 6 `Slider` API.
594
+ *
595
+ * Written out rather than derived from the primitive, so what is public is exactly what is listed
596
+ * here: the Radix-era spelling (`number[]` values, `onValueChange`, `onValueCommit`, `inverted`,
597
+ * `dir`, `minStepsBetweenThumbs`) keeps compiling beside antd's (`number` values, `onChange`,
598
+ * `onChangeComplete`, `reverse`, `vertical`, `range` objects, `step={null}`).
599
+ *
600
+ * The union is on `range`, as in antd: without it `onChange` reports a `number`, with a literal
601
+ * `range` (or a range object) it reports `number[]`. A `range` held in a boolean variable cannot
602
+ * say which, so that spelling takes `onValueChange` — which always reports every thumb.
603
+ */
604
+ export type SliderProp = Omit<React.HTMLAttributes<HTMLDivElement>, "defaultValue" | "onChange" | "dir" | "children"> & {
605
+ /** The low end of the scale. Default 0. */
606
+ min?: number;
607
+ /** The high end of the scale. Default 100. */
608
+ max?: number;
486
609
  /**
487
- * antd `range` two thumbs bounding a span rather than one thumb over a point. It is a
488
- * DECLARATION, not an inference: a single-thumb slider whose `defaultValue` happens to be a
489
- * two-element array used to become a range by accident, and a range whose value arrived
490
- * asynchronously used to render as a point.
610
+ * Granularity. `null` is antd's marks-only mode: the thumbs can only rest on a mark, `min` or
611
+ * `max`. Default 1.
491
612
  */
492
- range?: boolean;
613
+ step?: number | null;
614
+ /**
615
+ * Disable the whole slider, or — antd's array form — one thumb each: `[true, false]` locks the
616
+ * first thumb of a range. A disabled thumb leaves the tab order and does not submit.
617
+ */
618
+ disabled?: boolean | boolean[];
619
+ /** Layout axis. Default `horizontal`. Wins over `vertical`, as in antd 6. */
620
+ orientation?: "horizontal" | "vertical";
621
+ /** antd's boolean spelling of `orientation="vertical"`. */
622
+ vertical?: boolean;
623
+ /**
624
+ * Reading direction of a horizontal slider — which end is `min` and which arrow increases.
625
+ * Defaults to the locale's direction (the `I18nProvider` that `AppProvider` sets).
626
+ */
627
+ dir?: "ltr" | "rtl";
628
+ /** antd `reverse` — run the scale the other way (`min` at the inline end, or at the top). */
629
+ reverse?: boolean;
630
+ /** The Radix-era name for `reverse`. When both are given, `inverted` wins. */
631
+ inverted?: boolean;
632
+ /** Radix-era: the fewest steps two neighbouring thumbs may be apart. Default 0. */
633
+ minStepsBetweenThumbs?: number;
634
+ /** Every change, with EVERY thumb — the Radix-era callback, valid in every spelling. */
635
+ onValueChange?: (value: number[]) => void;
636
+ /** Once per finished gesture (pointer release, key press), with every thumb. */
637
+ onValueCommit?: (value: number[]) => void;
638
+ /**
639
+ * Native form field name. One thumb submits `name`; several submit `name[]`, once each.
640
+ */
641
+ name?: string;
642
+ /** Associate the thumbs' inputs with a form elsewhere in the document, by id. */
643
+ form?: string;
493
644
  /** antd `marks` — labelled ticks along the rail. */
494
645
  marks?: SliderMarksProp;
495
- /** antd `dots` — a tick at every `step`. Requires a `step`. */
646
+ /** antd `dots` — a tick at every `step` (at every mark when `step={null}`). */
496
647
  dots?: boolean;
497
648
  /**
498
- * antd `included` — whether the painted range is the span from the start to the thumb
499
- * (`true`, the default) or nothing at all (`false`, for a rail that only holds marks).
649
+ * antd `included` — whether the painted span runs from the start to the thumb (`true`, the
650
+ * default) or nothing is painted at all (`false`, for a rail that only holds marks).
500
651
  */
501
652
  included?: boolean;
502
- /** antd `reverse` — run the scale the other way. Radix spells the same thing `inverted`. */
503
- reverse?: boolean;
504
- /** antd `tooltip` — the value bubble over a dragging thumb. Off by default. */
653
+ /** antd `tooltip` — the value bubble over a thumb. Off by default. */
505
654
  tooltip?: SliderTooltipProp;
506
- };
655
+ } & ({
656
+ /**
657
+ * One thumb. An array `value` with no `range` still draws a thumb per entry — the
658
+ * Radix-era inference — but `onChange` then reports only the first; use `onValueChange`
659
+ * for all of them, or declare `range`.
660
+ */
661
+ range?: false;
662
+ /** Controlled value — a number, or the Radix-era `number[]`. */
663
+ value?: number | number[];
664
+ /** Uncontrolled initial value. With nothing given the thumb starts at `min`. */
665
+ defaultValue?: number | number[];
666
+ /** antd `onChange` — every change, as a number. */
667
+ onChange?: (value: number) => void;
668
+ /** antd `onChangeComplete` — pointer release / key press, as a number. */
669
+ onChangeComplete?: (value: number) => void;
670
+ } | {
671
+ /**
672
+ * antd `range` — two or more thumbs bounding spans. A DECLARATION: a range whose value is
673
+ * still loading does not render as a point, and without a value it spans `[min, max]`.
674
+ */
675
+ range: true | SliderRangeConfigProp;
676
+ value?: number[];
677
+ defaultValue?: number[];
678
+ onChange?: (value: number[]) => void;
679
+ onChangeComplete?: (value: number[]) => void;
680
+ } | {
681
+ /** A `range` known only at run time (a boolean variable) — report through `onValueChange`. */
682
+ range: boolean;
683
+ value?: number | number[];
684
+ defaultValue?: number | number[];
685
+ onChange?: never;
686
+ onChangeComplete?: never;
687
+ });
507
688
  /** @see Calendar — react-day-picker DayPicker plus an opt-in footer. */
508
689
  /**
509
690
  * Decorate one day cell — antd's `cellRender`, in the shape the Japanese market actually needs it:
@@ -579,28 +760,90 @@ export type PickerChromeProp = {
579
760
  };
580
761
  /** date-fns pattern, Intl options (including Japanese era), or a display function. */
581
762
  export type PickerDateFormatProp = string | Intl.DateTimeFormatOptions | ((date: Date) => string);
582
- /** @see DatePicker */
763
+ /**
764
+ * @see DatePicker — ONE date control for every date-shaped question this library used to ask with
765
+ * four components (`DatePicker`, `DateRangePicker`, `MonthPicker`, `MonthRangePicker`).
766
+ *
767
+ * Two axes, both antd's: `picker` chooses the GRANULARITY of a selection, `range` chooses its
768
+ * CARDINALITY. Everything else — bounds, disabling, formatting, clearing, the open triad, the
769
+ * chrome ladder — is written once and therefore behaves the same on all eight combinations.
770
+ *
771
+ * ON THE NAME `picker`. It is antd's own prop name for this axis, and it already shipped here with
772
+ * exactly this union, so keeping it renames nothing and breaks no call site. (`granularity` is
773
+ * react-aria's spelling; this cluster is not on react-aria.) The house rule stated on `TreeProp` —
774
+ * map Ant's KEY-SHAPED names onto this package's controlled vocabulary and do not re-spell the
775
+ * rest — is what the surrounding props already do: `showTime`, `needConfirm`, `allowClear`,
776
+ * `cellRender`, `disabledDate`, `inputReadOnly`, `preserveInvalidOnBlur`, `renderExtraFooter`,
777
+ * `presets`, `order`, `minDate`/`maxDate` are all spelled antd's way, while selection is spelled
778
+ * `value`/`defaultValue`/`onValueChange` rather than antd's `onChange`.
779
+ */
583
780
  export type DatePickerBaseProp = FieldA11yProps & PickerChromeProp & {
584
781
  /** Display format; native submission remains ISO. */
585
782
  format?: PickerDateFormatProp;
586
783
  /** Parser for a custom display function or Intl era display; ISO always remains accepted. */
587
784
  parseFormat?: (text: string) => Date | undefined;
785
+ /**
786
+ * Selectable bounds, inclusive, at day precision (antd `minDate`/`maxDate`).
787
+ *
788
+ * These are the ONLY bounds props. `MonthPicker`/`MonthRangePicker` used to take
789
+ * `fromYear`/`toYear` numbers instead, which expressed strictly less (a whole year is the
790
+ * smallest thing they could say) and — measurably — clamped nothing: they only greyed the
791
+ * grid's year chevrons, while both routes into the value, the grid cells and the typed text,
792
+ * ignored them. `minDate`/`maxDate` are enforced on BOTH routes for every `picker`, so the
793
+ * keyboard is not a way around the rule the mouse obeys. Migration is mechanical:
794
+ * `fromYear={2024}` → `minDate={new Date(2024, 0, 1)}`, `toYear={2027}` →
795
+ * `maxDate={new Date(2027, 11, 31)}`.
796
+ */
588
797
  minDate?: Date;
589
798
  maxDate?: Date;
590
799
  showWeek?: boolean;
591
800
  needConfirm?: boolean;
801
+ /**
802
+ * Which period the PANEL opens on, independently of the value (antd `defaultPickerValue`, and
803
+ * like antd's it is RE-APPLIED every time the panel opens rather than only at mount).
804
+ *
805
+ * Without it a panel can only open on the value or on today, so "open on the fiscal year's
806
+ * start month" and "open on the month of the row being edited" have no expression — the two
807
+ * cases the parity audit files as P1. Only the period matters; the day is ignored.
808
+ */
809
+ defaultPickerValue?: Date;
810
+ /** Controlled panel period (antd `pickerValue`) — wins over `defaultPickerValue` and over the value. */
811
+ pickerValue?: Date;
812
+ /**
813
+ * GRANULARITY of one selection (antd `picker`). `date` picks a day from a month grid; `week`
814
+ * picks a day and normalises it to the locale's week start; `month`, `quarter` and `year` swap
815
+ * the day grid for a period grid and normalise to the period's first day.
816
+ *
817
+ * The emitted value is always a `Date` at the START of the chosen period, so a coarse
818
+ * selection interoperates with a fine one and with `DateRange`.
819
+ */
592
820
  picker?: "date" | "week" | "month" | "quarter" | "year";
821
+ /**
822
+ * Normalise the selection into ascending order (antd `order`; default `true`).
823
+ *
824
+ * ONE rule, applied to whichever value shape is in play: a `range` whose endpoints were picked
825
+ * backwards is SWAPPED, and a `multiple` selection is SORTED. The four split components spelled
826
+ * this two ways — `DatePicker.order` sorted an array, `DateRangePicker.order` swapped a pair,
827
+ * `MonthRangePicker` swapped unconditionally with no prop at all — which read as a collision
828
+ * but is one invariant seen through three value shapes. Set `false` to keep pick order.
829
+ */
593
830
  order?: boolean;
594
831
  showTime?: boolean | Pick<TimePickerProp, "hourStep" | "minuteStep" | "secondStep" | "showSeconds" | "use12Hours" | "disabledTime">;
595
- presets?: {
596
- label: React.ReactNode;
597
- value: Date | (() => Date);
598
- }[];
599
832
  placeholder?: PlaceholderProp;
600
- disabled?: DisabledProp;
833
+ /**
834
+ * Inert control. With `range`, the TUPLE form `[from, to]` locks one endpoint and leaves the
835
+ * other editable (antd's RangePicker `disabled`) — "the start date is fixed by the contract,
836
+ * only the end is negotiable" is a real screen that a scalar cannot say. The tuple is
837
+ * meaningless without `range` and is ignored there.
838
+ */
839
+ disabled?: DisabledProp | [boolean, boolean];
601
840
  className?: ClassNameProp;
602
841
  id?: IdProp;
603
- /** Form field name — emits the value as an ISO-8601 `yyyy-MM-dd` string for native submission. */
842
+ /**
843
+ * Form field name. Submits ISO-8601 at the precision `picker` selects — `2026-03-01` for
844
+ * `date`/`week`, `2026-03` for `month` and `quarter` (the period's first month), `2026` for
845
+ * `year`. With `range`, the pair submits as `${name}_from` / `${name}_to`.
846
+ */
604
847
  name?: NameProp;
605
848
  locale?: DayPickerProps["locale"];
606
849
  fromDate?: Date;
@@ -608,11 +851,11 @@ export type DatePickerBaseProp = FieldA11yProps & PickerChromeProp & {
608
851
  /** Decorate a day cell — 祝日, a booked day, a deadline. @see CalendarCellRenderProp */
609
852
  cellRender?: CalendarCellRenderProp;
610
853
  /**
611
- * Forbid individual dates by predicate — the rule `fromDate`/`toDate` cannot express, because a
854
+ * Forbid individual dates by predicate — the rule `minDate`/`maxDate` cannot express, because a
612
855
  * business calendar is rarely one contiguous range: 土日, a closed accounting period, a 祝日, a
613
856
  * day already fully booked.
614
857
  *
615
- * Applies to BOTH routes into the value. The calendar greys the cell out, and a date typed into
858
+ * Applies to BOTH routes into the value. The grid greys the cell out, and a date typed into
616
859
  * the field is rejected the same way an unparseable one is — otherwise the keyboard becomes a
617
860
  * way around the rule the mouse obeys.
618
861
  */
@@ -623,104 +866,50 @@ export type DatePickerBaseProp = FieldA11yProps & PickerChromeProp & {
623
866
  */
624
867
  allowClear?: AllowClearProp;
625
868
  } & Pick<CalendarFooterProp, "showToday" | "showClose">;
626
- /** Single and multiple selections keep their callback types distinct. */
869
+ /**
870
+ * CARDINALITY. One `Date`, an array of them, or a `DateRange` — each keeps its own callback type,
871
+ * so a consumer never has to narrow what it gets back.
872
+ */
627
873
  export type DatePickerProp = DatePickerBaseProp & ({
874
+ range?: false;
628
875
  multiple?: false;
629
876
  value?: Date;
630
877
  defaultValue?: Date;
631
878
  onValueChange?: (value: Date | undefined) => void;
879
+ presets?: {
880
+ label: React.ReactNode;
881
+ value: Date | (() => Date);
882
+ }[];
632
883
  } | {
884
+ range?: false;
633
885
  multiple: true;
634
886
  value?: Date[];
635
887
  defaultValue?: Date[];
636
888
  onValueChange?: (value: Date[] | undefined) => void;
637
889
  showTime?: false;
638
- });
639
- /** @see MonthPicker */
640
- export type MonthPickerProp = FieldA11yProps & PickerChromeProp & {
641
- value?: ValueProp<Date>;
642
- defaultValue?: DefaultValueProp<Date | undefined>;
643
- onValueChange?: OnValueChangeProp<Date | undefined>;
644
- placeholder?: PlaceholderProp;
645
- disabled?: DisabledProp;
646
- className?: ClassNameProp;
647
- id?: IdProp;
648
- /** Form field name — submits the display text (`yyyy/MM`). */
649
- name?: NameProp;
650
- /** Clamp the year navigation (inclusive). */
651
- fromYear?: number;
652
- toYear?: number;
653
- /**
654
- * Show an inline ✕ to clear the value when one is set (default true). The OBJECT form
655
- * additionally replaces the icon and/or the accessible label (antd `allowClear`).
656
- */
657
- allowClear?: AllowClearProp;
658
- /** Node appended below the month grid (antd `renderExtraFooter`). */
659
- renderExtraFooter?: () => React.ReactNode;
660
- };
661
- /**
662
- * @see MonthRangePicker — both edges are normalized to the FIRST day of their month
663
- * (the `DateRange` shape is shared with DateRangePicker so ranges interop).
664
- */
665
- export type MonthRangePickerProp = FieldA11yProps & PickerChromeProp & {
666
- value?: ValueProp<DateRange>;
667
- defaultValue?: DefaultValueProp<DateRange | undefined>;
668
- onValueChange?: OnValueChangeProp<DateRange | undefined>;
669
- placeholder?: PlaceholderProp;
670
- disabled?: DisabledProp;
671
- className?: ClassNameProp;
672
- id?: IdProp;
673
- /** Form field name — emits the range as `${name}_from` / `${name}_to` `yyyy/MM` fields. */
674
- name?: NameProp;
675
- /** Clamp the year navigation (inclusive). */
676
- fromYear?: number;
677
- toYear?: number;
890
+ presets?: {
891
+ label: React.ReactNode;
892
+ value: Date | (() => Date);
893
+ }[];
894
+ } | {
678
895
  /**
679
- * Show an inline to clear the range when one is set (default true). The OBJECT form
680
- * additionally replaces the icon and/or the accessible label (antd `allowClear`).
896
+ * Two endpoints in one field antd's `DatePicker.RangePicker`, which this library used to
897
+ * ship as two separate components (`DateRangePicker`, `MonthRangePicker`). It composes with
898
+ * `picker`, so a month range is `<DatePicker range picker="month" />`.
681
899
  */
682
- allowClear?: AllowClearProp;
683
- /** Node appended below the month grid (antd `renderExtraFooter`). */
684
- renderExtraFooter?: () => React.ReactNode;
685
- };
686
- /** @see DateRangePicker */
687
- export type DateRangePickerProp = FieldA11yProps & PickerChromeProp & {
688
- /** Display format; native submission remains ISO. */
689
- format?: PickerDateFormatProp;
690
- /** Parser for a custom display function or Intl era display; ISO always remains accepted. */
691
- parseFormat?: (text: string) => Date | undefined;
692
- minDate?: Date;
693
- maxDate?: Date;
694
- showWeek?: boolean;
695
- needConfirm?: boolean;
900
+ range: true;
901
+ multiple?: false;
902
+ value?: DateRange;
903
+ defaultValue?: DateRange;
904
+ onValueChange?: (value: DateRange | undefined) => void;
905
+ showTime?: false;
906
+ /** Which endpoints may stay empty (antd `allowEmpty`), as `[from, to]`. */
907
+ allowEmpty?: [boolean, boolean];
696
908
  presets?: {
697
909
  label: React.ReactNode;
698
910
  value: DateRange | (() => DateRange);
699
911
  }[];
700
- allowEmpty?: [boolean, boolean];
701
- order?: boolean;
702
- value?: ValueProp<DateRange>;
703
- defaultValue?: DefaultValueProp<DateRange | undefined>;
704
- onValueChange?: OnValueChangeProp<DateRange | undefined>;
705
- placeholder?: PlaceholderProp;
706
- disabled?: DisabledProp;
707
- className?: ClassNameProp;
708
- id?: IdProp;
709
- /** Form field name — emits the range as `${name}_from` / `${name}_to` ISO `yyyy-MM-dd` fields. */
710
- name?: NameProp;
711
- locale?: DayPickerProps["locale"];
712
- fromDate?: Date;
713
- toDate?: Date;
714
- /** Decorate a day cell — see `CalendarCellRenderProp`. */
715
- cellRender?: CalendarCellRenderProp;
716
- /** Forbid individual dates by predicate — see `DatePickerProp.disabledDate`. */
717
- disabledDate?: (date: Date) => boolean;
718
- /**
719
- * antd `allowClear` — an inline ✕ that clears the range when one is set (default true). The
720
- * OBJECT form additionally replaces the icon and/or the accessible label.
721
- */
722
- allowClear?: AllowClearProp;
723
- } & Pick<CalendarFooterProp, "showToday" | "showClose">;
912
+ });
724
913
  /**
725
914
  * Which times a TimePicker refuses, in antd's shape: one call returns the two predicates, so a
726
915
  * consumer computing them from the same source (a start time, a shift window) does that work once
@@ -841,13 +1030,77 @@ export type SearchSelectLoadResultProp = {
841
1030
  /** True if another page is available (drives infinite scroll). */
842
1031
  hasMore?: boolean;
843
1032
  };
1033
+ /**
1034
+ * antd `fieldNames` — read rows in a FOREIGN shape (`{id, name}`, `{code, title}`) without mapping
1035
+ * them first. The spelling matches the `fieldNames` Cascader and TreeSelect already take.
1036
+ */
1037
+ export type SelectFieldNamesProp = {
1038
+ label?: string;
1039
+ value?: string;
1040
+ /** Key holding a group's child rows — antd nests a group's options under the group. */
1041
+ options?: string;
1042
+ /** Key holding a group's heading; defaults to `label`, as in antd. */
1043
+ groupLabel?: string;
1044
+ disabled?: string;
1045
+ };
1046
+ /**
1047
+ * A GROUP in antd's nested `options` shape — a heading plus its own rows. The flat
1048
+ * `option.group` spelling this library already had keeps working; both arrive at the same list.
1049
+ */
1050
+ export type SelectOptionGroupProp = {
1051
+ label: string;
1052
+ options: SearchSelectOptionProp[];
1053
+ disabled?: boolean;
1054
+ };
1055
+ /** What `<Select options>` accepts: a row, a group of rows, or (with `fieldNames`) a foreign row. */
1056
+ export type SelectOptionInputProp = SearchSelectOptionProp | SelectOptionGroupProp | Record<string, unknown>;
1057
+ /**
1058
+ * antd `labelInValue` — the value carries its own label, so a screen that only ever sees
1059
+ * `{ value, label }` never has to keep the option list around to render what was picked (an async
1060
+ * edit form whose page has not loaded yet is the case that needs it).
1061
+ */
1062
+ export type SelectLabeledValueProp = {
1063
+ value: string;
1064
+ label: React.ReactNode;
1065
+ };
1066
+ /**
1067
+ * antd `placement`, spelled on the LOGICAL inline axis — the same vocabulary
1068
+ * `DropdownMenuPlacementProp` publishes, and for the same reason: antd's `bottomLeft` / `topRight`
1069
+ * cannot mirror for an Arabic or Hebrew layout.
1070
+ */
1071
+ export type SelectPlacementProp = "bottomStart" | "bottomEnd" | "topStart" | "topEnd";
1072
+ /**
1073
+ * antd `showSearch`'s OBJECT form. Every field is the antd one, including
1074
+ * `filterOption(input, option)` — note the argument order is antd's here, while the long-standing
1075
+ * top-level `filterOption(option, query)` keeps this library's. Pass whichever you prefer; the
1076
+ * object form wins when both are given.
1077
+ */
1078
+ export type SelectShowSearchProp = {
1079
+ /** `false` keeps every row (a server-filtered list); a function decides per row. */
1080
+ filterOption?: boolean | ((input: string, option: SearchSelectOptionProp) => boolean);
1081
+ /** Which field the default filter matches. antd's default is `value`; `label` is the common one. */
1082
+ optionFilterProp?: "label" | "value" | "sublabel";
1083
+ filterSort?: (a: SearchSelectOptionProp, b: SearchSelectOptionProp, info: {
1084
+ searchValue: string;
1085
+ }) => number;
1086
+ searchValue?: string;
1087
+ onSearch?: (value: string) => void;
1088
+ autoClearSearchValue?: boolean;
1089
+ };
844
1090
  /**
845
1091
  * @see Select — the data-driven entry point (`<Select options|loadOptions showSearch …/>`).
846
1092
  * This is the shape of its internal engine (`SelectDataProp` extends it); use `Select` directly.
847
1093
  */
848
1094
  export type SearchSelectBaseProp = {
849
- /** Static option list (client-side filtered). Provide this OR `loadOptions`, not both. */
850
- options?: SearchSelectOptionProp[];
1095
+ /**
1096
+ * Static option list (client-side filtered). Provide this OR `loadOptions`, not both.
1097
+ *
1098
+ * A row, or one of antd's nested GROUPS (`{ label, options }`) — both land in the same list, the
1099
+ * group's heading becoming the `group` this library's flat rows already carry. Rows in a foreign
1100
+ * shape go through `fieldNames` and need a cast at the call site, exactly as Cascader's and
1101
+ * TreeSelect's do.
1102
+ */
1103
+ options?: (SearchSelectOptionProp | SelectOptionGroupProp)[];
851
1104
  /** Remote fetcher — debounced search + infinite-scroll pagination call into this. Provide this
852
1105
  * OR `options`. */
853
1106
  loadOptions?: (params: SearchSelectLoadParamsProp) => Promise<SearchSelectLoadResultProp>;
@@ -889,6 +1142,18 @@ export type SearchSelectBaseProp = {
889
1142
  readOnly?: boolean;
890
1143
  /** Trigger height tier — forwarded to the underlying Button. Default matches Button's own default. */
891
1144
  size?: SizeProp;
1145
+ /**
1146
+ * Trigger width, the SAME axis `SelectTrigger` carries on the compound API — `full` (default,
1147
+ * the width a field wants), `auto` (the width the current label wants), `bounded` (one width
1148
+ * from `--control-bounded-width`, for a trigger whose value varies in length).
1149
+ *
1150
+ * It exists here because the two APIs are one component to a caller: `docs/CONSUMER-RULES.md`
1151
+ * rule 5 tells everyone that "a Select outside a form takes `width=\"auto\"`", and until this
1152
+ * prop existed that sentence was false for the `options` form — a filter bar with two of them
1153
+ * stretched each to full width and stacked them, and the only way out was to wrap each in a
1154
+ * `<Flex width={280}>`.
1155
+ */
1156
+ width?: ControlWidthProp;
892
1157
  /**
893
1158
  * Validation status (antd `status`). `error` recolours the trigger AND sets `aria-invalid`;
894
1159
  * `warning` recolours only. A `status` set here never overrides an `aria-invalid` arriving from
@@ -987,6 +1252,45 @@ export type SearchSelectBaseProp = {
987
1252
  "data-testid"?: string;
988
1253
  /** Normally injected by `FormField`. */
989
1254
  "data-field"?: string;
1255
+ /**
1256
+ * antd `fieldNames` — map `{label, value, options, groupLabel, disabled}` onto foreign rows, so a
1257
+ * server payload can be passed straight through instead of being copied into a second array.
1258
+ */
1259
+ fieldNames?: SelectFieldNamesProp;
1260
+ /**
1261
+ * antd `prefix` — a node pinned BEFORE the value on the trigger (a currency mark, an icon, a
1262
+ * "To:" label). Decorative: it is not part of the control's accessible name.
1263
+ */
1264
+ prefix?: React.ReactNode;
1265
+ /**
1266
+ * antd `suffixIcon` — replaces the trailing chevron. `null` removes the indicator entirely (antd
1267
+ * spells that `showArrow={false}`, which it deprecated in favour of exactly this).
1268
+ */
1269
+ suffixIcon?: React.ReactNode;
1270
+ /**
1271
+ * antd `placement`, on the logical inline axis. Absent = `bottomStart` with collision flipping,
1272
+ * which is what a picker wants; set it only when the popup must open a specific way.
1273
+ */
1274
+ placement?: SelectPlacementProp;
1275
+ /**
1276
+ * antd `popupRender` — wrap the popup's own node (add a footer, a "create" action, a hint line).
1277
+ * Receives the list and must render it: dropping `originNode` leaves a popup with no options.
1278
+ */
1279
+ popupRender?: (originNode: React.ReactNode) => React.ReactNode;
1280
+ /**
1281
+ * antd `listHeight` — the option list's maximum height in px. It overrides
1282
+ * `--select-content-max-height` for this one control; the token stays the default everywhere
1283
+ * else, so this is a per-instance override of a knob, not a new hard-coded height.
1284
+ */
1285
+ listHeight?: number;
1286
+ /** antd `onPopupScroll` — fires on the option list's own scroll (an infinite-scroll hook). */
1287
+ onPopupScroll?: (event: React.UIEvent<HTMLElement>) => void;
1288
+ /**
1289
+ * antd `optionFilterProp` — which field the default filter matches while searching. antd's
1290
+ * default is `value`; this library keeps matching BOTH label and value when it is unset, because
1291
+ * every call site that has ever relied on the default expects a label search.
1292
+ */
1293
+ optionFilterProp?: "label" | "value" | "sublabel";
990
1294
  };
991
1295
  /**
992
1296
  * Single-select (the default): one `string` in, one `string` out — `""` means nothing selected.
@@ -994,6 +1298,8 @@ export type SearchSelectBaseProp = {
994
1298
  */
995
1299
  export type SearchSelectSingleProp = {
996
1300
  mode?: undefined;
1301
+ /** @see SelectLabelInValueSingleProp for the `{value,label}` dialect. */
1302
+ labelInValue?: false;
997
1303
  value?: ValueProp;
998
1304
  /** Uncontrolled initial value — the trigger shows its option's label at rest (controlled-triad). */
999
1305
  defaultValue?: DefaultValueProp;
@@ -1011,7 +1317,13 @@ export type SearchSelectSingleProp = {
1011
1317
  * per-chip remove button inside it would be a button nested in a button.
1012
1318
  */
1013
1319
  export type SearchSelectMultipleProp = {
1014
- mode: "multiple";
1320
+ /**
1321
+ * `multiple` picks from the list; `tags` also ACCEPTS what was typed, so a value that is not in
1322
+ * the list can still be committed (antd's own distinction between the two).
1323
+ */
1324
+ mode: "multiple" | "tags";
1325
+ /** @see SelectLabelInValueMultipleProp for the `{value,label}` dialect. */
1326
+ labelInValue?: false;
1015
1327
  value?: ValueProp<string[]>;
1016
1328
  /** Uncontrolled initial selection (controlled-triad). */
1017
1329
  defaultValue?: DefaultValueProp<string[]>;
@@ -1030,6 +1342,64 @@ export type SearchSelectMultipleProp = {
1030
1342
  maxTagCount?: MaxTagCountProp;
1031
1343
  /** The node standing in for what `maxTagCount` hid (antd `maxTagPlaceholder`). */
1032
1344
  maxTagPlaceholder?: MaxTagPlaceholderProp;
1345
+ /**
1346
+ * antd `maxTagTextLength` — cut each chip's text to this many characters (an ellipsis marks the
1347
+ * cut). It trims what the TRIGGER shows only; the value keeps its whole label.
1348
+ */
1349
+ maxTagTextLength?: number;
1350
+ /**
1351
+ * antd `tagRender` — render one chip yourself. Exactly the shape `TagInput`'s `tagRender` takes,
1352
+ * so the two chip surfaces in this library are configured the same way. The `onClose` handed in
1353
+ * is the same remover the built-in ✕ calls, so a custom chip cannot end up unremovable.
1354
+ */
1355
+ tagRender?: (props: {
1356
+ value: string;
1357
+ label: React.ReactNode;
1358
+ onClose: () => void;
1359
+ index: number;
1360
+ disabled: boolean;
1361
+ }) => React.ReactNode;
1362
+ /**
1363
+ * antd `tokenSeparators` — characters that commit what has been typed. Typing or PASTING
1364
+ * "a,b,c" with `[","]` commits three values in one change, which is the point: a run pasted out
1365
+ * of a spreadsheet becomes a selection instead of one long nonsense token. In `mode="multiple"`
1366
+ * a token only counts when it matches a row; in `mode="tags"` it is accepted as it stands.
1367
+ */
1368
+ tokenSeparators?: string[];
1369
+ };
1370
+ /**
1371
+ * antd `labelInValue`, single. The value carries its own label, so a screen that never sees the
1372
+ * option list can still render what was picked.
1373
+ */
1374
+ export type SelectLabelInValueSingleProp = {
1375
+ labelInValue: true;
1376
+ mode?: undefined;
1377
+ value?: SelectLabeledValueProp | null;
1378
+ defaultValue?: SelectLabeledValueProp | null;
1379
+ onValueChange?: (value: SelectLabeledValueProp | undefined, option?: SearchSelectOptionProp) => void;
1380
+ onSelect?: (value: SelectLabeledValueProp, option: SearchSelectOptionProp) => void;
1381
+ };
1382
+ /** antd `labelInValue`, multiple/tags. */
1383
+ export type SelectLabelInValueMultipleProp = {
1384
+ labelInValue: true;
1385
+ mode: "multiple" | "tags";
1386
+ value?: SelectLabeledValueProp[];
1387
+ defaultValue?: SelectLabeledValueProp[];
1388
+ onValueChange?: (value: SelectLabeledValueProp[], options?: SearchSelectOptionProp[]) => void;
1389
+ onSelect?: (value: SelectLabeledValueProp, option: SearchSelectOptionProp) => void;
1390
+ onDeselect?: (value: SelectLabeledValueProp, option: SearchSelectOptionProp) => void;
1391
+ maxCount?: number;
1392
+ maxTagCount?: MaxTagCountProp;
1393
+ maxTagPlaceholder?: MaxTagPlaceholderProp;
1394
+ maxTagTextLength?: number;
1395
+ tokenSeparators?: string[];
1396
+ tagRender?: (props: {
1397
+ value: string;
1398
+ label: React.ReactNode;
1399
+ onClose: () => void;
1400
+ index: number;
1401
+ disabled: boolean;
1402
+ }) => React.ReactNode;
1033
1403
  };
1034
1404
  /** @see Select — the searchable engine. Single by default; `mode="multiple"` switches the shape. */
1035
1405
  export type SearchSelectProp = SearchSelectBaseProp & (SearchSelectSingleProp | SearchSelectMultipleProp);
@@ -1040,11 +1410,15 @@ export type SearchSelectProp = SearchSelectBaseProp & (SearchSelectSingleProp |
1040
1410
  */
1041
1411
  export type SelectDataProp = SearchSelectBaseProp & {
1042
1412
  /**
1043
- * Show the search box (combobox). Defaults to true when `loadOptions` is set or
1044
- * `mode="multiple"` is in force (antd's own defaults), otherwise false.
1413
+ * Show the search box (combobox). Defaults to true when `loadOptions` is set or a multi-value
1414
+ * `mode` is in force (antd's own defaults), otherwise false.
1415
+ *
1416
+ * The OBJECT form is antd's, and configures the search in one place —
1417
+ * `{ filterOption, optionFilterProp, filterSort, searchValue, onSearch, autoClearSearchValue }`.
1418
+ * Passing it also turns the search on.
1045
1419
  */
1046
- showSearch?: boolean;
1047
- } & (SearchSelectSingleProp | SearchSelectMultipleProp);
1420
+ showSearch?: boolean | SelectShowSearchProp;
1421
+ } & (SearchSelectSingleProp | SearchSelectMultipleProp | SelectLabelInValueSingleProp | SelectLabelInValueMultipleProp);
1048
1422
  /** @see UploadFileItem */
1049
1423
  export type UploadFileItemProp = UploadFileItem;
1050
1424
  /** @see Upload */