@astryxdesign/core 0.1.2-canary.bfcbf64 → 0.1.2-canary.c395fca

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 (132) hide show
  1. package/dist/Breadcrumbs/BreadcrumbItem.d.ts +1 -1
  2. package/dist/Breadcrumbs/BreadcrumbItem.d.ts.map +1 -1
  3. package/dist/Breadcrumbs/BreadcrumbItem.js +4 -1
  4. package/dist/Button/Button.d.ts.map +1 -1
  5. package/dist/Button/Button.js +2 -4
  6. package/dist/Calendar/Calendar.d.ts.map +1 -1
  7. package/dist/Calendar/Calendar.js +33 -14
  8. package/dist/Calendar/hooks/index.d.ts +0 -2
  9. package/dist/Calendar/hooks/index.d.ts.map +1 -1
  10. package/dist/Calendar/hooks/index.js +1 -2
  11. package/dist/Calendar/index.d.ts +2 -2
  12. package/dist/Calendar/index.d.ts.map +1 -1
  13. package/dist/Calendar/index.js +1 -1
  14. package/dist/CheckboxList/CheckboxList.js +3 -3
  15. package/dist/Citation/Citation.d.ts.map +1 -1
  16. package/dist/Citation/Citation.js +3 -3
  17. package/dist/ContextMenu/ContextMenu.d.ts +1 -7
  18. package/dist/ContextMenu/ContextMenu.d.ts.map +1 -1
  19. package/dist/ContextMenu/ContextMenu.js +7 -13
  20. package/dist/DropdownMenu/DropdownMenu.d.ts +1 -8
  21. package/dist/DropdownMenu/DropdownMenu.d.ts.map +1 -1
  22. package/dist/DropdownMenu/DropdownMenu.js +4 -9
  23. package/dist/Field/Field.d.ts +4 -4
  24. package/dist/Field/Field.d.ts.map +1 -1
  25. package/dist/Field/Field.js +2 -2
  26. package/dist/Field/FieldLabel.d.ts +4 -4
  27. package/dist/Field/FieldLabel.d.ts.map +1 -1
  28. package/dist/Field/FieldLabel.js +2 -2
  29. package/dist/InputGroup/InputGroup.js +3 -3
  30. package/dist/Link/Link.d.ts.map +1 -1
  31. package/dist/Link/Link.js +2 -4
  32. package/dist/MoreMenu/MoreMenu.d.ts +1 -7
  33. package/dist/MoreMenu/MoreMenu.d.ts.map +1 -1
  34. package/dist/MoreMenu/MoreMenu.js +0 -2
  35. package/dist/MultiSelector/MultiSelector.d.ts +25 -2
  36. package/dist/MultiSelector/MultiSelector.d.ts.map +1 -1
  37. package/dist/MultiSelector/MultiSelector.js +31 -6
  38. package/dist/ProgressBar/ProgressBar.d.ts.map +1 -1
  39. package/dist/ProgressBar/ProgressBar.js +2 -4
  40. package/dist/RadioList/RadioList.js +3 -3
  41. package/dist/SegmentedControl/SegmentedControl.d.ts +1 -1
  42. package/dist/SegmentedControl/SegmentedControl.d.ts.map +1 -1
  43. package/dist/SegmentedControl/SegmentedControl.js +51 -61
  44. package/dist/Selector/Selector.d.ts +22 -1
  45. package/dist/Selector/Selector.d.ts.map +1 -1
  46. package/dist/Selector/Selector.js +31 -6
  47. package/dist/Switch/Switch.d.ts.map +1 -1
  48. package/dist/Switch/Switch.js +2 -4
  49. package/dist/TabList/TabList.d.ts +3 -2
  50. package/dist/TabList/TabList.d.ts.map +1 -1
  51. package/dist/TabList/TabList.js +55 -33
  52. package/dist/Table/tableContextMenu.d.ts.map +1 -1
  53. package/dist/Table/tableContextMenu.js +0 -3
  54. package/dist/TextArea/TextArea.d.ts.map +1 -1
  55. package/dist/TextArea/TextArea.js +2 -4
  56. package/dist/Toolbar/Toolbar.d.ts +3 -3
  57. package/dist/Toolbar/Toolbar.d.ts.map +1 -1
  58. package/dist/Toolbar/Toolbar.js +46 -6
  59. package/dist/TreeList/TreeList.d.ts.map +1 -1
  60. package/dist/TreeList/TreeList.js +16 -22
  61. package/dist/TreeList/TreeListItem.d.ts +3 -2
  62. package/dist/TreeList/TreeListItem.d.ts.map +1 -1
  63. package/dist/astryx.css +3 -0
  64. package/dist/astryx.umd.js +47 -47
  65. package/dist/astryx.umd.js.map +4 -4
  66. package/dist/hooks/index.d.ts +4 -2
  67. package/dist/hooks/index.d.ts.map +1 -1
  68. package/dist/hooks/index.js +1 -0
  69. package/dist/hooks/useGridFocus.d.ts +56 -0
  70. package/dist/hooks/useGridFocus.d.ts.map +1 -1
  71. package/dist/hooks/useGridFocus.js +138 -24
  72. package/dist/hooks/useKeyboardHint.d.ts +82 -0
  73. package/dist/hooks/useKeyboardHint.d.ts.map +1 -0
  74. package/dist/hooks/useKeyboardHint.js +220 -0
  75. package/dist/hooks/useTreeFocus.d.ts +27 -3
  76. package/dist/hooks/useTreeFocus.d.ts.map +1 -1
  77. package/dist/hooks/useTreeFocus.js +69 -6
  78. package/package.json +1 -1
  79. package/src/Breadcrumbs/BreadcrumbItem.tsx +5 -2
  80. package/src/Button/Button.tsx +3 -16
  81. package/src/Calendar/Calendar.tsx +52 -22
  82. package/src/Calendar/hooks/index.ts +0 -6
  83. package/src/Calendar/index.ts +0 -3
  84. package/src/CheckboxList/CheckboxList.tsx +3 -3
  85. package/src/Citation/Citation.doc.mjs +10 -0
  86. package/src/Citation/Citation.test.tsx +117 -0
  87. package/src/Citation/Citation.tsx +9 -1
  88. package/src/ContextMenu/ContextMenu.doc.mjs +0 -6
  89. package/src/ContextMenu/ContextMenu.test.tsx +4 -6
  90. package/src/ContextMenu/ContextMenu.tsx +7 -19
  91. package/src/DropdownMenu/DropdownMenu.doc.mjs +1 -8
  92. package/src/DropdownMenu/DropdownMenu.test.tsx +0 -23
  93. package/src/DropdownMenu/DropdownMenu.tsx +4 -16
  94. package/src/Field/Field.test.tsx +2 -2
  95. package/src/Field/Field.tsx +5 -5
  96. package/src/Field/FieldLabel.tsx +5 -5
  97. package/src/InputGroup/InputGroup.tsx +3 -3
  98. package/src/Link/Link.tsx +2 -13
  99. package/src/MoreMenu/MoreMenu.doc.mjs +2 -17
  100. package/src/MoreMenu/MoreMenu.tsx +0 -9
  101. package/src/MultiSelector/MultiSelector.doc.mjs +25 -0
  102. package/src/MultiSelector/MultiSelector.test.tsx +150 -1
  103. package/src/MultiSelector/MultiSelector.tsx +55 -3
  104. package/src/ProgressBar/ProgressBar.tsx +2 -3
  105. package/src/RadioList/RadioList.tsx +3 -3
  106. package/src/SegmentedControl/SegmentedControl.tsx +51 -77
  107. package/src/Selector/Selector.doc.mjs +21 -0
  108. package/src/Selector/Selector.test.tsx +123 -1
  109. package/src/Selector/Selector.tsx +53 -3
  110. package/src/Switch/Switch.tsx +2 -16
  111. package/src/TabList/TabList.test.tsx +41 -0
  112. package/src/TabList/TabList.tsx +66 -39
  113. package/src/Table/tableContextMenu.tsx +1 -5
  114. package/src/TextArea/TextArea.tsx +3 -13
  115. package/src/Toolbar/Toolbar.test.tsx +64 -6
  116. package/src/Toolbar/Toolbar.tsx +55 -4
  117. package/src/TreeList/TreeList.tsx +17 -28
  118. package/src/TreeList/TreeListItem.tsx +3 -2
  119. package/src/VisuallyHidden/VisuallyHidden.doc.mjs +7 -7
  120. package/src/hooks/index.ts +12 -5
  121. package/src/hooks/useGridFocus.doc.mjs +40 -2
  122. package/src/hooks/useGridFocus.test.tsx +132 -0
  123. package/src/hooks/useGridFocus.ts +179 -23
  124. package/src/hooks/useKeyboardHint.doc.mjs +101 -0
  125. package/src/hooks/useKeyboardHint.test.tsx +70 -0
  126. package/src/hooks/useKeyboardHint.tsx +332 -0
  127. package/src/hooks/useTreeFocus.doc.mjs +15 -1
  128. package/src/hooks/useTreeFocus.ts +101 -6
  129. package/dist/Calendar/hooks/useCalendarRovingTabindex.d.ts +0 -57
  130. package/dist/Calendar/hooks/useCalendarRovingTabindex.d.ts.map +0 -1
  131. package/dist/Calendar/hooks/useCalendarRovingTabindex.js +0 -96
  132. package/src/Calendar/hooks/useCalendarRovingTabindex.ts +0 -118
