@astryxdesign/core 0.1.7-canary.04cd8f7 → 0.1.7-canary.1055df2

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/README.md +6 -4
  2. package/dist/Avatar/Avatar.d.ts +10 -5
  3. package/dist/Avatar/Avatar.d.ts.map +1 -1
  4. package/dist/Avatar/Avatar.js +12 -8
  5. package/dist/Avatar/AvatarSizeContext.d.ts +1 -1
  6. package/dist/Avatar/AvatarSizeContext.js +1 -1
  7. package/dist/Avatar/AvatarStatusDot.d.ts +2 -2
  8. package/dist/Avatar/AvatarStatusDot.js +2 -2
  9. package/dist/AvatarGroup/AvatarGroup.d.ts +2 -2
  10. package/dist/AvatarGroup/AvatarGroup.d.ts.map +1 -1
  11. package/dist/AvatarGroup/AvatarGroup.js +2 -2
  12. package/dist/AvatarGroup/AvatarGroupOverflow.d.ts +1 -1
  13. package/dist/AvatarGroup/AvatarGroupOverflow.d.ts.map +1 -1
  14. package/dist/AvatarGroup/AvatarGroupOverflow.js +16 -14
  15. package/dist/Carousel/Carousel.d.ts +3 -2
  16. package/dist/Carousel/Carousel.d.ts.map +1 -1
  17. package/dist/Carousel/Carousel.js +32 -2
  18. package/dist/Chat/ChatMessage.d.ts +1 -1
  19. package/dist/Chat/ChatMessage.d.ts.map +1 -1
  20. package/dist/Chat/ChatMessage.js +1 -1
  21. package/dist/Icon/Icon.d.ts +26 -1
  22. package/dist/Icon/Icon.d.ts.map +1 -1
  23. package/dist/Icon/Icon.js +34 -7
  24. package/dist/Outline/Outline.d.ts +69 -3
  25. package/dist/Outline/Outline.d.ts.map +1 -1
  26. package/dist/Outline/Outline.js +129 -26
  27. package/dist/Outline/useScrollSpy.d.ts +27 -7
  28. package/dist/Outline/useScrollSpy.d.ts.map +1 -1
  29. package/dist/Outline/useScrollSpy.js +202 -70
  30. package/dist/Table/Table.d.ts +1 -1
  31. package/dist/Table/Table.js +1 -1
  32. package/dist/Table/plugins/rowExpansion/useTableRowExpansion.d.ts.map +1 -1
  33. package/dist/Table/plugins/rowExpansion/useTableRowExpansion.js +24 -2
  34. package/dist/Table/plugins/sortable/useTableSortable.d.ts.map +1 -1
  35. package/dist/Table/plugins/sortable/useTableSortable.js +18 -7
  36. package/dist/TreeList/TreeListItem.d.ts.map +1 -1
  37. package/dist/TreeList/TreeListItem.js +5 -14
  38. package/dist/astryx.css +6 -2
  39. package/dist/astryx.umd.js +50 -50
  40. package/dist/astryx.umd.js.map +4 -4
  41. package/docs.mjs +32 -461
  42. package/locales/en.json +192 -172
  43. package/locales/pseudo.json +15 -0
  44. package/package.json +3 -1
  45. package/scripts/postinstall.mjs +93 -0
  46. package/src/Avatar/Avatar.doc.mjs +6 -6
  47. package/src/Avatar/Avatar.tsx +16 -11
  48. package/src/Avatar/AvatarSizeContext.ts +1 -1
  49. package/src/Avatar/AvatarStatusDot.tsx +2 -2
  50. package/src/AvatarGroup/AvatarGroup.doc.mjs +1 -1
  51. package/src/AvatarGroup/AvatarGroup.test.tsx +17 -3
  52. package/src/AvatarGroup/AvatarGroup.tsx +3 -3
  53. package/src/AvatarGroup/AvatarGroupOverflow.doc.mjs +4 -4
  54. package/src/AvatarGroup/AvatarGroupOverflow.tsx +21 -5
  55. package/src/Carousel/Carousel.doc.mjs +1 -0
  56. package/src/Carousel/Carousel.test.tsx +96 -1
  57. package/src/Carousel/Carousel.tsx +29 -2
  58. package/src/Chat/Chat.doc.mjs +1 -1
  59. package/src/Chat/ChatMessage.tsx +4 -2
  60. package/src/Icon/Icon.doc.mjs +12 -0
  61. package/src/Icon/Icon.test.tsx +96 -0
  62. package/src/Icon/Icon.tsx +61 -6
  63. package/src/Item/Item.doc.mjs +1 -1
  64. package/src/Outline/Outline.doc.mjs +123 -3
  65. package/src/Outline/Outline.test.tsx +735 -0
  66. package/src/Outline/Outline.tsx +184 -33
  67. package/src/Outline/useScrollSpy.ts +248 -72
  68. package/src/Table/Table.tsx +1 -1
  69. package/src/Table/plugins/rowExpansion/useTableRowExpansion.test.tsx +90 -1
  70. package/src/Table/plugins/rowExpansion/useTableRowExpansion.tsx +37 -5
  71. package/src/Table/plugins/sortable/useTableSortable.test.tsx +95 -9
  72. package/src/Table/plugins/sortable/useTableSortable.tsx +23 -7
  73. package/src/TreeList/TreeList.test.tsx +32 -1
  74. package/src/TreeList/TreeListItem.tsx +19 -10
  75. package/src/docs-script.test.mjs +18 -13
  76. package/src/postinstall.test.mjs +71 -0
  77. package/dist/TreeList/treeListItem.markers.stylex.d.ts +0 -16
  78. package/dist/TreeList/treeListItem.markers.stylex.d.ts.map +0 -1
  79. package/dist/TreeList/treeListItem.markers.stylex.js +0 -22
  80. package/src/TreeList/treeListItem.markers.stylex.ts +0 -20
