@astryxdesign/core 0.5.2-canary.4a88299 → 0.5.2-canary.501e975

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 (80) hide show
  1. package/dist/AppShell/AppShell.d.ts.map +1 -1
  2. package/dist/AppShell/AppShell.js +6 -2
  3. package/dist/Banner/Banner.d.ts +5 -0
  4. package/dist/Banner/Banner.d.ts.map +1 -1
  5. package/dist/Banner/Banner.js +7 -2
  6. package/dist/Breadcrumbs/BreadcrumbItem.d.ts +3 -2
  7. package/dist/Breadcrumbs/BreadcrumbItem.d.ts.map +1 -1
  8. package/dist/Breadcrumbs/BreadcrumbItem.js +22 -15
  9. package/dist/Resizable/ResizeHandle.d.ts.map +1 -1
  10. package/dist/Resizable/ResizeHandle.js +81 -44
  11. package/dist/Spinner/Spinner.d.ts.map +1 -1
  12. package/dist/Spinner/Spinner.js +8 -9
  13. package/dist/Toast/ToastViewport.d.ts.map +1 -1
  14. package/dist/Toast/ToastViewport.js +1 -0
  15. package/dist/astryx.css +4 -0
  16. package/package.json +2 -2
  17. package/src/AppShell/AppShell.test.tsx +21 -0
  18. package/src/AppShell/AppShell.tsx +8 -2
  19. package/src/Banner/Banner.doc.mjs +5 -1
  20. package/src/Banner/Banner.tsx +12 -1
  21. package/src/BottomSheet/BottomSheet.spec.md +2 -1
  22. package/src/Breadcrumbs/BreadcrumbItem.tsx +18 -9
  23. package/src/Breadcrumbs/Breadcrumbs.doc.mjs +4 -1
  24. package/src/Breadcrumbs/Breadcrumbs.test.tsx +12 -0
  25. package/src/CheckboxList/CheckboxList.spec.md +2 -1
  26. package/src/CommandPalette/CommandPalette.spec.md +2 -1
  27. package/src/ComplexSelector/ComplexSelector.spec.md +2 -1
  28. package/src/ContextMenu/ContextMenu.spec.md +2 -1
  29. package/src/DateTimeInput/DateTimeInput.doc.mjs +3 -3
  30. package/src/Divider/Divider.spec.md +2 -1
  31. package/src/DropdownMenu/DropdownMenu.spec.md +2 -1
  32. package/src/FieldStatus/FieldStatus.spec.md +2 -1
  33. package/src/Grid/Grid.spec.md +2 -1
  34. package/src/Icon/Icon.spec.md +2 -1
  35. package/src/Kbd/Kbd.spec.md +2 -1
  36. package/src/Layout/Layout.spec.md +2 -1
  37. package/src/Lightbox/Lightbox.spec.md +2 -1
  38. package/src/Markdown/Markdown.spec.md +2 -1
  39. package/src/MobileNav/MobileNav.spec.md +2 -1
  40. package/src/MoreMenu/MoreMenu.spec.md +2 -1
  41. package/src/MultiSelector/MultiSelector.spec.md +2 -1
  42. package/src/NavIcon/NavIcon.spec.md +2 -1
  43. package/src/NavMenu/NavHeadingMenu.spec.md +2 -1
  44. package/src/Outline/Outline.spec.md +2 -1
  45. package/src/OverflowList/OverflowList.spec.md +2 -1
  46. package/src/Pagination/Pagination.spec.md +2 -1
  47. package/src/Popover/Popover.doc.mjs +3 -3
  48. package/src/Popover/Popover.spec.md +2 -1
  49. package/src/PowerSearch/PowerSearch.spec.md +2 -1
  50. package/src/ProgressBar/ProgressBar.spec.md +2 -1
  51. package/src/Resizable/Resizable.spec.md +2 -1
  52. package/src/Resizable/ResizeHandle.test.tsx +99 -54
  53. package/src/Resizable/ResizeHandle.tsx +98 -45
  54. package/src/Section/Section.spec.md +2 -1
  55. package/src/SegmentedControl/SegmentedControl.spec.md +2 -1
  56. package/src/Selector/Selector.spec.md +2 -1
  57. package/src/SideNav/SideNav.test.tsx +3 -3
  58. package/src/SideNav/SideNavItem.doc.mjs +1 -1
  59. package/src/Skeleton/Skeleton.spec.md +2 -1
  60. package/src/Slider/Slider.spec.md +2 -1
  61. package/src/Spinner/Spinner.doc.mjs +5 -5
  62. package/src/Spinner/Spinner.test.tsx +32 -7
  63. package/src/Spinner/Spinner.tsx +25 -13
  64. package/src/Stack/Stack.spec.md +2 -1
  65. package/src/StatusDot/StatusDot.spec.md +2 -1
  66. package/src/Stepper/Stepper.doc.mjs +1 -1
  67. package/src/Switch/Switch.spec.md +2 -1
  68. package/src/Table/Table.spec.md +93 -53
  69. package/src/Table/plugins/rowStatus/useTableRowStatus.spec.md +354 -0
  70. package/src/Table/useTableGroupedRows.doc.mjs +2 -2
  71. package/src/Text/Text.spec.md +2 -1
  72. package/src/TextArea/TextArea.spec.md +2 -1
  73. package/src/Toast/ToastViewport.test.tsx +17 -0
  74. package/src/Toast/ToastViewport.tsx +10 -0
  75. package/src/Tokenizer/Tokenizer.spec.md +2 -1
  76. package/src/Toolbar/Toolbar.spec.md +2 -1
  77. package/src/Tooltip/Tooltip.spec.md +2 -1
  78. package/src/TreeList/TreeList.spec.md +2 -1
  79. package/src/Typeahead/Typeahead.spec.md +2 -1
  80. package/src/theme/themingTargets.test.ts +39 -7