package/dist/Link/Link.js CHANGED
@@ -21,6 +21,7 @@ import { colorVars, durationVars, easeVars, spacingVars, typeScaleVars } from ".
21
21
  import { Icon } from "../Icon/index.js";
22
22
  import { Tooltip } from "../Tooltip/index.js";
23
23
  import { Text } from "../Text/index.js";
24
+ import { VisuallyHidden } from "../VisuallyHidden/index.js";
24
25
  import { useLinkComponent } from "./useLinkComponent.js";
25
26
  import { mergeProps } from "../utils/index.js";
26
27
  import { computeTargetAndRel } from "./computeTargetAndRel.js";
@@ -179,10 +180,7 @@ export function Link({
179
180
  icon: "externalLink",
180
181
  size: "xsm",
181
182
  color: "inherit"
182
- }), /*#__PURE__*/_jsx("span", {
183
- ...{
184
- className: "x10l6tqk x1i1rx1s xjm9jq1 xkdpibf x1717udv xb3r6kr xzpqnlu xuxw1ft xng3xce"
185
- },
183
+ }), /*#__PURE__*/_jsx(VisuallyHidden, {
186
184
  children: newTabLabel
187
185
  })]
188
186
  })]
@@ -59,12 +59,6 @@ export interface MoreMenuProps extends Pick<BaseProps, 'xstyle' | 'className' |
59
59
  * Callback fired when the menu visibility changes.
60
60
  */
61
61
  onOpenChange?: (isOpen: boolean) => void;
62
- /**
63
- * Whether to auto-focus the first menu item when the menu opens.
64
- * Set to `false` for inline showcases or documentation previews.
65
- * @default true
66
- */
67
- hasAutoFocus?: boolean;
68
62
  /** Test ID for testing frameworks. */
69
63
  'data-testid'?: string;
70
64
  }
@@ -83,7 +77,7 @@ export interface MoreMenuProps extends Pick<BaseProps, 'xstyle' | 'className' |
83
77
  * />