package/README.md CHANGED
@@ -13,14 +13,16 @@ Core UI components, theme system, and utilities for the Astryx design system. Fo
13
13
 
14
14
  ## Component Docs
15
15
 
16
- Look up any component's full API (props, types, best practices, and theming):
16
+ Look up any component's full API (props, variants, examples, best practices, and theming) via the Astryx CLI:
17
17
 
18
18
  ```bash
19
- node node_modules/@astryxdesign/core/docs.mjs Button # full docs for a component
20
- node node_modules/@astryxdesign/core/docs.mjs --list # list all components
21
- node node_modules/@astryxdesign/core/docs.mjs --list --brief # brief summaries
19
+ npx @astryxdesign/cli init # one-time: writes the component guide into AGENTS.md / CLAUDE.md
20
+ npx @astryxdesign/cli component Button # full docs for a component
21
+ npx @astryxdesign/cli component --list # list all components
22
22
  ```
23
23
 
24
+ > Use the scoped `@astryxdesign/cli` to run without installing; bare `npx astryx` only resolves once the CLI is a dependency.
25
+
24
26
  ## Page Layouts
25
27
 
26
28
  Building a full page? Start with a template rather than composing from scratch.
@@ -13,9 +13,13 @@
13
13
  import { type ReactNode } from 'react';
14
14
  import type { BaseProps } from '../BaseProps';
15
15
  /**
16
- * Named size options
16
+ * Named size options.
17
+ *
18
+ * Avatar uses the same abbreviated scale as Icon (`xsm`/`sm`/`md`/`lg`/`xl`),
19
+ * but the values are larger because avatars align with media rather than
20
+ * glyphs. The tiers match EPS's avatar sizes.
17
21
  */
18
- type AvatarNamedSize = 'tiny' | 'xsmall' | 'small' | 'medium' | 'large';
22
+ type AvatarNamedSize = 'xsm' | 'sm' | 'md' | 'lg' | 'xl';
19
23
  /**
20
24
  * Numeric size options (in pixels)
21
25
  */
