@astryxdesign/core 0.5.0-canary.89abbb3 → 0.5.0-canary.8bb01b1

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 (54) hide show
  1. package/dist/Carousel/Carousel.d.ts.map +1 -1
  2. package/dist/Carousel/Carousel.js +7 -108
  3. package/dist/Layer/useLayer.d.ts.map +1 -1
  4. package/dist/Layer/useLayer.js +22 -24
  5. package/dist/SideNav/SideNavItem.d.ts +4 -29
  6. package/dist/SideNav/SideNavItem.d.ts.map +1 -1
  7. package/dist/SideNav/SideNavItem.js +15 -71
  8. package/dist/astryx.css +0 -4
  9. package/dist/theme/useTheme.d.ts.map +1 -1
  10. package/dist/theme/useTheme.js +7 -6
  11. package/dist/utils/focusOutline.stylex.d.ts +0 -25
  12. package/dist/utils/focusOutline.stylex.d.ts.map +1 -1
  13. package/dist/utils/focusOutline.stylex.js +0 -15
  14. package/locales/af-ZA.json +1 -1
  15. package/locales/ar-SA.json +1 -1
  16. package/locales/ca-ES.json +1 -1
  17. package/locales/cs-CZ.json +1 -1
  18. package/locales/da-DK.json +1 -1
  19. package/locales/de-DE.json +1 -1
  20. package/locales/el-GR.json +1 -1
  21. package/locales/es-ES.json +1 -1
  22. package/locales/fi-FI.json +1 -1
  23. package/locales/fr-FR.json +1 -1
  24. package/locales/he-IL.json +1 -1
  25. package/locales/hu-HU.json +1 -1
  26. package/locales/it-IT.json +1 -1
  27. package/locales/ja-JP.json +1 -1
  28. package/locales/ko-KR.json +1 -1
  29. package/locales/nl-NL.json +1 -1
  30. package/locales/no-NO.json +1 -1
  31. package/locales/pl-PL.json +1 -1
  32. package/locales/pt-BR.json +1 -1
  33. package/locales/pt-PT.json +1 -1
  34. package/locales/ro-RO.json +1 -1
  35. package/locales/ru-RU.json +1 -1
  36. package/locales/sr-SP.json +1 -1
  37. package/locales/sv-SE.json +1 -1
  38. package/locales/tr-TR.json +1 -1
  39. package/locales/uk-UA.json +1 -1
  40. package/locales/vi-VN.json +1 -1
  41. package/locales/zh-CN.json +1 -1
  42. package/locales/zh-TW.json +1 -1
  43. package/package.json +2 -2
  44. package/src/Carousel/Carousel.doc.mjs +0 -3
  45. package/src/Carousel/Carousel.test.tsx +0 -360
  46. package/src/Carousel/Carousel.tsx +15 -116
  47. package/src/Layer/useLayer.test.tsx +1 -44
  48. package/src/Layer/useLayer.tsx +31 -48
  49. package/src/SideNav/SideNav.test.tsx +5 -705
  50. package/src/SideNav/SideNavItem.doc.mjs +3 -24
  51. package/src/SideNav/SideNavItem.tsx +39 -131
  52. package/src/theme/useTheme.test.tsx +0 -10
  53. package/src/theme/useTheme.ts +10 -16
  54. package/src/utils/focusOutline.stylex.ts +0 -50