84
78
  * ```
85
79
  */
86
- export declare function MoreMenu({ items, label, variant, size: sizeProp, icon, isDisabled, isMenuOpen, onOpenChange, hasAutoFocus, xstyle, className: classNameProp, style, 'data-testid': testId, ref, }: MoreMenuProps): import("react").JSX.Element;
80
+ export declare function MoreMenu({ items, label, variant, size: sizeProp, icon, isDisabled, isMenuOpen, onOpenChange, xstyle, className: classNameProp, style, 'data-testid': testId, ref, }: MoreMenuProps): import("react").JSX.Element;
87
81
  export declare namespace MoreMenu {
88
82
  var displayName: string;
89
83
  }
@@ -1 +1 @@
1
- {"version":3,"file":"MoreMenu.d.ts","sourceRoot":"","sources":["../../src/MoreMenu/MoreMenu.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,OAAO,CAAC;AAIrC,OAAO,KAAK,EAAC,kBAAkB,EAAC,MAAM,iBAAiB,CAAC;AACxD,OAAO,KAAK,EAAC,aAAa,EAAE,UAAU,EAAC,MAAM,WAAW,CAAC;AACzD,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AAG5C,MAAM,WAAW,aAAc,SAAQ,IAAI,CACzC,SAAS,EACT,QAAQ,GAAG,WAAW,GAAG,OAAO,CACjC;IACC,0CAA0C;IAC1C,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC;IAEnC;;;OAGG;IACH,KAAK,EAAE,kBAAkB,EAAE,CAAC;IAE5B;;;;OAIG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf;;;OAGG;IACH,OAAO,CAAC,EAAE,aAAa,CAAC;IAExB;;;OAGG;IACH,IAAI,CAAC,EAAE,UAAU,CAAC;IAElB;;;OAGG;IACH,IAAI,CAAC,EAAE,SAAS,CAAC;IAEjB;;;OAGG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IAErB;;OAEG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IAErB;;OAEG;IACH,YAAY,CAAC,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,IAAI,CAAC;IAEzC;;;;OAIG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;IAEvB,sCAAsC;IACtC,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,QAAQ,CAAC,EACvB,KAAK,EACL,KAAsB,EACtB,OAAiB,EACjB,IAAI,EAAE,QAAQ,EACd,IAAI,EACJ,UAAkB,EAClB,UAAU,EACV,YAAY,EACZ,YAAY,EACZ,MAAM,EACN,SAAS,EAAE,aAAa,EACxB,KAAK,EACL,aAAa,EAAE,MAAM,EACrB,GAAG,GACJ,EAAE,aAAa,+BA+Bf;yBA9Ce,QAAQ"}
1
+ {"version":3,"file":"MoreMenu.d.ts","sourceRoot":"","sources":["../../src/MoreMenu/MoreMenu.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,OAAO,CAAC;AAIrC,OAAO,KAAK,EAAC,kBAAkB,EAAC,MAAM,iBAAiB,CAAC;AACxD,OAAO,KAAK,EAAC,aAAa,EAAE,UAAU,EAAC,MAAM,WAAW,CAAC;AACzD,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AAG5C,MAAM,WAAW,aAAc,SAAQ,IAAI,CACzC,SAAS,EACT,QAAQ,GAAG,WAAW,GAAG,OAAO,CACjC;IACC,0CAA0C;IAC1C,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC;IAEnC;;;OAGG;IACH,KAAK,EAAE,kBAAkB,EAAE,CAAC;IAE5B;;;;OAIG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf;;;OAGG;IACH,OAAO,CAAC,EAAE,aAAa,CAAC;IAExB;;;OAGG;IACH,IAAI,CAAC,EAAE,UAAU,CAAC;IAElB;;;OAGG;IACH,IAAI,CAAC,EAAE,SAAS,CAAC;IAEjB;;;OAGG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IAErB;;OAEG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IAErB;;OAEG;IACH,YAAY,CAAC,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,IAAI,CAAC;IAEzC,sCAAsC;IACtC,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,QAAQ,CAAC,EACvB,KAAK,EACL,KAAsB,EACtB,OAAiB,EACjB,IAAI,EAAE,QAAQ,EACd,IAAI,EACJ,UAAkB,EAClB,UAAU,EACV,YAAY,EACZ,MAAM,EACN,SAAS,EAAE,aAAa,EACxB,KAAK,EACL,aAAa,EAAE,MAAM,EACrB,GAAG,GACJ,EAAE,aAAa,+BA8Bf;yBA5Ce,QAAQ"}
@@ -46,7 +46,6 @@ export function MoreMenu({
46
46
  isDisabled = false,
47
47
  isMenuOpen,
48
48
  onOpenChange,
49
- hasAutoFocus,
50
49
  xstyle,
51
50
  className: classNameProp,
52
51
  style,
@@ -73,7 +72,6 @@ export function MoreMenu({
73
72
  },
74
73
  items: items,
75
74
  hasChevron: false,
76
- hasAutoFocus: hasAutoFocus,
77
75
  "data-testid": testId
78
76
  });
79
77
  }
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * @file MultiSelector.tsx
3
- * @input Uses React, StyleX, usePopover, CheckboxInput, Field, Badge, Icon
3
+ * @input Uses React, StyleX, usePopover, useTooltip, CheckboxInput, Field, Badge, Icon
4
4
  * @output Exports MultiSelector component
5
5
  * @position Core implementation; consumed by index.ts
6
6
  *
@@ -46,6 +46,29 @@ export interface MultiSelectorProps<T extends MultiSelectorOptionType = MultiSel
46
46
  * @default false
47
47
  */
48
48
  isDisabled?: boolean;
49
+ /**
50
+ * Explains why the selector is disabled. When set together with
51
+ * `isDisabled`, the selector shows a tooltip with this text on hover and
52
+ * keyboard focus, and the trigger stays focusable (via `aria-disabled`)
53
+ * so the reason is discoverable by keyboard and assistive technology.
54
+ * Activation stays blocked.
55
+ *
56
+ * Use this instead of wrapping a disabled selector in `Tooltip` — disabled
57
+ * controls don't emit the pointer events an external tooltip needs.
58
+ *
59
+ * @example
60
+ * ```
61
+ * <MultiSelector
62
+ * label="Columns"
63
+ * options={columns}
64
+ * value={selected}
65
+ * onChange={setSelected}
66
+ * isDisabled
67
+ * disabledMessage="Select a table first"
68
+ * />
69
+ * ```
70
+ */
71
+ disabledMessage?: string;
49
72
  /**
50
73
  * The options to display in the selector.
51
74
  * Can be strings, objects, dividers, or sections.
@@ -167,7 +190,7 @@ export interface MultiSelectorProps<T extends MultiSelectorOptionType = MultiSel
167
190
  * />
168
191
  * ```
169
192
  */
170
- export declare function MultiSelector<T extends MultiSelectorOptionType>({ label, isLabelHidden, description, isOptional, isRequired, isDisabled, options, value, onChange, changeAction, isLoading, placeholder, size: sizeProp, status, labelTooltip, startIcon, hasClear, hasSelectAll, selectAllLabel, hasSearch, searchPlaceholder, triggerDisplay, maxBadges, renderOption, isDefaultOpen, 'data-testid': testId, width, xstyle, className, style, }: MultiSelectorProps<T>): React.JSX.Element;
193
+ export declare function MultiSelector<T extends MultiSelectorOptionType>({ label, isLabelHidden, description, isOptional, isRequired, isDisabled, disabledMessage, options, value, onChange, changeAction, isLoading, placeholder, size: sizeProp, status, labelTooltip, startIcon, hasClear, hasSelectAll, selectAllLabel, hasSearch, searchPlaceholder, triggerDisplay, maxBadges, renderOption, isDefaultOpen, 'data-testid': testId, width, xstyle, className, style, }: MultiSelectorProps<T>): React.JSX.Element;
171
194
  export declare namespace MultiSelector {
172
195
  var displayName: string;
173
196
  }
@@ -1 +1 @@
1
- {"version":3,"file":"MultiSelector.d.ts","sourceRoot":"","sources":["../../src/MultiSelector/MultiSelector.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"MultiSelector.d.ts","sourceRoot":"","sources":["../../src/MultiSelector/MultiSelector.tsx"],"names":[],"mappings":"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"}
@@ -4,7 +4,7 @@
4
4
 
5
5
  /**
6
6
  * @file MultiSelector.tsx
7
- * @input Uses React, StyleX, usePopover, CheckboxInput, Field, Badge, Icon
7
+ * @input Uses React, StyleX, usePopover, useTooltip, CheckboxInput, Field, Badge, Icon
8
8
  * @output Exports MultiSelector component
9
9
  * @position Core implementation; consumed by index.ts
10
10
  *
@@ -16,6 +16,7 @@
16
16
  import React, { useCallback, useEffect, useId, useMemo, useOptimistic, useRef, useState, useTransition } from 'react';
17
17
  import * as stylex from '@stylexjs/stylex';
18
18
  import { usePopover } from "../Popover/usePopover.js";
19
+ import { useTooltip } from "../Tooltip/index.js";
19
20
  import { Icon, renderIconSlot } from "../Icon/index.js";
20
21
  import { Field, inputStatusBorderStyles, inputStatusHoverShadowStyles, inputWrapperStyles } from "../Field/index.js";
21
22
  import { Divider } from "../Divider/index.js";
@@ -175,6 +176,7 @@ export function MultiSelector({
175
176
  isOptional = false,
176
177
  isRequired = false,
177
178
  isDisabled = false,
179
+ disabledMessage,
178
180
  options,
179
181
  value,
180
182
  onChange,
@@ -218,8 +220,22 @@ export function MultiSelector({
218
220
  const [optimisticValue, setOptimisticValue] = useOptimistic(value);
219
221
  const isBusy = isLoading || optimisticValue !== value;
220
222
 
223
+ // Disabled-reason tooltip. Disabled controls swallow pointer events, so the
224
+ // tooltip listeners attach to the trigger container (which already exists)
225
+ // and the trigger button stays perceivable via aria-disabled instead of the
226
+ // disabled attribute. Activation is blocked by the isDisabled guards in
227
+ // useMultiCombobox (onTriggerClick / onKeyDown).
228
+ const showsDisabledMessage = isDisabled && !!disabledMessage;
229
+ const disabledMessageTooltip = useTooltip({
230
+ placement: 'above',
231
+ // The container div is not naturally focusable; focusin bubbles up from
232
+ // the trigger button, so always attach focus listeners.
233
+ focusTrigger: 'always',
234
+ isEnabled: showsDisabledMessage
235
+ });
236
+
221
237
  // Build aria-describedby
222
- const ariaDescribedBy = [description ? descriptionId : null, status?.message ? statusMessageId : null].filter(Boolean).join(' ') || undefined;
238
+ const ariaDescribedBy = [description ? descriptionId : null, status?.message ? statusMessageId : null, showsDisabledMessage ? disabledMessageTooltip.describedBy : null].filter(Boolean).join(' ') || undefined;
223
239
 
224
240
  // Flatten options for keyboard navigation
225
241
  const selectableItems = useMemo(() => getSelectableOptions(options), [options]);
@@ -686,6 +702,10 @@ export function MultiSelector({
686
702
  children: [/*#__PURE__*/_jsxs("div", {
687
703
  ref: el => {
688
704
  popover.triggerRef(el);
705
+ // Anchor + hover/focus listeners for the disabled-message tooltip.
706
+ // Handlers are gated internally by isEnabled, and anchor names
707
+ // compose, so attaching unconditionally is safe.
708
+ disabledMessageTooltip.ref(el);
689
709
  },
690
710
  onClick: onTriggerClick,
691
711
  "data-testid": testId,
@@ -712,10 +732,15 @@ export function MultiSelector({
712
732
  "aria-describedby": ariaDescribedBy,
713
733
  "aria-required": isRequired ? 'true' : undefined,
714
734
  "aria-invalid": status?.type === 'error' ? 'true' : undefined,
715
- "aria-busy": isBusy || undefined,
716
- disabled: isDisabled,
735
+ "aria-busy": isBusy || undefined
736
+ // With a disabledMessage the trigger keeps focusability via
737
+ // aria-disabled so the reason is focus-discoverable; activation is
738
+ // still blocked by the isDisabled guards in useMultiCombobox.
739
+ ,
740
+ disabled: isDisabled && !showsDisabledMessage,
741
+ "aria-disabled": showsDisabledMessage ? 'true' : undefined,
717
742
  onKeyDown: onKeyDown,
718
- tabIndex: isDisabled ? -1 : 0,
743
+ tabIndex: isDisabled && !showsDisabledMessage ? -1 : 0,
719
744
  ...{
720
745
  className: "x78zum5 x6s0dn4 x1qughib x1txdalj x1iyjqo2 xs83m0k x1r8uery xeuugli x1717udv x1ghz6dp xc342km xng3xce xjbqb8w xjb2p0i x1qlqyl8 x15bjb6t x1heor9g x1ypdohk x1a2a7pz x1p25gnr x1wfwxd8 xh6dtrn"
721
746
  },
@@ -779,7 +804,7 @@ export function MultiSelector({
779
804
  placement: 'below',
780
805
  alignment: 'start',
781
806
  xstyle: styles.popover
782
- })]
807
+ }), showsDisabledMessage && disabledMessageTooltip.renderTooltip(disabledMessage)]
783
808
  });
784
809
  }
785
810
  MultiSelector.displayName = 'MultiSelector';
@@ -1 +1 @@
1
- {"version":3,"file":"ProgressBar.d.ts","sourceRoot":"","sources":["../../src/ProgressBar/ProgressBar.tsx"],"names":[],"mappings":"AA+BA,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AAG5C;;;;;;;;;;;;GAYG;AACH,MAAM,WAAW,qBAAqB;IACpC,MAAM,EAAE,IAAI,CAAC;IACb,OAAO,EAAE,IAAI,CAAC;IACd,OAAO,EAAE,IAAI,CAAC;IACd,OAAO,EAAE,IAAI,CAAC;IACd,KAAK,EAAE,IAAI,CAAC;CACb;AAED;;;GAGG;AACH,MAAM,MAAM,kBAAkB,GAAG,MAAM,qBAAqB,CAAC;AAE7D,MAAM,WAAW,gBAAiB,SAAQ,SAAS,CAAC,cAAc,CAAC;IACjE,wCAAwC;IACxC,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;IAChC;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;OAGG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;;;OAGG;IACH,KAAK,EAAE,MAAM,CAAC;IACd;;;OAGG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB;;;;OAIG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB;;;OAGG;IACH,gBAAgB,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,KAAK,MAAM,CAAC;IAC1D;;;OAGG;IACH,OAAO,CAAC,EAAE,kBAAkB,CAAC;IAC7B;;;;;;OAMG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B;;;;OAIG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;OAEG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAkHD;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,WAAW,CAAC,EAC1B,KAAS,EACT,GAAS,EACT,KAAK,EACL,aAAqB,EACrB,aAAqB,EACrB,gBAA0C,EAC1C,OAAkB,EAClB,eAAuB,EACvB,UAAkB,EAClB,MAAM,EACN,SAAS,EACT,KAAK,EACL,aAAa,EAAE,UAAU,EACzB,GAAG,EACH,GAAG,IAAI,EACR,EAAE,gBAAgB,+BAmFlB;yBAnGe,WAAW"}
1
+ {"version":3,"file":"ProgressBar.d.ts","sourceRoot":"","sources":["../../src/ProgressBar/ProgressBar.tsx"],"names":[],"mappings":"AA+BA,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AAI5C;;;;;;;;;;;;GAYG;AACH,MAAM,WAAW,qBAAqB;IACpC,MAAM,EAAE,IAAI,CAAC;IACb,OAAO,EAAE,IAAI,CAAC;IACd,OAAO,EAAE,IAAI,CAAC;IACd,OAAO,EAAE,IAAI,CAAC;IACd,KAAK,EAAE,IAAI,CAAC;CACb;AAED;;;GAGG;AACH,MAAM,MAAM,kBAAkB,GAAG,MAAM,qBAAqB,CAAC;AAE7D,MAAM,WAAW,gBAAiB,SAAQ,SAAS,CAAC,cAAc,CAAC;IACjE,wCAAwC;IACxC,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;IAChC;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;OAGG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;;;OAGG;IACH,KAAK,EAAE,MAAM,CAAC;IACd;;;OAGG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB;;;;OAIG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB;;;OAGG;IACH,gBAAgB,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,KAAK,MAAM,CAAC;IAC1D;;;OAGG;IACH,OAAO,CAAC,EAAE,kBAAkB,CAAC;IAC7B;;;;;;OAMG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B;;;;OAIG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;OAEG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAkHD;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,WAAW,CAAC,EAC1B,KAAS,EACT,GAAS,EACT,KAAK,EACL,aAAqB,EACrB,aAAqB,EACrB,gBAA0C,EAC1C,OAAkB,EAClB,eAAuB,EACvB,UAAkB,EAClB,MAAM,EACN,SAAS,EACT,KAAK,EACL,aAAa,EAAE,UAAU,EACzB,GAAG,EACH,GAAG,IAAI,EACR,EAAE,gBAAgB,+BAiFlB;yBAjGe,WAAW"}
@@ -21,6 +21,7 @@ import "../theme/tokens.stylex.js";
21
21
  import { colorVars, spacingVars, radiusVars, fontWeightVars, durationVars, easeVars, typeScaleVars } from "../theme/tokens.stylex.js";
22
22
  import { mergeProps } from "../utils/index.js";
23
23
  import { themeProps } from "../utils/themeProps.js";
24
+ import { VisuallyHidden } from "../VisuallyHidden/index.js";
24
25
 
25
26
  /**
26
27
  * Extensible variant map for ProgressBar.
@@ -194,11 +195,8 @@ export function ProgressBar({
194
195
  }[!!isDisabled << 0],
195
196
  children: valueText
196
197
  })]
197
- }) : /*#__PURE__*/_jsx("span", {
198
+ }) : /*#__PURE__*/_jsx(VisuallyHidden, {
198
199
  id: labelId,
199
- ...{
200
- className: "x10l6tqk x1i1rx1s xjm9jq1 x1717udv xkdpibf xb3r6kr xzpqnlu xuxw1ft xc342km"
201
- },
202
200
  children: label
203
201
  }), /*#__PURE__*/_jsx("div", {
204
202
  role: "progressbar",
@@ -67,7 +67,7 @@ export function RadioList({
67
67
  }) {
68
68
  const name = useId();
69
69
  const inputID = useId();
70
- const labelElementID = useId();
70
+ const labelID = useId();
71
71
  const descriptionID = useId();
72
72
  const statusMessageID = useId();
73
73
  const groupRef = useRef(null);
@@ -154,7 +154,7 @@ export function RadioList({
154
154
  isLabelHidden: isLabelHidden,
155
155
  description: description,
156
156
  inputID: inputID,
157
- labelElementID: labelElementID,
157
+ labelID: labelID,
158
158
  isGroupLabel: true,
159
159
  descriptionID: description ? descriptionID : undefined,
160
160
  isOptional: isOptional,
@@ -174,7 +174,7 @@ export function RadioList({
174
174
  children: /*#__PURE__*/_jsx("div", {
175
175
  ref: groupRef,
176
176
  role: "radiogroup",
177
- "aria-labelledby": labelElementID,
177
+ "aria-labelledby": labelID,
178
178
  onFocus: handleFocus,
179
179
  "aria-describedby": [description ? descriptionID : null, status?.message ? statusMessageID : null].filter(Boolean).join(' ') || undefined,
180
180
  "aria-invalid": status?.type === 'error' ? true : undefined,
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * @file SegmentedControl.tsx
3
- * @input Uses React, StyleX, SegmentedControlContext
3
+ * @input Uses React, StyleX, SegmentedControlContext, useListFocus, useKeyboardHint
4
4
  * @output Exports SegmentedControl component and SegmentedControlProps type
5
5
  * @position Container wrapper; provides context to SegmentedControlItem children
6
6
  *
@@ -1 +1 @@
1
- {"version":3,"file":"SegmentedControl.d.ts","sourceRoot":"","sources":["../../src/SegmentedControl/SegmentedControl.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,EAA+B,KAAK,SAAS,EAAC,MAAM,OAAO,CAAC;AAK1E,OAAO,KAAK,EACV,oBAAoB,EACpB,sBAAsB,EACvB,MAAM,2BAA2B,CAAC;AAGnC,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AAG5C,MAAM,WAAW,qBAAsB,SAAQ,IAAI,CACjD,SAAS,CAAC,cAAc,CAAC,EACzB,UAAU,CACX;IACC,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;IAChC;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;IACd;;OAEG;IACH,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;IACd;;;OAGG;IACH,IAAI,CAAC,EAAE,oBAAoB,CAAC;IAC5B;;;;;OAKG;IACH,MAAM,CAAC,EAAE,sBAAsB,CAAC;IAChC;;;OAGG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;OAEG;IACH,QAAQ,EAAE,SAAS,CAAC;CACrB;AAwCD;;;;;;;;;;;;GAYG;AACH,wBAAgB,gBAAgB,CAAC,EAC/B,GAAG,EACH,KAAK,EACL,QAAQ,EACR,KAAK,EACL,IAAI,EAAE,QAAQ,EACd,MAAc,EACd,UAAkB,EAClB,QAAQ,EACR,MAAM,EACN,SAAS,EACT,KAAK,GACN,EAAE,qBAAqB,qBAmHvB;yBA/He,gBAAgB"}
1
+ {"version":3,"file":"SegmentedControl.d.ts","sourceRoot":"","sources":["../../src/SegmentedControl/SegmentedControl.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,EAAuB,KAAK,SAAS,EAAC,MAAM,OAAO,CAAC;AAMlE,OAAO,KAAK,EACV,oBAAoB,EACpB,sBAAsB,EACvB,MAAM,2BAA2B,CAAC;AAGnC,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AAG5C,MAAM,WAAW,qBAAsB,SAAQ,IAAI,CACjD,SAAS,CAAC,cAAc,CAAC,EACzB,UAAU,CACX;IACC,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;IAChC;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;IACd;;OAEG;IACH,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;IACd;;;OAGG;IACH,IAAI,CAAC,EAAE,oBAAoB,CAAC;IAC5B;;;;;OAKG;IACH,MAAM,CAAC,EAAE,sBAAsB,CAAC;IAChC;;;OAGG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;OAEG;IACH,QAAQ,EAAE,SAAS,CAAC;CACrB;AAwCD;;;;;;;;;;;;GAYG;AACH,wBAAgB,gBAAgB,CAAC,EAC/B,GAAG,EACH,KAAK,EACL,QAAQ,EACR,KAAK,EACL,IAAI,EAAE,QAAQ,EACd,MAAc,EACd,UAAkB,EAClB,QAAQ,EACR,MAAM,EACN,SAAS,EACT,KAAK,GACN,EAAE,qBAAqB,qBAwFvB;yBApGe,gBAAgB"}
@@ -4,7 +4,7 @@
4
4
 
5
5
  /**
6
6
  * @file SegmentedControl.tsx
7
- * @input Uses React, StyleX, SegmentedControlContext
7
+ * @input Uses React, StyleX, SegmentedControlContext, useListFocus, useKeyboardHint
8
8
  * @output Exports SegmentedControl component and SegmentedControlProps type
9
9
  * @position Container wrapper; provides context to SegmentedControlItem children
10
10
  *
@@ -14,16 +14,17 @@
14
14
  * - /packages/core/src/SegmentedControl/SegmentedControl.test.tsx
15
15
  * - /packages/cli/templates/blocks/components/SegmentedControl/ (showcase blocks)
16
16
  */
17
- import React, { useMemo, useRef, useCallback } from 'react';
17
+ import React, { useMemo, useCallback } from 'react';
18
18
  import * as stylex from '@stylexjs/stylex';
19
19
  import "../theme/tokens.stylex.js";
20
20
  import { colorVars, spacingVars, radiusVars } from "../theme/tokens.stylex.js";
21
21
  import { SegmentedControlContext } from "./SegmentedControlContext.js";
22
- import { useIsomorphicLayoutEffect } from "../hooks/useIsomorphicLayoutEffect.js";
22
+ import { useListFocus } from "../hooks/useListFocus.js";
23
+ import { useKeyboardHint } from "../hooks/useKeyboardHint.js";
23
24
  import { mergeProps, mergeRefs } from "../utils/index.js";
24
25
  import { useSize } from "../SizeContext/SizeContext.js";
25
26
  import { themeProps } from "../utils/themeProps.js";
26
- import { jsx as _jsx } from "react/jsx-runtime";
27
+ import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
27
28
  // =============================================================================
28
29
  // Styles
29
30
  // =============================================================================
@@ -94,45 +95,53 @@ export function SegmentedControl({
94
95
  style
95
96
  }) {
96
97
  const size = useSize(sizeProp, 'md');
97
- const containerRef = useRef(null);
98
- const handleKeyDown = useCallback(e => {
98
+
99
+ // Roving tabindex + arrow/Home/End navigation is owned by the shared
100
+ // useListFocus primitive: it stamps a single tab stop (tabIndex 0/-1) across
101
+ // the radios, skips disabled ones, wraps at the ends, handles Home/End, and
102
+ // repairs the tab stop on mount and whenever items mount/disable — replacing
103
+ // the component's former inline keyboard handler and tab-stop repair effect.
104
+ const {
105
+ listRef,
106
+ handleKeyDown,
107
+ handleFocus
108
+ } = useListFocus({
109
+ itemSelector: '[role="radio"]:not([aria-disabled="true"])',
110
+ hasRovingTabIndex: true,
111
+ wrap: true,
112
+ orientation: 'horizontal'
113
+ });
114
+ const hint = useKeyboardHint({
115
+ orientation: 'horizontal',
116
+ isEnabled: !isDisabled
117
+ });
118
+ const handleContainerKeyDown = useCallback(e => {
119
+ hint.onKeyDown(e);
120
+ handleKeyDown(e);
121
+ }, [hint, handleKeyDown]);
122
+
123
+ // Selection-follows-focus (APG radiogroup): useListFocus only *moves* focus,
124
+ // so whenever it lands focus on a new radio (arrow/Home/End, or a click) we
125
+ // select that radio's value. Reading the focused element's data-value here
126
+ // keeps selection in lockstep with focus without duplicating the navigation
127
+ // logic. Disabled radios are ignored (they should never become the value),
128
+ // and the already-selected value is skipped so an initial Tab-in (or a click
129
+ // on the current segment) is a no-op, matching click behavior.
130
+ const handleContainerFocus = useCallback(e => {
131
+ hint.onFocus(e);
132
+ handleFocus(e);
99
133
  if (isDisabled) {
100
134
  return;
101
135
  }
102
- const container = containerRef.current;
103
- if (!container) {
136
+ const focused = e.target?.closest('[role="radio"][data-value]');
137
+ if (!focused || focused.getAttribute('aria-disabled') === 'true') {
104
138
  return;
105
139
  }
106
- const items = Array.from(container.querySelectorAll('[role="radio"]:not([aria-disabled="true"])'));
107
- if (items.length === 0) {
108
- return;
109
- }
110
- const currentIndex = items.findIndex(item => item === document.activeElement);
111
- let nextIndex;
112
- switch (e.key) {
113
- case 'ArrowRight':
114
- nextIndex = currentIndex === -1 ? 0 : (currentIndex + 1) % items.length;
115
- break;
116
- case 'ArrowLeft':
117
- nextIndex = currentIndex === -1 ? items.length - 1 : (currentIndex - 1 + items.length) % items.length;
118
- break;
119
- case 'Home':
120
- nextIndex = 0;
121
- break;
122
- case 'End':
123
- nextIndex = items.length - 1;
124
- break;
125
- default:
126
- return;
127
- }
128
- e.preventDefault();
129
- const nextItem = items[nextIndex];
130
- nextItem.focus();
131
- const nextValue = nextItem.dataset.value;
132
- if (nextValue != null) {
140
+ const nextValue = focused.dataset.value;
141
+ if (nextValue != null && nextValue !== value) {
133
142
  onChange(nextValue);
134
143
  }
135
- }, [isDisabled, onChange]);
144
+ }, [hint, handleFocus, isDisabled, onChange, value]);
136
145
  const contextValue = useMemo(() => ({
137
146
  value,
138
147
  onChange,
@@ -140,39 +149,20 @@ export function SegmentedControl({
140
149
  layout,
141
150
  isDisabled
142
151
  }), [value, onChange, size, layout, isDisabled]);
143
-
144
- // Tab-stop repair (navigation-6): each item sets tabIndex=0 only when its
145
- // value matches the group value, so a stale/unmatched `value` (or a disabled
146
- // selected item) can leave every segment at tabIndex=-1 — making the whole
147
- // radiogroup unreachable by Tab. After render, if no enabled radio is
148
- // tabbable, promote the first enabled radio to tabIndex=0 so the group always
149
- // has exactly one tab stop. Mirrors Base UI's Composite tab-stop repair.
150
- useIsomorphicLayoutEffect(() => {
151
- const container = containerRef.current;
152
- if (!container) {
153
- return;
154
- }
155
- const enabled = Array.from(container.querySelectorAll('[role="radio"]:not([aria-disabled="true"])'));
156
- if (enabled.length === 0) {
157
- return;
158
- }
159
- const hasTabStop = enabled.some(el => el.tabIndex === 0);
160
- if (!hasTabStop) {
161
- enabled[0].tabIndex = 0;
162
- }
163
- });
164
152
  return /*#__PURE__*/_jsx(SegmentedControlContext, {
165
153
  value: contextValue,
166
- children: /*#__PURE__*/_jsx("div", {
167
- ref: mergeRefs(ref, containerRef),
154
+ children: /*#__PURE__*/_jsxs("div", {
155
+ ref: mergeRefs(ref, listRef),
168
156
  role: "radiogroup",
169
157
  "aria-label": label,
170
158
  "aria-disabled": isDisabled || undefined,
171
- onKeyDown: handleKeyDown,
159
+ onKeyDown: handleContainerKeyDown,
160
+ onFocus: handleContainerFocus,
161
+ onBlur: hint.onBlur,
172
162
  ...mergeProps(themeProps('segmented-control', {
173
163
  size
174
164
  }), stylex.props(styles.container, sizeStyles[size], layout === 'fill' && styles.fill, isDisabled && styles.disabled, xstyle), className, style),
175
- children: children
165
+ children: [children, hint.hintElement]
176
166
  })
177
167
  });
178
168
  }
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * @file Selector.tsx
3
- * @input Uses React, StyleX, usePopover, Icon
3
+ * @input Uses React, StyleX, usePopover, useTooltip, Icon
4
4
  * @output Exports Selector component
5
5
  * @position Core implementation; consumed by index.ts
6
6
  *
@@ -56,6 +56,27 @@ interface SelectorPropsBase<T extends SelectorOptionType = SelectorOptionType> e
56
56
  * @default false
57
57
  */
58
58
  isDisabled?: boolean;
59
+ /**
60
+ * Explains why the selector is disabled. When set together with
61
+ * `isDisabled`, the selector shows a tooltip with this text on hover and
62
+ * keyboard focus, and the trigger stays focusable (via `aria-disabled`)
63
+ * so the reason is discoverable by keyboard and assistive technology.
64
+ * Activation stays blocked.
65
+ *
66
+ * Use this instead of wrapping a disabled selector in `Tooltip` — disabled
67
+ * controls don't emit the pointer events an external tooltip needs.
68
+ *
69
+ * @example
70
+ * ```
71
+ * <Selector
72
+ * label="Owner"
73
+ * options={owners}
74
+ * isDisabled
75
+ * disabledMessage="You need the Editor role to change this"
76
+ * />
77
+ * ```
78
+ */
79
+ disabledMessage?: string;
59
80
  /**
60
81
  * The options to display in the selector.
61
82
  * Can be strings, objects, dividers, or sections.
@@ -1 +1 @@
1
- {"version":3,"file":"Selector.d.ts","sourceRoot":"","sources":["../../src/Selector/Selector.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"Selector.d.ts","sourceRoot":"","sources":["../../src/Selector/Selector.tsx"],"names":[],"mappings":"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"}
@@ -4,7 +4,7 @@
4
4
 
5
5
  /**
6
6
  * @file Selector.tsx
7
- * @input Uses React, StyleX, usePopover, Icon
7
+ * @input Uses React, StyleX, usePopover, useTooltip, Icon
8
8
  * @output Exports Selector component
9
9
  * @position Core implementation; consumed by index.ts
10
10
  *
@@ -16,6 +16,7 @@
16
16
  import React, { useCallback, useEffect, useId, useMemo, useOptimistic, useRef, useState, useTransition } from 'react';
17
17
  import * as stylex from '@stylexjs/stylex';
18
18
  import { usePopover } from "../Popover/usePopover.js";
19
+ import { useTooltip } from "../Tooltip/index.js";
19
20
  import { Icon, renderIconSlot } from "../Icon/index.js";
20
21
  import { Field, inputStatusBorderStyles, inputStatusHoverShadowStyles, inputWrapperStyles } from "../Field/index.js";
21
22
  import { Divider } from "../Divider/index.js";
@@ -180,6 +181,7 @@ export function Selector(props) {
180
181
  isOptional = false,
181
182
  isRequired = false,
182
183
  isDisabled = false,
184
+ disabledMessage,
183
185
  options,
184
186
  value,
185
187
  onChange,
@@ -220,8 +222,22 @@ export function Selector(props) {
220
222
  const [optimisticValue, setOptimisticValue] = useOptimistic(normalizedValue);
221
223
  const isBusy = isLoading || optimisticValue !== normalizedValue;
222
224
 
225
+ // Disabled-reason tooltip. Disabled controls swallow pointer events, so the
226
+ // tooltip listeners attach to the trigger container (which already exists)
227
+ // and the trigger button stays perceivable via aria-disabled instead of the
228
+ // disabled attribute. Activation is blocked by the isDisabled guards in
229
+ // useCombobox (onTriggerClick / onKeyDown).
230
+ const showsDisabledMessage = isDisabled && !!disabledMessage;
231
+ const disabledMessageTooltip = useTooltip({
232
+ placement: 'above',
233
+ // The container div is not naturally focusable; focusin bubbles up from
234
+ // the trigger button, so always attach focus listeners.
235
+ focusTrigger: 'always',
236
+ isEnabled: showsDisabledMessage
237
+ });
238
+
223
239
  // Build aria-describedby
224
- const ariaDescribedBy = [description ? descriptionId : null, status?.message ? statusMessageId : null].filter(Boolean).join(' ') || undefined;
240
+ const ariaDescribedBy = [description ? descriptionId : null, status?.message ? statusMessageId : null, showsDisabledMessage ? disabledMessageTooltip.describedBy : null].filter(Boolean).join(' ') || undefined;
225
241
 
226
242
  // Flatten options for keyboard navigation
227
243
  const selectableItems = useMemo(() => getSelectableOptions(options), [options]);
@@ -491,6 +507,10 @@ export function Selector(props) {
491
507
  children: [/*#__PURE__*/_jsxs("div", {
492
508
  ref: el => {
493
509
  popover.triggerRef(el);
510
+ // Anchor + hover/focus listeners for the disabled-message tooltip.
511
+ // Handlers are gated internally by isEnabled, and anchor names
512
+ // compose, so attaching unconditionally is safe.
513
+ disabledMessageTooltip.ref(el);
494
514
  },
495
515
  onClick: onTriggerClick,
496
516
  "data-testid": testId,
@@ -518,10 +538,15 @@ export function Selector(props) {
518
538
  "aria-describedby": ariaDescribedBy,
519
539
  "aria-required": isRequired ? 'true' : undefined,
520
540
  "aria-invalid": status?.type === 'error' ? 'true' : undefined,
521
- "aria-busy": isBusy || undefined,
522
- disabled: isDisabled,
541
+ "aria-busy": isBusy || undefined
542
+ // With a disabledMessage the trigger keeps focusability via
543
+ // aria-disabled so the reason is focus-discoverable; activation is
544
+ // still blocked by the isDisabled guards in useCombobox.
545
+ ,
546
+ disabled: isDisabled && !showsDisabledMessage,
547
+ "aria-disabled": showsDisabledMessage ? 'true' : undefined,
523
548
  onKeyDown: onKeyDown,
524
- tabIndex: isDisabled ? -1 : 0,
549
+ tabIndex: isDisabled && !showsDisabledMessage ? -1 : 0,
525
550
  ...{
526
551
  className: "x78zum5 x6s0dn4 x1qughib x1txdalj x1iyjqo2 xs83m0k x1r8uery xeuugli x1717udv x1ghz6dp xc342km xng3xce xjbqb8w xjb2p0i x1qlqyl8 x15bjb6t x1heor9g x1ypdohk x1a2a7pz"
527
552
  },
@@ -600,7 +625,7 @@ export function Selector(props) {
600
625
  alignment: 'start',
601
626
  xstyle: [styles.popover, layerAnimations[popoverPlacement]],
602
627
  style: popoverOffsetStyle
603
- })]
628
+ }), showsDisabledMessage && disabledMessageTooltip.renderTooltip(disabledMessage)]
604
629
  });
605
630
  }
606
631
  Selector.displayName = 'Selector';
@@ -1 +1 @@
1
- {"version":3,"file":"Switch.d.ts","sourceRoot":"","sources":["../../src/Switch/Switch.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAIL,KAAK,WAAW,EAChB,KAAK,UAAU,EACf,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AAaf,OAAO,KAAK,EAAC,QAAQ,EAAC,MAAM,SAAS,CAAC;AACtC,OAAO,KAAK,EAAC,WAAW,EAAC,MAAM,gBAAgB,CAAC;AAIhD,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AAC5C,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,gBAAgB,CAAC;AAsJ9C,MAAM,MAAM,mBAAmB,GAAG,OAAO,GAAG,KAAK,CAAC;AAElD,MAAM,MAAM,kBAAkB,GAAG,SAAS,GAAG,QAAQ,CAAC;AAEtD,MAAM,WAAW,WAAY,SAAQ,IAAI,CAAC,SAAS,EAAE,UAAU,CAAC;IAC9D,wCAAwC;IACxC,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;IAClC;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;IACd;;;OAGG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB;;OAEG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;OAEG;IACH,QAAQ,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,WAAW,CAAC,gBAAgB,CAAC,KAAK,IAAI,CAAC;IACxE;;OAEG;IACH,YAAY,CAAC,EAAE,CACb,OAAO,EAAE,OAAO,EAChB,CAAC,EAAE,WAAW,CAAC,gBAAgB,CAAC,KAC7B,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1B;;;OAGG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB;;OAEG;IACH,KAAK,EAAE,OAAO,CAAC;IACf;;;OAGG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;;OAGG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;;OAGG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;OAEG;IACH,OAAO,CAAC,EAAE,CAAC,CAAC,EAAE,UAAU,CAAC,gBAAgB,CAAC,KAAK,IAAI,CAAC;IACpD;;OAEG;IACH,MAAM,CAAC,EAAE,CAAC,CAAC,EAAE,UAAU,CAAC,gBAAgB,CAAC,KAAK,IAAI,CAAC;IACnD;;OAEG;IACH,SAAS,CAAC,EAAE,SAAS,GAAG,QAAQ,CAAC;IACjC;;;;OAIG;IACH,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB;;OAEG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;;;;OAKG;IACH,aAAa,CAAC,EAAE,mBAAmB,CAAC;IACpC;;;;;OAKG;IACH,YAAY,CAAC,EAAE,kBAAkB,CAAC;IAClC;;;OAGG;IACH,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AAOD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,MAAM,CAAC,EACrB,KAAK,EACL,aAAqB,EACrB,WAAW,EACX,QAAQ,EACR,YAAY,EACZ,SAAiB,EACjB,KAAK,EACL,UAAkB,EAClB,UAAkB,EAClB,UAAkB,EAClB,OAAO,EACP,MAAM,EACN,SAAS,EACT,YAAY,EACZ,aAAqB,EACrB,YAAwB,EACxB,MAAM,EACN,KAAK,EACL,MAAM,EACN,SAAS,EACT,KAAK,EACL,GAAG,GACJ,EAAE,WAAW,+BAmJb;yBA1Ke,MAAM"}
1
+ {"version":3,"file":"Switch.d.ts","sourceRoot":"","sources":["../../src/Switch/Switch.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAIL,KAAK,WAAW,EAChB,KAAK,UAAU,EACf,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AAaf,OAAO,KAAK,EAAC,QAAQ,EAAC,MAAM,SAAS,CAAC;AACtC,OAAO,KAAK,EAAC,WAAW,EAAC,MAAM,gBAAgB,CAAC;AAIhD,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AAC5C,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,gBAAgB,CAAC;AA4I9C,MAAM,MAAM,mBAAmB,GAAG,OAAO,GAAG,KAAK,CAAC;AAElD,MAAM,MAAM,kBAAkB,GAAG,SAAS,GAAG,QAAQ,CAAC;AAEtD,MAAM,WAAW,WAAY,SAAQ,IAAI,CAAC,SAAS,EAAE,UAAU,CAAC;IAC9D,wCAAwC;IACxC,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;IAClC;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;IACd;;;OAGG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB;;OAEG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;OAEG;IACH,QAAQ,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,WAAW,CAAC,gBAAgB,CAAC,KAAK,IAAI,CAAC;IACxE;;OAEG;IACH,YAAY,CAAC,EAAE,CACb,OAAO,EAAE,OAAO,EAChB,CAAC,EAAE,WAAW,CAAC,gBAAgB,CAAC,KAC7B,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1B;;;OAGG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB;;OAEG;IACH,KAAK,EAAE,OAAO,CAAC;IACf;;;OAGG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;;OAGG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;;OAGG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;OAEG;IACH,OAAO,CAAC,EAAE,CAAC,CAAC,EAAE,UAAU,CAAC,gBAAgB,CAAC,KAAK,IAAI,CAAC;IACpD;;OAEG;IACH,MAAM,CAAC,EAAE,CAAC,CAAC,EAAE,UAAU,CAAC,gBAAgB,CAAC,KAAK,IAAI,CAAC;IACnD;;OAEG;IACH,SAAS,CAAC,EAAE,SAAS,GAAG,QAAQ,CAAC;IACjC;;;;OAIG;IACH,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB;;OAEG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;;;;OAKG;IACH,aAAa,CAAC,EAAE,mBAAmB,CAAC;IACpC;;;;;OAKG;IACH,YAAY,CAAC,EAAE,kBAAkB,CAAC;IAClC;;;OAGG;IACH,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AAOD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,MAAM,CAAC,EACrB,KAAK,EACL,aAAqB,EACrB,WAAW,EACX,QAAQ,EACR,YAAY,EACZ,SAAiB,EACjB,KAAK,EACL,UAAkB,EAClB,UAAkB,EAClB,UAAkB,EAClB,OAAO,EACP,MAAM,EACN,SAAS,EACT,YAAY,EACZ,aAAqB,EACrB,YAAwB,EACxB,MAAM,EACN,KAAK,EACL,MAAM,EACN,SAAS,EACT,KAAK,EACL,GAAG,GACJ,EAAE,WAAW,+BA+Ib;yBAtKe,MAAM"}
@@ -26,6 +26,7 @@ import { mergeProps } from "../utils/index.js";
26
26
  import "./switch.markers.stylex.js";
27
27
  import { switchScope } from "./switch.markers.stylex.js";
28
28
  import { themeProps } from "../utils/themeProps.js";
29
+ import { VisuallyHidden } from "../VisuallyHidden/index.js";
29
30
 
30
31
  // Fixed dimensions: 40px width, 24px height, 16px thumb (off), 20px thumb (on)
31
32
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
@@ -235,10 +236,7 @@ export function Switch({
235
236
  size: "sm"
236
237
  })
237
238
  })
238
- }), isBusy && /*#__PURE__*/_jsx("span", {
239
- ...{
240
- className: "x10l6tqk x1i1rx1s xjm9jq1 x1717udv xkdpibf xb3r6kr xzpqnlu xuxw1ft xc342km"
241
- },
239
+ }), isBusy && /*#__PURE__*/_jsx(VisuallyHidden, {
242
240
  role: "status",
243
241
  children: "Loading"
244
242
  })]