@@ -52,8 +56,9 @@ export interface AvatarProps extends BaseProps<HTMLDivElement> {
52
56
  */
53
57
  name?: string;
54
58
  /**
55
- * The size of the avatar.
56
- * @default 'small'
59
+ * The size of the avatar. A named size (`xsm` 20px, `sm` 24px, `md` 36px,
60
+ * `lg` 48px, `xl` 128px) or a specific pixel value.
61
+ * @default 'md'
57
62
  */
58
63
  size?: AvatarSize;
59
64
  /**
@@ -75,7 +80,7 @@ export interface AvatarProps extends BaseProps<HTMLDivElement> {
75
80
  * @example
76
81
  * ```
77
82
  * <Avatar src="/user.jpg" name="John Doe" />
78
- * <Avatar name="Jane Smith" size="large" />
83
+ * <Avatar name="Jane Smith" size="xl" />
79
84
  * <Avatar src="/user.jpg" status={<OnlineIndicator />} />
80
85
  * ```
81
86
  */
@@ -1 +1 @@
1
- {"version":3,"file":"Avatar.d.ts","sourceRoot":"","sources":["../../src/Avatar/Avatar.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAoB,KAAK,SAAS,EAAC,MAAM,OAAO,CAAC;AACxD,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AAsC5C;;GAEG;AACH,KAAK,eAAe,GAAG,MAAM,GAAG,QAAQ,GAAG,OAAO,GAAG,QAAQ,GAAG,OAAO,CAAC;AAExE;;GAEG;AACH,KAAK,iBAAiB,GACpB,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC;AAEzE;;GAEG;AACH,MAAM,MAAM,UAAU,GAAG,eAAe,GAAG,iBAAiB,CAAC;AAE7D;;GAEG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,UAAU,GAAG,MAAM,CAgBpD;AAqFD,MAAM,WAAW,WAAY,SAAQ,SAAS,CAAC,cAAc,CAAC;IAC5D,wCAAwC;IACxC,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;IAChC;;;OAGG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;;OAEG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;OAIG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;OAGG;IACH,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB;;OAEG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;;;OAGG;IACH,MAAM,CAAC,EAAE,SAAS,CAAC;CACpB;AAsCD;;;;;;;;;;;;GAYG;AACH,wBAAgB,MAAM,CAAC,EACrB,GAAG,EACH,aAAa,EAAE,MAAM,EACrB,WAAW,EACX,IAAI,EACJ,IAAc,EACd,GAAG,EACH,MAAM,EACN,MAAM,EACN,SAAS,EACT,KAAK,EACL,GAAG,EACH,GAAG,KAAK,EACT,EAAE,WAAW,+BAwFb;yBArGe,MAAM"}
1
+ {"version":3,"file":"Avatar.d.ts","sourceRoot":"","sources":["../../src/Avatar/Avatar.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAoB,KAAK,SAAS,EAAC,MAAM,OAAO,CAAC;AACxD,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AAsC5C;;;;;;GAMG;AACH,KAAK,eAAe,GAAG,KAAK,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;AAEzD;;GAEG;AACH,KAAK,iBAAiB,GACpB,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC;AAEzE;;GAEG;AACH,MAAM,MAAM,UAAU,GAAG,eAAe,GAAG,iBAAiB,CAAC;AAE7D;;GAEG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,UAAU,GAAG,MAAM,CAgBpD;AAqFD,MAAM,WAAW,WAAY,SAAQ,SAAS,CAAC,cAAc,CAAC;IAC5D,wCAAwC;IACxC,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;IAChC;;;OAGG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;;OAEG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;OAIG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;;OAIG;IACH,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB;;OAEG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;;;OAGG;IACH,MAAM,CAAC,EAAE,SAAS,CAAC;CACpB;AAsCD;;;;;;;;;;;;GAYG;AACH,wBAAgB,MAAM,CAAC,EACrB,GAAG,EACH,aAAa,EAAE,MAAM,EACrB,WAAW,EACX,IAAI,EACJ,IAAW,EACX,GAAG,EACH,MAAM,EACN,MAAM,EACN,SAAS,EACT,KAAK,EACL,GAAG,EACH,GAAG,KAAK,EACT,EAAE,WAAW,+BAwFb;yBArGe,MAAM"}
@@ -50,7 +50,11 @@ const CIRCLE_EDGE_OFFSET_RATIO = (1 - 1 / Math.SQRT2) / 2;
50
50
  const INITIALS_FONT_SIZE_RATIO = 0.4;
51
51
 
52
52
  /**
53
- * Named size options
53
+ * Named size options.
54
+ *
55
+ * Avatar uses the same abbreviated scale as Icon (`xsm`/`sm`/`md`/`lg`/`xl`),
56
+ * but the values are larger because avatars align with media rather than
57
+ * glyphs. The tiers match EPS's avatar sizes.
54
58
  */
55
59
 
56
60
  /**
@@ -69,15 +73,15 @@ export function resolveSize(size) {
69
73
  return size;
70
74
  }
71
75
  switch (size) {
72
- case 'tiny':
76
+ case 'xsm':
73
77
  return 20;
74
- case 'xsmall':
78
+ case 'sm':
75
79
  return 24;
76
- case 'small':
80
+ case 'md':
77
81
  return 36;
78
- case 'medium':
82
+ case 'lg':
79
83
  return 48;
80
- case 'large':
84
+ case 'xl':
81
85
  return 128;
82
86
  }
83
87
  }
@@ -223,7 +227,7 @@ function DefaultIcon({
223
227
  * @example
224
228
  * ```
225
229
  * <Avatar src="/user.jpg" name="John Doe" />
226
- * <Avatar name="Jane Smith" size="large" />
230
+ * <Avatar name="Jane Smith" size="xl" />
227
231
  * <Avatar src="/user.jpg" status={<OnlineIndicator />} />
228
232
  * ```
229
233
  */
@@ -232,7 +236,7 @@ export function Avatar({
232
236
  'data-testid': testId,
233
237
  fallbackSrc,
234
238
  name,
235
- size = 'small',
239
+ size = 'md',
236
240
  src,
237
241
  status,
238
242
  xstyle,
@@ -2,7 +2,7 @@
2
2
  * Context that provides the resolved numeric avatar size (in pixels)
3
3
  * to child components like AvatarStatusDot.
4
4
  *
5
- * Default value of 36 matches the default 'small' avatar size.
5
+ * Default value of 36 matches the default 'md' avatar size.
6
6
  */
7
7
  export declare const AvatarSizeContext: import("react").Context<number>;
8
8
  //# sourceMappingURL=AvatarSizeContext.d.ts.map
@@ -17,7 +17,7 @@ import { createContext } from 'react';
17
17
  * Context that provides the resolved numeric avatar size (in pixels)
18
18
  * to child components like AvatarStatusDot.
19
19
  *
20
- * Default value of 36 matches the default 'small' avatar size.
20
+ * Default value of 36 matches the default 'md' avatar size.
21
21
  */
22
22
  export const AvatarSizeContext = /*#__PURE__*/createContext(36);
23
23
  AvatarSizeContext.displayName = 'AvatarSizeContext';
@@ -76,12 +76,12 @@ export interface AvatarStatusDotProps extends BaseProps<HTMLDivElement> {
76
76
  * ```
77
77
  * <Avatar
78
78
  * name="John Doe"
79
- * size="medium"
79
+ * size="lg"
80
80
  * status={<AvatarStatusDot variant="success" label="Online" />}
81
81
  * />
82
82
  * <Avatar
83
83
  * name="Jane Smith"
84
- * size="large"
84
+ * size="xl"
85
85
  * status={<AvatarStatusDot variant="success" label="Verified" icon={<CheckIcon />} />}
86
86
  * />
87
87
  * ```
@@ -148,12 +148,12 @@ const variantStyleMap = {
148
148
  * ```
149
149
  * <Avatar
150
150
  * name="John Doe"
151
- * size="medium"
151
+ * size="lg"
152
152
  * status={<AvatarStatusDot variant="success" label="Online" />}
153
153
  * />
154
154
  * <Avatar
155
155
  * name="Jane Smith"
156
- * size="large"
156
+ * size="xl"
157
157
  * status={<AvatarStatusDot variant="success" label="Verified" icon={<CheckIcon />} />}
158
158
  * />
159
159
  * ```
@@ -27,7 +27,7 @@ export interface AvatarGroupProps extends BaseProps<HTMLDivElement> {
27
27
  children: ReactNode;
28
28
  /**
29
29
  * Size applied to all avatars via context.
30
- * @default 'small'
30
+ * @default 'md'
31
31
  */
32
32
  size?: AvatarSize;
33
33
  /**
@@ -45,7 +45,7 @@ export interface AvatarGroupProps extends BaseProps<HTMLDivElement> {
45
45
  *
46
46
  * @example
47
47
  * ```
48
- * <AvatarGroup size="medium">
48
+ * <AvatarGroup size="lg">
49
49
  * {users.slice(0, 3).map(u => (
50
50
  * <Avatar key={u.id} src={u.src} name={u.name} />
51
51
  * ))}
@@ -1 +1 @@
1
- {"version":3,"file":"AvatarGroup.d.ts","sourceRoot":"","sources":["../../src/AvatarGroup/AvatarGroup.tsx"],"names":[],"mappings":"AAGA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EAAU,KAAK,SAAS,EAAC,MAAM,OAAO,CAAC;AAC9C,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AAC5C,OAAO,EAAc,KAAK,UAAU,EAAC,MAAM,WAAW,CAAC;AASvD,MAAM,WAAW,gBAAiB,SAAQ,SAAS,CAAC,cAAc,CAAC;IACjE,yCAAyC;IACzC,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;IAChC;;;OAGG;IACH,QAAQ,EAAE,SAAS,CAAC;IACpB;;;OAGG;IACH,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB;;OAEG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AASD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,WAAW,CAAC,EAC1B,QAAQ,EACR,IAAc,EACd,aAAa,EAAE,MAAM,EACrB,YAAY,EAAE,kBAAkB,EAChC,MAAM,EACN,SAAS,EACT,KAAK,EACL,GAAG,EACH,GAAG,KAAK,EACT,EAAE,gBAAgB,GAAG,SAAS,CA6B9B;yBAvCe,WAAW"}
1
+ {"version":3,"file":"AvatarGroup.d.ts","sourceRoot":"","sources":["../../src/AvatarGroup/AvatarGroup.tsx"],"names":[],"mappings":"AAGA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EAAU,KAAK,SAAS,EAAC,MAAM,OAAO,CAAC;AAC9C,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AAC5C,OAAO,EAAc,KAAK,UAAU,EAAC,MAAM,WAAW,CAAC;AASvD,MAAM,WAAW,gBAAiB,SAAQ,SAAS,CAAC,cAAc,CAAC;IACjE,yCAAyC;IACzC,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;IAChC;;;OAGG;IACH,QAAQ,EAAE,SAAS,CAAC;IACpB;;;OAGG;IACH,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB;;OAEG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AASD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,WAAW,CAAC,EAC1B,QAAQ,EACR,IAAW,EACX,aAAa,EAAE,MAAM,EACrB,YAAY,EAAE,kBAAkB,EAChC,MAAM,EACN,SAAS,EACT,KAAK,EACL,GAAG,EACH,GAAG,KAAK,EACT,EAAE,gBAAgB,GAAG,SAAS,CA6B9B;yBAvCe,WAAW"}
@@ -44,7 +44,7 @@ const styles = {
44
44
  *
45
45
  * @example
46
46
  * ```
47
- * <AvatarGroup size="medium">
47
+ * <AvatarGroup size="lg">
48
48
  * {users.slice(0, 3).map(u => (
49
49
  * <Avatar key={u.id} src={u.src} name={u.name} />
50
50
  * ))}
@@ -54,7 +54,7 @@ const styles = {
54
54
  */
55
55
  export function AvatarGroup({
56
56
  children,
57
- size = 'small',
57
+ size = 'md',
58
58
  'data-testid': testId,
59
59
  'aria-label': ariaLabelFromProps,
60
60
  xstyle,
@@ -33,7 +33,7 @@ export interface AvatarGroupOverflowProps extends Omit<BaseProps<HTMLElement>, '
33
33
  *
34
34
  * @example
35
35
  * ```
36
- * <AvatarGroup size="medium">
36
+ * <AvatarGroup size="lg">
37
37
  * {users.slice(0, 3).map(u => (
38
38
  * <Avatar key={u.id} src={u.src} name={u.name} />
39
39
  * ))}
@@ -1 +1 @@
1
- {"version":3,"file":"AvatarGroupOverflow.d.ts","sourceRoot":"","sources":["../../src/AvatarGroup/AvatarGroupOverflow.tsx"],"names":[],"mappings":"AAGA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,EAAC,KAAK,SAAS,EAAC,MAAM,OAAO,CAAC;AAU5C,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AAM5C,MAAM,WAAW,wBAAyB,SAAQ,IAAI,CACpD,SAAS,CAAC,WAAW,CAAC,EACtB,SAAS,CACV;IACC,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;IAC7B;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;IAEd;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IAErB;;OAEG;IACH,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB;AA6DD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,mBAAmB,CAAC,EAClC,GAAG,EACH,KAAK,EACL,OAAO,EACP,QAAQ,EACR,MAAM,EACN,SAAS,EACT,KAAK,EACL,GAAG,IAAI,EACR,EAAE,wBAAwB,GAAG,SAAS,CAwDtC;yBAjEe,mBAAmB"}
1
+ {"version":3,"file":"AvatarGroupOverflow.d.ts","sourceRoot":"","sources":["../../src/AvatarGroup/AvatarGroupOverflow.tsx"],"names":[],"mappings":"AAGA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,EAAC,KAAK,SAAS,EAAC,MAAM,OAAO,CAAC;AAW5C,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AAM5C,MAAM,WAAW,wBAAyB,SAAQ,IAAI,CACpD,SAAS,CAAC,WAAW,CAAC,EACtB,SAAS,CACV;IACC,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;IAC7B;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;IAEd;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IAErB;;OAEG;IACH,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB;AA4ED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,mBAAmB,CAAC,EAClC,GAAG,EACH,KAAK,EACL,OAAO,EACP,QAAQ,EACR,MAAM,EACN,SAAS,EACT,KAAK,EACL,GAAG,IAAI,EACR,EAAE,wBAAwB,GAAG,SAAS,CAwDtC;yBAjEe,mBAAmB"}
@@ -15,7 +15,7 @@
15
15
  import React from 'react';
16
16
  import * as stylex from '@stylexjs/stylex';
17
17
  import "../theme/tokens.stylex.js";
18
- import { colorVars, typographyVars, fontWeightVars, radiusVars } from "../theme/tokens.stylex.js";
18
+ import { colorVars, typographyVars, fontWeightVars, radiusVars, spacingVars } from "../theme/tokens.stylex.js";
19
19
  import { mergeProps } from "../utils/index.js";
20
20
  import { useAvatarGroup } from "./AvatarGroupContext.js";
21
21
  import { themeProps } from "../utils/themeProps.js";
@@ -37,13 +37,14 @@ const styles = {
37
37
  kMzoRj: "xdh2fpr",
38
38
  ksu8eU: "x1y0btm7",
39
39
  kVAM5u: "x1touxvs",
40
- kB7OPa: "x1afcbsf",
40
+ kB7OPa: "x9f619",
41
+ kg3NbH: "xf314gf",
41
42
  kKwaWg: "x14bno8m",
42
43
  $$css: true
43
44
  },
44
45
  button: {
45
46
  kkrTdU: "x1ypdohk",
46
- kmVPX3: "x1717udv",
47
+ k8WAf4: "xt970qd",
47
48
  kKwaWg: "x14bno8m xbfmc0r x1nocapi",
48
49
  kI3sdo: "x1a2a7pz x17nn4n9",
49
50
  kInvED: "x7s97pk",
@@ -55,26 +56,27 @@ const styles = {
55
56
  }
56
57
  };
57
58
  const _temp = {
58
- kGuDYH: "xdmh292",
59
+ k7Eaqz: "xkj4a21",
60
+ kZKoxP: "x16ye13r",
59
61
  "$$css": true
60
62
  };
61
63
  const _temp2 = {
64
+ kGuDYH: "xdmh292",
65
+ "$$css": true
66
+ };
67
+ const _temp3 = {
62
68
  "--_avatar-group-overlap": "xlz5hwt",
63
69
  "$$css": true
64
70
  };
65
71
  const dynamicStyles = {
66
- size: s => [{
67
- kzqmXN: s != null ? "x5lhr3w" : s,
68
- kZKoxP: s != null ? "x16ye13r" : s,
69
- $$css: true
70
- }, {
71
- "--x-width": (val => typeof val === "number" ? val + "px" : val != null ? val : undefined)(s),
72
- "--x-height": (val => typeof val === "number" ? val + "px" : val != null ? val : undefined)(s)
72
+ size: s => [_temp, {
73
+ "--x-minWidth": (val => typeof val === "number" ? val + "px" : val != null ? val : undefined)(s + BORDER_WIDTH * 2),
74
+ "--x-height": (val => typeof val === "number" ? val + "px" : val != null ? val : undefined)(s + BORDER_WIDTH * 2)
73
75
  }],
74
- fontSize: s => [_temp, {
76
+ fontSize: s => [_temp2, {
75
77
  "--x-fontSize": (val => typeof val === "number" ? val + "px" : val != null ? val : undefined)(s * OVERFLOW_FONT_RATIO)
76
78
  }],
77
- overlap: offset => [_temp2, {
79
+ overlap: offset => [_temp3, {
78
80
  "--x---_avatar-group-overlap": `${offset}px` != null ? `${offset}px` : undefined
79
81
  }]
80
82
  };
@@ -85,7 +87,7 @@ const dynamicStyles = {
85
87
  *
86
88
  * @example
87
89
  * ```
88
- * <AvatarGroup size="medium">
90
+ * <AvatarGroup size="lg">
89
91
  * {users.slice(0, 3).map(u => (
90
92
  * <Avatar key={u.id} src={u.src} name={u.name} />
91
93
  * ))}
@@ -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
  ...{
@@ -46,7 +46,7 @@ export interface ChatMessageProps extends BaseProps<HTMLElement> {
46
46
  *
47
47
  * @example
48
48
  * ```
49
- * <ChatMessage sender="assistant" name="Navi" avatar={<Avatar name="Navi" size="small" />}>
49
+ * <ChatMessage sender="assistant" name="Navi" avatar={<Avatar name="Navi" size="md" />}>
50
50
  * <ChatMessageBubble>Hello!</ChatMessageBubble>
51
51
  * <ChatMessageMetadata timestamp="2:30 PM" />
52
52
  * </ChatMessage>
@@ -1 +1 @@
1
- {"version":3,"file":"ChatMessage.d.ts","sourceRoot":"","sources":["../../src/Chat/ChatMessage.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EAAC,KAAK,SAAS,EAAiB,MAAM,OAAO,CAAC;AAQrD,OAAO,EAGL,KAAK,iBAAiB,EACtB,KAAK,WAAW,EACjB,MAAM,eAAe,CAAC;AAEvB,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AAI5C,MAAM,WAAW,gBAAiB,SAAQ,SAAS,CAAC,WAAW,CAAC;IAC9D,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;IAC7B,MAAM,EAAE,iBAAiB,CAAC;IAC1B,QAAQ,EAAE,SAAS,CAAC;IACpB,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB;;;;;OAKG;IACH,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,OAAO,CAAC,EAAE,WAAW,CAAC;CACvB;AAoFD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,WAAW,CAAC,EAC1B,MAAM,EACN,QAAQ,EACR,MAAM,EACN,IAAI,EACJ,QAAQ,EACR,OAAO,EAAE,WAAW,EACpB,MAAM,EACN,SAAS,EACT,KAAK,EAAE,SAAS,EAChB,aAAa,EAAE,MAAM,EACrB,GAAG,EACH,GAAG,IAAI,EACR,EAAE,gBAAgB,+BAyFlB;yBAtGe,WAAW"}
1
+ {"version":3,"file":"ChatMessage.d.ts","sourceRoot":"","sources":["../../src/Chat/ChatMessage.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EAAC,KAAK,SAAS,EAAiB,MAAM,OAAO,CAAC;AAQrD,OAAO,EAGL,KAAK,iBAAiB,EACtB,KAAK,WAAW,EACjB,MAAM,eAAe,CAAC;AAEvB,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AAI5C,MAAM,WAAW,gBAAiB,SAAQ,SAAS,CAAC,WAAW,CAAC;IAC9D,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;IAC7B,MAAM,EAAE,iBAAiB,CAAC;IAC1B,QAAQ,EAAE,SAAS,CAAC;IACpB,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB;;;;;OAKG;IACH,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,OAAO,CAAC,EAAE,WAAW,CAAC;CACvB;AAoFD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,WAAW,CAAC,EAC1B,MAAM,EACN,QAAQ,EACR,MAAM,EACN,IAAI,EACJ,QAAQ,EACR,OAAO,EAAE,WAAW,EACpB,MAAM,EACN,SAAS,EACT,KAAK,EAAE,SAAS,EAChB,aAAa,EAAE,MAAM,EACrB,GAAG,EACH,GAAG,IAAI,EACR,EAAE,gBAAgB,+BA2FlB;yBAxGe,WAAW"}
@@ -122,7 +122,7 @@ const styles = {
122
122
  *
123
123
  * @example
124
124
  * ```
125
- * <ChatMessage sender="assistant" name="Navi" avatar={<Avatar name="Navi" size="small" />}>
125
+ * <ChatMessage sender="assistant" name="Navi" avatar={<Avatar name="Navi" size="md" />}>
126
126
  * <ChatMessageBubble>Hello!</ChatMessageBubble>
127
127
  * <ChatMessageMetadata timestamp="2:30 PM" />
128
128
  * </ChatMessage>
@@ -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,
@@ -19,6 +19,50 @@ export interface OutlineProps extends BaseProps<HTMLElement> {
19
19
  * @default 'default'
20
20
  */
21
21
  density?: 'default' | 'compact';
22
+ /**
23
+ * Called when navigation to an item begins, before the scroll starts.
24
+ * Receives the item `id`. Pair with `onNavigateEnd` to drive an arrival
25
+ * effect (flash, ring, pulse) on the target heading.
26
+ */
27
+ onNavigateStart?: (id: string) => void;
28
+ /**
29
+ * Called once when navigation to an item resolves — when the smooth scroll
30
+ * settles, or immediately-ish when reduced motion turns it into a jump.
31
+ *
32
+ * Fires exactly once for every `onNavigateStart`, including when the user
33
+ * interrupts the scroll by scrolling manually, so a "navigating" state can
34
+ * never leak. It does not fire if the Outline unmounts mid-scroll.
35
+ */
36
+ onNavigateEnd?: (id: string) => void;
37
+ /**
38
+ * Height in px of a fixed header overlaying the top of the scroll root.
39
+ *
40
+ * Shifts both the activation line *and* the scroll landing by the same
41
+ * amount, so a heading activates exactly where navigating to it puts it —
42
+ * below the header rather than hidden underneath it.
43
+ *
44
+ * It composes with each heading's own `scroll-margin-top` (the header, then
45
+ * the breathing room below it) rather than replacing it. When nothing
46
+ * overlays the content, leave this at 0 and let `scroll-margin-top` do the
47
+ * work — the browser already honors it.
48
+ *
49
+ * @default 0
50
+ */
51
+ offset?: number;
52
+ /**
53
+ * Scroll container to track, instead of auto-detecting the nearest scrollable
54
+ * ancestor. Use this when the content scrolls inside a split pane, modal, or
55
+ * dashboard panel rather than the viewport.
56
+ */
57
+ scrollContainerRef?: React.RefObject<HTMLElement | null>;
58
+ /**
59
+ * Whether activating an item smooth-scrolls to it. Set to false to own the
60
+ * scrolling yourself (virtualized content, a router) — the Outline still
61
+ * updates the active item, the hash, and the navigate callbacks, but performs
62
+ * no scroll and suppresses the anchor's default jump.
63
+ * @default true
64
+ */
65
+ hasScrollOnClick?: boolean;
22
66
  /** Test ID for testing frameworks. */
23
67
  'data-testid'?: string;
24
68
  }
@@ -30,8 +74,15 @@ export interface OutlineProps extends BaseProps<HTMLElement> {
30
74
  * track that animates to the active item.
31
75
  *
32
76
  * When `activeId` is omitted, it tracks scroll position and marks the last
33
- * heading whose top has passed its activation line (its scroll-margin-top)
34
- * active — defaulting to the first item at the top and the last at the bottom.
77
+ * heading whose top has passed its activation line — which is exactly where
78
+ * navigating to that heading lands it: `offset` (a fixed header overlaying the
79
+ * scroll root) plus the heading's own `scroll-margin-top`. It defaults to the
80
+ * first item at the top and the last at the bottom.
81
+ *
82
+ * Keyboard: the list is a single tab stop (roving tabindex), seated on the
83
+ * active heading. Arrow keys move between headings, Home/End jump to the ends,
84
+ * and Enter/Space activate — so a long table of contents costs one Tab press,
85
+ * not one per heading.
35
86
  *
36
87
  * @example
37
88
  * ```
@@ -43,8 +94,23 @@ export interface OutlineProps extends BaseProps<HTMLElement> {
43
94
  * ]}
44
95
  * />
45
96
  * ```
97
+ *
98
+ * Scoped to a custom scroll container, under a fixed header:
99
+ *
100
+ * @example
101
+ * ```
102
+ * const scrollContainerRef = useRef<HTMLDivElement>(null);
103
+ *
104
+ * <div ref={scrollContainerRef} style={{overflowY: 'auto'}}>...</div>
105
+ * <Outline
106
+ * items={items}
107
+ * scrollContainerRef={scrollContainerRef}
108
+ * offset={64}
109
+ * onNavigateEnd={id => flashHeading(id)}
110
+ * />
111
+ * ```
46
112
  */
47
- export declare function Outline({ items, activeId, onActiveIdChange, label: labelFromProps, density, xstyle, className, style, ref, 'data-testid': testId, ...props }: OutlineProps): import("react").JSX.Element;
113
+ export declare function Outline({ items, activeId, onActiveIdChange, label: labelFromProps, density, onNavigateStart, onNavigateEnd, offset, scrollContainerRef, hasScrollOnClick, xstyle, className, style, ref, 'data-testid': testId, ...props }: OutlineProps): import("react").JSX.Element;
48
114
  export declare namespace Outline {
49
115
  var displayName: string;
50
116
  }
@@ -1 +1 @@
1
- {"version":3,"file":"Outline.d.ts","sourceRoot":"","sources":["../../src/Outline/Outline.tsx"],"names":[],"mappings":"AAmCA,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AAE5C,OAAO,KAAK,EAAC,WAAW,EAAC,MAAM,SAAS,CAAC;AAIzC,YAAY,EAAC,WAAW,EAAC,MAAM,SAAS,CAAC;AAEzC,MAAM,WAAW,YAAa,SAAQ,SAAS,CAAC,WAAW,CAAC;IAC1D,6CAA6C;IAC7C,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;IAE7B,+CAA+C;IAC/C,KAAK,EAAE,WAAW,EAAE,CAAC;IAErB,oFAAoF;IACpF,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB,oEAAoE;IACpE,gBAAgB,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IAExC,0EAA0E;IAC1E,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf;;;;;OAKG;IACH,OAAO,CAAC,EAAE,SAAS,GAAG,SAAS,CAAC;IAEhC,sCAAsC;IACtC,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAgJD;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,OAAO,CAAC,EACtB,KAAK,EACL,QAAQ,EACR,gBAAgB,EAChB,KAAK,EAAE,cAAc,EACrB,OAAmB,EACnB,MAAM,EACN,SAAS,EACT,KAAK,EACL,GAAG,EACH,aAAa,EAAE,MAAM,EACrB,GAAG,KAAK,EACT,EAAE,YAAY,+BA2Gd;yBAvHe,OAAO"}
1
+ {"version":3,"file":"Outline.d.ts","sourceRoot":"","sources":["../../src/Outline/Outline.tsx"],"names":[],"mappings":"AAwCA,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AAE5C,OAAO,KAAK,EAAC,WAAW,EAAC,MAAM,SAAS,CAAC;AAIzC,YAAY,EAAC,WAAW,EAAC,MAAM,SAAS,CAAC;AAEzC,MAAM,WAAW,YAAa,SAAQ,SAAS,CAAC,WAAW,CAAC;IAC1D,6CAA6C;IAC7C,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;IAE7B,+CAA+C;IAC/C,KAAK,EAAE,WAAW,EAAE,CAAC;IAErB,oFAAoF;IACpF,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB,oEAAoE;IACpE,gBAAgB,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IAExC,0EAA0E;IAC1E,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf;;;;;OAKG;IACH,OAAO,CAAC,EAAE,SAAS,GAAG,SAAS,CAAC;IAEhC;;;;OAIG;IACH,eAAe,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IAEvC;;;;;;;OAOG;IACH,aAAa,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IAErC;;;;;;;;;;;;;OAaG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB;;;;OAIG;IACH,kBAAkB,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC,WAAW,GAAG,IAAI,CAAC,CAAC;IAEzD;;;;;;OAMG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAE3B,sCAAsC;IACtC,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAgJD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2CG;AACH,wBAAgB,OAAO,CAAC,EACtB,KAAK,EACL,QAAQ,EACR,gBAAgB,EAChB,KAAK,EAAE,cAAc,EACrB,OAAmB,EACnB,eAAe,EACf,aAAa,EACb,MAAU,EACV,kBAAkB,EAClB,gBAAuB,EACvB,MAAM,EACN,SAAS,EACT,KAAK,EACL,GAAG,EACH,aAAa,EAAE,MAAM,EACrB,GAAG,KAAK,EACT,EAAE,YAAY,+BAiLd;yBAlMe,OAAO"}