@@ -1 +1 @@
1
- {"version":3,"file":"Carousel.d.ts","sourceRoot":"","sources":["../../src/Carousel/Carousel.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,EACL,KAAK,SAAS,EAOf,MAAM,OAAO,CAAC;AAef,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AAE5C,OAAO,KAAK,EAAC,WAAW,EAAC,MAAM,gBAAgB,CAAC;AAKhD;;;;GAIG;AACH,MAAM,WAAW,cAAc;IAC7B;;;OAGG;IACH,UAAU,IAAI,IAAI,CAAC;IACnB;;;OAGG;IACH,UAAU,IAAI,IAAI,CAAC;IACnB;;;;OAIG;IACH,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B;;;;OAIG;IACH,aAAa,IAAI,OAAO,CAAC;IACzB;;;OAGG;IACH,aAAa,IAAI,OAAO,CAAC;CAC1B;AAED,MAAM,WAAW,aAAc,SAAQ,SAAS,CAAC,cAAc,CAAC;IAC9D,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;IAChC;;;OAGG;IACH,SAAS,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;IACtC,kEAAkE;IAClE,QAAQ,EAAE,SAAS,CAAC;IACpB;;;OAGG;IACH,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,GAAG,CAAC,GAAG,GAAG,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IACpC;;;OAGG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;;;;OAKG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB;;;;;;;;OAQG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB;;;OAGG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB;;;;;;;;OAQG;IACH,OAAO,CAAC,EAAE,WAAW,CAAC;IACtB;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAyJD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,QAAQ,CAAC,EACvB,GAAG,EACH,SAAS,EACT,QAAQ,EACR,GAAO,EACP,UAAiB,EACjB,WAAkB,EAClB,OAAe,EACf,OAAe,EACf,OAAO,EACP,YAAY,EAAE,kBAAkB,EAChC,MAAM,EACN,SAAS,EACT,KAAK,EACL,aAAa,EAAE,MAAM,EACrB,GAAG,SAAS,EACb,EAAE,aAAa,+BAgYf;yBAhZe,QAAQ"}
1
+ {"version":3,"file":"Carousel.d.ts","sourceRoot":"","sources":["../../src/Carousel/Carousel.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,EACL,KAAK,SAAS,EAOf,MAAM,OAAO,CAAC;AAef,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AAE5C,OAAO,KAAK,EAAC,WAAW,EAAC,MAAM,gBAAgB,CAAC;AAKhD;;;;GAIG;AACH,MAAM,WAAW,cAAc;IAC7B;;;OAGG;IACH,UAAU,IAAI,IAAI,CAAC;IACnB;;;OAGG;IACH,UAAU,IAAI,IAAI,CAAC;IACnB;;;;OAIG;IACH,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B;;;;OAIG;IACH,aAAa,IAAI,OAAO,CAAC;IACzB;;;OAGG;IACH,aAAa,IAAI,OAAO,CAAC;CAC1B;AAED,MAAM,WAAW,aAAc,SAAQ,SAAS,CAAC,cAAc,CAAC;IAC9D,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;IAChC;;;OAGG;IACH,SAAS,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;IACtC,kEAAkE;IAClE,QAAQ,EAAE,SAAS,CAAC;IACpB;;;OAGG;IACH,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,GAAG,CAAC,GAAG,GAAG,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IACpC;;;OAGG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;;;;OAKG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB;;;;;;;;OAQG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB;;;OAGG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB;;;;;;;;OAQG;IACH,OAAO,CAAC,EAAE,WAAW,CAAC;IACtB;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AA+JD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,QAAQ,CAAC,EACvB,GAAG,EACH,SAAS,EACT,QAAQ,EACR,GAAO,EACP,UAAiB,EACjB,WAAkB,EAClB,OAAe,EACf,OAAe,EACf,OAAO,EACP,YAAY,EAAE,kBAAkB,EAChC,MAAM,EACN,SAAS,EACT,KAAK,EACL,aAAa,EAAE,MAAM,EACrB,GAAG,SAAS,EACb,EAAE,aAAa,+BAqRf;yBArSe,QAAQ"}
@@ -66,6 +66,9 @@ const styles = {
66
66
  khEr5k: "xkcv6ua xg83hb1",
67
67
  k5wCbM: "x1rohswg",
68
68
  kX1K2I: "xw4ya9i",
69
+ k1ekBW: "x157bb6t",
70
+ kIyJzY: "x80gvsz x12w9bfk",
71
+ kAMwcw: "xlr8y92",
69
72
  $$css: true
70
73
  },
71
74
  fadeStart: {
@@ -226,13 +229,6 @@ export function Carousel({
226
229
  const t = useTranslator();
227
230
  const ariaLabel = ariaLabelFromProps ?? t('@astryx.carousel.label');
228
231
  const scrollElRef = useRef(null);
229
- const startButtonRef = useRef(null);
230
- const endButtonRef = useRef(null);
231
- // Which nav button last held focus, and what the overflow state was on the
232
- // previous render. Together they are how the Effect below recognises the one
233
- // transition it is allowed to act on.
234
- const focusedNavRef = useRef(null);
235
- const prevCanScrollRef = useRef(null);
236
232
  const {
237
233
  scrollRef,
238
234
  overflowStart,
@@ -363,76 +359,6 @@ export function Carousel({
363
359
  // something to scroll; without loop they follow the per-edge overflow state.
364
360
  const canScrollStart = hasLoop && hasOverflow ? true : overflowStart;
365
361
  const canScrollEnd = hasLoop && hasOverflow ? true : overflowEnd;
366
-
367
- // Keep the keyboard user where they are when a nav button disables under
368
- // them. The browser drops focus off a control it disables, so reaching an
369
- // edge used to land the user on <body> and cost them their place in the page.
370
- //
371
- // This is an Effect on purpose, and the exception is narrow. The thing that
372
- // disables the button IS this state transition, so it is the only correct
373
- // trigger: three attempts to predict it from the press -- the position after
374
- // the scroll, the position before it plus the step, and the settled position
375
- // reported by `scrollend` -- were each wrong somewhere, under reduced motion,
376
- // under mandatory scroll-snap, and on a browser that never fires the event.
377
- // Running after the commit also makes the opposite button a valid receiver,
378
- // which it is not during the press: at that moment it is still disabled and
379
- // focus() on a disabled control does nothing. Ruled acceptable by the
380
- // maintainer, 2026-08-27, on the conditions encoded below: it acts only on
381
- // the transition that newly disables the focused button, it moves focus and
382
- // nothing else, and it cannot fire twice for one transition.
383
- //
384
- // Which button the person is on is tracked by the buttons' own focus and blur
385
- // handlers, and the blur has to ignore the one the commit itself causes: a
386
- // tracker that outlived the person let a later edge -- a swipe, a resize, no
387
- // press at all -- pull their focus back onto a control they never chose.
388
- useEffect(() => {
389
- const previous = prevCanScrollRef.current;
390
- prevCanScrollRef.current = {
391
- start: canScrollStart,
392
- end: canScrollEnd
393
- };
394
- const side = focusedNavRef.current;
395
- if (previous == null || side == null) {
396
- return;
397
- }
398
-
399
- // Only the edge that just ran out, and only while it held focus. An edge
400
- // that was already disabled, or one the user was not on, is not ours.
401
- const wasEnabled = side === 'start' ? previous.start : previous.end;
402
- const isEnabled = side === 'start' ? canScrollStart : canScrollEnd;
403
- if (!wasEnabled || isEnabled) {
404
- return;
405
- }
406
- const pressed = side === 'start' ? startButtonRef.current : endButtonRef.current;
407
- if (pressed == null) {
408
- return;
409
- }
410
- // The browser has already blurred it, so focus reads as the body. Anything
411
- // else means the user moved on themselves and this is not ours to redirect.
412
- const active = pressed.ownerDocument.activeElement;
413
- if (active !== pressed && active !== pressed.ownerDocument.body) {
414
- return;
415
- }
416
- const opposite = side === 'start' ? endButtonRef.current : startButtonRef.current;
417
- // The opposite button is the receiver. It is disabled only when the
418
- // carousel stopped overflowing entirely, which happens when its content
419
- // shrinks; the scroll container is then the nearest tab stop still inside
420
- // the labelled region.
421
- const receiver = opposite != null && !opposite.disabled ? opposite : scrollElRef.current;
422
- if (receiver == null) {
423
- return;
424
- }
425
-
426
- // One move per transition: clearing the tracker first means a re-render or
427
- // a StrictMode double-invoke re-runs this and returns at the `side == null`
428
- // guard above. Focusing the receiver sets it again, to the other side.
429
- focusedNavRef.current = null;
430
- // preventScroll: a plain focus() scrolls its element into view, which on
431
- // the scroll container cancels the scroll the press just started.
432
- receiver.focus({
433
- preventScroll: true
434
- });
435
- }, [canScrollStart, canScrollEnd]);
436
362
  const fadeStyle = hasEdgeFade ? hasLoop && hasOverflow || overflowStart && overflowEnd ? styles.fadeBoth : overflowStart ? styles.fadeStart : overflowEnd ? styles.fadeEnd : null : null;
437
363
 
438
364
  // Self-authored position styles (positioning: 'custom' below): a cover
@@ -454,12 +380,7 @@ export function Carousel({
454
380
  ref: composedRef,
455
381
  tabIndex: 0,
456
382
  onWheel: handleWheel,
457
- ...mergeProps(themeProps('carousel-scroller', {
458
- gap,
459
- padding,
460
- snap: hasSnap ? 'snap' : null,
461
- edgeFade: hasEdgeFade ? 'edge-fade' : null
462
- }), stylex.props(styles.scroller, gapStyles[gap], padding != null && paddingStyles[padding], hasSnap && styles.snap, fadeStyle)),
383
+ ...stylex.props(styles.scroller, gapStyles[gap], padding != null && paddingStyles[padding], hasSnap && styles.snap, fadeStyle),
463
384
  children: slides.map((child, index) =>
464
385
  /*#__PURE__*/
465
386
  // APG carousel pattern: each slide container is a group with
@@ -489,7 +410,6 @@ export function Carousel({
489
410
  }
490
411
  }[!!!canScrollStart << 0],
491
412
  children: /*#__PURE__*/_jsx(Button, {
492
- ref: startButtonRef,
493
413
  icon: /*#__PURE__*/_jsx(Icon, {
494
414
  icon: "chevronLeft",
495
415
  size: "xsm",
@@ -500,22 +420,11 @@ export function Carousel({
500
420
  size: "sm",
501
421
  isIconOnly: true
502
422
  // Disabled when there's nothing to scroll toward. Keeps the
503
- // button mounted (stable layout) but removes it from the tab
504
- // order and a11y tree while it's visually hidden, so keyboard
505
- // users don't land on an invisible control. The Effect above
506
- // hands focus to the other button when the state behind this
507
- // one flips it disabled.
423
+ // button mounted (stable layout/focus) but removes it from the
424
+ // tab order and a11y tree while it's visually hidden, so
425
+ // keyboard users don't land on an invisible control.
508
426
  ,
509
427
  isDisabled: !canScrollStart,
510
- onFocus: () => {
511
- focusedNavRef.current = 'start';
512
- },
513
- onBlur: event => {
514
- // A disabled button was blurred by the commit, not the person.
515
- if (!event.currentTarget.disabled) {
516
- focusedNavRef.current = null;
517
- }
518
- },
519
428
  onClick: () => scrollBy(-1),
520
429
  xstyle: styles.buttonRadiusOverride
521
430
  })
@@ -529,7 +438,6 @@ export function Carousel({
529
438
  }
530
439
  }[!!!canScrollEnd << 0],
531
440
  children: /*#__PURE__*/_jsx(Button, {
532
- ref: endButtonRef,
533
441
  icon: /*#__PURE__*/_jsx(Icon, {
534
442
  icon: "chevronRight",
535
443
  size: "xsm",
@@ -543,15 +451,6 @@ export function Carousel({
543
451
  // button stays mounted but out of the tab order / a11y tree.
544
452
  ,
545
453
  isDisabled: !canScrollEnd,
546
- onFocus: () => {
547
- focusedNavRef.current = 'end';
548
- },
549
- onBlur: event => {
550
- // A disabled button was blurred by the commit, not the person.
551
- if (!event.currentTarget.disabled) {
552
- focusedNavRef.current = null;
553
- }
554
- },
555
454
  onClick: () => scrollBy(1),
556
455
  xstyle: styles.buttonRadiusOverride
557
456
  })
@@ -1 +1 @@
1
- {"version":3,"file":"useLayer.d.ts","sourceRoot":"","sources":["../../src/Layer/useLayer.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"useLayer.d.ts","sourceRoot":"","sources":["../../src/Layer/useLayer.tsx"],"names":[],"mappings":"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"}
@@ -384,8 +384,8 @@ function useLayerImplementation(options) {
384
384
  clearContextMount();
385
385
  }, [onHide, clearContextMount]);
386
386
 
387
- // Stable ref for the trigger element (context mode only).
388
- const contextRef = useCallback(el => {
387
+ // Ref for trigger element (context mode only)
388
+ const ref = mode === 'context' ? el => {
389
389
  // Remove only THIS layer's anchor name from the previous element so
390
390
  // other layers sharing the same trigger keep their anchors.
391
391
  if (triggerRef.current && triggerRef.current !== el) {
@@ -395,7 +395,7 @@ function useLayerImplementation(options) {
395
395
  addAnchorName(el, anchorId);
396
396
  }
397
397
  triggerRef.current = el;
398
- }, [anchorId]);
398
+ } : undefined;
399
399
 
400
400
  // Arm only when the dismissing gesture's click is still ahead of us. Some
401
401
  // engines deliver click first; in that order there is nothing left to absorb.
@@ -617,17 +617,19 @@ function useLayerImplementation(options) {
617
617
  children: children
618
618
  });
619
619
  }, [popoverRefCallback, id, lightDismiss]);
620
- const contextResult = useMemo(() => ({
621
- ref: contextRef,
622
- anchorId,
623
- show,
624
- hide,
625
- isOpen,
626
- wasJustDismissed,
627
- id,
628
- render: renderContext
629
- }), [contextRef, anchorId, show, hide, isOpen, wasJustDismissed, id, renderContext]);
630
- const fixedResult = useMemo(() => ({
620
+ if (mode === 'context') {
621
+ return {
622
+ ref: ref,
623
+ anchorId,
624
+ show,
625
+ hide,
626
+ isOpen,
627
+ wasJustDismissed,
628
+ id,
629
+ render: renderContext
630
+ };
631
+ }
632
+ return {
631
633
  ref: undefined,
632
634
  show,
633
635
  hide,
@@ -635,18 +637,14 @@ function useLayerImplementation(options) {
635
637
  wasJustDismissed,
636
638
  id,
637
639
  render: renderFixed
638
- }), [show, hide, isOpen, wasJustDismissed, id, renderFixed]);
639
- return mode === 'context' ? contextResult : fixedResult;
640
+ };
640
641
  }
641
642
  export function useLayer(options) {
642
- const internalLayer = useLayerImplementation(options);
643
- return useMemo(() => {
644
- const {
645
- wasJustDismissed: _,
646
- ...layer
647
- } = internalLayer;
648
- return layer;
649
- }, [internalLayer]);
643
+ const {
644
+ wasJustDismissed: _,
645
+ ...layer
646
+ } = useLayerImplementation(options);
647
+ return layer;
650
648
  }
651
649
 
652
650
  /** @internal Shared with usePopover; not exported from the package barrel. */
@@ -4,7 +4,7 @@
4
4
  * @output Exports SideNavItem component and SideNavItemProps
5
5
  * @position Core implementation; used inside SideNav children
6
6
  *
7
- * Navigation item with icon, selected state, row-level actions, and nesting.
7
+ * Navigation item with icon, selected state, and nesting.
8
8
  *
9
9
  * Collapsed items with children open their submenu flyout through
10
10
  * `useMenuHover`, the shared hover-intent hook (same one `SideNavHeading` and
@@ -63,24 +63,9 @@ export interface SideNavItemProps extends BaseProps<HTMLElement> {
63
63
  */
64
64
  onClick?: (e: React.MouseEvent) => void;
65
65
  /**
66
- * Passive right-side content only (badges, counts). Interactive
67
- * controls (icon buttons, menus) go in `actions`. `endContent`
68
- * renders inside the primary link or button.
66
+ * Right-side content (badges, counts).
69
67
  */
70
68
  endContent?: ReactNode;
71
- /**
72
- * Row-level secondary controls (icon buttons, menus) rendered as siblings
73
- * of the primary element at the trailing edge of the row — after the
74
- * expand/collapse toggle, and before any nested children in DOM and focus
75
- * order. Content is passthrough: each control owns its accessible name,
76
- * keyboard behavior, and disabled state. Hidden while the SideNav rail is
77
- * collapsed.
78
- *
79
- * Controls inherit the row's control size through `SizeContext`, so an
80
- * unsized icon button comes out the same box as the built-in
81
- * expand/collapse toggle. An explicit `size` still wins.
82
- */
83
- actions?: ReactNode;
84
69
  /**
85
70
  * Sub-items for nesting.
86
71
  */
@@ -110,10 +95,7 @@ export interface SideNavItemProps extends BaseProps<HTMLElement> {
110
95
  /**
111
96
  * Navigation item for SideNav.
112
97
  *
113
- * Supports icons, selected state, nesting, and end content like badges or
114
- * counts. Interactive row-level controls (menus, icon buttons) go in
115
- * `actions`, which renders them as siblings of the primary element — never
116
- * nested inside it — before any nested children in DOM and focus order.
98
+ * Supports icons, selected state, nesting, and end content like badges or counts.
117
99
  *
118
100
  * @example
119
101
  * ```
@@ -128,16 +110,9 @@ export interface SideNavItemProps extends BaseProps<HTMLElement> {
128
110
  * <SideNavItem label="General" href="/settings/general" />
129
111
  * <SideNavItem label="Security" href="/settings/security" />
130
112
  * </SideNavItem>
131
- * <SideNavItem
132
- * label="Projects"
133
- * href="/projects"
134
- * collapsible
135
- * actions={<MoreMenu label="Project actions" items={items} />}>
136
- * <SideNavItem label="Alpha" href="/projects/alpha" />
137
- * </SideNavItem>
138
113
  * ```
139
114
  */
140
- export declare function SideNavItem({ as, label, icon, selectedIcon, isSelected, isDisabled, href, onClick, endContent, actions, children, collapsible: itemCollapsible, size, 'data-testid': testId, ref, xstyle, ...rest }: SideNavItemProps): import("react").JSX.Element | null;
115
+ export declare function SideNavItem({ as, label, icon, selectedIcon, isSelected, isDisabled, href, onClick, endContent, children, collapsible: itemCollapsible, size, 'data-testid': testId, ref, xstyle, ...rest }: SideNavItemProps): import("react").JSX.Element | null;
141
116
  export declare namespace SideNavItem {
142
117
  var displayName: string;
143
118
  }
@@ -1 +1 @@
1
- {"version":3,"file":"SideNavItem.d.ts","sourceRoot":"","sources":["../../src/SideNav/SideNavItem.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,EAML,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AAYf,OAAO,EAAuB,KAAK,QAAQ,EAAC,MAAM,SAAS,CAAC;AAE5D,OAAO,KAAK,EAAC,iBAAiB,EAAC,MAAM,eAAe,CAAC;AAIrD,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AAE5C,OAAO,EAAgB,KAAK,WAAW,EAAC,MAAM,iCAAiC,CAAC;AA2PhF,MAAM,WAAW,gBAAiB,SAAQ,SAAS,CAAC,WAAW,CAAC;IAC9D,wCAAwC;IACxC,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;IAC7B;;;;OAIG;IACH,EAAE,CAAC,EAAE,iBAAiB,CAAC;IACvB;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;IACd;;OAEG;IACH,IAAI,CAAC,EAAE,SAAS,GAAG,QAAQ,CAAC;IAC5B;;OAEG;IACH,YAAY,CAAC,EAAE,SAAS,GAAG,QAAQ,CAAC;IACpC;;;OAGG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;;OAGG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;OAEG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;OAEG;IACH,OAAO,CAAC,EAAE,CAAC,CAAC,EAAE,KAAK,CAAC,UAAU,KAAK,IAAI,CAAC;IACxC;;;;OAIG;IACH,UAAU,CAAC,EAAE,SAAS,CAAC;IACvB;;;;;;;;;;;OAWG;IACH,OAAO,CAAC,EAAE,SAAS,CAAC;IACpB;;OAEG;IACH,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB;;;;;;;;;;OAUG;IACH,WAAW,CAAC,EACR,OAAO,GACP;QACE,kBAAkB,CAAC,EAAE,OAAO,CAAC;QAC7B,WAAW,CAAC,EAAE,OAAO,CAAC;QACtB,iBAAiB,CAAC,EAAE,CAAC,WAAW,EAAE,OAAO,KAAK,IAAI,CAAC;KACpD,CAAC;IACN;;;OAGG;IACH,IAAI,CAAC,EAAE,WAAW,CAAC;CACpB;AAMD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,wBAAgB,WAAW,CAAC,EAC1B,EAAE,EACF,KAAK,EACL,IAAI,EACJ,YAAY,EACZ,UAAkB,EAClB,UAAkB,EAClB,IAAI,EACJ,OAAO,EACP,UAAU,EACV,OAAO,EACP,QAAQ,EACR,WAAW,EAAE,eAAe,EAC5B,IAAW,EACX,aAAa,EAAE,MAAM,EACrB,GAAG,EACH,MAAM,EACN,GAAG,IAAI,EACR,EAAE,gBAAgB,sCAuXlB;yBAzYe,WAAW"}
1
+ {"version":3,"file":"SideNavItem.d.ts","sourceRoot":"","sources":["../../src/SideNav/SideNavItem.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,EAML,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AAYf,OAAO,EAAuB,KAAK,QAAQ,EAAC,MAAM,SAAS,CAAC;AAE5D,OAAO,KAAK,EAAC,iBAAiB,EAAC,MAAM,eAAe,CAAC;AAIrD,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AAE5C,OAAO,EAAgB,KAAK,WAAW,EAAC,MAAM,iCAAiC,CAAC;AA8NhF,MAAM,WAAW,gBAAiB,SAAQ,SAAS,CAAC,WAAW,CAAC;IAC9D,wCAAwC;IACxC,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;IAC7B;;;;OAIG;IACH,EAAE,CAAC,EAAE,iBAAiB,CAAC;IACvB;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;IACd;;OAEG;IACH,IAAI,CAAC,EAAE,SAAS,GAAG,QAAQ,CAAC;IAC5B;;OAEG;IACH,YAAY,CAAC,EAAE,SAAS,GAAG,QAAQ,CAAC;IACpC;;;OAGG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;;OAGG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;OAEG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;OAEG;IACH,OAAO,CAAC,EAAE,CAAC,CAAC,EAAE,KAAK,CAAC,UAAU,KAAK,IAAI,CAAC;IACxC;;OAEG;IACH,UAAU,CAAC,EAAE,SAAS,CAAC;IACvB;;OAEG;IACH,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB;;;;;;;;;;OAUG;IACH,WAAW,CAAC,EACR,OAAO,GACP;QACE,kBAAkB,CAAC,EAAE,OAAO,CAAC;QAC7B,WAAW,CAAC,EAAE,OAAO,CAAC;QACtB,iBAAiB,CAAC,EAAE,CAAC,WAAW,EAAE,OAAO,KAAK,IAAI,CAAC;KACpD,CAAC;IACN;;;OAGG;IACH,IAAI,CAAC,EAAE,WAAW,CAAC;CACpB;AAMD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,WAAW,CAAC,EAC1B,EAAE,EACF,KAAK,EACL,IAAI,EACJ,YAAY,EACZ,UAAkB,EAClB,UAAkB,EAClB,IAAI,EACJ,OAAO,EACP,UAAU,EACV,QAAQ,EACR,WAAW,EAAE,eAAe,EAC5B,IAAW,EACX,aAAa,EAAE,MAAM,EACrB,GAAG,EACH,MAAM,EACN,GAAG,IAAI,EACR,EAAE,gBAAgB,sCAkVlB;yBAnWe,WAAW"}
@@ -8,7 +8,7 @@
8
8
  * @output Exports SideNavItem component and SideNavItemProps
9
9
  * @position Core implementation; used inside SideNav children
10
10
  *
11
- * Navigation item with icon, selected state, row-level actions, and nesting.
11
+ * Navigation item with icon, selected state, and nesting.
12
12
  *
13
13
  * Collapsed items with children open their submenu flyout through
14
14
  * `useMenuHover`, the shared hover-intent hook (same one `SideNavHeading` and
@@ -33,7 +33,6 @@ import { useMenuHover } from "../hooks/useMenuHover.js";
33
33
  import { mergeProps } from "../utils/index.js";
34
34
  import { Tooltip } from "../Tooltip/index.js";
35
35
  import { navItemStyles } from "../NavItem/navItemStyles.stylex.js";
36
- import { SizeProvider } from "../SizeContext/SizeContext.js";
37
36
  import { focusOutlineProps } from "../utils/focusOutline.stylex.js";
38
37
  import { interactionOverlayStyles } from "../utils/interactionOverlay.stylex.js";
39
38
  import { useSideNavCollapse, SideNavCollapseContext } from "./SideNavCollapseContext.js";
@@ -85,8 +84,6 @@ const styles = {
85
84
  $$css: true
86
85
  },
87
86
  expandToggle: {
88
- kzqmXN: "x1fvqzum",
89
- kZKoxP: "x6k0iem",
90
87
  k1xSpc: "x3nfvp2",
91
88
  kGNEyG: "x6s0dn4",
92
89
  kjj79g: "xl56j7k",
@@ -130,16 +127,6 @@ const styles = {
130
127
  }
131
128
  };
132
129
 
133
- /**
134
- * Cascaded to the `actions` slot through `SizeContext` so a consumer's row
135
- * controls come out the same height as the built-in expand/collapse toggle,
136
- * the way `SideNav` already cascades one size to its footer icons. An
137
- * explicit `size` on a supplied control still wins.
138
- *
139
- * SYNC: `styles.expandToggle` carries the matching box.
140
- */
141
- const ROW_CONTROL_SIZE = 'sm';
142
-
143
130
  // Non-collapsed state for popover children — ensures nested items render expanded
144
131
  const EXPANDED_COLLAPSE_STATE = {
145
132
  isCollapsed: false,
@@ -195,10 +182,7 @@ function NavItemElement({
195
182
  /**
196
183
  * Navigation item for SideNav.
197
184
  *
198
- * Supports icons, selected state, nesting, and end content like badges or
199
- * counts. Interactive row-level controls (menus, icon buttons) go in
200
- * `actions`, which renders them as siblings of the primary element — never
201
- * nested inside it — before any nested children in DOM and focus order.
185
+ * Supports icons, selected state, nesting, and end content like badges or counts.
202
186
  *
203
187
  * @example
204
188
  * ```
@@ -213,13 +197,6 @@ function NavItemElement({
213
197
  * <SideNavItem label="General" href="/settings/general" />
214
198
  * <SideNavItem label="Security" href="/settings/security" />
215
199
  * </SideNavItem>
216
- * <SideNavItem
217
- * label="Projects"
218
- * href="/projects"
219
- * collapsible
220
- * actions={<MoreMenu label="Project actions" items={items} />}>
221
- * <SideNavItem label="Alpha" href="/projects/alpha" />
222
- * </SideNavItem>
223
200
  * ```
224
201
  */
225
202
  export function SideNavItem({
@@ -232,7 +209,6 @@ export function SideNavItem({
232
209
  href,
233
210
  onClick,
234
211
  endContent,
235
- actions,
236
212
  children,
237
213
  collapsible: itemCollapsible,
238
214
  size = 'md',
@@ -286,7 +262,6 @@ export function SideNavItem({
286
262
  // clicking the chevron expands/collapses children.
287
263
  const hasPrimaryAction = !!href || !!onClick;
288
264
  const hasIndependentToggle = isItemCollapsible && hasPrimaryAction && !isCollapsed;
289
- const hasActions = !!actions;
290
265
  const handleClick = e => {
291
266
  if (isDisabled) {
292
267
  e.preventDefault();
@@ -448,42 +423,22 @@ export function SideNavItem({
448
423
  });
449
424
  const itemStyleArgs = [navItemStyles.item, interactionOverlayStyles.backgroundColor, navItemStyles[size], isSelected && navItemStyles.selected, isDisabled && navItemStyles.disabled];
450
425
 
451
- // Three shapes of the same row appearance:
452
- // - `rowProps` — split-action path (toggle, no actions): presentational
453
- // <div>; the ring belongs on each child tab stop.
454
- // - `focusableRowProps` — ordinary row: the row element is the control.
455
- // - `actionsRowProps` — same pill, but the ring is drawn for the primary
456
- // only. The wrapper is not a tab stop, so `:focus-visible` on it would
457
- // never match, and matching any descendant instead would light the whole
458
- // row around the chevron's or an action's own ring.
426
+ // Two shapes of the same row appearance:
427
+ // - `rowProps` for the split-action path, where the row is a plain <div>
428
+ // container and its children take focus (so the ring belongs on them);
429
+ // - `focusableRowProps` for every other path, where the row element is
430
+ // itself the focusable control.
459
431
  const rowProps = mergeProps(itemThemeProps, stylex.props(...itemStyleArgs));
460
432
  const focusableRowProps = mergeProps(itemThemeProps, focusOutlineProps.focusVisible(...itemStyleArgs));
461
- const actionsRowProps = mergeProps(itemThemeProps, focusOutlineProps.focusWithinFirstChild(...itemStyleArgs));
462
433
 
463
- // Row-wrapper path: primary element + row controls as siblings.
464
- //
465
- // Used when the row carries more than one control: an independent
466
- // expand/collapse toggle (collapsible + href/onClick), consumer-supplied
467
- // actions, or both. A <div> is the styled flex row; the primary link or
468
- // button, the chevron toggle, and the actions slot render as siblings so
469
- // no interactive element nests inside another, and every row-level
470
- // control precedes the nested children group in DOM and focus order.
471
- const hasRowWrapper = hasIndependentToggle || hasActions;
434
+ // Split-action path: collapsible plus a primary action renders the primary
435
+ // element and the chevron toggle as siblings in a <div> row, since a
436
+ // <button> cannot nest inside an <a>.
472
437
  let itemElement;
473
- if (hasRowWrapper) {
474
- // aria-expanded/-controls stay on the primary element only when the
475
- // whole row is the collapse toggle (no independent chevron button).
476
- const rowPrimaryAriaProps = hasIndependentToggle ? {
477
- 'aria-current': isSelected ? 'page' : undefined
478
- } : {
479
- 'aria-current': isSelected ? 'page' : undefined,
480
- 'aria-disabled': isDisabled || undefined,
481
- 'aria-expanded': isItemCollapsible ? !isItemCollapsed : undefined,
482
- 'aria-controls': isItemCollapsible ? `${id}-children` : undefined
483
- };
438
+ if (hasIndependentToggle) {
484
439
  itemElement = /*#__PURE__*/_jsxs("div", {
485
440
  "data-testid": testId,
486
- ...(hasActions ? actionsRowProps : rowProps),
441
+ ...rowProps,
487
442
  children: [/*#__PURE__*/_jsx(NavItemElement, {
488
443
  ref: ref,
489
444
  href: href,
@@ -491,13 +446,10 @@ export function SideNavItem({
491
446
  isDisabled: isDisabled,
492
447
  onClick: handleClick,
493
448
  ...rest,
494
- ...rowPrimaryAriaProps,
495
- ...(hasActions ?
496
- // The wrapper rings for this element; suppressing here is what
497
- // keeps the UA's own ring from painting inside that one.
498
- focusOutlineProps.suppressed(styles.splitAction) : focusOutlineProps.focusVisible(styles.splitAction)),
449
+ "aria-current": isSelected ? 'page' : undefined,
450
+ ...focusOutlineProps.focusVisible(styles.splitAction),
499
451
  children: itemContent
500
- }), hasIndependentToggle && /*#__PURE__*/_jsx("button", {
452
+ }), /*#__PURE__*/_jsx("button", {
501
453
  type: "button",
502
454
  onClick: handleToggleClick,
503
455
  "aria-label": isItemCollapsed ? t('@astryx.sideNavItem.expand', {
@@ -514,14 +466,6 @@ export function SideNavItem({
514
466
  color: "inherit",
515
467
  xstyle: [styles.expandChevron, !isItemCollapsed && styles.expandChevronExpanded]
516
468
  })
517
- }), hasActions && /*#__PURE__*/_jsx("span", {
518
- ...{
519
- className: "x2lah0s x78zum5 x6s0dn4 xzye2dw x67bb7w"
520
- },
521
- children: /*#__PURE__*/_jsx(SizeProvider, {
522
- value: ROW_CONTROL_SIZE,
523
- children: actions
524
- })
525
469
  })]
526
470
  });
527
471
  } else {
package/dist/astryx.css CHANGED
@@ -1347,13 +1347,9 @@
1347
1347
  .x92e2el:has(> [data-astryx-edge-comp]:last-child):not(#\#):not(#\#):not(#\#){margin-inline-end:var(--x-4drmnv)}
1348
1348
  .x1kftj4p:has(> [data-astryx-edge-comp]:first-child):not(#\#):not(#\#):not(#\#){margin-inline-start:var(--x-126w13d)}
1349
1349
  .x1uy843r:has(:focus-visible):not(#\#):not(#\#):not(#\#){outline-color:var(--focus-outline-color)}
1350
- .xobxmqy:has(> :first-child:focus-visible):not(#\#):not(#\#):not(#\#){outline-color:var(--focus-outline-color)}
1351
1350
  .x1jumodi:has(:focus-visible):not(#\#):not(#\#):not(#\#){outline-offset:var(--focus-outline-offset)}
1352
- .x2vr5qc:has(> :first-child:focus-visible):not(#\#):not(#\#):not(#\#){outline-offset:var(--focus-outline-offset)}
1353
1351
  .xciu248:has(:focus-visible):not(#\#):not(#\#):not(#\#){outline-style:var(--focus-outline-style)}
1354
- .xfd04fr:has(> :first-child:focus-visible):not(#\#):not(#\#):not(#\#){outline-style:var(--focus-outline-style)}
1355
1352
  .x11j6mr8:has(:focus-visible):not(#\#):not(#\#):not(#\#){outline-width:var(--focus-outline-width)}
1356
- .xmmisi4:has(> :first-child:focus-visible):not(#\#):not(#\#):not(#\#){outline-width:var(--focus-outline-width)}
1357
1353
  .xmnmr5y:has(.astryx-nav-icon):not(#\#):not(#\#):not(#\#){padding-inline-start:0}
1358
1354
  .x1xrp5p4:first-child:not(#\#):not(#\#):not(#\#){border-end-start-radius:var(--radius-element)}
1359
1355
  .xyf0ibl:first-child:not(#\#):not(#\#):not(#\#){border-inline-start-style:none}
@@ -1 +1 @@
1
- {"version":3,"file":"useTheme.d.ts","sourceRoot":"","sources":["../../src/theme/useTheme.ts"],"names":[],"mappings":"AA8BA,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,SAAS,CAAC;AACvC,OAAO,KAAK,EAAC,YAAY,EAAC,MAAM,eAAe,CAAC;AAUhD;;;GAGG;AACH,MAAM,WAAW,iBAAiB;IAChC,+BAA+B;IAC/B,KAAK,EAAE,YAAY,CAAC;IACpB,0CAA0C;IAC1C,IAAI,EAAE,SAAS,CAAC;CACjB;AAED;;;;GAIG;AACH,eAAO,MAAM,YAAY,mDAAgD,CAAC;AAO1E;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,iBAAiB;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,kEAAkE;IAClE,IAAI,EAAE,OAAO,GAAG,MAAM,CAAC;IACvB;;;;;;;;;;;;;OAaG;IACH,KAAK,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC;IAChC;;;;;;;OAOG;IACH,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAChC;AA+HD;;;;;;;GAOG;AACH,wBAAgB,YAAY,IAAI,MAAM,GAAG,IAAI,CAM5C;AAED;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,QAAQ,IAAI,cAAc,CAmCzC"}
1
+ {"version":3,"file":"useTheme.d.ts","sourceRoot":"","sources":["../../src/theme/useTheme.ts"],"names":[],"mappings":"AAwBA,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,SAAS,CAAC;AACvC,OAAO,KAAK,EAAC,YAAY,EAAC,MAAM,eAAe,CAAC;AAUhD;;;GAGG;AACH,MAAM,WAAW,iBAAiB;IAChC,+BAA+B;IAC/B,KAAK,EAAE,YAAY,CAAC;IACpB,0CAA0C;IAC1C,IAAI,EAAE,SAAS,CAAC;CACjB;AAED;;;;GAIG;AACH,eAAO,MAAM,YAAY,mDAAgD,CAAC;AAO1E;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,iBAAiB;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,kEAAkE;IAClE,IAAI,EAAE,OAAO,GAAG,MAAM,CAAC;IACvB;;;;;;;;;;;;;OAaG;IACH,KAAK,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC;IAChC;;;;;;;OAOG;IACH,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAChC;AA+HD;;;;;;;GAOG;AACH,wBAAgB,YAAY,IAAI,MAAM,GAAG,IAAI,CAM5C;AAED;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,QAAQ,IAAI,cAAc,CAmCzC"}
@@ -20,7 +20,7 @@
20
20
  * SYNC: When modified, update:
21
21
  * - /packages/core/src/theme/index.ts
22
22
  */
23
- import { createContext, use, useCallback, useMemo, useSyncExternalStore } from 'react';
23
+ import { createContext, use, useMemo, useSyncExternalStore } from 'react';
24
24
  import { resolveThemeTokens } from "./tokens.js";
25
25
  import { getRegisteredTheme } from "./themeRegistry.js";
26
26
  import { dataAttr } from "../naming.js";
@@ -207,12 +207,13 @@ export function useTheme() {
207
207
  const tokens = useMemo(() => resolveThemeTokens(theme, {
208
208
  mode: effectiveMode
209
209
  }), [theme, effectiveMode]);
210
- const token = useCallback(name => tokens[name] ?? '', [tokens]);
211
- const name = theme?.name ?? 'default';
212
- return useMemo(() => ({
213
- name,
210
+ const token = name => {
211
+ return tokens[name] ?? '';
212
+ };
213
+ return {
214
+ name: theme?.name ?? 'default',
214
215
  mode: effectiveMode,
215
216
  token,
216
217
  tokens
217
- }), [name, effectiveMode, token, tokens]);
218
+ };
218
219
  }
@@ -78,17 +78,6 @@ export declare const focusOutlineStyles: Readonly<{
78
78
  readonly outlineColor: stylex.StyleXClassNameFor<"outlineColor", "var(--color-accent)" | null>;
79
79
  readonly outlineOffset: stylex.StyleXClassNameFor<"outlineOffset", "0" | "3px">;
80
80
  }>;
81
- readonly focusWithinFirstChild: Readonly<{
82
- readonly outlineWidth: stylex.StyleXClassNameFor<"outlineWidth", "0" | "2px">;
83
- readonly outlineStyle: stylex.StyleXClassNameFor<"outlineStyle", "none" | "solid">;
84
- readonly outlineColor: stylex.StyleXClassNameFor<"outlineColor", "var(--color-accent)" | null>;
85
- readonly outlineOffset: stylex.StyleXClassNameFor<"outlineOffset", "0" | "3px">;
86
- }>;
87
- readonly suppressed: Readonly<{
88
- readonly outlineWidth: stylex.StyleXClassNameFor<"outlineWidth", "0">;
89
- readonly outlineStyle: stylex.StyleXClassNameFor<"outlineStyle", "none">;
90
- readonly outlineOffset: stylex.StyleXClassNameFor<"outlineOffset", "0">;
91
- }>;
92
81
  readonly publishFocusVisibleVars: Readonly<{
93
82
  readonly '--_focus-outline': stylex.StyleXClassNameFor<"--_focus-outline", string>;
94
83
  readonly '--_focus-outline-offset': stylex.StyleXClassNameFor<"--_focus-outline-offset", "0" | "3px">;
@@ -114,20 +103,6 @@ export declare const focusOutlineProps: {
114
103
  [$$Key$$: string]: string | number;
115
104
  }>;
116
105
  }>;
117
- readonly focusWithinFirstChild: (...styles: StyleXPropsArg[]) => Readonly<{
118
- className?: string;
119
- 'data-style-src'?: string;
120
- style?: Readonly<{
121
- [$$Key$$: string]: string | number;
122
- }>;
123
- }>;
124
- readonly suppressed: (...styles: StyleXPropsArg[]) => Readonly<{
125
- className?: string;
126
- 'data-style-src'?: string;
127
- style?: Readonly<{
128
- [$$Key$$: string]: string | number;
129
- }>;
130
- }>;
131
106
  readonly publishFocusVisibleVars: (...styles: StyleXPropsArg[]) => Readonly<{
132
107
  className?: string;
133
108
  'data-style-src'?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"focusOutline.stylex.d.ts","sourceRoot":"","sources":["../../src/utils/focusOutline.stylex.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,KAAK,MAAM,MAAM,kBAAkB,CAAC;AAS3C;;;;;;;;;GASG;AACH,eAAO,MAAM,aAAa,QAAyE,CAAC;AAgBpG;;;;;;;;;;;;;;;;;;;GAmBG;AACH,eAAO,MAAM,mBAAmB;;;;;CAKtB,CAAC;AAEX,+EAA+E;AAC/E,eAAO,MAAM,wBAAwB;;;;;CAK3B,CAAC;AAEX,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAiG7B,CAAC;AAIH,KAAK,cAAc,GAAG,OAAO,CAAC;AAiB9B,eAAO,MAAM,iBAAiB;uCAdT,cAAc,EAAE;;;;;;;sCAAhB,cAAc,EAAE;;;;;;;gDAAhB,cAAc,EAAE;;;;;;;qCAAhB,cAAc,EAAE;;;;;;;kDAAhB,cAAc,EAAE;;;;;;;iDAAhB,cAAc,EAAE;;;;;;;CA2B3B,CAAC"}
1
+ {"version":3,"file":"focusOutline.stylex.d.ts","sourceRoot":"","sources":["../../src/utils/focusOutline.stylex.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,KAAK,MAAM,MAAM,kBAAkB,CAAC;AAS3C;;;;;;;;;GASG;AACH,eAAO,MAAM,aAAa,QAAyE,CAAC;AAgBpG;;;;;;;;;;;;;;;;;;;GAmBG;AACH,eAAO,MAAM,mBAAmB;;;;;CAKtB,CAAC;AAEX,+EAA+E;AAC/E,eAAO,MAAM,wBAAwB;;;;;CAK3B,CAAC;AAEX,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;EAmD7B,CAAC;AAIH,KAAK,cAAc,GAAG,OAAO,CAAC;AAiB9B,eAAO,MAAM,iBAAiB;uCAdT,cAAc,EAAE;;;;;;;sCAAhB,cAAc,EAAE;;;;;;;kDAAhB,cAAc,EAAE;;;;;;;iDAAhB,cAAc,EAAE;;;;;;;CAuB3B,CAAC"}
@@ -106,19 +106,6 @@ export const focusOutlineStyles = {
106
106
  kInvED: "x1wfwxd8 x1jumodi",
107
107
  $$css: true
108
108
  },
109
- focusWithinFirstChild: {
110
- kMeerF: "x1k57tk5 xmmisi4",
111
- k3XXqK: "x1t137rt xfd04fr",
112
- kjBf7l: "xobxmqy",
113
- kInvED: "x1wfwxd8 x2vr5qc",
114
- $$css: true
115
- },
116
- suppressed: {
117
- kMeerF: "x1k57tk5",
118
- k3XXqK: "x1t137rt",
119
- kInvED: "x1wfwxd8",
120
- $$css: true
121
- },
122
109
  publishFocusVisibleVars: {
123
110
  "--_focus-outline": "x17wzz1v xqih627",
124
111
  "--_focus-outline-offset": "xgzxwq1 xqchwus",
@@ -151,8 +138,6 @@ function makeFocusOutlineProps(style) {
151
138
  export const focusOutlineProps = {
152
139
  focusVisible: makeFocusOutlineProps(focusOutlineStyles.focusVisible),
153
140
  focusWithin: makeFocusOutlineProps(focusOutlineStyles.focusWithin),
154
- focusWithinFirstChild: makeFocusOutlineProps(focusOutlineStyles.focusWithinFirstChild),
155
- suppressed: makeFocusOutlineProps(focusOutlineStyles.suppressed),
156
141
  publishFocusVisibleVars: makeFocusOutlineProps(focusOutlineStyles.publishFocusVisibleVars),
157
142
  focusWithinOrPublished: makeFocusOutlineProps(focusOutlineStyles.focusWithinOrPublished)
158
143
  };
@@ -257,7 +257,7 @@
257
257
  },
258
258
  "@astryx.banner.dismiss": {
259
259
  "defaultMessage": "Maak toe",
260
- "description": "\"Dismiss\" = close/hide this notification (not \"reject a person\"). Tooltip on the small X button on a Banner, and its aria label when the banner's title is not plain text."
260
+ "description": "\"Dismiss\" = close/hide this notification (not \"reject a person\"). Aria label AND tooltip on the small X button on a Banner."
261
261
  },
262
262
  "@astryx.calendar.previousMonth": {
263
263
  "defaultMessage": "Vorige maand",