@astryxdesign/core 0.1.7-canary.cbfb48e → 0.1.7-canary.cecb773

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 (34) hide show
  1. package/dist/Carousel/Carousel.d.ts +3 -2
  2. package/dist/Carousel/Carousel.d.ts.map +1 -1
  3. package/dist/Carousel/Carousel.js +32 -2
  4. package/dist/Icon/Icon.d.ts +26 -1
  5. package/dist/Icon/Icon.d.ts.map +1 -1
  6. package/dist/Icon/Icon.js +34 -7
  7. package/dist/Table/plugins/rowExpansion/useTableRowExpansion.d.ts.map +1 -1
  8. package/dist/Table/plugins/rowExpansion/useTableRowExpansion.js +24 -2
  9. package/dist/Table/plugins/sortable/useTableSortable.d.ts.map +1 -1
  10. package/dist/Table/plugins/sortable/useTableSortable.js +18 -7
  11. package/dist/TreeList/TreeListItem.d.ts.map +1 -1
  12. package/dist/TreeList/TreeListItem.js +5 -14
  13. package/dist/astryx.css +6 -2
  14. package/dist/astryx.umd.js +18 -18
  15. package/dist/astryx.umd.js.map +4 -4
  16. package/locales/en.json +20 -0
  17. package/locales/pseudo.json +15 -0
  18. package/package.json +1 -1
  19. package/src/Carousel/Carousel.doc.mjs +1 -0
  20. package/src/Carousel/Carousel.test.tsx +96 -1
  21. package/src/Carousel/Carousel.tsx +29 -2
  22. package/src/Icon/Icon.doc.mjs +12 -0
  23. package/src/Icon/Icon.test.tsx +96 -0
  24. package/src/Icon/Icon.tsx +61 -6
  25. package/src/Table/plugins/rowExpansion/useTableRowExpansion.test.tsx +90 -1
  26. package/src/Table/plugins/rowExpansion/useTableRowExpansion.tsx +37 -5
  27. package/src/Table/plugins/sortable/useTableSortable.test.tsx +95 -9
  28. package/src/Table/plugins/sortable/useTableSortable.tsx +23 -7
  29. package/src/TreeList/TreeList.test.tsx +32 -1
  30. package/src/TreeList/TreeListItem.tsx +19 -10
  31. package/dist/TreeList/treeListItem.markers.stylex.d.ts +0 -16
  32. package/dist/TreeList/treeListItem.markers.stylex.d.ts.map +0 -1
  33. package/dist/TreeList/treeListItem.markers.stylex.js +0 -22
  34. package/src/TreeList/treeListItem.markers.stylex.ts +0 -20
@@ -3,8 +3,9 @@
3
3
  * @input Uses React, StyleX, useScrollOverflow, useLayer, Button, Icon, theme tokens
4
4
  * @output Exports Carousel component
5
5
  * @position Horizontal scroll container with fade-edge overflow indication,
6
- * optional prev/next buttons on the top layer, scroll-snap, and a 1px
7
- * visual bleed allowance for child selection indicators.
6
+ * optional prev/next buttons on the top layer, scroll-snap, a 1px
7
+ * visual bleed allowance for child selection indicators, and Shift + wheel
8
+ * mapping so mouse users can scroll horizontally.
8
9
  *
9
10
  * SYNC: When modified, update:
10
11
  * - /packages/core/src/Carousel/index.ts (exports)