@@ -1 +1 @@
1
- {"version":3,"file":"AppShell.d.ts","sourceRoot":"","sources":["../../src/AppShell/AppShell.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAQL,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AAmBf,OAAO,KAAK,EAAC,WAAW,EAAC,MAAM,gBAAgB,CAAC;AAChD,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AAO5C,OAAO,KAAK,EAAC,kBAAkB,EAAC,MAAM,SAAS,CAAC;AA+BhD;;;;;;GAMG;AACH,MAAM,MAAM,kBAAkB,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,MAAM,CAAC;AAE7D;;;;;;;GAOG;AAEH;;GAEG;AACH,MAAM,MAAM,eAAe,GAAG,MAAM,kBAAkB,CAAC;AAEvD;;;GAGG;AACH,MAAM,WAAW,eAAe;IAC9B;;;;OAIG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IAEpB;;;OAGG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;IAEjB;;OAEG;IACH,YAAY,CAAC,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,IAAI,CAAC;IAEzC;;;;OAIG;IACH,OAAO,CAAC,EAAE,SAAS,CAAC;IAEpB;;;OAGG;IACH,UAAU,CAAC,EAAE,kBAAkB,CAAC;IAEhC;;;;;;;;;OASG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B;AAED,MAAM,WAAW,aAAc,SAAQ,SAAS,CAAC,cAAc,CAAC;IAC9D,wCAAwC;IACxC,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;IAChC;;;;;;;OAOG;IACH,OAAO,CAAC,EAAE,eAAe,CAAC;IAE1B;;;OAGG;IACH,MAAM,CAAC,EAAE,SAAS,CAAC;IAEnB;;OAEG;IACH,QAAQ,EAAE,SAAS,CAAC;IAEpB;;;;;;;OAOG;IACH,cAAc,CAAC,EAAE,WAAW,CAAC;IAE7B;;;;;OAKG;IACH,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAEzB;;;;;;;;;;;;;;;;;;;;;OAqBG;IACH,SAAS,CAAC,EAAE,KAAK,GAAG,eAAe,GAAG,SAAS,CAAC;IAEhD;;;;;;;;;;;;;;;;;;;;;;;;;OAyBG;IACH,OAAO,CAAC,EAAE,SAAS,CAAC;IAEpB;;;OAGG;IACH,MAAM,CAAC,EAAE,SAAS,CAAC;CACpB;AA2KD;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,QAAQ,CAAC,EACvB,OAAoB,EACpB,MAAM,EACN,QAAQ,EACR,cAAc,EACd,aAAa,EAAE,UAAU,EACzB,MAAe,EACf,SAAS,EACT,OAAO,EACP,MAAM,EACN,MAAM,EACN,SAAS,EACT,KAAK,EACL,GAAG,EACH,GAAG,IAAI,EACR,EAAE,aAAa,qBA6Yf;yBA5Ze,QAAQ"}
1
+ {"version":3,"file":"AppShell.d.ts","sourceRoot":"","sources":["../../src/AppShell/AppShell.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAQL,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AAmBf,OAAO,KAAK,EAAC,WAAW,EAAC,MAAM,gBAAgB,CAAC;AAChD,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AAO5C,OAAO,KAAK,EAAC,kBAAkB,EAAC,MAAM,SAAS,CAAC;AA+BhD;;;;;;GAMG;AACH,MAAM,MAAM,kBAAkB,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,MAAM,CAAC;AAE7D;;;;;;;GAOG;AAEH;;GAEG;AACH,MAAM,MAAM,eAAe,GAAG,MAAM,kBAAkB,CAAC;AAEvD;;;GAGG;AACH,MAAM,WAAW,eAAe;IAC9B;;;;OAIG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IAEpB;;;OAGG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;IAEjB;;OAEG;IACH,YAAY,CAAC,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,IAAI,CAAC;IAEzC;;;;OAIG;IACH,OAAO,CAAC,EAAE,SAAS,CAAC;IAEpB;;;OAGG;IACH,UAAU,CAAC,EAAE,kBAAkB,CAAC;IAEhC;;;;;;;;;OASG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B;AAED,MAAM,WAAW,aAAc,SAAQ,SAAS,CAAC,cAAc,CAAC;IAC9D,wCAAwC;IACxC,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;IAChC;;;;;;;OAOG;IACH,OAAO,CAAC,EAAE,eAAe,CAAC;IAE1B;;;OAGG;IACH,MAAM,CAAC,EAAE,SAAS,CAAC;IAEnB;;OAEG;IACH,QAAQ,EAAE,SAAS,CAAC;IAEpB;;;;;;;OAOG;IACH,cAAc,CAAC,EAAE,WAAW,CAAC;IAE7B;;;;;OAKG;IACH,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAEzB;;;;;;;;;;;;;;;;;;;;;OAqBG;IACH,SAAS,CAAC,EAAE,KAAK,GAAG,eAAe,GAAG,SAAS,CAAC;IAEhD;;;;;;;;;;;;;;;;;;;;;;;;;OAyBG;IACH,OAAO,CAAC,EAAE,SAAS,CAAC;IAEpB;;;OAGG;IACH,MAAM,CAAC,EAAE,SAAS,CAAC;CACpB;AA4KD;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,QAAQ,CAAC,EACvB,OAAoB,EACpB,MAAM,EACN,QAAQ,EACR,cAAc,EACd,aAAa,EAAE,UAAU,EACzB,MAAe,EACf,SAAS,EACT,OAAO,EACP,MAAM,EACN,MAAM,EACN,SAAS,EACT,KAAK,EACL,GAAG,EACH,GAAG,IAAI,EACR,EAAE,aAAa,qBAkZf;yBAjae,QAAQ"}
@@ -105,6 +105,7 @@ const styles = {
105
105
  k1xSpc: "x78zum5",
106
106
  kXwgrk: "xdt5ytf",
107
107
  kVAEAm: "x1n2onr6",
108
+ kVQacm: "x7giv3",
108
109
  $$css: true
109
110
  },
110
111
  variantWash: {
@@ -294,6 +295,9 @@ export function AppShell({
294
295
  const navHasDividers = variant === 'section';
295
296
  const isElevated = variant === 'elevated';
296
297
  const navAreaStyle = variant === 'wash' || variant === 'elevated' ? styles.navAreaWash : variant === 'surface' ? styles.navAreaSurface : undefined;
298
+ // Section normally inherits the shell's surface background. Its auto-height
299
+ // header needs to paint that surface itself while content scrolls beneath it.
300
+ const headerAreaStyle = navAreaStyle ?? (isAuto && variant === 'section' ? styles.navAreaSurface : undefined);
297
301
  const contentAreaStyle = variant === 'wash' ? styles.contentBgWash : variant === 'elevated' && hasTopNav && hasSideNav && !isBelowBreakpoint ? styles.contentBgTransparent : variant === 'surface' || variant === 'elevated' ? styles.contentBgSurface : undefined;
298
302
 
299
303
  // Background for sticky elements in auto mode — must be opaque so content
@@ -395,7 +399,7 @@ export function AppShell({
395
399
  role: "banner",
396
400
  ...mergeProps(themeProps('app-shell-header', {
397
401
  variant
398
- }), stylex.props(navAreaStyle, isAuto && styles.headerSticky)),
402
+ }), stylex.props(headerAreaStyle, isAuto && styles.headerSticky)),
399
403
  children: headerInner
400
404
  }) : undefined;
401
405
 
@@ -473,7 +477,7 @@ export function AppShell({
473
477
  role: headerContent == null ? 'banner' : undefined,
474
478
  ...mergeProps(themeProps('app-shell-header', {
475
479
  variant
476
- }), stylex.props(navAreaStyle, isAuto && styles.headerSticky)),
480
+ }), stylex.props(headerAreaStyle, isAuto && styles.headerSticky)),
477
481
  children: /*#__PURE__*/_jsx(LayoutHeader, {
478
482
  padding: 0,
479
483
  hasDivider: navHasDividers,
@@ -11,6 +11,11 @@
11
11
  * - Status icon (themeProps 'banner-icon'): the target rides on the default
12
12
  * <Icon> itself — the element that paints — so 'status:X' overrides reach
13
13
  * the glyph (#4166); for a custom `icon` node it stays on the layout wrapper
14
+ * - Description (themeProps 'banner-description'): the supporting line owns its
15
+ * own colour and type, and the space between it and the title
16
+ * - The end area carries no target: it is a layout row (flex, wrap, edge
17
+ * compensation) rather than a painted surface, and a theme that wants the
18
+ * header to grow around its buttons sets `padding-block` on 'banner'
14
19
  * - No left border accent — color is expressed through the full header background
15
20
  * - Each visual area owns its own border-radius (no overflow:clip on the container)
16
21
  * - Children are collapsible by default: a toggle appears in the header end
@@ -1 +1 @@
1
- {"version":3,"file":"Banner.d.ts","sourceRoot":"","sources":["../../src/Banner/Banner.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AAEH,OAAO,EAA0B,KAAK,SAAS,EAAC,MAAM,OAAO,CAAC;AAE9D,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AAgB5C,OAAO,KAAK,EAAC,iBAAiB,EAAC,MAAM,+BAA+B,CAAC;AAErE,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,gBAAgB,CAAC;AAI9C,OAAO,KAAK,EAAC,eAAe,EAAE,kBAAkB,EAAC,MAAM,SAAS,CAAC;AAMjE;;;GAGG;AACH,MAAM,MAAM,YAAY,GAAG,MAAM,eAAe,CAAC;AAEjD;;;;;;GAMG;AACH,MAAM,MAAM,eAAe,GAAG,MAAM,kBAAkB,CAAC;AAEvD,MAAM,WAAW,WAAY,SAAQ,SAAS,CAAC,cAAc,CAAC;IAC5D,wCAAwC;IACxC,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;IAChC;;OAEG;IACH,MAAM,EAAE,YAAY,CAAC;IACrB;;OAEG;IACH,KAAK,EAAE,SAAS,CAAC;IACjB;;OAEG;IACH,WAAW,CAAC,EAAE,SAAS,CAAC;IACxB;;OAEG;IACH,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB;;;;;OAKG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;IACvB;;;;;;;OAOG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;;;;;;;;;;OAWG;IACH,UAAU,CAAC,EAAE,SAAS,CAAC;IACvB;;;;;OAKG;IACH,SAAS,CAAC,EAAE,eAAe,CAAC;IAC5B;;;;;OAKG;IACH,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB;;;;;;;;;;;;;;;;;;OAkBG;IACH,WAAW,CAAC,EAAE,OAAO,GAAG,iBAAiB,CAAC;IAC1C;;;;OAIG;IACH,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB;AAmND;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkDG;AACH,wBAAgB,MAAM,CAAC,EACrB,MAAM,EACN,KAAK,EACL,WAAW,EACX,IAAI,EACJ,aAAqB,EACrB,SAAS,EACT,YAAY,EACZ,UAAU,EACV,SAAkB,EAClB,SAAkB,EAClB,WAAkB,EAClB,QAAQ,EACR,MAAM,EACN,SAAS,EACT,KAAK,EACL,GAAG,EACH,cAAc,EACd,oBAAoB,EACpB,GAAG,IAAI,EACR,EAAE,WAAW,sCA6Ob;yBAjQe,MAAM"}
1
+ {"version":3,"file":"Banner.d.ts","sourceRoot":"","sources":["../../src/Banner/Banner.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2CG;AAEH,OAAO,EAA0B,KAAK,SAAS,EAAC,MAAM,OAAO,CAAC;AAE9D,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AAgB5C,OAAO,KAAK,EAAC,iBAAiB,EAAC,MAAM,+BAA+B,CAAC;AAErE,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,gBAAgB,CAAC;AAI9C,OAAO,KAAK,EAAC,eAAe,EAAE,kBAAkB,EAAC,MAAM,SAAS,CAAC;AAMjE;;;GAGG;AACH,MAAM,MAAM,YAAY,GAAG,MAAM,eAAe,CAAC;AAEjD;;;;;;GAMG;AACH,MAAM,MAAM,eAAe,GAAG,MAAM,kBAAkB,CAAC;AAEvD,MAAM,WAAW,WAAY,SAAQ,SAAS,CAAC,cAAc,CAAC;IAC5D,wCAAwC;IACxC,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;IAChC;;OAEG;IACH,MAAM,EAAE,YAAY,CAAC;IACrB;;OAEG;IACH,KAAK,EAAE,SAAS,CAAC;IACjB;;OAEG;IACH,WAAW,CAAC,EAAE,SAAS,CAAC;IACxB;;OAEG;IACH,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB;;;;;OAKG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;IACvB;;;;;;;OAOG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;;;;;;;;;;OAWG;IACH,UAAU,CAAC,EAAE,SAAS,CAAC;IACvB;;;;;OAKG;IACH,SAAS,CAAC,EAAE,eAAe,CAAC;IAC5B;;;;;OAKG;IACH,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB;;;;;;;;;;;;;;;;;;OAkBG;IACH,WAAW,CAAC,EAAE,OAAO,GAAG,iBAAiB,CAAC;IAC1C;;;;OAIG;IACH,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB;AAmND;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkDG;AACH,wBAAgB,MAAM,CAAC,EACrB,MAAM,EACN,KAAK,EACL,WAAW,EACX,IAAI,EACJ,aAAqB,EACrB,SAAS,EACT,YAAY,EACZ,UAAU,EACV,SAAkB,EAClB,SAAkB,EAClB,WAAkB,EAClB,QAAQ,EACR,MAAM,EACN,SAAS,EACT,KAAK,EACL,GAAG,EACH,cAAc,EACd,oBAAoB,EACpB,GAAG,IAAI,EACR,EAAE,WAAW,sCAmPb;yBAvQe,MAAM"}
@@ -15,6 +15,11 @@
15
15
  * - Status icon (themeProps 'banner-icon'): the target rides on the default
16
16
  * <Icon> itself — the element that paints — so 'status:X' overrides reach
17
17
  * the glyph (#4166); for a custom `icon` node it stays on the layout wrapper
18
+ * - Description (themeProps 'banner-description'): the supporting line owns its
19
+ * own colour and type, and the space between it and the title
20
+ * - The end area carries no target: it is a layout row (flex, wrap, edge
21
+ * compensation) rather than a painted surface, and a theme that wants the
22
+ * header to grow around its buttons sets `padding-block` on 'banner'
18
23
  * - No left border accent — color is expressed through the full header background
19
24
  * - Each visual area owns its own border-radius (no overflow:clip on the container)
20
25
  * - Children are collapsible by default: a toggle appears in the header end
@@ -429,9 +434,9 @@ export function Banner({
429
434
  },
430
435
  children: title
431
436
  }), isRenderable(description) && /*#__PURE__*/_jsx("div", {
432
- ...{
437
+ ...mergeProps(themeProps('banner-description'), {
433
438
  className: "x1ghz6dp xjb2p0i x141an7d x1sodnla x1ltkj2j xv1l7n4 xj0a0fe"
434
- },
439
+ }),
435
440
  children: description
436
441
  })]
437
442
  }), showEndArea && /*#__PURE__*/_jsxs("div", {
@@ -1,8 +1,9 @@
1
1
  /**
2
2
  * @file BreadcrumbItem.tsx
3
3
  * @input Uses React use/useRef/useEffect, stylex, theme tokens, BreadcrumbContext,
4
- * and (for the menu trigger) usePopover + the shared DropdownMenu item API
5
- * (renderDropdownItems, DropdownMenuContext, MENU_ITEM_SELECTOR, useListFocus)
4
+ * rtlStyles for the contextual default slash, and (for the menu trigger)
5
+ * usePopover + the shared DropdownMenu item API (renderDropdownItems,
6
+ * DropdownMenuContext, MENU_ITEM_SELECTOR, useListFocus)
6
7
  * @output Exports BreadcrumbItem component and BreadcrumbItemProps
7
8
  * @position Individual breadcrumb item; used inside Breadcrumbs
8
9
  *
@@ -1 +1 @@
1
- {"version":3,"file":"BreadcrumbItem.d.ts","sourceRoot":"","sources":["../../src/Breadcrumbs/BreadcrumbItem.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,KAAK,EAAE,EAOZ,KAAK,SAAS,EACd,KAAK,UAAU,EAChB,MAAM,OAAO,CAAC;AAWf,OAAO,KAAK,EAAC,iBAAiB,EAAC,MAAM,eAAe,CAAC;AAErD,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AAS5C,OAAO,EAGL,KAAK,gBAAgB,EACtB,MAAM,qCAAqC,CAAC;AAM7C,OAAO,KAAK,EAAC,kBAAkB,EAAC,MAAM,8BAA8B,CAAC;AAOrE,MAAM,WAAW,mBAAoB,SAAQ,IAAI,CAC/C,SAAS,CAAC,aAAa,CAAC,EACxB,SAAS,CACV;IACC,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;IAC/B;;;;OAIG;IACH,EAAE,CAAC,EAAE,iBAAiB,CAAC;IACvB;;OAEG;IACH,QAAQ,EAAE,SAAS,CAAC;IACpB;;OAEG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;OAEG;IACH,OAAO,CAAC,EAAE,CAAC,CAAC,EAAE,UAAU,CAAC,WAAW,CAAC,KAAK,IAAI,CAAC;IAC/C;;;;OAIG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB;;OAEG;IACH,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB;;;;;;;;;;;;;OAaG;IACH,IAAI,CAAC,EAAE,kBAAkB,EAAE,GAAG,SAAS,CAAC;IACxC;;;;OAIG;IACH,QAAQ,CAAC,EAAE,gBAAgB,CAAC;CAC7B;AAyHD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,cAAc,CAAC,EAC7B,GAAG,EACH,EAAE,EACF,QAAQ,EACR,IAAI,EACJ,OAAO,EACP,SAAS,EAAE,aAAa,EACxB,SAAS,EACT,IAAI,EACJ,QAAQ,EACR,MAAM,EACN,SAAS,EACT,KAAK,EACL,aAAa,EAAE,MAAM,EACrB,GAAG,IAAI,EACR,EAAE,mBAAmB,qBAsMrB;yBArNe,cAAc"}
1
+ {"version":3,"file":"BreadcrumbItem.d.ts","sourceRoot":"","sources":["../../src/Breadcrumbs/BreadcrumbItem.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,KAAK,EAAE,EAOZ,KAAK,SAAS,EACd,KAAK,UAAU,EAChB,MAAM,OAAO,CAAC;AAWf,OAAO,KAAK,EAAC,iBAAiB,EAAC,MAAM,eAAe,CAAC;AAErD,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AAS5C,OAAO,EAGL,KAAK,gBAAgB,EACtB,MAAM,qCAAqC,CAAC;AAM7C,OAAO,KAAK,EAAC,kBAAkB,EAAC,MAAM,8BAA8B,CAAC;AAOrE,MAAM,WAAW,mBAAoB,SAAQ,IAAI,CAC/C,SAAS,CAAC,aAAa,CAAC,EACxB,SAAS,CACV;IACC,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;IAC/B;;;;OAIG;IACH,EAAE,CAAC,EAAE,iBAAiB,CAAC;IACvB;;OAEG;IACH,QAAQ,EAAE,SAAS,CAAC;IACpB;;OAEG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;OAEG;IACH,OAAO,CAAC,EAAE,CAAC,CAAC,EAAE,UAAU,CAAC,WAAW,CAAC,KAAK,IAAI,CAAC;IAC/C;;;;OAIG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB;;OAEG;IACH,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB;;;;;;;;;;;;;OAaG;IACH,IAAI,CAAC,EAAE,kBAAkB,EAAE,GAAG,SAAS,CAAC;IACxC;;;;OAIG;IACH,QAAQ,CAAC,EAAE,gBAAgB,CAAC;CAC7B;AAqID;;;;;;;;;;;;;GAaG;AACH,wBAAgB,cAAc,CAAC,EAC7B,GAAG,EACH,EAAE,EACF,QAAQ,EACR,IAAI,EACJ,OAAO,EACP,SAAS,EAAE,aAAa,EACxB,SAAS,EACT,IAAI,EACJ,QAAQ,EACR,MAAM,EACN,SAAS,EACT,KAAK,EACL,aAAa,EAAE,MAAM,EACrB,GAAG,IAAI,EACR,EAAE,mBAAmB,qBAkMrB;yBAjNe,cAAc"}
@@ -5,8 +5,9 @@
5
5
  /**
6
6
  * @file BreadcrumbItem.tsx
7
7
  * @input Uses React use/useRef/useEffect, stylex, theme tokens, BreadcrumbContext,
8
- * and (for the menu trigger) usePopover + the shared DropdownMenu item API
9
- * (renderDropdownItems, DropdownMenuContext, MENU_ITEM_SELECTOR, useListFocus)
8
+ * rtlStyles for the contextual default slash, and (for the menu trigger)
9
+ * usePopover + the shared DropdownMenu item API (renderDropdownItems,
10
+ * DropdownMenuContext, MENU_ITEM_SELECTOR, useListFocus)
10
11
  * @output Exports BreadcrumbItem component and BreadcrumbItemProps
11
12
  * @position Individual breadcrumb item; used inside Breadcrumbs
12
13
  *
@@ -27,7 +28,7 @@ import "../theme/tokens.stylex.js";
27
28
  import { colorVars, spacingVars, typeScaleVars, radiusVars, fontWeightVars } from "../theme/tokens.stylex.js";
28
29
  import { BreadcrumbContext } from "./Breadcrumbs.js";
29
30
  import { useLinkComponent } from "../Link/useLinkComponent.js";
30
- import { mergeProps } from "../utils/index.js";
31
+ import { mergeProps, rtlStyles } from "../utils/index.js";
31
32
  import { themeProps } from "../utils/themeProps.js";
32
33
  import { focusOutlineProps } from "../utils/focusOutline.stylex.js";
33
34
  import { Icon } from "../Icon/index.js";
@@ -99,6 +100,20 @@ const itemStyles = {
99
100
  $$css: true
100
101
  }
101
102
  };
103
+ function BreadcrumbSeparator({
104
+ separator
105
+ }) {
106
+ return /*#__PURE__*/_jsx("span", {
107
+ "aria-hidden": "true",
108
+ ...{
109
+ className: "x11ke7fs x6s0dn4 xv1l7n4 xu0wf1k x87ps6o"
110
+ },
111
+ children: separator === '/' ? /*#__PURE__*/_jsx("span", {
112
+ ...stylex.props(rtlStyles.mirror),
113
+ children: "/"
114
+ }) : separator
115
+ });
116
+ }
102
117
  const menuStyles = {
103
118
  popover: {
104
119
  k7Eaqz: "x5w4yej",
@@ -220,12 +235,8 @@ export function BreadcrumbItem({
220
235
  }), stylex.props(itemStyles.root, isSupporting ? itemStyles.supportingSize : itemStyles.defaultSize, xstyle), className, style),
221
236
  "data-testid": testId,
222
237
  ...rest,
223
- children: [/*#__PURE__*/_jsx("span", {
224
- "aria-hidden": "true",
225
- ...{
226
- className: "x11ke7fs x6s0dn4 xv1l7n4 xu0wf1k x87ps6o"
227
- },
228
- children: ctx.separator
238
+ children: [/*#__PURE__*/_jsx(BreadcrumbSeparator, {
239
+ separator: ctx.separator
229
240
  }), hasMenu ?
230
241
  /*#__PURE__*/
231
242
  // A current crumb can also open a sibling menu — the trigger keeps
@@ -262,12 +273,8 @@ export function BreadcrumbItem({
262
273
  }), stylex.props(itemStyles.root, isSupporting ? itemStyles.supportingSize : itemStyles.defaultSize, xstyle), className, style),
263
274
  "data-testid": testId,
264
275
  ...rest,
265
- children: [/*#__PURE__*/_jsx("span", {
266
- "aria-hidden": "true",
267
- ...{
268
- className: "x11ke7fs x6s0dn4 xv1l7n4 xu0wf1k x87ps6o"
269
- },
270
- children: ctx.separator
276
+ children: [/*#__PURE__*/_jsx(BreadcrumbSeparator, {
277
+ separator: ctx.separator
271
278
  }), hasMenu ? /*#__PURE__*/_jsx(BreadcrumbMenuTrigger, {
272
279
  ref: contentRef,
273
280
  menu: menu,
@@ -1 +1 @@
1
- {"version":3,"file":"ResizeHandle.d.ts","sourceRoot":"","sources":["../../src/Resizable/ResizeHandle.tsx"],"names":[],"mappings":"AA0BA,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,OAAO,CAAC;AAErC,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AAU5C,OAAO,KAAK,EAAC,cAAc,EAAC,MAAM,gBAAgB,CAAC;AAQnD,KAAK,aAAa,GAAG,OAAO,GAAG,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAC;AA0NzD,MAAM,WAAW,iBAAkB,SAAQ,IAAI,CAC7C,SAAS,CAAC,cAAc,CAAC,EACzB,OAAO,CACR;IACC,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;IAEhC;;;OAGG;IACH,SAAS,CAAC,EAAE,YAAY,GAAG,UAAU,CAAC;IAEtC;;;;;;OAMG;IACH,QAAQ,CAAC,EAAE,QAAQ,GAAG,SAAS,CAAC;IAEhC;;;;;OAKG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IAErB;;;OAGG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IAErB;;;;;OAKG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IAErB;;;;OAIG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;IAE1B;;;;;;;OAOG;IACH,aAAa,CAAC,EAAE,aAAa,CAAC;IAE9B;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf,6CAA6C;IAC7C,SAAS,CAAC,EAAE,cAAc,CAAC;IAE3B,yDAAyD;IACzD,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,YAAY,CAAC,EAC3B,SAAwB,EACxB,QAAQ,EAAE,YAAuB,EACjC,UAAkB,EAClB,UAAkB,EAClB,UAAkB,EAClB,eAAsB,EACtB,aAAsB,EACtB,KAAK,EAAE,cAAc,EACrB,SAAS,EACT,QAAQ,EACR,MAAM,EACN,SAAS,EACT,GAAG,EACH,GAAG,KAAK,EACT,EAAE,iBAAiB,+BA6RnB;yBA5Se,YAAY"}
1
+ {"version":3,"file":"ResizeHandle.d.ts","sourceRoot":"","sources":["../../src/Resizable/ResizeHandle.tsx"],"names":[],"mappings":"AAmCA,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,OAAO,CAAC;AAErC,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AAU5C,OAAO,KAAK,EAAC,cAAc,EAAC,MAAM,gBAAgB,CAAC;AAQnD,KAAK,aAAa,GAAG,OAAO,GAAG,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAC;AAyOzD,MAAM,WAAW,iBAAkB,SAAQ,IAAI,CAC7C,SAAS,CAAC,cAAc,CAAC,EACzB,OAAO,CACR;IACC,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;IAEhC;;;OAGG;IACH,SAAS,CAAC,EAAE,YAAY,GAAG,UAAU,CAAC;IAEtC;;;;;;OAMG;IACH,QAAQ,CAAC,EAAE,QAAQ,GAAG,SAAS,CAAC;IAEhC;;;;;OAKG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IAErB;;;OAGG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IAErB;;;;;OAKG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IAErB;;;;OAIG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;IAE1B;;;;;;;OAOG;IACH,aAAa,CAAC,EAAE,aAAa,CAAC;IAE9B;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf,6CAA6C;IAC7C,SAAS,CAAC,EAAE,cAAc,CAAC;IAE3B,yDAAyD;IACzD,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,YAAY,CAAC,EAC3B,SAAwB,EACxB,QAAQ,EAAE,YAAuB,EACjC,UAAkB,EAClB,UAAkB,EAClB,UAAkB,EAClB,eAAsB,EACtB,aAAsB,EACtB,KAAK,EAAE,cAAc,EACrB,SAAS,EACT,QAAQ,EACR,MAAM,EACN,SAAS,EACT,GAAG,EACH,GAAG,KAAK,EACT,EAAE,iBAAiB,+BA0TnB;yBAzUe,YAAY"}
@@ -21,6 +21,15 @@
21
21
  * While the panel is collapsed, aria-valuenow is clamped to aria-valuemin
22
22
  * (a value below the minimum is invalid per WCAG 4.1.2) and a localized
23
23
  * "Collapsed" aria-valuetext announces the real state.
24
+ *
25
+ * Dragging takes pointer capture on the grab zone, so the rest of the gesture
26
+ * is delivered to that element instead of being hit-tested against whatever
27
+ * the cursor happens to be over. A resizable region that contains an embedded
28
+ * frame otherwise loses the drag the moment the cursor crosses the frame: the
29
+ * events go to the guest document, and a listener on the host window never
30
+ * hears them again. Captured events are delivered to the capturing element,
31
+ * so the move/up/cancel handlers live on the grab zone (as in Slider), not on
32
+ * window.
24
33
  */
25
34
  import { useCallback, useEffect, useRef, useState } from 'react';
26
35
  import * as stylex from '@stylexjs/stylex';
@@ -66,6 +75,20 @@ function hitAreaBiasDir(effectiveSide) {
66
75
  }
67
76
  return effectiveSide === 'start' ? -1 : 1;
68
77
  }
78
+
79
+ /**
80
+ * Drag feedback lives on `<body>`, not on the handle: the pointer spends the
81
+ * drag off the handle, over whatever the panels contain, and the resize cursor
82
+ * has to hold there. Module scope so the writes stay outside the component.
83
+ */
84
+ function applyBodyDragStyles(isHorizontal) {
85
+ document.body.style.cursor = isHorizontal ? 'col-resize' : 'row-resize';
86
+ document.body.style.userSelect = 'none';
87
+ }
88
+ function clearBodyDragStyles() {
89
+ document.body.style.cursor = '';
90
+ document.body.style.userSelect = '';
91
+ }
69
92
  const styles = {
70
93
  handle: {
71
94
  kVAEAm: "x1n2onr6",
@@ -273,9 +296,10 @@ export function ResizeHandle({
273
296
  const t = useTranslator();
274
297
  const label = labelFromProps ?? t('@astryx.resizable.handle.label');
275
298
  const handleRef = useRef(null);
276
- // Removes the in-flight drag's window listeners (and resets body styles).
277
- // Held in a ref so unmount can tear down a drag that never got a pointerup.
278
- const dragCleanupRef = useRef(null);
299
+ // The pointer that owns the in-flight drag, plus the values its deltas are
300
+ // measured against. A ref so moves don't re-render, and so unmount can tell
301
+ // a live drag from a finished one.
302
+ const dragRef = useRef(null);
279
303
  const [isDragging, setIsDragging] = useState(false);
280
304
  const [isHovered, setIsHovered] = useState(false);
281
305
  const [isFocused, setIsFocused] = useState(false);
@@ -296,47 +320,56 @@ export function ResizeHandle({
296
320
  const isInteracting = isHovered || isFocused;
297
321
 
298
322
  // --- Pointer drag ---
323
+ const clearDrag = useCallback(() => {
324
+ dragRef.current = null;
325
+ setIsDragging(false);
326
+ clearBodyDragStyles();
327
+ }, []);
299
328
  const handlePointerDown = useCallback(e => {
300
- if (isDisabled || !resizable) {
329
+ if (isDisabled || !resizable || dragRef.current) {
301
330
  return;
302
331
  }
303
332
  e.preventDefault();
304
333
  e.stopPropagation();
334
+ // Take the pointer for the whole gesture. Without capture the browser
335
+ // re-hit-tests every move, so a frame anywhere under the drag path
336
+ // swallows the rest of it into the guest document.
337
+ e.currentTarget.setPointerCapture?.(e.pointerId);
338
+ dragRef.current = {
339
+ pointerId: e.pointerId,
340
+ startPos: isHorizontal ? e.clientX : e.clientY,
341
+ rtl: isHorizontal ? getRTLMultiplier() : 1
342
+ };
305
343
  setIsDragging(true);
306
344
  resizable._onResizeStart();
307
- const startPos = isHorizontal ? e.clientX : e.clientY;
308
- const rtl = isHorizontal ? getRTLMultiplier() : 1;
309
- document.body.style.cursor = isHorizontal ? 'col-resize' : 'row-resize';
310
- document.body.style.userSelect = 'none';
311
- const onMove = ev => {
312
- const currentPos = isHorizontal ? ev.clientX : ev.clientY;
313
- const delta = (currentPos - startPos) * rtl * sign;
314
- resizable._onResizeMove(delta);
315
- };
316
- const onUp = () => {
317
- cleanup();
318
- setIsDragging(false);
319
- resizable._onResizeEnd();
320
- document.body.style.cursor = '';
321
- document.body.style.userSelect = '';
322
- };
323
- const onCancel = () => {
324
- cleanup();
325
- setIsDragging(false);
326
- document.body.style.cursor = '';
327
- document.body.style.userSelect = '';
328
- };
329
- function cleanup() {
330
- window.removeEventListener('pointermove', onMove);
331
- window.removeEventListener('pointerup', onUp);
332
- window.removeEventListener('pointercancel', onCancel);
333
- dragCleanupRef.current = null;
345
+ applyBodyDragStyles(isHorizontal);
346
+ }, [isDisabled, resizable, isHorizontal, getRTLMultiplier]);
347
+ const handlePointerMove = useCallback(e => {
348
+ const drag = dragRef.current;
349
+ if (!drag || drag.pointerId !== e.pointerId || !resizable) {
350
+ return;
334
351
  }
335
- window.addEventListener('pointermove', onMove);
336
- window.addEventListener('pointerup', onUp);
337
- window.addEventListener('pointercancel', onCancel);
338
- dragCleanupRef.current = cleanup;
339
- }, [isDisabled, resizable, isHorizontal, getRTLMultiplier, sign]);
352
+ const currentPos = isHorizontal ? e.clientX : e.clientY;
353
+ resizable._onResizeMove((currentPos - drag.startPos) * drag.rtl * sign);
354
+ }, [resizable, isHorizontal, sign]);
355
+ const handlePointerUp = useCallback(e => {
356
+ if (dragRef.current?.pointerId !== e.pointerId) {
357
+ return;
358
+ }
359
+ clearDrag();
360
+ resizable?._onResizeEnd();
361
+ }, [clearDrag, resizable]);
362
+
363
+ // Serves pointercancel and lostpointercapture alike: an interrupted drag
364
+ // ends without signalling a resize end. lostpointercapture also fires on the
365
+ // implicit release after every pointerup/pointercancel, by which point the
366
+ // drag is already cleared and this is a no-op.
367
+ const cancelDrag = useCallback(e => {
368
+ if (dragRef.current?.pointerId !== e.pointerId) {
369
+ return;
370
+ }
371
+ clearDrag();
372
+ }, [clearDrag]);
340
373
 
341
374
  // --- Keyboard ---
342
375
  const handleKeyDown = useCallback(e => {
@@ -406,16 +439,16 @@ export function ResizeHandle({
406
439
  }, [isDisabled, resizable]);
407
440
 
408
441
  // --- Cleanup on unmount ---
409
- // A drag in flight when the handle unmounts never gets its pointerup, so
410
- // tear down the window listeners here too — otherwise every pointermove
411
- // keeps driving the (still-mounted) region's resize state after the handle
412
- // is gone, and the body cursor/user-select overrides stick.
442
+ // Removing the grab zone implicitly releases its captured pointer and takes
443
+ // its listeners with it, so an in-flight drag stops driving the region on
444
+ // its own. The body cursor/user-select overrides are not on the element,
445
+ // though, so they have to be released here or they stick after the handle
446
+ // is gone.
413
447
  useEffect(() => {
414
448
  return () => {
415
- if (dragCleanupRef.current) {
416
- dragCleanupRef.current();
417
- document.body.style.cursor = '';
418
- document.body.style.userSelect = '';
449
+ if (dragRef.current) {
450
+ dragRef.current = null;
451
+ clearBodyDragStyles();
419
452
  }
420
453
  };
421
454
  }, []);
@@ -464,6 +497,10 @@ export function ResizeHandle({
464
497
  // construction so the two stay aligned in LTR and RTL alike.
465
498
  hitBiasDir == null ? isHorizontal ? rtlStyles.centerInline('0px') : styles.hitAreaCenteredY : isHorizontal ? dynamicStyles.hitAreaOffsetX(hitBiasDir) : dynamicStyles.hitAreaOffsetY(hitBiasDir), isDisabled && styles.disabled),
466
499
  onPointerDown: handlePointerDown,
500
+ onPointerMove: handlePointerMove,
501
+ onPointerUp: handlePointerUp,
502
+ onPointerCancel: cancelDrag,
503
+ onLostPointerCapture: cancelDrag,
467
504
  onPointerEnter: () => setIsHovered(true),
468
505
  onPointerLeave: () => {
469
506
  if (!isDragging) {
@@ -1 +1 @@
1
- {"version":3,"file":"Spinner.d.ts","sourceRoot":"","sources":["../../src/Spinner/Spinner.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAQ,KAAK,SAAS,EAAC,MAAM,OAAO,CAAC;AAG5C,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AAyB5C,QAAA,MAAM,KAAK;;;;;;;;;;;;;;;;;CAKV,CAAC;AAgVF,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;;;;;;;;;OASG;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,+BAuHd;yBAlIe,OAAO"}
1
+ {"version":3,"file":"Spinner.d.ts","sourceRoot":"","sources":["../../src/Spinner/Spinner.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAQ,KAAK,SAAS,EAAC,MAAM,OAAO,CAAC;AAG5C,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AAyB5C,QAAA,MAAM,KAAK;;;;;;;;;;;;;;;;;CAKV,CAAC;AA+VF,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;;;;;;;;;OASG;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,+BAoHd;yBA/He,OAAO"}
@@ -238,6 +238,8 @@ const styles = {
238
238
  },
239
239
  circle: {
240
240
  kDwRjp: "xbh8q5q",
241
+ kR8GR0: "x1764fhq",
242
+ k3nNDw: "x1g0ag68",
241
243
  kU5bRw: "x1owpc8m",
242
244
  kPFa82: "xio8zfp",
243
245
  kfJifR: "xgw3ha0",
@@ -371,7 +373,6 @@ export function Spinner({
371
373
  diameter
372
374
  } = SIZES[size];
373
375
  const frameSize = diameter + border * 2;
374
- const center = frameSize / 2;
375
376
  const circumference = Math.PI * diameter;
376
377
  const arcLength = circumference * ARC_FRACTION;
377
378
  const hasLabel = label != null;
@@ -418,20 +419,19 @@ export function Spinner({
418
419
  ref: syncRotationPhase,
419
420
  width: frameSize,
420
421
  height: frameSize,
421
- viewBox: `0 0 ${frameSize} ${frameSize}`,
422
422
  "aria-hidden": "true",
423
423
  ...{
424
- className: "xlp1x4z x1lliihq x1so62im x1rea2x4 x14qxm4i xnh0sag xa4qsjk x1ka1v4i x1esw782"
424
+ className: "xlp1x4z x1lliihq x6v0vjy x7yyq19 x1so62im x1rea2x4 x14qxm4i xnh0sag xa4qsjk x1ka1v4i x1esw782"
425
425
  },
426
426
  children: [/*#__PURE__*/_jsx("circle", {
427
- cx: center,
428
- cy: center,
427
+ cx: "50%",
428
+ cy: "50%",
429
429
  r: diameter / 2,
430
430
  strokeWidth: border,
431
431
  ...stylex.props(styles.circle, styles.track, trackOpacityStyles[shade])
432
432
  }), /*#__PURE__*/_jsx("circle", {
433
- cx: center,
434
- cy: center,
433
+ cx: "50%",
434
+ cy: "50%",
435
435
  r: diameter / 2,
436
436
  strokeWidth: border
437
437
  // The size's own dash, for the render with no stylesheet. The rule
@@ -439,9 +439,8 @@ export function Spinner({
439
439
  // themed ring keeps this fraction of arc rather than this length.
440
440
  ,
441
441
  strokeDasharray: `${arcLength} ${circumference - arcLength}`,
442
- transform: `rotate(-90 ${center} ${center})`,
443
442
  ...{
444
- className: "xbh8q5q x1owpc8m xio8zfp xgw3ha0 xtve3lm x1vy8frr"
443
+ className: "xbh8q5q x1764fhq x1g0ag68 x1owpc8m xio8zfp xgw3ha0 xtve3lm x9tu13d x1vy8frr"
445
444
  }
446
445
  })]
447
446
  })
@@ -1 +1 @@
1
- {"version":3,"file":"ToastViewport.d.ts","sourceRoot":"","sources":["../../src/Toast/ToastViewport.tsx"],"names":[],"mappings":"AAiCA,OAAO,KAAK,EAAa,aAAa,EAAqB,MAAM,SAAS,CAAC;AA8H3E,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,EAAE,aAAa,CAAC;IACzB,mDAAmD;IACnD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE;QAAC,GAAG,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,GAAG,CAAC,EAAE,MAAM,CAAA;KAAC,CAAC;IACtE;;;;OAIG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CAC5B;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,aAAa,CAAC,EAC5B,QAAsB,EACtB,UAAc,EACd,KAAK,EACL,UAAiB,EACjB,QAAQ,GACT,EAAE,kBAAkB,+BAkWpB;yBAxWe,aAAa"}
1
+ {"version":3,"file":"ToastViewport.d.ts","sourceRoot":"","sources":["../../src/Toast/ToastViewport.tsx"],"names":[],"mappings":"AAiCA,OAAO,KAAK,EAAa,aAAa,EAAqB,MAAM,SAAS,CAAC;AAwI3E,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,EAAE,aAAa,CAAC;IACzB,mDAAmD;IACnD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE;QAAC,GAAG,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,GAAG,CAAC,EAAE,MAAM,CAAA;KAAC,CAAC;IACtE;;;;OAIG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CAC5B;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,aAAa,CAAC,EAC5B,QAAsB,EACtB,UAAc,EACd,KAAK,EACL,UAAiB,EACjB,QAAQ,GACT,EAAE,kBAAkB,+BAkWpB;yBAxWe,aAAa"}
@@ -43,6 +43,7 @@ const styles = {
43
43
  kwRFfy: "x1g0rcpp x1n6uwha",
44
44
  kfzvcC: "x47corl",
45
45
  kpwlN0: "xh3736h",
46
+ kzqmXN: "x14atkfc",
46
47
  kogj98: "x1ghz6dp",
47
48
  kWkggS: "xjbqb8w",
48
49
  kVQacm: "x1rea2x4",
package/dist/astryx.css CHANGED
@@ -1175,9 +1175,11 @@
1175
1175
  .x5ve5x3:not(#\#):not(#\#):not(#\#){touch-action:none}
1176
1176
  .x1bblx7b:not(#\#):not(#\#):not(#\#){touch-action:pan-x}
1177
1177
  .xx69xxh:not(#\#):not(#\#):not(#\#){touch-action:pan-y}
1178
+ .x1764fhq:not(#\#):not(#\#):not(#\#){transform-box:fill-box}
1178
1179
  .x1g0ag68:not(#\#):not(#\#):not(#\#){transform-origin:center}
1179
1180
  .x1oyok0e:not(#\#):not(#\#):not(#\#){transform-style:preserve-3d}
1180
1181
  .x1c071of:not(#\#):not(#\#):not(#\#){transform:none}
1182
+ .x9tu13d:not(#\#):not(#\#):not(#\#){transform:rotate(-90deg)}
1181
1183
  .x7p49u4:not(#\#):not(#\#):not(#\#){transform:rotate(0deg)}
1182
1184
  .x19jd1h0:not(#\#):not(#\#):not(#\#){transform:rotate(180deg)}
1183
1185
  .x1iffjtl:not(#\#):not(#\#):not(#\#){transform:rotate(90deg)}
@@ -1532,6 +1534,7 @@
1532
1534
  .xw1wawg:not(#\#):not(#\#):not(#\#):not(#\#){height:calc(44px - 8px)}
1533
1535
  .xg7h5cd:not(#\#):not(#\#):not(#\#):not(#\#){height:fit-content}
1534
1536
  .xhovv34:not(#\#):not(#\#):not(#\#):not(#\#){height:var(--_progressbar-mark-height,8px)}
1537
+ .x7yyq19:not(#\#):not(#\#):not(#\#):not(#\#){height:var(--_spinner-box-size)}
1535
1538
  .xsyqizj:not(#\#):not(#\#):not(#\#):not(#\#){height:var(--border-width)}
1536
1539
  .x5kfih4:not(#\#):not(#\#):not(#\#):not(#\#){height:var(--resize-handle-hit-area,16px)}
1537
1540
  .xssyfek:not(#\#):not(#\#):not(#\#):not(#\#){height:var(--size-element-lg)}
@@ -1777,6 +1780,7 @@
1777
1780
  .x1y2t9nm:not(#\#):not(#\#):not(#\#):not(#\#){width:calc(44px - 8px)}
1778
1781
  .xeq5yr9:not(#\#):not(#\#):not(#\#):not(#\#){width:fit-content}
1779
1782
  .x63cpjl:not(#\#):not(#\#):not(#\#):not(#\#){width:var(--_progressbar-mark-width,2px)}
1783
+ .x6v0vjy:not(#\#):not(#\#):not(#\#):not(#\#){width:var(--_spinner-box-size)}
1780
1784
  .xjk4fl7:not(#\#):not(#\#):not(#\#):not(#\#){width:var(--border-width)}
1781
1785
  .xkhob8h:not(#\#):not(#\#):not(#\#):not(#\#){width:var(--resize-handle-hit-area,16px)}
1782
1786
  .x1m747yf:not(#\#):not(#\#):not(#\#):not(#\#){width:var(--size-element-lg)}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@astryxdesign/core",
3
- "version": "0.5.2-canary.4a88299",
3
+ "version": "0.5.2-canary.501e975",
4
4
  "displayName": "Astryx Core",
5
5
  "description": "The component library. Accessible, themeable React components with built-in spacing, dark mode, and StyleX styling.",
6
6
  "author": "Meta Open Source",
@@ -661,7 +661,7 @@
661
661
  "react-dom": ">=19.0.0"
662
662
  },
663
663
  "devDependencies": {
664
- "@astryxdesign/cli": "0.5.2-canary.4a88299",
664
+ "@astryxdesign/cli": "0.5.2-canary.501e975",
665
665
  "@babel/cli": "^8.0.4",
666
666
  "@babel/core": "^7.29.7",
667
667
  "@babel/preset-react": "^8.0.1",
@@ -579,6 +579,27 @@ describe('AppShell', () => {
579
579
  ).toBeDefined();
580
580
  });
581
581
 
582
+ it('renders an opaque section header only in auto mode', () => {
583
+ const {rerender} = render(
584
+ <AppShell height="auto" variant="section" topNav={<div>Nav</div>}>
585
+ <div>Content</div>
586
+ </AppShell>,
587
+ );
588
+
589
+ expect(
590
+ getComputedStyle(screen.getByRole('banner')).backgroundColor,
591
+ ).not.toBe('rgba(0, 0, 0, 0)');
592
+
593
+ rerender(
594
+ <AppShell height="fill" variant="section" topNav={<div>Nav</div>}>
595
+ <div>Content</div>
596
+ </AppShell>,
597
+ );
598
+ expect(getComputedStyle(screen.getByRole('banner')).backgroundColor).toBe(
599
+ 'rgba(0, 0, 0, 0)',
600
+ );
601
+ });
602
+
582
603
  it('does not apply sticky wrapper in fill mode', () => {
583
604
  render(
584
605
  <AppShell
@@ -269,6 +269,7 @@ const styles = stylex.create({
269
269
  display: 'flex',
270
270
  flexDirection: 'column',
271
271
  position: 'relative',
272
+ overflow: 'clip',
272
273
  },
273
274
  variantWash: {
274
275
  backgroundColor: colorVars['--color-background-body'],
@@ -554,6 +555,11 @@ export function AppShell({
554
555
  : variant === 'surface'
555
556
  ? styles.navAreaSurface
556
557
  : undefined;
558
+ // Section normally inherits the shell's surface background. Its auto-height
559
+ // header needs to paint that surface itself while content scrolls beneath it.
560
+ const headerAreaStyle =
561
+ navAreaStyle ??
562
+ (isAuto && variant === 'section' ? styles.navAreaSurface : undefined);
557
563
  const contentAreaStyle =
558
564
  variant === 'wash'
559
565
  ? styles.contentBgWash
@@ -684,7 +690,7 @@ export function AppShell({
684
690
  role="banner"
685
691
  {...mergeProps(
686
692
  themeProps('app-shell-header', {variant}),
687
- stylex.props(navAreaStyle, isAuto && styles.headerSticky),
693
+ stylex.props(headerAreaStyle, isAuto && styles.headerSticky),
688
694
  )}>
689
695
  {headerInner}
690
696
  </div>
@@ -773,7 +779,7 @@ export function AppShell({
773
779
  role={headerContent == null ? 'banner' : undefined}
774
780
  {...mergeProps(
775
781
  themeProps('app-shell-header', {variant}),
776
- stylex.props(navAreaStyle, isAuto && styles.headerSticky),
782
+ stylex.props(headerAreaStyle, isAuto && styles.headerSticky),
777
783
  )}>
778
784
  <LayoutHeader padding={0} hasDivider={navHasDividers}>
779
785
  <div
@@ -17,7 +17,7 @@ export const docs = {
17
17
  {guidance: true, description: 'Keep titles short and scannable: "Payment failed" not "There was a problem processing your most recent payment."'},
18
18
  {guidance: false, description: 'Use Banner for short-lived messages that disappear on their own; use Toast instead.'},
19
19
  {guidance: false, description: 'Stack multiple banners with the same status; combine related messages into one banner.'},
20
- {guidance: true, description: 'Set collapsible={false} when the user needs the content to act on the message, like the list of fields that failed validation. Keep the default toggle when the detail is long enough to bury the banner\u2019s own message.'},
20
+ {guidance: true, description: 'Set collapsible={false} when the user needs the content to act on the message, like the list of fields that failed validation. Keep the default toggle when the detail is long enough to bury the banner\'s own message.'},
21
21
  {guidance: true, description: 'Error and warning banners render as role="alert"; info and success render as role="status". Mount an alert banner in response to an event rather than on first paint, so assistive tech has a change to report.'},
22
22
  {guidance: false, description: 'Rely on the status color or icon alone to carry meaning; say which status it is in the title text, because the icon is decorative to a screen reader.'},
23
23
  ],
@@ -129,6 +129,7 @@ export const docs = {
129
129
  targets: [
130
130
  {className: 'astryx-banner', visualProps: ['container', 'status']},
131
131
  {className: 'astryx-banner-icon', visualProps: ['status']},
132
+ {className: 'astryx-banner-description'},
132
133
  {className: 'astryx-banner-content', visualProps: ['container', 'status']},
133
134
  ],
134
135
  vars: [
@@ -199,6 +200,9 @@ export const docsZh = {
199
200
  'status',
200
201
  ],
201
202
  },
203
+ {
204
+ className: 'astryx-banner-description',
205
+ },
202
206
  {
203
207
  className: 'astryx-banner-content',
204
208
  visualProps: [
@@ -15,6 +15,11 @@
15
15
  * - Status icon (themeProps 'banner-icon'): the target rides on the default
16
16
  * <Icon> itself — the element that paints — so 'status:X' overrides reach
17
17
  * the glyph (#4166); for a custom `icon` node it stays on the layout wrapper
18
+ * - Description (themeProps 'banner-description'): the supporting line owns its
19
+ * own colour and type, and the space between it and the title
20
+ * - The end area carries no target: it is a layout row (flex, wrap, edge
21
+ * compensation) rather than a painted surface, and a theme that wants the
22
+ * header to grow around its buttons sets `padding-block` on 'banner'
18
23
  * - No left border accent — color is expressed through the full header background
19
24
  * - Each visual area owns its own border-radius (no overflow:clip on the container)
20
25
  * - Children are collapsible by default: a toggle appears in the header end
@@ -631,7 +636,13 @@ export function Banner({
631
636
  )}>
632
637
  <div {...stylex.props(styles.title)}>{title}</div>
633
638
  {isRenderable(description) && (
634
- <div {...stylex.props(styles.description)}>{description}</div>
639
+ <div
640
+ {...mergeProps(
641
+ themeProps('banner-description'),
642
+ stylex.props(styles.description),
643
+ )}>
644
+ {description}
645
+ </div>
635
646
  )}
636
647
  </div>
637
648
  {showEndArea && (
@@ -1,5 +1,5 @@
1
1
  ---
2
- schema_version: 1
2
+ schema_version: 3
3
3
  template_version: 3
4
4
  kind: component
5
5
  id: component:BottomSheet
@@ -16,6 +16,7 @@ verified_by:
16
16
  packages/core/src/BottomSheet/BottomSheetPanel.test.tsx,
17
17
  scripts/check-knowledge.mjs,
18
18
  ]
19
+ modules: []
19
20
  families: [family:overlay-dismissal]
20
21
  design_specs: []
21
22
  architecture: