@astryxdesign/core 0.1.9-canary.eff3e5f → 0.1.9-canary.f7bce66
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.
- package/dist/Card/Card.js +1 -1
- package/dist/Divider/Divider.d.ts +2 -2
- package/dist/Divider/Divider.d.ts.map +1 -1
- package/dist/Divider/Divider.js +13 -0
- package/dist/FileInput/FileInput.d.ts.map +1 -1
- package/dist/FileInput/FileInput.js +64 -47
- package/dist/List/List.d.ts.map +1 -1
- package/dist/List/List.js +6 -3
- package/dist/Outline/Outline.js +2 -2
- package/dist/Slider/Slider.d.ts.map +1 -1
- package/dist/Slider/Slider.js +26 -1
- package/dist/Spinner/Spinner.d.ts +3 -2
- package/dist/Spinner/Spinner.d.ts.map +1 -1
- package/dist/Spinner/Spinner.js +11 -2
- package/dist/TabList/TabList.d.ts +2 -11
- package/dist/TabList/TabList.d.ts.map +1 -1
- package/dist/TabList/TabList.js +5 -9
- package/dist/TabList/TabListContext.d.ts +0 -5
- package/dist/TabList/TabListContext.d.ts.map +1 -1
- package/dist/TabList/TabListContext.js +0 -5
- package/dist/Table/plugins/selection/useTableSelection.d.ts.map +1 -1
- package/dist/Table/plugins/selection/useTableSelection.js +3 -0
- package/dist/Tooltip/useTooltip.d.ts.map +1 -1
- package/dist/Tooltip/useTooltip.js +17 -1
- package/dist/TopNav/TopNavItem.d.ts +3 -1
- package/dist/TopNav/TopNavItem.d.ts.map +1 -1
- package/dist/TopNav/TopNavItem.js +30 -3
- package/dist/astryx.umd.js +42 -42
- package/dist/astryx.umd.js.map +3 -3
- package/dist/hooks/useAnnounce.d.ts +3 -0
- package/dist/hooks/useAnnounce.d.ts.map +1 -1
- package/dist/hooks/useAnnounce.js +39 -1
- package/dist/hooks/useFocusTrap.d.ts.map +1 -1
- package/dist/hooks/useFocusTrap.js +52 -11
- package/dist/hooks/useHotkeys.d.ts +9 -0
- package/dist/hooks/useHotkeys.d.ts.map +1 -1
- package/dist/hooks/useHotkeys.js +9 -0
- package/dist/utils/plainDate.d.ts.map +1 -1
- package/dist/utils/plainDate.js +12 -3
- package/package.json +1 -1
- package/src/Card/Card.tsx +1 -1
- package/src/Chat/ChatSystemMessage.test.tsx +5 -0
- package/src/CheckboxInput/CheckboxInput.doc.mjs +6 -0
- package/src/CheckboxList/CheckboxList.doc.mjs +6 -0
- package/src/DateInput/DateInput.doc.mjs +6 -0
- package/src/DateRangeInput/DateRangeInput.doc.mjs +6 -0
- package/src/DateTimeInput/DateTimeInput.doc.mjs +6 -0
- package/src/Divider/Divider.test.tsx +32 -8
- package/src/Divider/Divider.tsx +14 -1
- package/src/FileInput/FileInput.doc.mjs +7 -1
- package/src/FileInput/FileInput.test.tsx +24 -7
- package/src/FileInput/FileInput.tsx +67 -43
- package/src/List/List.test.tsx +17 -29
- package/src/List/List.tsx +6 -1
- package/src/MultiSelector/MultiSelector.doc.mjs +6 -0
- package/src/NumberInput/NumberInput.doc.mjs +6 -0
- package/src/Outline/Outline.test.tsx +12 -12
- package/src/Outline/Outline.tsx +2 -2
- package/src/RadioList/RadioList.doc.mjs +6 -0
- package/src/Selector/Selector.doc.mjs +6 -0
- package/src/Slider/Slider.doc.mjs +6 -0
- package/src/Slider/Slider.test.tsx +52 -0
- package/src/Slider/Slider.tsx +28 -1
- package/src/Spinner/Spinner.test.tsx +10 -8
- package/src/Spinner/Spinner.tsx +15 -5
- package/src/Switch/Switch.doc.mjs +6 -0
- package/src/TabList/TabList.doc.mjs +0 -6
- package/src/TabList/TabList.test.tsx +3 -15
- package/src/TabList/TabList.tsx +6 -17
- package/src/TabList/TabListContext.ts +0 -6
- package/src/Table/plugins/selection/useTableSelection.test.tsx +61 -3
- package/src/Table/plugins/selection/useTableSelection.tsx +3 -0
- package/src/TextArea/TextArea.doc.mjs +6 -0
- package/src/TextInput/TextInput.doc.mjs +6 -0
- package/src/TimeInput/TimeInput.doc.mjs +6 -0
- package/src/Tokenizer/Tokenizer.doc.mjs +8 -1
- package/src/Tooltip/Tooltip.test.tsx +46 -0
- package/src/Tooltip/useTooltip.tsx +20 -0
- package/src/TopNav/TopNav.test.tsx +93 -2
- package/src/TopNav/TopNavItem.doc.mjs +3 -3
- package/src/TopNav/TopNavItem.tsx +35 -6
- package/src/Typeahead/Typeahead.doc.mjs +6 -0
- package/src/__tests__/inputWidthContract.test.tsx +62 -0
- package/src/doc-mjs.d.ts +19 -0
- package/src/hooks/useAnnounce.test.tsx +75 -2
- package/src/hooks/useAnnounce.ts +47 -1
- package/src/hooks/useFocusTrap.test.tsx +104 -0
- package/src/hooks/useFocusTrap.ts +61 -12
- package/src/hooks/useHotkeys.ts +9 -0
- package/src/utils/plainDate.test.ts +24 -6
- package/src/utils/plainDate.ts +8 -3
package/dist/Card/Card.js
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
* - /apps/storybook/stories/Divider.stories.tsx
|
|
11
11
|
* - /packages/cli/templates/blocks/components/Divider/ (showcase blocks)
|
|
12
12
|
*/
|
|
13
|
-
import type
|
|
13
|
+
import { type ReactNode } from 'react';
|
|
14
14
|
import type { BaseProps } from '../BaseProps';
|
|
15
15
|
/**
|
|
16
16
|
* Extensible variant map for Divider.
|
|
@@ -71,7 +71,7 @@ export interface DividerProps extends BaseProps<HTMLDivElement> {
|
|
|
71
71
|
* <Divider label="or" />
|
|
72
72
|
* ```
|
|
73
73
|
*/
|
|
74
|
-
export declare function Divider({ orientation, label, variant, isFullBleed, xstyle, className, style, ref, ...props }: DividerProps): import("react").JSX.Element;
|
|
74
|
+
export declare function Divider({ orientation, label, variant, isFullBleed, xstyle, className, style, ref, 'aria-label': ariaLabel, 'aria-labelledby': ariaLabelledBy, ...props }: DividerProps): import("react").JSX.Element;
|
|
75
75
|
export declare namespace Divider {
|
|
76
76
|
var displayName: string;
|
|
77
77
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Divider.d.ts","sourceRoot":"","sources":["../../src/Divider/Divider.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"Divider.d.ts","sourceRoot":"","sources":["../../src/Divider/Divider.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAQ,KAAK,SAAS,EAAC,MAAM,OAAO,CAAC;AAC5C,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AAY5C;;;;;;;;;;;;GAYG;AACH,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,IAAI,CAAC;IACb,MAAM,EAAE,IAAI,CAAC;CACd;AAED;;GAEG;AACH,MAAM,MAAM,cAAc,GAAG,MAAM,iBAAiB,CAAC;AAErD,MAAM,WAAW,YAAa,SAAQ,SAAS,CAAC,cAAc,CAAC;IAC7D,wCAAwC;IACxC,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;IAChC;;;OAGG;IACH,WAAW,CAAC,EAAE,YAAY,GAAG,UAAU,CAAC;IAExC;;;OAGG;IACH,KAAK,CAAC,EAAE,SAAS,CAAC;IAElB;;;;;OAKG;IACH,OAAO,CAAC,EAAE,cAAc,CAAC;IAEzB;;;;OAIG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAiED;;;;;;;;;;GAUG;AACH,wBAAgB,OAAO,CAAC,EACtB,WAA0B,EAC1B,KAAK,EACL,OAAkB,EAClB,WAAmB,EACnB,MAAM,EACN,SAAS,EACT,KAAK,EACL,GAAG,EACH,YAAY,EAAE,SAAS,EACvB,iBAAiB,EAAE,cAAc,EACjC,GAAG,KAAK,EACT,EAAE,YAAY,+BA0Dd;yBAtEe,OAAO"}
|
package/dist/Divider/Divider.js
CHANGED
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
* - /apps/storybook/stories/Divider.stories.tsx
|
|
15
15
|
* - /packages/cli/templates/blocks/components/Divider/ (showcase blocks)
|
|
16
16
|
*/
|
|
17
|
+
import { useId } from 'react';
|
|
17
18
|
import * as stylex from '@stylexjs/stylex';
|
|
18
19
|
import "../theme/tokens.stylex.js";
|
|
19
20
|
import { colorVars, spacingVars, typeScaleVars, borderVars } from "../theme/tokens.stylex.js";
|
|
@@ -110,14 +111,25 @@ export function Divider({
|
|
|
110
111
|
className,
|
|
111
112
|
style,
|
|
112
113
|
ref,
|
|
114
|
+
'aria-label': ariaLabel,
|
|
115
|
+
'aria-labelledby': ariaLabelledBy,
|
|
113
116
|
...props
|
|
114
117
|
}) {
|
|
115
118
|
const isHorizontal = orientation === 'horizontal';
|
|
119
|
+
const labelId = useId();
|
|
120
|
+
|
|
121
|
+
// A separator does not derive its accessible name from its content, so the
|
|
122
|
+
// rendered label must be referenced explicitly via aria-labelledby to be
|
|
123
|
+
// exposed as the separator's name (WCAG 1.3.1). An explicit aria-label or
|
|
124
|
+
// aria-labelledby from the consumer takes precedence.
|
|
125
|
+
const resolvedLabelledBy = ariaLabelledBy ?? (label && ariaLabel == null ? labelId : undefined);
|
|
116
126
|
return /*#__PURE__*/_jsxs("div", {
|
|
117
127
|
ref: ref,
|
|
118
128
|
...props,
|
|
119
129
|
role: "separator",
|
|
120
130
|
"aria-orientation": orientation,
|
|
131
|
+
"aria-label": ariaLabel,
|
|
132
|
+
"aria-labelledby": resolvedLabelledBy,
|
|
121
133
|
...mergeProps(themeProps('divider', {
|
|
122
134
|
variant,
|
|
123
135
|
orientation
|
|
@@ -125,6 +137,7 @@ export function Divider({
|
|
|
125
137
|
children: [/*#__PURE__*/_jsx("div", {
|
|
126
138
|
...stylex.props(isHorizontal ? lineStyles.horizontalLine : lineStyles.verticalLine, lineStyles[variant])
|
|
127
139
|
}), label && /*#__PURE__*/_jsx("div", {
|
|
140
|
+
id: labelId,
|
|
128
141
|
...{
|
|
129
142
|
0: {
|
|
130
143
|
className: "x2lah0s xrrkdod x141an7d x1ltkj2j xv1l7n4"
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FileInput.d.ts","sourceRoot":"","sources":["../../src/FileInput/FileInput.tsx"],"names":[],"mappings":"AAsCA,OAAO,EAGL,KAAK,WAAW,EAChB,KAAK,kBAAkB,EACxB,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"FileInput.d.ts","sourceRoot":"","sources":["../../src/FileInput/FileInput.tsx"],"names":[],"mappings":"AAsCA,OAAO,EAGL,KAAK,WAAW,EAChB,KAAK,kBAAkB,EACxB,MAAM,UAAU,CAAC;AASlB,YAAY,EACV,WAAW,IAAI,eAAe,EAC9B,eAAe,IAAI,mBAAmB,GACvC,MAAM,UAAU,CAAC;AAElB,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AAC5C,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,gBAAgB,CAAC;AA+M9C,MAAM,WAAW,cAAe,SAAQ,IAAI,CAC1C,SAAS,EACT,UAAU,GAAG,cAAc,GAAG,OAAO,CACtC;IACC,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,KAAK,EAAE,IAAI,GAAG,IAAI,EAAE,GAAG,IAAI,CAAC;IAC5B;;OAEG;IACH,QAAQ,EAAE,CAAC,KAAK,EAAE,IAAI,GAAG,IAAI,EAAE,GAAG,IAAI,KAAK,IAAI,CAAC;IAChD;;;OAGG;IACH,YAAY,CAAC,EAAE,CAAC,KAAK,EAAE,IAAI,GAAG,IAAI,EAAE,GAAG,IAAI,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9D;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;;OAIG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;OAEG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;OAGG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;;;;;;;;;;;;;;;;;;OAmBG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB;;;OAGG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;;OAGG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB;;OAEG;IACH,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB;;;;;;OAMG;IACH,aAAa,CAAC,EAAE,kBAAkB,CAAC;IACnC;;OAEG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;;OAKG;IACH,IAAI,CAAC,EAAE,UAAU,GAAG,OAAO,CAAC;IAC5B;;;OAGG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;;;OAIG;IACH,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB;;OAEG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;;;;;;GAOG;AACH,wBAAgB,SAAS,CAAC,EACxB,KAAK,EACL,aAAqB,EACrB,KAAK,EACL,QAAQ,EACR,YAAY,EACZ,MAAM,EACN,UAAkB,EAClB,OAAO,EACP,QAAQ,EACR,UAAkB,EAClB,eAAe,EACf,UAAkB,EAClB,SAAiB,EACjB,MAAM,EAAE,UAAU,EAClB,aAA0B,EAC1B,WAAW,EACX,WAAW,EACX,IAAc,EACd,UAAkB,EAClB,YAAY,EACZ,KAAK,EACL,MAAM,EACN,SAAS,EACT,KAAK,EACL,GAAG,EACH,GAAG,IAAI,EACR,EAAE,cAAc,+BA2ZhB;yBAtbe,SAAS"}
|
|
@@ -25,6 +25,7 @@ import { Spinner } from "../Spinner/index.js";
|
|
|
25
25
|
import { VisuallyHidden } from "../VisuallyHidden/index.js";
|
|
26
26
|
import { useAnnounce } from "../hooks/useAnnounce.js";
|
|
27
27
|
import { useInputStatusIcon } from "../hooks/useInputStatusIcon.js";
|
|
28
|
+
import { useClickableContainer } from "../hooks/useClickableContainer.js";
|
|
28
29
|
import { useTooltip } from "../Tooltip/index.js";
|
|
29
30
|
import { mergeProps, mergeRefs } from "../utils/index.js";
|
|
30
31
|
import { themeProps } from "../utils/themeProps.js";
|
|
@@ -203,6 +204,7 @@ export function FileInput({
|
|
|
203
204
|
const statusMessageID = useId();
|
|
204
205
|
const requiredID = useId();
|
|
205
206
|
const inputRef = useRef(null);
|
|
207
|
+
const containerRef = useRef(null);
|
|
206
208
|
const [isDragOver, setIsDragOver] = useState(false);
|
|
207
209
|
const [validationError, setValidationError] = useState(null);
|
|
208
210
|
const [, startTransition] = useTransition();
|
|
@@ -214,10 +216,10 @@ export function FileInput({
|
|
|
214
216
|
const announce = useAnnounce();
|
|
215
217
|
|
|
216
218
|
// Disabled-reason tooltip. Disabled controls swallow pointer events, so the
|
|
217
|
-
// tooltip listeners attach to the
|
|
218
|
-
//
|
|
219
|
-
//
|
|
220
|
-
//
|
|
219
|
+
// tooltip listeners attach to the visible container (which stays hoverable)
|
|
220
|
+
// and the trigger stays perceivable via aria-disabled instead of the native
|
|
221
|
+
// disabled attribute. Opening the picker is blocked by the isDisabled guards
|
|
222
|
+
// in the handlers.
|
|
221
223
|
const showsDisabledMessage = isDisabled && !!disabledMessage;
|
|
222
224
|
const disabledMessageTooltip = useTooltip({
|
|
223
225
|
placement: 'above',
|
|
@@ -236,11 +238,11 @@ export function FileInput({
|
|
|
236
238
|
statusVariant
|
|
237
239
|
});
|
|
238
240
|
|
|
239
|
-
// Required state.
|
|
240
|
-
//
|
|
241
|
-
//
|
|
242
|
-
//
|
|
243
|
-
//
|
|
241
|
+
// Required state. The trigger is a real button, but AT does not reliably
|
|
242
|
+
// announce aria-required, so the trigger instead points its aria-describedby
|
|
243
|
+
// at a visually hidden "Required" span — mirroring the Field label's visible
|
|
244
|
+
// indicator (where isOptional takes precedence) and the pattern Slider uses
|
|
245
|
+
// for its thumbs.
|
|
244
246
|
const conveysRequired = isRequired && !isOptional;
|
|
245
247
|
const ariaDescribedBy = [description ? descriptionID : null, statusVariant !== 'tooltip' && status?.message ? statusMessageID : null,
|
|
246
248
|
// The tooltip variant renders no message box; describe the input by the
|
|
@@ -302,12 +304,28 @@ export function FileInput({
|
|
|
302
304
|
inputRef.current?.click();
|
|
303
305
|
}
|
|
304
306
|
}, [isDisabled]);
|
|
307
|
+
|
|
308
|
+
// Explicit keyboard activation so Enter/Space open the picker even where a
|
|
309
|
+
// synthetic keydown does not raise a native click. The isDisabled guard
|
|
310
|
+
// blocks activation while focusable-disabled.
|
|
305
311
|
const handleKeyDown = useCallback(e => {
|
|
306
312
|
if ((e.key === 'Enter' || e.key === ' ') && !isDisabled) {
|
|
307
313
|
e.preventDefault();
|
|
308
314
|
inputRef.current?.click();
|
|
309
315
|
}
|
|
310
316
|
}, [isDisabled]);
|
|
317
|
+
|
|
318
|
+
// Make the surface clickable without giving it an interactive role. Clicks on
|
|
319
|
+
// the nested clear/status controls are ignored by the hook, so those buttons
|
|
320
|
+
// are plain siblings — no nested-interactive violation.
|
|
321
|
+
const {
|
|
322
|
+
onClick: onContainerClick,
|
|
323
|
+
onMouseUp: onContainerMouseUp
|
|
324
|
+
} = useClickableContainer({
|
|
325
|
+
containerRef,
|
|
326
|
+
onClick: handleClick,
|
|
327
|
+
disabled: isDisabled
|
|
328
|
+
});
|
|
311
329
|
const handleDragEnter = useCallback(e => {
|
|
312
330
|
e.preventDefault();
|
|
313
331
|
e.stopPropagation();
|
|
@@ -437,50 +455,49 @@ export function FileInput({
|
|
|
437
455
|
width: width,
|
|
438
456
|
children: [/*#__PURE__*/_jsxs("div", {
|
|
439
457
|
ref: el => {
|
|
440
|
-
|
|
441
|
-
//
|
|
442
|
-
//
|
|
458
|
+
containerRef.current = el;
|
|
459
|
+
// Anchor + hover/focus listeners for the disabled-message tooltip on
|
|
460
|
+
// the visible container (the focusable trigger is visually hidden, so
|
|
461
|
+
// anchoring there would place the tooltip at a 1px box). focusin
|
|
462
|
+
// bubbles from the trigger button, so the tooltip still opens on
|
|
463
|
+
// keyboard focus. Handlers are gated internally by isEnabled.
|
|
443
464
|
disabledMessageTooltip.ref(el);
|
|
444
465
|
},
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
// aria-disabled so the reason is focus-discoverable; opening the picker
|
|
448
|
-
// is still blocked by the isDisabled guards in the handlers.
|
|
449
|
-
,
|
|
450
|
-
tabIndex: isDisabled && !showsDisabledMessage ? -1 : 0,
|
|
451
|
-
"aria-disabled": showsDisabledMessage ? 'true' : undefined,
|
|
452
|
-
onClick: handleClick,
|
|
453
|
-
onKeyDown: handleKeyDown
|
|
454
|
-
// aria-label suppresses child content from the accessible name, so
|
|
455
|
-
// compose the selected filenames into it — otherwise a screen-reader
|
|
456
|
-
// user refocusing the control hears only the field label and cannot
|
|
457
|
-
// tell what (if anything) is attached.
|
|
458
|
-
,
|
|
459
|
-
"aria-label": hasFiles && fileNames ? t('@astryx.fileInput.triggerWithFiles', {
|
|
460
|
-
label,
|
|
461
|
-
fileNames
|
|
462
|
-
}) : label,
|
|
463
|
-
"aria-busy": isLoading || undefined
|
|
464
|
-
// These describe the operable control, so they belong on the focusable
|
|
465
|
-
// role="button" wrapper — not the hidden tabIndex={-1} file input the
|
|
466
|
-
// user never focuses (forms-6). Required state is conveyed through
|
|
467
|
-
// the visually hidden "Required" node in aria-describedby, not
|
|
468
|
-
// aria-required, which role="button" does not support in ARIA 1.2.
|
|
469
|
-
,
|
|
470
|
-
"aria-describedby": ariaDescribedBy
|
|
471
|
-
// aria-invalid is likewise unsupported on role="button", but it stays:
|
|
472
|
-
// a message-less error status (`status={{type: 'error'}}`) has no
|
|
473
|
-
// described-by replacement, and some AT still honor the attribute, so
|
|
474
|
-
// removing it would not be strictly better. Errors *with* a message
|
|
475
|
-
// are described via statusMessageID above.
|
|
476
|
-
,
|
|
477
|
-
"aria-invalid": status?.type === 'error' ? 'true' : undefined,
|
|
466
|
+
onClick: !isDisabled ? onContainerClick : undefined,
|
|
467
|
+
onMouseUp: !isDisabled ? onContainerMouseUp : undefined,
|
|
478
468
|
...dragDropProps,
|
|
479
469
|
...mergeProps(themeProps('file-input', {
|
|
480
470
|
mode,
|
|
481
471
|
status: status?.type ?? null
|
|
482
472
|
}), stylex.props(isDropzone ? styles.dropzone : styles.compact, isDropzone && !isDisabled && styles.dropzoneHover, isDropzone && isDragOver && styles.dropzoneActive, isDropzone && isDisabled && styles.dropzoneDisabled, !isDropzone && isDisabled && styles.compactDisabled, status && statusBorderStyles[status.type], xstyle), className, style),
|
|
483
|
-
children: [/*#__PURE__*/_jsx(
|
|
473
|
+
children: [/*#__PURE__*/_jsx(VisuallyHidden, {
|
|
474
|
+
children: /*#__PURE__*/_jsx("button", {
|
|
475
|
+
type: "button"
|
|
476
|
+
// With a disabledMessage the trigger keeps focusability via
|
|
477
|
+
// aria-disabled so the reason is focus-discoverable; opening the
|
|
478
|
+
// picker is still blocked by the isDisabled guards in the handlers.
|
|
479
|
+
// Otherwise the native disabled attribute removes it from the tab
|
|
480
|
+
// order.
|
|
481
|
+
,
|
|
482
|
+
disabled: isDisabled && !showsDisabledMessage,
|
|
483
|
+
tabIndex: isDisabled && !showsDisabledMessage ? -1 : 0,
|
|
484
|
+
"aria-disabled": showsDisabledMessage ? 'true' : undefined,
|
|
485
|
+
onClick: handleClick,
|
|
486
|
+
onKeyDown: handleKeyDown
|
|
487
|
+
// aria-label suppresses child content from the accessible name, so
|
|
488
|
+
// compose the selected filenames into it — otherwise a
|
|
489
|
+
// screen-reader user refocusing the control hears only the field
|
|
490
|
+
// label and cannot tell what (if anything) is attached.
|
|
491
|
+
,
|
|
492
|
+
"aria-label": hasFiles && fileNames ? t('@astryx.fileInput.triggerWithFiles', {
|
|
493
|
+
label,
|
|
494
|
+
fileNames
|
|
495
|
+
}) : label,
|
|
496
|
+
"aria-busy": isLoading || undefined,
|
|
497
|
+
"aria-describedby": ariaDescribedBy,
|
|
498
|
+
"aria-invalid": status?.type === 'error' ? 'true' : undefined
|
|
499
|
+
})
|
|
500
|
+
}), /*#__PURE__*/_jsx("input", {
|
|
484
501
|
...rest,
|
|
485
502
|
ref: mergeRefs(ref, inputRef),
|
|
486
503
|
id: id,
|
|
@@ -490,7 +507,7 @@ export function FileInput({
|
|
|
490
507
|
disabled: isDisabled,
|
|
491
508
|
onChange: handleInputChange
|
|
492
509
|
// The visually-hidden native input is never focused (tabIndex={-1});
|
|
493
|
-
// its describedby/required/invalid live on the
|
|
510
|
+
// its describedby/required/invalid live on the trigger button.
|
|
494
511
|
,
|
|
495
512
|
"aria-hidden": "true",
|
|
496
513
|
tabIndex: -1,
|
package/dist/List/List.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"List.d.ts","sourceRoot":"","sources":["../../src/List/List.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAiB,KAAK,SAAS,EAAC,MAAM,OAAO,CAAC;AAGrD,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AAC5C,OAAO,EAEL,KAAK,WAAW,EAChB,KAAK,eAAe,EACrB,MAAM,eAAe,CAAC;AAIvB,OAAO,EACL,KAAK,WAAW,EAChB,KAAK,eAAe,IAAI,SAAS,GAClC,MAAM,eAAe,CAAC;AAEvB,MAAM,WAAW,SAAU,SAAQ,SAAS,CAC1C,gBAAgB,GAAG,gBAAgB,CACpC;IACC,wCAAwC;IACxC,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,gBAAgB,GAAG,gBAAgB,CAAC,CAAC;IACrD;;OAEG;IACH,QAAQ,EAAE,SAAS,CAAC;IAEpB;;;;;;OAMG;IACH,OAAO,CAAC,EAAE,WAAW,CAAC;IAEtB;;;OAGG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;IAEtB;;;OAGG;IACH,MAAM,CAAC,EAAE,SAAS,CAAC;IAEnB;;;;OAIG;IACH,SAAS,CAAC,EAAE,eAAe,CAAC;IAE5B;;;;OAIG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf;;OAEG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAwCD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,IAAI,CAAC,EACnB,QAAQ,EACR,OAAoB,EACpB,WAAmB,EACnB,MAAM,EACN,SAAkB,EAClB,KAAK,EACL,MAAM,EACN,SAAS,EACT,KAAK,EACL,aAAa,EAAE,MAAM,EACrB,GAAG,GACJ,EAAE,SAAS,+
|
|
1
|
+
{"version":3,"file":"List.d.ts","sourceRoot":"","sources":["../../src/List/List.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAiB,KAAK,SAAS,EAAC,MAAM,OAAO,CAAC;AAGrD,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AAC5C,OAAO,EAEL,KAAK,WAAW,EAChB,KAAK,eAAe,EACrB,MAAM,eAAe,CAAC;AAIvB,OAAO,EACL,KAAK,WAAW,EAChB,KAAK,eAAe,IAAI,SAAS,GAClC,MAAM,eAAe,CAAC;AAEvB,MAAM,WAAW,SAAU,SAAQ,SAAS,CAC1C,gBAAgB,GAAG,gBAAgB,CACpC;IACC,wCAAwC;IACxC,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,gBAAgB,GAAG,gBAAgB,CAAC,CAAC;IACrD;;OAEG;IACH,QAAQ,EAAE,SAAS,CAAC;IAEpB;;;;;;OAMG;IACH,OAAO,CAAC,EAAE,WAAW,CAAC;IAEtB;;;OAGG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;IAEtB;;;OAGG;IACH,MAAM,CAAC,EAAE,SAAS,CAAC;IAEnB;;;;OAIG;IACH,SAAS,CAAC,EAAE,eAAe,CAAC;IAE5B;;;;OAIG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf;;OAEG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAwCD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,IAAI,CAAC,EACnB,QAAQ,EACR,OAAoB,EACpB,WAAmB,EACnB,MAAM,EACN,SAAkB,EAClB,KAAK,EACL,MAAM,EACN,SAAS,EACT,KAAK,EACL,aAAa,EAAE,MAAM,EACrB,GAAG,GACJ,EAAE,SAAS,+BAsDX;yBAlEe,IAAI"}
|
package/dist/List/List.js
CHANGED
|
@@ -106,9 +106,12 @@ export function List({
|
|
|
106
106
|
...(isOrdered && start != null && start !== 1 ? {
|
|
107
107
|
start
|
|
108
108
|
} : {}),
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
109
|
+
// The base list style always sets list-style-type: none (markers are
|
|
110
|
+
// custom-rendered by ListItem), and Safari/VoiceOver drops implicit
|
|
111
|
+
// list semantics for lists styled with list-style: none. The explicit
|
|
112
|
+
// role restores "list, N items" announcements for every listStyle
|
|
113
|
+
// variant.
|
|
114
|
+
role: "list",
|
|
112
115
|
...mergeProps(themeProps('list', {
|
|
113
116
|
density,
|
|
114
117
|
listStyle
|
package/dist/Outline/Outline.js
CHANGED
|
@@ -241,7 +241,7 @@ export function Outline({
|
|
|
241
241
|
return;
|
|
242
242
|
}
|
|
243
243
|
const links = Array.from(list.querySelectorAll('a[href]'));
|
|
244
|
-
const active = links.find(link => link.getAttribute('aria-current') === '
|
|
244
|
+
const active = links.find(link => link.getAttribute('aria-current') === 'location');
|
|
245
245
|
if (active == null) {
|
|
246
246
|
return;
|
|
247
247
|
}
|
|
@@ -326,7 +326,7 @@ export function Outline({
|
|
|
326
326
|
role: "listitem",
|
|
327
327
|
children: /*#__PURE__*/_jsx(LinkComponent, {
|
|
328
328
|
href: `#${item.id}`,
|
|
329
|
-
"aria-current": isActive ? '
|
|
329
|
+
"aria-current": isActive ? 'location' : undefined,
|
|
330
330
|
onClick: handleClick(item.id),
|
|
331
331
|
onKeyDown: handleKeyDown(item.id),
|
|
332
332
|
...mergeProps(themeProps('outline-item', {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Slider.d.ts","sourceRoot":"","sources":["../../src/Slider/Slider.tsx"],"names":[],"mappings":"AAyCA,OAAO,KAAK,EAAC,WAAW,EAAC,MAAM,gBAAgB,CAAC;AAGhD,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AAC5C,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,gBAAgB,CAAC;AAO9C,MAAM,WAAW,eAAgB,SAAQ,IAAI,CAC3C,SAAS,CAAC,cAAc,CAAC,EACzB,UAAU,CACX;IACC,wCAAwC;IACxC,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;IAChC,qEAAqE;IACrE,KAAK,EAAE,MAAM,CAAC;IACd,8FAA8F;IAC9F,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,kDAAkD;IAClD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,qDAAqD;IACrD,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;;;;;;;;;;;;;;;;;;OAmBG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,oDAAoD;IACpD,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,oDAAoD;IACpD,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,uCAAuC;IACvC,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB;;;;OAIG;IACH,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,uEAAuE;IACvE,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,gCAAgC;IAChC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,kCAAkC;IAClC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,iCAAiC;IACjC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,uDAAuD;IACvD,WAAW,CAAC,EAAE,YAAY,GAAG,UAAU,CAAC;IACxC,uEAAuE;IACvE,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC;IACxC,6DAA6D;IAC7D,YAAY,CAAC,EAAE,SAAS,GAAG,MAAM,GAAG,MAAM,CAAC;IAC3C,8DAA8D;IAC9D,KAAK,CAAC,EAAE;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAC,EAAE,CAAC;IAC1C;;;;OAIG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,oCAAoC;IACpC,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,iBAAkB,SAAQ,eAAe;IACxD,yCAAyC;IACzC,KAAK,EAAE,MAAM,CAAC;IACd,kDAAkD;IAClD,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACnC,iEAAiE;IACjE,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;CACvC;AAED,MAAM,WAAW,gBAAiB,SAAQ,eAAe;IACvD,8CAA8C;IAC9C,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACxB,kDAAkD;IAClD,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,KAAK,IAAI,CAAC;IAC7C,iEAAiE;IACjE,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,KAAK,IAAI,CAAC;IAChD,8CAA8C;IAC9C,qBAAqB,CAAC,EAAE,MAAM,CAAC;CAChC;AAED,MAAM,MAAM,WAAW,GAAG,iBAAiB,GAAG,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"Slider.d.ts","sourceRoot":"","sources":["../../src/Slider/Slider.tsx"],"names":[],"mappings":"AAyCA,OAAO,KAAK,EAAC,WAAW,EAAC,MAAM,gBAAgB,CAAC;AAGhD,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AAC5C,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,gBAAgB,CAAC;AAO9C,MAAM,WAAW,eAAgB,SAAQ,IAAI,CAC3C,SAAS,CAAC,cAAc,CAAC,EACzB,UAAU,CACX;IACC,wCAAwC;IACxC,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;IAChC,qEAAqE;IACrE,KAAK,EAAE,MAAM,CAAC;IACd,8FAA8F;IAC9F,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,kDAAkD;IAClD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,qDAAqD;IACrD,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;;;;;;;;;;;;;;;;;;OAmBG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,oDAAoD;IACpD,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,oDAAoD;IACpD,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,uCAAuC;IACvC,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB;;;;OAIG;IACH,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,uEAAuE;IACvE,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,gCAAgC;IAChC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,kCAAkC;IAClC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,iCAAiC;IACjC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,uDAAuD;IACvD,WAAW,CAAC,EAAE,YAAY,GAAG,UAAU,CAAC;IACxC,uEAAuE;IACvE,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC;IACxC,6DAA6D;IAC7D,YAAY,CAAC,EAAE,SAAS,GAAG,MAAM,GAAG,MAAM,CAAC;IAC3C,8DAA8D;IAC9D,KAAK,CAAC,EAAE;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAC,EAAE,CAAC;IAC1C;;;;OAIG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,oCAAoC;IACpC,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,iBAAkB,SAAQ,eAAe;IACxD,yCAAyC;IACzC,KAAK,EAAE,MAAM,CAAC;IACd,kDAAkD;IAClD,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACnC,iEAAiE;IACjE,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;CACvC;AAED,MAAM,WAAW,gBAAiB,SAAQ,eAAe;IACvD,8CAA8C;IAC9C,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACxB,kDAAkD;IAClD,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,KAAK,IAAI,CAAC;IAC7C,iEAAiE;IACjE,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,KAAK,IAAI,CAAC;IAChD,8CAA8C;IAC9C,qBAAqB,CAAC,EAAE,MAAM,CAAC;CAChC;AAED,MAAM,MAAM,WAAW,GAAG,iBAAiB,GAAG,gBAAgB,CAAC;AAoP/D;;;;;;;;GAQG;AACH,wBAAgB,MAAM,CAAC,EAAC,GAAG,EAAE,GAAG,KAAK,EAAC,EAAE,WAAW,+BA0mBlD;yBA1mBe,MAAM"}
|
package/dist/Slider/Slider.js
CHANGED
|
@@ -49,12 +49,37 @@ const THUMB_SIZE = 20;
|
|
|
49
49
|
function clamp(val, min, max) {
|
|
50
50
|
return Math.min(Math.max(val, min), max);
|
|
51
51
|
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Number of decimal places a value carries, including values in exponent
|
|
55
|
+
* notation (e.g. 1e-7 → 7). Used to round away binary floating-point error
|
|
56
|
+
* after step arithmetic.
|
|
57
|
+
*/
|
|
58
|
+
function getDecimalPrecision(num) {
|
|
59
|
+
if (Math.abs(num) < 1) {
|
|
60
|
+
const parts = num.toExponential().split('e-');
|
|
61
|
+
if (parts.length === 2) {
|
|
62
|
+
const mantissaDecimals = parts[0].split('.')[1]?.length ?? 0;
|
|
63
|
+
return mantissaDecimals + parseInt(parts[1], 10);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
const decimalPart = String(num).split('.')[1];
|
|
67
|
+
return decimalPart ? decimalPart.length : 0;
|
|
68
|
+
}
|
|
52
69
|
function snapToStep(val, min, step) {
|
|
53
70
|
if (step <= 0) {
|
|
54
71
|
return val;
|
|
55
72
|
}
|
|
56
73
|
const steps = Math.round((val - min) / step);
|
|
57
|
-
|
|
74
|
+
const snapped = min + steps * step;
|
|
75
|
+
// `min + steps * step` accumulates binary floating-point error with
|
|
76
|
+
// fractional steps (0 + 3 * 0.1 → 0.30000000000000004), which leaks into
|
|
77
|
+
// onChange/onChangeEnd payloads, aria-valuenow, and the value tooltip.
|
|
78
|
+
// Snapped values can never carry more decimals than min/step combined, so
|
|
79
|
+
// rounding to that precision removes only the error.
|
|
80
|
+
const precision = Math.min(Math.max(getDecimalPrecision(min), getDecimalPrecision(step)), 20 // toFixed() throws past 20 digits
|
|
81
|
+
);
|
|
82
|
+
return Number(snapped.toFixed(precision));
|
|
58
83
|
}
|
|
59
84
|
function getPercent(val, min, max) {
|
|
60
85
|
if (max === min) {
|
|
@@ -60,8 +60,9 @@ export interface SpinnerProps extends BaseProps<HTMLSpanElement> {
|
|
|
60
60
|
* Visible content displayed below the spinner.
|
|
61
61
|
* Accepts a string or ReactNode for rich content.
|
|
62
62
|
*
|
|
63
|
-
* When `label` is a string,
|
|
64
|
-
* (
|
|
63
|
+
* When `label` is a string, the visible text also provides the accessible
|
|
64
|
+
* name of the status element (via aria-labelledby, avoiding a duplicate
|
|
65
|
+
* announcement) unless `aria-label` is explicitly set.
|
|
65
66
|
*
|
|
66
67
|
* @example
|
|
67
68
|
* ```
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Spinner.d.ts","sourceRoot":"","sources":["../../src/Spinner/Spinner.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;;;GAYG;AAEH,OAAO,
|
|
1
|
+
{"version":3,"file":"Spinner.d.ts","sourceRoot":"","sources":["../../src/Spinner/Spinner.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAA2B,KAAK,SAAS,EAAC,MAAM,OAAO,CAAC;AAI/D,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AAc5C,QAAA,MAAM,KAAK;;;;;;;;;;;;;;;;;CAKV,CAAC;AAiDF,MAAM,MAAM,WAAW,GAAG,MAAM,OAAO,KAAK,CAAC;AAE7C,MAAM,MAAM,YAAY,GAAG,SAAS,GAAG,SAAS,GAAG,QAAQ,GAAG,SAAS,CAAC;AAExE,MAAM,WAAW,YAAa,SAAQ,SAAS,CAAC,eAAe,CAAC;IAC9D,wCAAwC;IACxC,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;IACjC;;;;;;;OAOG;IACH,IAAI,CAAC,EAAE,WAAW,CAAC;IACnB;;;;;;;;;OASG;IACH,KAAK,CAAC,EAAE,YAAY,CAAC;IACrB;;;;;;;;;;;;;OAaG;IACH,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB;;OAEG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAMD;;;;;;;;;;;GAWG;AACH,wBAAgB,OAAO,CAAC,EACtB,IAAW,EACX,KAAiB,EACjB,KAAK,EACL,MAAM,EACN,SAAS,EACT,KAAK,EACL,YAAY,EAAE,SAAS,EACvB,aAAa,EAAE,MAAM,EACrB,GAAG,EACH,GAAG,SAAS,EACb,EAAE,YAAY,+BAqJd;yBAhKe,OAAO"}
|
package/dist/Spinner/Spinner.js
CHANGED
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
* - /apps/storybook/stories/Spinner.stories.tsx
|
|
16
16
|
* - /packages/cli/templates/blocks/components/Spinner/ (showcase blocks)
|
|
17
17
|
*/
|
|
18
|
-
import { useEffect, useRef } from 'react';
|
|
18
|
+
import { useEffect, useId, useRef } from 'react';
|
|
19
19
|
import * as stylex from '@stylexjs/stylex';
|
|
20
20
|
import "../theme/tokens.stylex.js";
|
|
21
21
|
import { durationVars, spacingVars } from "../theme/tokens.stylex.js";
|
|
@@ -183,13 +183,21 @@ export function Spinner({
|
|
|
183
183
|
} = SIZES[size];
|
|
184
184
|
const frameSize = diameter + border * 2;
|
|
185
185
|
const hasLabel = label != null;
|
|
186
|
+
const labelId = useId();
|
|
187
|
+
|
|
188
|
+
// When a visible string label renders (and no explicit aria-label is set),
|
|
189
|
+
// name the status element from the visible Text via aria-labelledby instead
|
|
190
|
+
// of duplicating the same string as aria-label — the duplicate would be
|
|
191
|
+
// announced twice by screen readers (WCAG 4.1.2).
|
|
192
|
+
const namedByVisibleLabel = hasLabel && typeof label === 'string' && ariaLabel == null;
|
|
186
193
|
|
|
187
194
|
// Resolve accessible name: explicit aria-label > string label > "Loading"
|
|
188
195
|
const resolvedAriaLabel = ariaLabel ?? (typeof label === 'string' ? label : undefined) ?? 'Loading';
|
|
189
196
|
const spinner = /*#__PURE__*/_jsx("span", {
|
|
190
197
|
ref: hasLabel ? undefined : ref,
|
|
191
198
|
role: "status",
|
|
192
|
-
"aria-label": resolvedAriaLabel,
|
|
199
|
+
"aria-label": namedByVisibleLabel ? undefined : resolvedAriaLabel,
|
|
200
|
+
"aria-labelledby": namedByVisibleLabel ? labelId : undefined,
|
|
193
201
|
"data-testid": hasLabel ? undefined : testId,
|
|
194
202
|
...(hasLabel ? {} : restProps),
|
|
195
203
|
...mergeProps(hasLabel ? '' : themeProps('spinner', {
|
|
@@ -219,6 +227,7 @@ export function Spinner({
|
|
|
219
227
|
shade
|
|
220
228
|
}), stylex.props(styles.wrapper, xstyle), className, style),
|
|
221
229
|
children: [spinner, typeof label === 'string' ? /*#__PURE__*/_jsx(Text, {
|
|
230
|
+
id: labelId,
|
|
222
231
|
type: "body",
|
|
223
232
|
weight: "bold",
|
|
224
233
|
children: label
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
*/
|
|
15
15
|
import React, { type ReactNode } from 'react';
|
|
16
16
|
import type { BaseProps } from '../BaseProps';
|
|
17
|
-
import type {
|
|
17
|
+
import type { TabListSize } from './TabListContext';
|
|
18
18
|
import { EDGE_COMP_ATTR } from '../Layout/edgeCompensation.stylex';
|
|
19
19
|
export interface TabListProps extends Omit<BaseProps<HTMLElement>, 'onChange'> {
|
|
20
20
|
ref?: React.Ref<HTMLElement>;
|
|
@@ -44,15 +44,6 @@ export interface TabListProps extends Omit<BaseProps<HTMLElement>, 'onChange'> {
|
|
|
44
44
|
* @default false
|
|
45
45
|
*/
|
|
46
46
|
hasDivider?: boolean;
|
|
47
|
-
/**
|
|
48
|
-
* Orientation of the tab strip, controlling which arrow keys move
|
|
49
|
-
* focus between tabs.
|
|
50
|
-
* - `'horizontal'` (default): ArrowLeft / ArrowRight (ArrowUp / ArrowDown
|
|
51
|
-
* also work per the WAI-ARIA APG).
|
|
52
|
-
* - `'vertical'`: ArrowUp / ArrowDown (ArrowLeft / ArrowRight also work).
|
|
53
|
-
* @default 'horizontal'
|
|
54
|
-
*/
|
|
55
|
-
orientation?: TabListOrientation;
|
|
56
47
|
/**
|
|
57
48
|
* Tab and TabMenu children.
|
|
58
49
|
*/
|
|
@@ -74,7 +65,7 @@ export interface TabListProps extends Omit<BaseProps<HTMLElement>, 'onChange'> {
|
|
|
74
65
|
* </TabList>
|
|
75
66
|
* ```
|
|
76
67
|
*/
|
|
77
|
-
export declare function TabList({ ref, value, onChange, size: sizeProp, layout, hasDivider,
|
|
68
|
+
export declare function TabList({ ref, value, onChange, size: sizeProp, layout, hasDivider, xstyle, className, style, children, onKeyDown: onKeyDownProp, onFocus: onFocusProp, onBlur: onBlurProp, 'aria-label': ariaLabelFromProps, 'aria-orientation': _ariaOrientation, [EDGE_COMP_ATTR]: _edgeCompAttr, ...restProps }: TabListProps): React.JSX.Element;
|
|
78
69
|
export declare namespace TabList {
|
|
79
70
|
var displayName: string;
|
|
80
71
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TabList.d.ts","sourceRoot":"","sources":["../../src/TabList/TabList.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EAAE,EAAuB,KAAK,SAAS,EAAC,MAAM,OAAO,CAAC;AAGlE,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AAE5C,OAAO,KAAK,EAAC,
|
|
1
|
+
{"version":3,"file":"TabList.d.ts","sourceRoot":"","sources":["../../src/TabList/TabList.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EAAE,EAAuB,KAAK,SAAS,EAAC,MAAM,OAAO,CAAC;AAGlE,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AAE5C,OAAO,KAAK,EAAC,WAAW,EAAC,MAAM,kBAAkB,CAAC;AAKlD,OAAO,EAAC,cAAc,EAAC,MAAM,mCAAmC,CAAC;AAWjE,MAAM,WAAW,YAAa,SAAQ,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,EAAE,UAAU,CAAC;IAC5E,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;IAC7B;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;IACd;;OAEG;IACH,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC;;;;OAIG;IACH,IAAI,CAAC,EAAE,WAAW,CAAC;IACnB;;;;;OAKG;IACH,MAAM,CAAC,EAAE,KAAK,GAAG,MAAM,CAAC;IACxB;;;OAGG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;OAEG;IACH,QAAQ,EAAE,SAAS,CAAC;CACrB;AA4BD;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,OAAO,CAAC,EACtB,GAAG,EACH,KAAK,EACL,QAAQ,EACR,IAAI,EAAE,QAAQ,EACd,MAAc,EACd,UAAkB,EAClB,MAAM,EACN,SAAS,EACT,KAAK,EACL,QAAQ,EACR,SAAS,EAAE,aAAa,EACxB,OAAO,EAAE,WAAW,EACpB,MAAM,EAAE,UAAU,EAClB,YAAY,EAAE,kBAAkB,EAChC,kBAAkB,EAAE,gBAAgB,EACpC,CAAC,cAAc,CAAC,EAAE,aAAa,EAC/B,GAAG,SAAS,EACb,EAAE,YAAY,qBAkGd;yBApHe,OAAO"}
|
package/dist/TabList/TabList.js
CHANGED
|
@@ -82,7 +82,6 @@ export function TabList({
|
|
|
82
82
|
size: sizeProp,
|
|
83
83
|
layout = 'hug',
|
|
84
84
|
hasDivider = false,
|
|
85
|
-
orientation = 'horizontal',
|
|
86
85
|
xstyle,
|
|
87
86
|
className,
|
|
88
87
|
style,
|
|
@@ -102,14 +101,13 @@ export function TabList({
|
|
|
102
101
|
// Roving-tabindex keyboard navigation across the tab strip via the shared
|
|
103
102
|
// hook. `orientation: 'both'` accepts both arrow axes per the WAI-ARIA APG
|
|
104
103
|
// allowance for tab strips (ArrowRight/ArrowDown advance, ArrowLeft/ArrowUp
|
|
105
|
-
// retreat)
|
|
106
|
-
//
|
|
107
|
-
//
|
|
108
|
-
// navigation role and triggers an axe `aria-allowed-attr` violation.
|
|
104
|
+
// retreat). We do not set `aria-orientation` on the `<nav>`: that attribute
|
|
105
|
+
// is invalid on the navigation role and triggers an axe `aria-allowed-attr`
|
|
106
|
+
// violation.
|
|
109
107
|
//
|
|
110
108
|
// `hasRovingTabIndex` makes the hook own the single tab stop: it stamps
|
|
111
109
|
// tabindex 0/-1, repairs the stop on mount and as stops mount/unmount or
|
|
112
|
-
// toggle disabled, and
|
|
110
|
+
// toggle disabled, and -- via `handleFocus` on the nav -- keeps the stop in
|
|
113
111
|
// sync after clicks or programmatic focus. Individual Tabs still render
|
|
114
112
|
// `tabIndex={isSelected ? 0 : -1}` (see Tab.tsx) as the initial source of
|
|
115
113
|
// truth; the hook's repair preserves an existing tab stop and only promotes
|
|
@@ -128,9 +126,7 @@ export function TabList({
|
|
|
128
126
|
onKeyDown: onHintKeyDown,
|
|
129
127
|
onFocus: onHintFocus,
|
|
130
128
|
onBlur: onHintBlur
|
|
131
|
-
} = useKeyboardHint(
|
|
132
|
-
orientation
|
|
133
|
-
});
|
|
129
|
+
} = useKeyboardHint();
|
|
134
130
|
const contextValue = useMemo(() => ({
|
|
135
131
|
value,
|
|
136
132
|
onChange,
|
|
@@ -9,11 +9,6 @@ export type TabListSize = 'sm' | 'md' | 'lg';
|
|
|
9
9
|
* - `'fill'`: tabs stretch equally to fill the container width.
|
|
10
10
|
*/
|
|
11
11
|
export type TabListLayout = 'hug' | 'fill';
|
|
12
|
-
/**
|
|
13
|
-
* Orientation of the tab strip. Controls which arrow keys move focus
|
|
14
|
-
* between tabs and the reported `aria-orientation`.
|
|
15
|
-
*/
|
|
16
|
-
export type TabListOrientation = 'horizontal' | 'vertical';
|
|
17
12
|
/**
|
|
18
13
|
* Context for communicating value/onChange/size/layout from TabList to children.
|
|
19
14
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TabListContext.d.ts","sourceRoot":"","sources":["../../src/TabList/TabListContext.ts"],"names":[],"mappings":"AAeA;;;GAGG;AACH,MAAM,MAAM,WAAW,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;AAE7C;;;;GAIG;AACH,MAAM,MAAM,aAAa,GAAG,KAAK,GAAG,MAAM,CAAC;AAE3C
|
|
1
|
+
{"version":3,"file":"TabListContext.d.ts","sourceRoot":"","sources":["../../src/TabList/TabListContext.ts"],"names":[],"mappings":"AAeA;;;GAGG;AACH,MAAM,MAAM,WAAW,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;AAE7C;;;;GAIG;AACH,MAAM,MAAM,aAAa,GAAG,KAAK,GAAG,MAAM,CAAC;AAE3C;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,IAAI,EAAE,WAAW,CAAC;IAClB,MAAM,EAAE,aAAa,CAAC;CACvB;AAED,eAAO,MAAM,cAAc,qDAAkD,CAAC;AAG9E;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,mBAAmB,CASvD"}
|
|
@@ -23,11 +23,6 @@ import { createContext, use } from 'react';
|
|
|
23
23
|
* - `'fill'`: tabs stretch equally to fill the container width.
|
|
24
24
|
*/
|
|
25
25
|
|
|
26
|
-
/**
|
|
27
|
-
* Orientation of the tab strip. Controls which arrow keys move focus
|
|
28
|
-
* between tabs and the reported `aria-orientation`.
|
|
29
|
-
*/
|
|
30
|
-
|
|
31
26
|
/**
|
|
32
27
|
* Context for communicating value/onChange/size/layout from TabList to children.
|
|
33
28
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useTableSelection.d.ts","sourceRoot":"","sources":["../../../../src/Table/plugins/selection/useTableSelection.tsx"],"names":[],"mappings":"AA+CA,OAAO,KAAK,EAAC,WAAW,EAAkC,MAAM,aAAa,CAAC;AAQ9E,MAAM,WAAW,uBAAuB,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IACxE,uCAAuC;IACvC,iBAAiB,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,OAAO,CAAC;IACxC,6EAA6E;IAC7E,YAAY,EAAE,CAAC,KAAK,EAAE;QAAC,IAAI,EAAE,CAAC,CAAC;QAAC,UAAU,EAAE,OAAO,CAAA;KAAC,KAAK,IAAI,CAAC;IAC9D,kDAAkD;IAClD,WAAW,EAAE,CAAC,KAAK,EAAE;QAAC,aAAa,EAAE,OAAO,CAAA;KAAC,KAAK,IAAI,CAAC;IACvD,mDAAmD;IACnD,gBAAgB,EAAE,MAAM,OAAO,CAAC;IAChC,iFAAiF;IACjF,kBAAkB,CAAC,EAAE,MAAM,OAAO,CAAC;IACnC,+FAA+F;IAC/F,mBAAmB,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,OAAO,CAAC;IAC3C,oGAAoG;IACpG,gBAAgB,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,OAAO,CAAC;IACxC;;;;;;;;;;;OAWG;IACH,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,MAAM,CAAC;CACnC;AAuND,wBAAgB,iBAAiB,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACjE,MAAM,EAAE,uBAAuB,CAAC,CAAC,CAAC,GACjC,WAAW,CAAC,CAAC,CAAC,
|
|
1
|
+
{"version":3,"file":"useTableSelection.d.ts","sourceRoot":"","sources":["../../../../src/Table/plugins/selection/useTableSelection.tsx"],"names":[],"mappings":"AA+CA,OAAO,KAAK,EAAC,WAAW,EAAkC,MAAM,aAAa,CAAC;AAQ9E,MAAM,WAAW,uBAAuB,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IACxE,uCAAuC;IACvC,iBAAiB,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,OAAO,CAAC;IACxC,6EAA6E;IAC7E,YAAY,EAAE,CAAC,KAAK,EAAE;QAAC,IAAI,EAAE,CAAC,CAAC;QAAC,UAAU,EAAE,OAAO,CAAA;KAAC,KAAK,IAAI,CAAC;IAC9D,kDAAkD;IAClD,WAAW,EAAE,CAAC,KAAK,EAAE;QAAC,aAAa,EAAE,OAAO,CAAA;KAAC,KAAK,IAAI,CAAC;IACvD,mDAAmD;IACnD,gBAAgB,EAAE,MAAM,OAAO,CAAC;IAChC,iFAAiF;IACjF,kBAAkB,CAAC,EAAE,MAAM,OAAO,CAAC;IACnC,+FAA+F;IAC/F,mBAAmB,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,OAAO,CAAC;IAC3C,oGAAoG;IACpG,gBAAgB,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,OAAO,CAAC;IACxC;;;;;;;;;;;OAWG;IACH,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,MAAM,CAAC;CACnC;AAuND,wBAAgB,iBAAiB,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACjE,MAAM,EAAE,uBAAuB,CAAC,CAAC,CAAC,GACjC,WAAW,CAAC,CAAC,CAAC,CAsFhB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useTooltip.d.ts","sourceRoot":"","sources":["../../src/Tooltip/useTooltip.tsx"],"names":[],"mappings":"AAIA;;;;;;;;GAQG;AAEH,OAAO,EAKL,KAAK,SAAS,EACd,KAAK,WAAW,EACjB,MAAM,OAAO,CAAC;AAEf,OAAO,EAEL,KAAK,kBAAkB,EACvB,KAAK,cAAc,EACnB,KAAK,cAAc,EACpB,MAAM,mBAAmB,CAAC;AAsD3B;;GAEG;AACH,MAAM,MAAM,mBAAmB,GAAG,MAAM,GAAG,QAAQ,GAAG,OAAO,CAAC;AAE9D,MAAM,WAAW,cAAc;IAC7B;;;OAGG;IACH,SAAS,CAAC,EAAE,cAAc,CAAC;IAE3B;;;OAGG;IACH,SAAS,CAAC,EAAE,cAAc,CAAC;IAE3B;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;;;;;;OAOG;IACH,YAAY,CAAC,EAAE,mBAAmB,CAAC;IAEnC;;;;;OAKG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IAEpB;;;;;OAKG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;IAEjB;;;OAGG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IAExB;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IAEpB;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;CACrB;AAED,MAAM,WAAW,aAAa;IAC5B;;;OAGG;IACH,GAAG,EAAE,WAAW,CAAC,WAAW,CAAC,CAAC;IAE9B;;;OAGG;IACH,WAAW,EAAE,WAAW,CAAC,WAAW,CAAC,CAAC;IAEtC;;;;OAIG;IACH,cAAc,EAAE,WAAW,CAAC,WAAW,CAAC,CAAC;IAEzC;;;OAGG;IACH,QAAQ,EAAE,MAAM,CAAC;IAEjB;;;OAGG;IACH,WAAW,EAAE,MAAM,CAAC;IAEpB;;;;;;;OAOG;IACH,aAAa,EAAE,CACb,QAAQ,EAAE,SAAS,EACnB,KAAK,CAAC,EAAE,IAAI,CAAC,kBAAkB,EAAE,aAAa,CAAC,KAC5C,SAAS,CAAC;CAChB;AAyBD;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,UAAU,CAAC,OAAO,GAAE,cAAmB,GAAG,aAAa,
|
|
1
|
+
{"version":3,"file":"useTooltip.d.ts","sourceRoot":"","sources":["../../src/Tooltip/useTooltip.tsx"],"names":[],"mappings":"AAIA;;;;;;;;GAQG;AAEH,OAAO,EAKL,KAAK,SAAS,EACd,KAAK,WAAW,EACjB,MAAM,OAAO,CAAC;AAEf,OAAO,EAEL,KAAK,kBAAkB,EACvB,KAAK,cAAc,EACnB,KAAK,cAAc,EACpB,MAAM,mBAAmB,CAAC;AAsD3B;;GAEG;AACH,MAAM,MAAM,mBAAmB,GAAG,MAAM,GAAG,QAAQ,GAAG,OAAO,CAAC;AAE9D,MAAM,WAAW,cAAc;IAC7B;;;OAGG;IACH,SAAS,CAAC,EAAE,cAAc,CAAC;IAE3B;;;OAGG;IACH,SAAS,CAAC,EAAE,cAAc,CAAC;IAE3B;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;;;;;;OAOG;IACH,YAAY,CAAC,EAAE,mBAAmB,CAAC;IAEnC;;;;;OAKG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IAEpB;;;;;OAKG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;IAEjB;;;OAGG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IAExB;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IAEpB;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;CACrB;AAED,MAAM,WAAW,aAAa;IAC5B;;;OAGG;IACH,GAAG,EAAE,WAAW,CAAC,WAAW,CAAC,CAAC;IAE9B;;;OAGG;IACH,WAAW,EAAE,WAAW,CAAC,WAAW,CAAC,CAAC;IAEtC;;;;OAIG;IACH,cAAc,EAAE,WAAW,CAAC,WAAW,CAAC,CAAC;IAEzC;;;OAGG;IACH,QAAQ,EAAE,MAAM,CAAC;IAEjB;;;OAGG;IACH,WAAW,EAAE,MAAM,CAAC;IAEpB;;;;;;;OAOG;IACH,aAAa,EAAE,CACb,QAAQ,EAAE,SAAS,EACnB,KAAK,CAAC,EAAE,IAAI,CAAC,kBAAkB,EAAE,aAAa,CAAC,KAC5C,SAAS,CAAC;CAChB;AAyBD;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,UAAU,CAAC,OAAO,GAAE,cAAmB,GAAG,aAAa,CAsRtE"}
|
|
@@ -201,6 +201,19 @@ export function useTooltip(options = {}) {
|
|
|
201
201
|
scheduleHide();
|
|
202
202
|
}, [scheduleHide]);
|
|
203
203
|
|
|
204
|
+
// Pressing the trigger hides its own tooltip: once the control is activated
|
|
205
|
+
// the hint has served its purpose, and a tooltip lingering over a
|
|
206
|
+
// just-pressed control reads as stale. Fires on pointerdown so it feels
|
|
207
|
+
// immediate. Uncontrolled tooltips only — a controlled tooltip's visibility
|
|
208
|
+
// is owned by the consumer. `layer.hide()` self-guards when already closed.
|
|
209
|
+
const handlePointerDown = useCallback(() => {
|
|
210
|
+
if (isOpen !== undefined) {
|
|
211
|
+
return;
|
|
212
|
+
}
|
|
213
|
+
clearTimeouts();
|
|
214
|
+
layer.hide();
|
|
215
|
+
}, [isOpen, clearTimeouts, layer]);
|
|
216
|
+
|
|
204
217
|
// Interaction ref that handles event listeners only
|
|
205
218
|
const interactionRef = useCallback(el => {
|
|
206
219
|
// Cleanup previous element
|
|
@@ -209,11 +222,14 @@ export function useTooltip(options = {}) {
|
|
|
209
222
|
triggerRef.current.removeEventListener('mouseleave', handleMouseLeave);
|
|
210
223
|
triggerRef.current.removeEventListener('focusin', handleFocusIn);
|
|
211
224
|
triggerRef.current.removeEventListener('focusout', handleFocusOut);
|
|
225
|
+
triggerRef.current.removeEventListener('pointerdown', handlePointerDown);
|
|
212
226
|
}
|
|
213
227
|
if (el) {
|
|
214
228
|
// Attach hover listeners
|
|
215
229
|
el.addEventListener('mouseenter', handleMouseEnter);
|
|
216
230
|
el.addEventListener('mouseleave', handleMouseLeave);
|
|
231
|
+
// Press-to-dismiss: activating the trigger hides its own tooltip.
|
|
232
|
+
el.addEventListener('pointerdown', handlePointerDown);
|
|
217
233
|
|
|
218
234
|
// Attach focus listeners based on focusTrigger option
|
|
219
235
|
const shouldAttachFocus = focusTrigger === 'always' || focusTrigger === 'auto' && isFocusable(el);
|
|
@@ -223,7 +239,7 @@ export function useTooltip(options = {}) {
|
|
|
223
239
|
}
|
|
224
240
|
}
|
|
225
241
|
triggerRef.current = el;
|
|
226
|
-
}, [focusTrigger, handleMouseEnter, handleMouseLeave, handleFocusIn, handleFocusOut]);
|
|
242
|
+
}, [focusTrigger, handleMouseEnter, handleMouseLeave, handleFocusIn, handleFocusOut, handlePointerDown]);
|
|
227
243
|
|
|
228
244
|
// Combined ref - shorthand for calling both positionRef and interactionRef
|
|
229
245
|
const ref = useCallback(el => {
|
|
@@ -47,6 +47,8 @@ export interface TopNavItemProps extends BaseProps<HTMLAnchorElement> {
|
|
|
47
47
|
isSelected?: boolean;
|
|
48
48
|
/**
|
|
49
49
|
* Whether the nav item is disabled.
|
|
50
|
+
* A disabled item renders as a plain anchor without an href (and without
|
|
51
|
+
* target), so it cannot navigate and is removed from the tab order.
|
|
50
52
|
* @default false
|
|
51
53
|
*/
|
|
52
54
|
isDisabled?: boolean;
|
|
@@ -91,7 +93,7 @@ export interface TopNavItemProps extends BaseProps<HTMLAnchorElement> {
|
|
|
91
93
|
* />
|
|
92
94
|
* ```
|
|
93
95
|
*/
|
|
94
|
-
export declare function TopNavItem({ as, label, isSelected, isDisabled, isIconOnly, icon, children, size, xstyle, className, style, ref, ...props }: TopNavItemProps): import("react").JSX.Element;
|
|
96
|
+
export declare function TopNavItem({ as, href, target, onClick, label, isSelected, isDisabled, isIconOnly, icon, children, size, xstyle, className, style, ref, ...props }: TopNavItemProps): import("react").JSX.Element;
|
|
95
97
|
export declare namespace TopNavItem {
|
|
96
98
|
var displayName: string;
|
|
97
99
|
}
|