@@ -1 +1 @@
1
- {"version":3,"file":"Carousel.d.ts","sourceRoot":"","sources":["../../src/Carousel/Carousel.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAC,KAAK,SAAS,EAA2C,MAAM,OAAO,CAAC;AAc/E,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AAE5C,OAAO,KAAK,EAAC,WAAW,EAAC,MAAM,gBAAgB,CAAC;AAIhD,MAAM,WAAW,aAAc,SAAQ,SAAS,CAAC,cAAc,CAAC;IAC9D,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;IAChC,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;;;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,QAAQ,EACR,GAAO,EACP,UAAiB,EACjB,WAAkB,EAClB,OAAe,EACf,OAAO,EACP,YAAY,EAAE,kBAAkB,EAChC,MAAM,EACN,SAAS,EACT,KAAK,EACL,aAAa,EAAE,MAAM,EACrB,GAAG,SAAS,EACb,EAAE,aAAa,+BAmJf;yBAjKe,QAAQ"}
1
+ {"version":3,"file":"Carousel.d.ts","sourceRoot":"","sources":["../../src/Carousel/Carousel.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAC,KAAK,SAAS,EAA2C,MAAM,OAAO,CAAC;AAc/E,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AAE5C,OAAO,KAAK,EAAC,WAAW,EAAC,MAAM,gBAAgB,CAAC;AAIhD,MAAM,WAAW,aAAc,SAAQ,SAAS,CAAC,cAAc,CAAC;IAC9D,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;IAChC,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;;;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,QAAQ,EACR,GAAO,EACP,UAAiB,EACjB,WAAkB,EAClB,OAAe,EACf,OAAO,EACP,YAAY,EAAE,kBAAkB,EAChC,MAAM,EACN,SAAS,EACT,KAAK,EACL,aAAa,EAAE,MAAM,EACrB,GAAG,SAAS,EACb,EAAE,aAAa,+BA6Kf;yBA3Le,QAAQ"}
@@ -7,8 +7,9 @@
7
7
  * @input Uses React, StyleX, useScrollOverflow, useLayer, Button, Icon, theme tokens
8
8
  * @output Exports Carousel component
9
9
  * @position Horizontal scroll container with fade-edge overflow indication,
10
- * optional prev/next buttons on the top layer, scroll-snap, and a 1px
11
- * visual bleed allowance for child selection indicators.
10
+ * optional prev/next buttons on the top layer, scroll-snap, a 1px
11
+ * visual bleed allowance for child selection indicators, and Shift + wheel
12
+ * mapping so mouse users can scroll horizontally.
12
13
  *
13
14
  * SYNC: When modified, update:
14
15
  * - /packages/core/src/Carousel/index.ts (exports)
@@ -234,6 +235,34 @@ export function Carousel({
234
235
  scrollElRef.current = el;
235
236
  scrollRef(el);
236
237
  }, [scrollRef]);
238
+
239
+ // Map Shift + vertical wheel to horizontal scroll. Trackpads emit
240
+ // horizontal deltas natively, but a standard mouse only produces deltaY —
241
+ // so mouse users can't wheel-scroll a horizontal container. Shift + wheel
242
+ // is the long-established convention for horizontal scroll containers; we
243
+ // honor it by translating the vertical delta into a horizontal scroll.
244
+ //
245
+ // Only kicks in when Shift is held and the wheel is purely vertical
246
+ // (deltaX === 0), so native trackpad horizontal scrolling is untouched.
247
+ const handleWheel = useCallback(event => {
248
+ if (!event.shiftKey || event.deltaY === 0 || event.deltaX !== 0) {
249
+ return;
250
+ }
251
+ const el = scrollElRef.current;
252
+ if (!el) {
253
+ return;
254
+ }
255
+ // Nothing to scroll horizontally — let the event fall through so the page
256
+ // can scroll as it normally would.
257
+ if (el.scrollWidth <= el.clientWidth) {
258
+ return;
259
+ }
260
+ event.preventDefault();
261
+ el.scrollBy({
262
+ left: event.deltaY,
263
+ behavior: 'auto'
264
+ });
265
+ }, []);
237
266
  const scrollBy = useCallback(direction => {
238
267
  const el = scrollElRef.current;
239
268
  if (!el) {
@@ -271,6 +300,7 @@ export function Carousel({
271
300
  children: [/*#__PURE__*/_jsx("div", {
272
301
  ref: composedRef,
273
302
  tabIndex: 0,
303
+ onWheel: handleWheel,
274
304
  ...stylex.props(styles.scroller, gapStyles[gap], padding != null && paddingStyles[padding], hasSnap && styles.snap, fadeStyle),
275
305
  children: Children.map(children, child => /*#__PURE__*/_jsx("div", {
276
306
  ...{
@@ -140,6 +140,31 @@ export interface IconProps extends Omit<SVGProps<SVGSVGElement>, 'ref' | 'color'
140
140
  * @default 'md'
141
141
  */
142
142
  size?: IconSize;
143
+ /**
144
+ * Accessible name for the icon. Set this only when the icon is MEANINGFUL on
145
+ * its own — a standalone status glyph or an icon-only indicator with no
146
+ * adjacent text conveying the same information. Providing it exposes the icon
147
+ * to assistive tech as `role="img"` with this string as the accessible name
148
+ * (via `aria-label`) and drops the default `aria-hidden="true"`.
149
+ *
150
+ * Omit it (the default) for decorative icons — the common case, e.g. an icon
151
+ * beside a text label — and the icon stays hidden from assistive tech
152
+ * (`aria-hidden="true"`). An empty string (`''`) is treated the same as
153
+ * omitting it (decorative), since an empty accessible name is meaningless.
154
+ *
155
+ * Don't set `label` when an interactive parent (Button, IconButton, link)
156
+ * already names the control — that produces a duplicate announcement.
157
+ *
158
+ * @example
159
+ * ```
160
+ * // Meaningful, standalone icon
161
+ * <Icon icon="success" label="Completed" />
162
+ *
163
+ * // Decorative icon (default) — omit label
164
+ * <Icon icon="search" />
165
+ * ```
166
+ */
167
+ label?: string;
143
168
  }
144
169
  /**
145
170
  * Renders an icon from the icon registry or a custom SVG component.
@@ -149,7 +174,7 @@ export interface IconProps extends Omit<SVGProps<SVGSVGElement>, 'ref' | 'color'
149
174
  * <Icon icon="close" size="md" color="primary" />
150
175
  * ```
151
176
  */
152
- export declare function Icon({ icon, color, size, ref, ...props }: IconProps): React.JSX.Element;
177
+ export declare function Icon({ icon, color, size, label, ref, ...props }: IconProps): React.JSX.Element;
153
178
  export declare namespace Icon {
154
179
  var displayName: string;
155
180
  }
@@ -1 +1 @@
1
- {"version":3,"file":"Icon.d.ts","sourceRoot":"","sources":["../../src/Icon/Icon.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,KAAK,EAAE,EAAC,KAAK,aAAa,EAAE,KAAK,QAAQ,EAAC,MAAM,OAAO,CAAC;AAC/D,OAAO,KAAK,MAAM,MAAM,kBAAkB,CAAC;AAG3C,OAAO,KAAK,EAAC,QAAQ,EAAC,MAAM,sBAAsB,CAAC;AAqBnD,QAAA,MAAM,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA2Df,CAAC;AAEH;;;;;;;;GAQG;AACH,QAAA,MAAM,UAAU;;;;;;;;;;;;;;;;;EAiBd,CAAC;AAyCH,MAAM,MAAM,SAAS,GAAG,MAAM,OAAO,WAAW,CAAC;AACjD,MAAM,MAAM,QAAQ,GAAG,MAAM,OAAO,UAAU,CAAC;AAE/C;;;GAGG;AACH,MAAM,MAAM,QAAQ,GAAG,aAAa,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC,CAAC;AAE9D;;;GAGG;AACH,MAAM,WAAW,SAAU,SAAQ,IAAI,CACrC,QAAQ,CAAC,aAAa,CAAC,EACvB,KAAK,GAAG,OAAO,CAChB;IACC,wCAAwC;IACxC,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;IAC/B;;;;OAIG;IACH,IAAI,EAAE,QAAQ,GAAG,QAAQ,CAAC;IAC1B;;;OAGG;IACH,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB;;;;;;;OAOG;IACH,IAAI,CAAC,EAAE,QAAQ,CAAC;CACjB;AAMD;;;;;;;GAOG;AACH,wBAAgB,IAAI,CAAC,EACnB,IAAI,EACJ,KAAiB,EACjB,IAAW,EACX,GAAG,EACH,GAAG,KAAK,EACT,EAAE,SAAS,qBA0BX;yBAhCe,IAAI;;;AAiFpB;;;;;;GAMG;AACH,wBAAgB,cAAc,CAC5B,IAAI,EAAE,KAAK,CAAC,SAAS,GAAG,QAAQ,EAChC,KAAK,CAAC,EAAE;IAAC,IAAI,CAAC,EAAE,QAAQ,CAAC;IAAC,KAAK,CAAC,EAAE,SAAS,CAAA;CAAC,GAC3C,KAAK,CAAC,SAAS,CAYjB"}
1
+ {"version":3,"file":"Icon.d.ts","sourceRoot":"","sources":["../../src/Icon/Icon.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,KAAK,EAAE,EAAC,KAAK,aAAa,EAAE,KAAK,QAAQ,EAAC,MAAM,OAAO,CAAC;AAC/D,OAAO,KAAK,MAAM,MAAM,kBAAkB,CAAC;AAG3C,OAAO,KAAK,EAAC,QAAQ,EAAC,MAAM,sBAAsB,CAAC;AAqBnD,QAAA,MAAM,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA2Df,CAAC;AAEH;;;;;;;;GAQG;AACH,QAAA,MAAM,UAAU;;;;;;;;;;;;;;;;;EAiBd,CAAC;AAyCH,MAAM,MAAM,SAAS,GAAG,MAAM,OAAO,WAAW,CAAC;AACjD,MAAM,MAAM,QAAQ,GAAG,MAAM,OAAO,UAAU,CAAC;AAE/C;;;GAGG;AACH,MAAM,MAAM,QAAQ,GAAG,aAAa,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC,CAAC;AAE9D;;;GAGG;AACH,MAAM,WAAW,SAAU,SAAQ,IAAI,CACrC,QAAQ,CAAC,aAAa,CAAC,EACvB,KAAK,GAAG,OAAO,CAChB;IACC,wCAAwC;IACxC,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;IAC/B;;;;OAIG;IACH,IAAI,EAAE,QAAQ,GAAG,QAAQ,CAAC;IAC1B;;;OAGG;IACH,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB;;;;;;;OAOG;IACH,IAAI,CAAC,EAAE,QAAQ,CAAC;IAChB;;;;;;;;;;;;;;;;;;;;;;;OAuBG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAyBD;;;;;;;GAOG;AACH,wBAAgB,IAAI,CAAC,EACnB,IAAI,EACJ,KAAiB,EACjB,IAAW,EACX,KAAK,EACL,GAAG,EACH,GAAG,KAAK,EACT,EAAE,SAAS,qBAkCX;yBAzCe,IAAI;;;AA4FpB;;;;;;GAMG;AACH,wBAAgB,cAAc,CAC5B,IAAI,EAAE,KAAK,CAAC,SAAS,GAAG,QAAQ,EAChC,KAAK,CAAC,EAAE;IAAC,IAAI,CAAC,EAAE,QAAQ,CAAC;IAAC,KAAK,CAAC,EAAE,SAAS,CAAA;CAAC,GAC3C,KAAK,CAAC,SAAS,CAYjB"}
package/dist/Icon/Icon.js CHANGED
@@ -205,6 +205,26 @@ const spanSizeStyles = {
205
205
  * Extends SVGProps to allow passing additional SVG attributes (used when icon is a component).
206
206
  */
207
207
 
208
+ /**
209
+ * Derives the ARIA attributes for an icon from its `label` prop.
210
+ *
211
+ * - Non-empty `label` → meaningful image: `role="img"` + `aria-label`, and no
212
+ * `aria-hidden` (an `aria-hidden` element is removed from the accessibility
213
+ * tree, so its accessible name would be ignored).
214
+ * - Omitted or empty `label` → decorative default: `aria-hidden="true"`.
215
+ *
216
+ * The result is spread BEFORE `{...props}` in both render modes so an explicit
217
+ * `aria-hidden` / `role` / `aria-label` from the consumer always wins.
218
+ */
219
+ function getIconA11yProps(label) {
220
+ return label != null && label !== '' ? {
221
+ role: 'img',
222
+ 'aria-label': label
223
+ } : {
224
+ 'aria-hidden': 'true'
225
+ };
226
+ }
227
+
208
228
  // =============================================================================
209
229
  // Component
210
230
  // =============================================================================
@@ -221,15 +241,21 @@ export function Icon({
221
241
  icon,
222
242
  color = 'inherit',
223
243
  size = 'md',
244
+ label,
224
245
  ref,
225
246
  ...props
226
247
  }) {
248
+ // Derive ARIA from `label`: decorative (aria-hidden) by default, or a
249
+ // meaningful image (role="img" + aria-label) when `label` is non-empty.
250
+ const a11yProps = getIconA11yProps(label);
251
+
227
252
  // String mode: resolve from icon registry, wrap in styled span
228
253
  if (typeof icon === 'string') {
229
254
  return /*#__PURE__*/_jsx(IconFromRegistry, {
230
255
  name: icon,
231
256
  color: color,
232
257
  size: size,
258
+ a11yProps: a11yProps,
233
259
  spanProps: props
234
260
  });
235
261
  }
@@ -237,8 +263,12 @@ export function Icon({
237
263
  // Component mode: render SVG component directly with ref forwarding
238
264
  const IconComponent = icon;
239
265
  return /*#__PURE__*/_jsx(IconComponent, {
240
- ref: ref,
241
- "aria-hidden": "true",
266
+ ref: ref
267
+ // Derived a11y (decorative default or meaningful `label`) is spread
268
+ // BEFORE {...props} so an explicit aria-hidden/role/aria-label from the
269
+ // consumer still wins as an escape hatch.
270
+ ,
271
+ ...a11yProps,
242
272
  ...mergeProps(themeProps('icon', {
243
273
  size,
244
274
  color
@@ -263,6 +293,7 @@ function IconFromRegistry({
263
293
  name,
264
294
  color,
265
295
  size,
296
+ a11yProps,
266
297
  spanProps
267
298
  }) {
268
299
  const resolvedIcon = getIcon(name);
@@ -270,11 +301,7 @@ function IconFromRegistry({
270
301
  return null;
271
302
  }
272
303
  return /*#__PURE__*/_jsx("span", {
273
- // Decorative by default, but placed BEFORE the prop spread so consumers
274
- // can override it (e.g. `aria-hidden={false}` + `role="img"` +
275
- // `aria-label`) to expose a meaningful standalone icon. This matches
276
- // component-mode Icon, which already sets aria-hidden before its spread.
277
- "aria-hidden": "true",
304
+ ...a11yProps,
278
305
  ...spanProps,
279
306
  ...mergeProps(themeProps('icon', {
280
307
  size,
@@ -1 +1 @@
1
- {"version":3,"file":"useTableRowExpansion.d.ts","sourceRoot":"","sources":["../../../../src/Table/plugins/rowExpansion/useTableRowExpansion.tsx"],"names":[],"mappings":"AAoBA,OAAO,KAAK,EACV,WAAW,EAKZ,MAAM,aAAa,CAAC;AAMrB;;;;;;;GAOG;AACH,MAAM,WAAW,0BAA0B,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAC3E,0CAA0C;IAC1C,YAAY,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAC1B,gDAAgD;IAChD,QAAQ,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IAChC,kDAAkD;IAClD,SAAS,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,MAAM,CAAC;IAC/B,sEAAsE;IACtE,WAAW,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC;IAC9B,kEAAkE;IAClE,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,MAAM,CAAC;IAC/B,uFAAuF;IACvF,mBAAmB,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,OAAO,CAAC;IAC3C;;;OAGG;IACH,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B;;;;OAIG;IACH,aAAa,CAAC,EAAE,OAAO,GAAG,eAAe,CAAC;IAC1C,2DAA2D;IAC3D,iBAAiB,CAAC,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,IAAI,CAAC;CAC/C;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,+BAA+B,CAC9C,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAEjC,mCAAmC;IACnC,QAAQ,EAAE,CAAC,EAAE,CAAC;IACd,qEAAqE;IACrE,WAAW,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC;IAC9B,kDAAkD;IAClD,SAAS,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,MAAM,CAAC;IAC/B;;;OAGG;IACH,mBAAmB,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,OAAO,CAAC;IAC3C,qDAAqD;IACrD,YAAY,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAC1B,+CAA+C;IAC/C,eAAe,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;CACpE;AAED,MAAM,WAAW,+BAA+B,CAC9C,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAEjC,qEAAqE;IACrE,IAAI,EAAE,CAAC,EAAE,CAAC;IACV,4DAA4D;IAC5D,eAAe,EAAE,0BAA0B,CAAC,CAAC,CAAC,CAAC;CAChD;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,yBAAyB,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,EAC3E,QAAQ,EACR,WAAW,EACX,SAAS,EACT,mBAAmB,EACnB,YAAY,EACZ,eAAe,GAChB,EAAE,+BAA+B,CAAC,CAAC,CAAC,GAAG,+BAA+B,CAAC,CAAC,CAAC,CAyHzE;AAuGD,wBAAgB,oBAAoB,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACpE,MAAM,EAAE,0BAA0B,CAAC,CAAC,CAAC,GACpC,WAAW,CAAC,CAAC,CAAC,CAwOhB"}
1
+ {"version":3,"file":"useTableRowExpansion.d.ts","sourceRoot":"","sources":["../../../../src/Table/plugins/rowExpansion/useTableRowExpansion.tsx"],"names":[],"mappings":"AAoBA,OAAO,KAAK,EACV,WAAW,EAKZ,MAAM,aAAa,CAAC;AAMrB;;;;;;;GAOG;AACH,MAAM,WAAW,0BAA0B,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAC3E,0CAA0C;IAC1C,YAAY,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAC1B,gDAAgD;IAChD,QAAQ,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IAChC,kDAAkD;IAClD,SAAS,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,MAAM,CAAC;IAC/B,sEAAsE;IACtE,WAAW,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC;IAC9B,kEAAkE;IAClE,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,MAAM,CAAC;IAC/B,uFAAuF;IACvF,mBAAmB,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,OAAO,CAAC;IAC3C;;;OAGG;IACH,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B;;;;OAIG;IACH,aAAa,CAAC,EAAE,OAAO,GAAG,eAAe,CAAC;IAC1C,2DAA2D;IAC3D,iBAAiB,CAAC,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,IAAI,CAAC;CAC/C;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,+BAA+B,CAC9C,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAEjC,mCAAmC;IACnC,QAAQ,EAAE,CAAC,EAAE,CAAC;IACd,qEAAqE;IACrE,WAAW,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC;IAC9B,kDAAkD;IAClD,SAAS,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,MAAM,CAAC;IAC/B;;;OAGG;IACH,mBAAmB,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,OAAO,CAAC;IAC3C,qDAAqD;IACrD,YAAY,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAC1B,+CAA+C;IAC/C,eAAe,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;CACpE;AAED,MAAM,WAAW,+BAA+B,CAC9C,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAEjC,qEAAqE;IACrE,IAAI,EAAE,CAAC,EAAE,CAAC;IACV,4DAA4D;IAC5D,eAAe,EAAE,0BAA0B,CAAC,CAAC,CAAC,CAAC;CAChD;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,yBAAyB,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,EAC3E,QAAQ,EACR,WAAW,EACX,SAAS,EACT,mBAAmB,EACnB,YAAY,EACZ,eAAe,GAChB,EAAE,+BAA+B,CAAC,CAAC,CAAC,GAAG,+BAA+B,CAAC,CAAC,CAAC,CA+IzE;AAuGD,wBAAgB,oBAAoB,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACpE,MAAM,EAAE,0BAA0B,CAAC,CAAC,CAAC,GACpC,WAAW,CAAC,CAAC,CAAC,CAkPhB"}
@@ -72,12 +72,19 @@ export function useTableRowExpansionState({
72
72
  const isExpandable = useCallback(item => getIsItemExpandable ? getIsItemExpandable(item) : getChildren(item).length > 0, [getIsItemExpandable, getChildren]);
73
73
  const depthMap = useMemo(() => {
74
74
  const map = new Map();
75
+ // Ancestor keys on the current walk path — guards against cyclic data.
76
+ const path = new Set();
75
77
  function walk(items, depth) {
76
78
  for (const item of items) {
77
79
  const key = getRowKey(item);
80
+ if (path.has(key)) {
81
+ continue; // cyclic edge — skip
82
+ }
78
83
  map.set(key, depth);
79
84
  if (expandedKeys.has(key)) {
85
+ path.add(key);
80
86
  walk(getChildren(item), depth + 1);
87
+ path.delete(key);
81
88
  }
82
89
  }
83
90
  }
@@ -86,12 +93,19 @@ export function useTableRowExpansionState({
86
93
  }, [baseData, getChildren, getRowKey, expandedKeys]);
87
94
  const data = useMemo(() => {
88
95
  const result = [];
96
+ // Ancestor keys on the current walk path — guards against cyclic data.
97
+ const path = new Set();
89
98
  function walk(items) {
90
99
  for (const item of items) {
91
- result.push(item);
92
100
  const key = getRowKey(item);
101
+ if (path.has(key)) {
102
+ continue; // cyclic edge — skip
103
+ }
104
+ result.push(item);
93
105
  if (expandedKeys.has(key)) {
106
+ path.add(key);
94
107
  walk(getChildren(item));
108
+ path.delete(key);
95
109
  }
96
110
  }
97
111
  }
@@ -102,11 +116,19 @@ export function useTableRowExpansionState({
102
116
  // Every expandable key across the whole tree (drives expand-all).
103
117
  const allExpandableKeys = useMemo(() => {
104
118
  const keys = [];
119
+ // Ancestor keys on the current walk path — guards against cyclic data.
120
+ const path = new Set();
105
121
  function walk(items) {
106
122
  for (const item of items) {
123
+ const key = getRowKey(item);
124
+ if (path.has(key)) {
125
+ continue; // cyclic edge — skip
126
+ }
107
127
  if (isExpandable(item)) {
108
- keys.push(getRowKey(item));
128
+ keys.push(key);
129
+ path.add(key);
109
130
  walk(getChildren(item));
131
+ path.delete(key);
110
132
  }
111
133
  }
112
134
  }
@@ -1 +1 @@
1
- {"version":3,"file":"useTableSortable.d.ts","sourceRoot":"","sources":["../../../../src/Table/plugins/sortable/useTableSortable.tsx"],"names":[],"mappings":"AAqBA,OAAO,KAAK,EACV,WAAW,EAIZ,MAAM,aAAa,CAAC;AAMrB;;GAEG;AACH,MAAM,MAAM,kBAAkB,GAAG,WAAW,GAAG,YAAY,CAAC;AAE5D;;GAEG;AACH,MAAM,WAAW,cAAc,CAAC,QAAQ,SAAS,MAAM,GAAG,MAAM;IAC9D,2EAA2E;IAC3E,OAAO,EAAE,QAAQ,CAAC;IAClB,0BAA0B;IAC1B,SAAS,EAAE,kBAAkB,CAAC;CAC/B;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,MAAM,cAAc,CAAC,QAAQ,SAAS,MAAM,GAAG,MAAM,IACzD,cAAc,CAAC,QAAQ,CAAC,EAAE,CAAC;AAM7B;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,WAAW,sBAAsB,CAAC,QAAQ,SAAS,MAAM,GAAG,MAAM;IACtE,iEAAiE;IACjE,IAAI,EAAE,cAAc,CAAC,QAAQ,CAAC,CAAC;IAE/B;;;OAGG;IACH,YAAY,EAAE,CAAC,IAAI,EAAE,cAAc,CAAC,QAAQ,CAAC,KAAK,IAAI,CAAC;IAEvD;;;;;;OAMG;IACH,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAE7B;;;;;;OAMG;IACH,kBAAkB,CAAC,EAAE,OAAO,CAAC;CAC9B;AAmND;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,gBAAgB,CAC9B,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACjC,QAAQ,SAAS,MAAM,GAAG,MAAM,EAChC,MAAM,EAAE,sBAAsB,CAAC,QAAQ,CAAC,GAAG,WAAW,CAAC,CAAC,CAAC,CA2F1D"}
1
+ {"version":3,"file":"useTableSortable.d.ts","sourceRoot":"","sources":["../../../../src/Table/plugins/sortable/useTableSortable.tsx"],"names":[],"mappings":"AAqBA,OAAO,KAAK,EACV,WAAW,EAIZ,MAAM,aAAa,CAAC;AAMrB;;GAEG;AACH,MAAM,MAAM,kBAAkB,GAAG,WAAW,GAAG,YAAY,CAAC;AAE5D;;GAEG;AACH,MAAM,WAAW,cAAc,CAAC,QAAQ,SAAS,MAAM,GAAG,MAAM;IAC9D,2EAA2E;IAC3E,OAAO,EAAE,QAAQ,CAAC;IAClB,0BAA0B;IAC1B,SAAS,EAAE,kBAAkB,CAAC;CAC/B;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,MAAM,cAAc,CAAC,QAAQ,SAAS,MAAM,GAAG,MAAM,IACzD,cAAc,CAAC,QAAQ,CAAC,EAAE,CAAC;AAM7B;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,WAAW,sBAAsB,CAAC,QAAQ,SAAS,MAAM,GAAG,MAAM;IACtE,iEAAiE;IACjE,IAAI,EAAE,cAAc,CAAC,QAAQ,CAAC,CAAC;IAE/B;;;OAGG;IACH,YAAY,EAAE,CAAC,IAAI,EAAE,cAAc,CAAC,QAAQ,CAAC,KAAK,IAAI,CAAC;IAEvD;;;;;;OAMG;IACH,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAE7B;;;;;;OAMG;IACH,kBAAkB,CAAC,EAAE,OAAO,CAAC;CAC9B;AAmOD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,gBAAgB,CAC9B,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACjC,QAAQ,SAAS,MAAM,GAAG,MAAM,EAChC,MAAM,EAAE,sBAAsB,CAAC,QAAQ,CAAC,GAAG,WAAW,CAAC,CAAC,CAAC,CA2F1D"}
@@ -4,7 +4,7 @@
4
4
 
5
5
  /**
6
6
  * @file useTableSortable.tsx
7
- * @input React, types, Icon, theme tokens
7
+ * @input React, types, Icon, theme tokens, i18n (useTranslator)
8
8
  * @output Exports useTableSortable hook and sort-related types
9
9
  * @position Sortable plugin; consumed by Table via plugins prop
10
10
  *
@@ -95,16 +95,26 @@ function getHeaderLabel(column) {
95
95
  }
96
96
  return column.key;
97
97
  }
98
- function buildAriaLabel(column, direction, rank, total) {
98
+ function buildAriaLabel(t, column, direction, rank, total) {
99
99
  const label = getHeaderLabel(column);
100
100
  if (direction == null) {
101
- return `Sort by ${label}`;
101
+ return t('@astryx.table.sort.sortBy', {
102
+ label
103
+ });
102
104
  }
103
- let ariaLabel = `Sort by ${label}, sorted ${direction}`;
105
+ const directionLabel = direction === 'ascending' ? t('@astryx.table.sort.direction.ascending') : t('@astryx.table.sort.direction.descending');
104
106
  if (rank != null && total > 1) {
105
- ariaLabel += `, priority ${rank} of ${total}`;
107
+ return t('@astryx.table.sort.sortedByWithPriority', {
108
+ label,
109
+ direction: directionLabel,
110
+ rank,
111
+ total
112
+ });
106
113
  }
107
- return ariaLabel;
114
+ return t('@astryx.table.sort.sortedBy', {
115
+ label,
116
+ direction: directionLabel
117
+ });
108
118
  }
109
119
  function getNextDirection(current, allowUnsortedState) {
110
120
  if (current == null) {
@@ -126,6 +136,7 @@ function SortHeaderButton({
126
136
  children,
127
137
  configRef
128
138
  }) {
139
+ const t = useTranslator();
129
140
  const config = configRef.current;
130
141
  const sortKey = resolveSortKey(column) ?? '';
131
142
  const entryIndex = config.sort.findIndex(e => e.sortKey === sortKey);
@@ -134,7 +145,7 @@ function SortHeaderButton({
134
145
  const isMultiSort = config.isMultiSortEnabled === true && config.sort.length > 1;
135
146
  const rank = isMultiSort && entryIndex >= 0 ? entryIndex + 1 : null;
136
147
  const iconName = direction === 'ascending' ? 'arrowUp' : direction === 'descending' ? 'arrowDown' : 'arrowsUpDown';
137
- const ariaLabel = buildAriaLabel(column, direction, rank, config.sort.length);
148
+ const ariaLabel = buildAriaLabel(t, column, direction, rank, config.sort.length);
138
149
  const handleClick = e => {
139
150
  const cfg = configRef.current;
140
151
  const isShift = e.shiftKey && cfg.isMultiSortEnabled;
@@ -1 +1 @@
1
- {"version":3,"file":"TreeListItem.d.ts","sourceRoot":"","sources":["../../src/TreeList/TreeListItem.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;GAUG;AAEH,OAAO,EAAiB,KAAK,SAAS,EAAC,MAAM,OAAO,CAAC;AAcrD,OAAO,KAAK,EAAC,eAAe,EAAC,MAAM,iBAAiB,CAAC;AAqNrD,MAAM,WAAW,yBAAyB;IACxC,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,KAAK,CAAC,SAAS,CAAC;IACvB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC/B,UAAU,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC7B,OAAO,CAAC,EAAE,CAAC,CAAC,EAAE,KAAK,CAAC,UAAU,KAAK,IAAI,CAAC;IACxC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,WAAW,EAAE,OAAO,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,OAAO,CAAC;IAChB,eAAe,EAAE,aAAa,CAAC,OAAO,CAAC,CAAC;IACxC,UAAU,EAAE,OAAO,CAAC;IACpB,QAAQ,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IAChC,OAAO,EAAE,eAAe,CAAC;IACzB,uEAAuE;IACvE,gBAAgB,CAAC,EAAE,SAAS,CAAC;IAC7B,wEAAwE;IACxE,QAAQ,EAAE,MAAM,CAAC;IACjB,uDAAuD;IACvD,OAAO,EAAE,MAAM,CAAC;IAChB;;;;OAIG;IACH,UAAU,EAAE,OAAO,CAAC;CACrB;AAMD,wBAAgB,YAAY,CAAC,EAC3B,EAAE,EACF,KAAK,EACL,WAAW,EACX,YAAY,EACZ,UAAU,EACV,OAAO,EACP,IAAI,EACJ,MAAM,EACN,UAAkB,EAClB,UAAkB,EAClB,WAAW,EACX,WAAW,EACX,MAAM,EACN,eAAe,EACf,UAAU,EACV,QAAQ,EACR,OAAO,EACP,gBAAgB,EAChB,QAAQ,EACR,OAAO,EACP,UAAU,GACX,EAAE,yBAAyB,+BA+L3B;yBArNe,YAAY"}
1
+ {"version":3,"file":"TreeListItem.d.ts","sourceRoot":"","sources":["../../src/TreeList/TreeListItem.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;GAUG;AAEH,OAAO,EAAiB,KAAK,SAAS,EAAC,MAAM,OAAO,CAAC;AAcrD,OAAO,KAAK,EAAC,eAAe,EAAC,MAAM,iBAAiB,CAAC;AA8NrD,MAAM,WAAW,yBAAyB;IACxC,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,KAAK,CAAC,SAAS,CAAC;IACvB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC/B,UAAU,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC7B,OAAO,CAAC,EAAE,CAAC,CAAC,EAAE,KAAK,CAAC,UAAU,KAAK,IAAI,CAAC;IACxC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,WAAW,EAAE,OAAO,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,OAAO,CAAC;IAChB,eAAe,EAAE,aAAa,CAAC,OAAO,CAAC,CAAC;IACxC,UAAU,EAAE,OAAO,CAAC;IACpB,QAAQ,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IAChC,OAAO,EAAE,eAAe,CAAC;IACzB,uEAAuE;IACvE,gBAAgB,CAAC,EAAE,SAAS,CAAC;IAC7B,wEAAwE;IACxE,QAAQ,EAAE,MAAM,CAAC;IACjB,uDAAuD;IACvD,OAAO,EAAE,MAAM,CAAC;IAChB;;;;OAIG;IACH,UAAU,EAAE,OAAO,CAAC;CACrB;AAMD,wBAAgB,YAAY,CAAC,EAC3B,EAAE,EACF,KAAK,EACL,WAAW,EACX,YAAY,EACZ,UAAU,EACV,OAAO,EACP,IAAI,EACJ,MAAM,EACN,UAAkB,EAClB,UAAkB,EAClB,WAAW,EACX,WAAW,EACX,MAAM,EACN,eAAe,EACf,UAAU,EACV,QAAQ,EACR,OAAO,EACP,gBAAgB,EAChB,QAAQ,EACR,OAAO,EACP,UAAU,GACX,EAAE,yBAAyB,+BA+L3B;yBArNe,YAAY"}
@@ -21,8 +21,6 @@ import { getIcon } from "../Icon/globalIconRegistry.js";
21
21
  import { mergeProps } from "../utils/index.js";
22
22
  import { useLinkComponent } from "../Link/useLinkComponent.js";
23
23
  import { TreeListBranches } from "./TreeListBranches.js";
24
- import "./treeListItem.markers.stylex.js";
25
- import { treeItemScope } from "./treeListItem.markers.stylex.js";
26
24
  import { themeProps } from "../utils/themeProps.js";
27
25
  import { useTranslator } from "../i18n/index.js";
28
26
 
@@ -31,15 +29,6 @@ import { useTranslator } from "../i18n/index.js";
31
29
  // =============================================================================
32
30
  import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
33
31
  const styles = {
34
- wrapper: {
35
- kH6xsr: "x3ct3a4",
36
- kogj98: "x1ghz6dp",
37
- kmVPX3: "x1717udv",
38
- kVAEAm: "x1n2onr6",
39
- kzqmXN: "xh8yej3",
40
- kI3sdo: "x1a2a7pz",
41
- $$css: true
42
- },
43
32
  contentWrapper: {
44
33
  kaIpWk: "xh6dtrn",
45
34
  k1xSpc: "x78zum5",
@@ -62,8 +51,8 @@ const styles = {
62
51
  $$css: true
63
52
  },
64
53
  focusVisibleOutline: {
65
- kI3sdo: "x1a2a7pz xr21g96 x1irc7jg",
66
- kInvED: "x1wfwxd8 xs4y3kv xdjuwb3",
54
+ kI3sdo: "x11h0toi x1irc7jg",
55
+ kInvED: "x1g710d4 xdjuwb3",
67
56
  $$css: true
68
57
  },
69
58
  disabled: {
@@ -299,7 +288,9 @@ export function TreeListItem({
299
288
  "data-tree-id": id,
300
289
  "data-tree-level": nestedLevel + 1,
301
290
  "data-tree-disabled": isDisabled || undefined,
302
- ...stylex.props(styles.wrapper, treeItemScope),
291
+ ...{
292
+ className: "x3ct3a4 x1ghz6dp x1717udv x1n2onr6 xh8yej3 x1a2a7pz x1hb5tod xtoutpx x1f8er9e x1aefuf3"
293
+ },
303
294
  children: [/*#__PURE__*/_jsx("div", {
304
295
  ...{
305
296
  className: "x12gdq22"
package/dist/astryx.css CHANGED
@@ -75,6 +75,8 @@
75
75
  .x9icjy1{--_segmented-control-radius:var(--radius-element)}
76
76
  .xficto1{--_tab-indicator-bottom:calc(-1 * (var(--spacing-1) + var(--border-width)))}
77
77
  .xbrl7fg{--_tab-indicator-bottom:var(--x---_tab-indicator-bottom)}
78
+ .x1f8er9e{--_tree-focus-outline-offset:0}
79
+ .x1hb5tod{--_tree-focus-outline:none}
78
80
  .xnvcwyz{--astryx-section-padding:var(--spacing-0-5)}
79
81
  .xvdw317{--astryx-section-padding:var(--spacing-0)}
80
82
  .x1rj2uvf{--astryx-section-padding:var(--spacing-1-5)}
@@ -252,6 +254,8 @@
252
254
  .x1t5kicu{--layout-padding-outer-y:var(--spacing-9)}
253
255
  .xnpej1e{--radius-element:var(--radius-full)}
254
256
  .xkce8z9{--separator-display:flex}
257
+ .x1aefuf3:focus-visible{--_tree-focus-outline-offset:2px}
258
+ .xtoutpx:focus-visible{--_tree-focus-outline:2px solid var(--color-accent)}
255
259
  .x11woleg:focus-visible{--indicator-color:var(--color-accent)}
256
260
  .x1ibt0lz:first-child{--separator-display:none}
257
261
  .x1rht92:nth-child(even){--table-row-overlay:var(--color-background-muted)}
@@ -367,6 +371,7 @@
367
371
  .xhrcg97:not(#\#):not(#\#){margin-inline:var(--spacing-1)}
368
372
  .xvlecxo:not(#\#):not(#\#){margin-inline:var(--x-marginInline)}
369
373
  .x1a2a7pz:not(#\#):not(#\#){outline:none}
374
+ .x11h0toi:not(#\#):not(#\#){outline:var(--_tree-focus-outline,none)}
370
375
  .xysyzu8:not(#\#):not(#\#){overflow:auto}
371
376
  .x7giv3:not(#\#):not(#\#){overflow:clip}
372
377
  .xb3r6kr:not(#\#):not(#\#){overflow:hidden}
@@ -417,7 +422,6 @@
417
422
  .xq2gx43:not(#\#):not(#\#){transition:none}
418
423
  .x1ey1afo:not(#\#):not(#\#){transition:opacity var(--duration-fast)}
419
424
  .x1ob6yzd:not(#\#):not(#\#){transition:transform var(--duration-fast) var(--ease-standard)}
420
- .xr21g96.xr21g96:where(.x1g2q90y:focus-visible *):not(#\#):not(#\#){outline:2px solid var(--color-accent)}
421
425
  .x6q1khz:focus-within:not(#\#):not(#\#){border-color:var(--color-accent)}
422
426
  .xk2sxw7:focus-within:not(#\#):not(#\#){border-color:var(--color-error)}
423
427
  .xyq33ac:focus-within:not(#\#):not(#\#){border-color:var(--color-success)}
@@ -852,6 +856,7 @@
852
856
  .x1wfwxd8:not(#\#):not(#\#):not(#\#){outline-offset:0}
853
857
  .x1y3gkto:not(#\#):not(#\#):not(#\#){outline-offset:1px}
854
858
  .x1hl8ikr:not(#\#):not(#\#):not(#\#){outline-offset:2px}
859
+ .x1g710d4:not(#\#):not(#\#):not(#\#){outline-offset:var(--_tree-focus-outline-offset,0)}
855
860
  .x9y5y3v:not(#\#):not(#\#):not(#\#){overflow-clip-margin:1px}
856
861
  .x1mzt3pk:not(#\#):not(#\#):not(#\#){overflow-wrap:break-word}
857
862
  .x1h4wwuj:not(#\#):not(#\#):not(#\#){overflow-wrap:normal}
@@ -1040,7 +1045,6 @@
1040
1045
  .x6cuj84:not(#\#):not(#\#):not(#\#){z-index:500}
1041
1046
  .x1q2oy4v:not(#\#):not(#\#):not(#\#){z-index:9999}
1042
1047
  .x1v2claj.x1v2claj:where(.x84s7jz:focus-within *):not(#\#):not(#\#):not(#\#){opacity:1}
1043
- .xs4y3kv.xs4y3kv:where(.x1g2q90y:focus-visible *):not(#\#):not(#\#):not(#\#){outline-offset:2px}
1044
1048
  .x3730vf.x3730vf:where(.x84s7jz:focus-within *):not(#\#):not(#\#):not(#\#){pointer-events:auto}
1045
1049
  .xuqivmr.xuqivmr:where(.x84s7jz:focus-within *):not(#\#):not(#\#):not(#\#){transform:translateY(0)}
1046
1050
  .x7v6acp.x7v6acp:where(.x84s7jz:focus-within *):not(#\#):not(#\#):not(#\#){visibility:visible}