@astryxdesign/core 0.1.4-canary.37c19d3 → 0.1.4-canary.39ffd21

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 (226) hide show
  1. package/dist/Banner/Banner.d.ts.map +1 -1
  2. package/dist/Banner/Banner.js +1 -8
  3. package/dist/Calendar/Calendar.d.ts.map +1 -1
  4. package/dist/Calendar/Calendar.js +11 -31
  5. package/dist/Calendar/styles.d.ts +2 -2
  6. package/dist/Calendar/styles.d.ts.map +1 -1
  7. package/dist/Calendar/styles.js +2 -2
  8. package/dist/Carousel/Carousel.d.ts.map +1 -1
  9. package/dist/Carousel/Carousel.js +0 -1
  10. package/dist/Chat/ChatToolCalls.d.ts.map +1 -1
  11. package/dist/Chat/ChatToolCalls.js +1 -8
  12. package/dist/CheckboxInput/CheckboxInput.d.ts +1 -1
  13. package/dist/CheckboxInput/CheckboxInput.d.ts.map +1 -1
  14. package/dist/CheckboxInput/CheckboxInput.js +1 -3
  15. package/dist/ClickableCard/ClickableCard.d.ts.map +1 -1
  16. package/dist/ClickableCard/ClickableCard.js +3 -26
  17. package/dist/CodeBlock/CodeBlock.d.ts +1 -10
  18. package/dist/CodeBlock/CodeBlock.d.ts.map +1 -1
  19. package/dist/CodeBlock/CodeBlock.js +5 -23
  20. package/dist/Collapsible/Collapsible.d.ts +3 -9
  21. package/dist/Collapsible/Collapsible.d.ts.map +1 -1
  22. package/dist/Collapsible/Collapsible.js +13 -101
  23. package/dist/Collapsible/CollapsibleGroup.d.ts +7 -39
  24. package/dist/Collapsible/CollapsibleGroup.d.ts.map +1 -1
  25. package/dist/Collapsible/CollapsibleGroup.js +9 -70
  26. package/dist/Collapsible/CollapsibleGroupContext.d.ts +0 -31
  27. package/dist/Collapsible/CollapsibleGroupContext.d.ts.map +1 -1
  28. package/dist/Collapsible/CollapsibleGroupContext.js +3 -33
  29. package/dist/Collapsible/index.d.ts +0 -1
  30. package/dist/Collapsible/index.d.ts.map +1 -1
  31. package/dist/ContextMenu/ContextMenu.d.ts.map +1 -1
  32. package/dist/ContextMenu/ContextMenu.js +0 -2
  33. package/dist/DateTimeInput/DateTimeInput.d.ts.map +1 -1
  34. package/dist/DateTimeInput/DateTimeInput.js +0 -2
  35. package/dist/Grid/Grid.d.ts +3 -4
  36. package/dist/Grid/Grid.d.ts.map +1 -1
  37. package/dist/Grid/Grid.js +9 -26
  38. package/dist/Icon/Icon.d.ts.map +1 -1
  39. package/dist/Icon/Icon.js +1 -5
  40. package/dist/Lightbox/Lightbox.d.ts.map +1 -1
  41. package/dist/Lightbox/Lightbox.js +2 -26
  42. package/dist/NumberInput/NumberInput.d.ts.map +1 -1
  43. package/dist/NumberInput/NumberInput.js +16 -32
  44. package/dist/Pagination/Pagination.d.ts.map +1 -1
  45. package/dist/Pagination/Pagination.js +36 -87
  46. package/dist/PowerSearch/PowerSearch.d.ts.map +1 -1
  47. package/dist/PowerSearch/PowerSearch.js +21 -39
  48. package/dist/ProgressBar/ProgressBar.d.ts.map +1 -1
  49. package/dist/ProgressBar/ProgressBar.js +1 -2
  50. package/dist/Resizable/ResizeHandle.d.ts.map +1 -1
  51. package/dist/Resizable/ResizeHandle.js +2 -10
  52. package/dist/SideNav/SideNav.d.ts.map +1 -1
  53. package/dist/SideNav/SideNav.js +2 -6
  54. package/dist/TabList/TabMenu.d.ts.map +1 -1
  55. package/dist/TabList/TabMenu.js +7 -34
  56. package/dist/Table/BaseTable.d.ts.map +1 -1
  57. package/dist/Table/BaseTable.js +2 -12
  58. package/dist/Table/plugins/columnResize/useTableColumnResize.d.ts.map +1 -1
  59. package/dist/Table/plugins/columnResize/useTableColumnResize.js +2 -5
  60. package/dist/Table/plugins/pagination/paginateData.d.ts.map +1 -1
  61. package/dist/Table/plugins/pagination/paginateData.js +1 -5
  62. package/dist/Table/plugins/selection/useTableSelectionState.d.ts.map +1 -1
  63. package/dist/Table/plugins/selection/useTableSelectionState.js +1 -11
  64. package/dist/Table/plugins/sortable/useTableSortableState.d.ts.map +1 -1
  65. package/dist/Table/plugins/sortable/useTableSortableState.js +4 -8
  66. package/dist/Thumbnail/Thumbnail.d.ts +2 -3
  67. package/dist/Thumbnail/Thumbnail.d.ts.map +1 -1
  68. package/dist/Thumbnail/Thumbnail.js +0 -1
  69. package/dist/TimeInput/TimeInput.d.ts.map +1 -1
  70. package/dist/TimeInput/TimeInput.js +1 -6
  71. package/dist/Toast/Toast.d.ts.map +1 -1
  72. package/dist/Toast/Toast.js +3 -11
  73. package/dist/Toast/ToastViewport.d.ts.map +1 -1
  74. package/dist/Toast/ToastViewport.js +0 -12
  75. package/dist/Typeahead/BaseTypeahead.d.ts.map +1 -1
  76. package/dist/Typeahead/BaseTypeahead.js +2 -5
  77. package/dist/astryx.css +0 -7
  78. package/dist/astryx.umd.js +48 -48
  79. package/dist/astryx.umd.js.map +4 -4
  80. package/dist/hooks/focusableSelector.d.ts +1 -1
  81. package/dist/hooks/focusableSelector.d.ts.map +1 -1
  82. package/dist/hooks/focusableSelector.js +1 -1
  83. package/dist/hooks/useFocusTrap.d.ts +0 -3
  84. package/dist/hooks/useFocusTrap.d.ts.map +1 -1
  85. package/dist/hooks/useFocusTrap.js +1 -38
  86. package/dist/theme/defineTheme.d.ts +1 -1
  87. package/dist/theme/defineTheme.d.ts.map +1 -1
  88. package/dist/theme/expandColorScale.d.ts.map +1 -1
  89. package/dist/theme/expandColorScale.js +3 -10
  90. package/dist/theme/hct.d.ts +15 -0
  91. package/dist/theme/hct.d.ts.map +1 -1
  92. package/dist/theme/hct.js +9 -9
  93. package/dist/theme/tokens.d.ts +2 -10
  94. package/dist/theme/tokens.d.ts.map +1 -1
  95. package/dist/theme/tokens.js +4 -220
  96. package/dist/utils/index.d.ts +0 -2
  97. package/dist/utils/index.d.ts.map +1 -1
  98. package/dist/utils/index.js +1 -2
  99. package/dist/utils/timeParser.d.ts.map +1 -1
  100. package/dist/utils/timeParser.js +5 -8
  101. package/package.json +1 -1
  102. package/src/Avatar/Avatar.doc.mjs +0 -11
  103. package/src/Banner/Banner.doc.mjs +0 -8
  104. package/src/Banner/Banner.test.tsx +0 -38
  105. package/src/Banner/Banner.tsx +1 -8
  106. package/src/Calendar/Calendar.doc.mjs +1 -1
  107. package/src/Calendar/Calendar.test.tsx +4 -112
  108. package/src/Calendar/Calendar.tsx +5 -26
  109. package/src/Calendar/styles.ts +2 -12
  110. package/src/Carousel/Carousel.doc.mjs +12 -12
  111. package/src/Carousel/Carousel.test.tsx +0 -13
  112. package/src/Carousel/Carousel.tsx +0 -1
  113. package/src/Chat/Chat.doc.mjs +1 -1
  114. package/src/Chat/ChatToolCalls.test.tsx +0 -55
  115. package/src/Chat/ChatToolCalls.tsx +12 -10
  116. package/src/CheckboxInput/CheckboxInput.doc.mjs +3 -3
  117. package/src/CheckboxInput/CheckboxInput.test.tsx +4 -71
  118. package/src/CheckboxInput/CheckboxInput.tsx +0 -2
  119. package/src/Citation/Citation.doc.mjs +0 -5
  120. package/src/ClickableCard/ClickableCard.tsx +2 -45
  121. package/src/CodeBlock/CodeBlock.doc.mjs +2 -7
  122. package/src/CodeBlock/CodeBlock.test.tsx +3 -87
  123. package/src/CodeBlock/CodeBlock.tsx +3 -43
  124. package/src/Collapsible/Collapsible.doc.mjs +4 -8
  125. package/src/Collapsible/Collapsible.tsx +10 -86
  126. package/src/Collapsible/CollapsibleGroup.doc.mjs +3 -27
  127. package/src/Collapsible/CollapsibleGroup.test.tsx +0 -288
  128. package/src/Collapsible/CollapsibleGroup.tsx +9 -107
  129. package/src/Collapsible/CollapsibleGroupContext.tsx +2 -42
  130. package/src/Collapsible/index.ts +0 -4
  131. package/src/CommandPalette/CommandPaletteEmpty.doc.mjs +0 -5
  132. package/src/CommandPalette/CommandPaletteGroup.doc.mjs +0 -10
  133. package/src/CommandPalette/CommandPaletteInput.doc.mjs +0 -6
  134. package/src/CommandPalette/CommandPaletteItem.doc.mjs +0 -6
  135. package/src/CommandPalette/CommandPaletteList.doc.mjs +0 -9
  136. package/src/ContextMenu/ContextMenu.doc.mjs +0 -15
  137. package/src/ContextMenu/ContextMenu.test.tsx +0 -15
  138. package/src/ContextMenu/ContextMenu.tsx +0 -2
  139. package/src/ContextMenu/ContextMenuItem.doc.mjs +0 -6
  140. package/src/DateTimeInput/DateTimeInput.test.tsx +0 -70
  141. package/src/DateTimeInput/DateTimeInput.tsx +0 -2
  142. package/src/Dialog/DialogHeader.doc.mjs +0 -45
  143. package/src/DropdownMenu/DropdownMenu.doc.mjs +1 -1
  144. package/src/Field/FieldLabel.test.tsx +2 -2
  145. package/src/FormLayout/__snapshots__/FormLayout.test.tsx.snap +3 -0
  146. package/src/Grid/Grid.test.tsx +18 -43
  147. package/src/Grid/Grid.tsx +9 -26
  148. package/src/Icon/Icon.test.tsx +29 -41
  149. package/src/Icon/Icon.tsx +2 -6
  150. package/src/Layout/LayoutContent.doc.mjs +0 -12
  151. package/src/Layout/LayoutPanel.doc.mjs +0 -40
  152. package/src/Lightbox/Lightbox.doc.mjs +0 -5
  153. package/src/Lightbox/Lightbox.test.tsx +2 -123
  154. package/src/Lightbox/Lightbox.tsx +1 -29
  155. package/src/NavMenu/NavMenu.doc.mjs +0 -15
  156. package/src/NumberInput/NumberInput.test.tsx +3 -48
  157. package/src/NumberInput/NumberInput.tsx +15 -32
  158. package/src/Overlay/Overlay.doc.mjs +0 -6
  159. package/src/Pagination/Pagination.test.tsx +0 -143
  160. package/src/Pagination/Pagination.tsx +23 -75
  161. package/src/Popover/Popover.test.tsx +0 -65
  162. package/src/PowerSearch/PowerSearch.doc.mjs +2 -2
  163. package/src/PowerSearch/PowerSearch.test.tsx +1 -109
  164. package/src/PowerSearch/PowerSearch.tsx +16 -37
  165. package/src/ProgressBar/ProgressBar.test.tsx +0 -10
  166. package/src/ProgressBar/ProgressBar.tsx +1 -2
  167. package/src/Resizable/ResizeHandle.tsx +2 -10
  168. package/src/SegmentedControl/SegmentedControl.doc.mjs +1 -1
  169. package/src/SelectableCard/SelectableCard.doc.mjs +1 -1
  170. package/src/SideNav/SideNav.doc.mjs +1 -7
  171. package/src/SideNav/SideNav.test.tsx +0 -20
  172. package/src/SideNav/SideNav.tsx +2 -6
  173. package/src/TabList/TabList.test.tsx +1 -185
  174. package/src/TabList/TabMenu.tsx +9 -45
  175. package/src/Table/BaseTable.tsx +1 -11
  176. package/src/Table/Table.test.tsx +0 -51
  177. package/src/Table/plugins/columnResize/useTableColumnResize.test.tsx +0 -13
  178. package/src/Table/plugins/columnResize/useTableColumnResize.tsx +1 -3
  179. package/src/Table/plugins/pagination/paginateData.ts +1 -5
  180. package/src/Table/plugins/pagination/useTablePagination.test.tsx +0 -13
  181. package/src/Table/plugins/selection/useTableSelectionState.test.tsx +0 -23
  182. package/src/Table/plugins/selection/useTableSelectionState.tsx +6 -11
  183. package/src/Table/plugins/sortable/useTableSortableState.test.tsx +1 -35
  184. package/src/Table/plugins/sortable/useTableSortableState.tsx +4 -8
  185. package/src/TextArea/TextArea.test.tsx +3 -3
  186. package/src/TextInput/TextInput.test.tsx +3 -3
  187. package/src/Thumbnail/Thumbnail.test.tsx +2 -36
  188. package/src/Thumbnail/Thumbnail.tsx +2 -4
  189. package/src/TimeInput/TimeInput.test.tsx +0 -37
  190. package/src/TimeInput/TimeInput.tsx +1 -11
  191. package/src/Timestamp/Timestamp.doc.mjs +1 -1
  192. package/src/Toast/Toast.tsx +3 -11
  193. package/src/Toast/ToastViewport.test.tsx +0 -64
  194. package/src/Toast/ToastViewport.tsx +0 -12
  195. package/src/ToggleButton/ToggleButton.doc.mjs +0 -1
  196. package/src/Tokenizer/Tokenizer.doc.mjs +2 -2
  197. package/src/TopNav/TopNav.doc.mjs +1 -1
  198. package/src/TreeList/TreeList.doc.mjs +2 -2
  199. package/src/Typeahead/BaseTypeahead.doc.mjs +0 -19
  200. package/src/Typeahead/BaseTypeahead.tsx +2 -5
  201. package/src/Typeahead/Typeahead.doc.mjs +1 -1
  202. package/src/Typeahead/Typeahead.test.tsx +1 -45
  203. package/src/hooks/focusableSelector.ts +1 -1
  204. package/src/hooks/useFocusTrap.doc.mjs +2 -4
  205. package/src/hooks/useFocusTrap.test.tsx +1 -149
  206. package/src/hooks/useFocusTrap.ts +1 -50
  207. package/src/theme/SyntaxTheme.doc.mjs +4 -4
  208. package/src/theme/defineTheme.ts +13 -4
  209. package/src/theme/derivedVarRegistry.test.ts +2 -2
  210. package/src/theme/expandColorScale.test.ts +0 -29
  211. package/src/theme/expandColorScale.ts +6 -11
  212. package/src/theme/hct.ts +17 -9
  213. package/src/theme/tokens.test.ts +9 -182
  214. package/src/theme/tokens.ts +4 -239
  215. package/src/theme/useTheme.test.tsx +0 -20
  216. package/src/utils/index.ts +0 -3
  217. package/src/utils/timeParser.test.ts +0 -13
  218. package/src/utils/timeParser.ts +5 -8
  219. package/dist/utils/color.d.ts +0 -42
  220. package/dist/utils/color.d.ts.map +0 -1
  221. package/dist/utils/color.js +0 -150
  222. package/src/Resizable/ResizeHandle.test.tsx +0 -180
  223. package/src/__tests__/TestIcon.tsx +0 -26
  224. package/src/docPropReferences.test.ts +0 -178
  225. package/src/utils/color.test.ts +0 -133
  226. package/src/utils/color.ts +0 -148
@@ -167,59 +167,6 @@ describe('CheckboxInput', () => {
167
167
  expect(handleChange).not.toHaveBeenCalled();
168
168
  });
169
169
 
170
- it('forwards data-testid to the input', () => {
171
- render(
172
- <CheckboxInput
173
- label="Accept terms"
174
- value={false}
175
- onChange={() => {}}
176
- data-testid="accept-terms-checkbox"
177
- />,
178
- );
179
- expect(screen.getByTestId('accept-terms-checkbox')).toBe(
180
- screen.getByRole('checkbox'),
181
- );
182
- });
183
-
184
- it('forwards arbitrary data-* attributes to the input', () => {
185
- render(
186
- <CheckboxInput
187
- label="Accept terms"
188
- value={false}
189
- onChange={() => {}}
190
- data-tracking-id="checkbox-42"
191
- />,
192
- );
193
- expect(screen.getByRole('checkbox')).toHaveAttribute(
194
- 'data-tracking-id',
195
- 'checkbox-42',
196
- );
197
- });
198
-
199
- it('does not let rest props override checked, disabled, or type', () => {
200
- // Not part of CheckboxInputProps; spread (rather than named attributes)
201
- // to sidestep JSX excess-property checks the same way a real caller's
202
- // spread rest-props object would arrive untyped at runtime.
203
- const foreignAttrs: Record<string, unknown> = {
204
- checked: false,
205
- disabled: false,
206
- type: 'text',
207
- };
208
- render(
209
- <CheckboxInput
210
- {...foreignAttrs}
211
- label="Accept terms"
212
- value={true}
213
- onChange={() => {}}
214
- isDisabled
215
- />,
216
- );
217
- const checkbox = screen.getByRole('checkbox');
218
- expect(checkbox).toBeChecked();
219
- expect(checkbox).toBeDisabled();
220
- expect(checkbox).toHaveAttribute('type', 'checkbox');
221
- });
222
-
223
170
  it('forwards ref correctly', () => {
224
171
  const ref = vi.fn();
225
172
  render(
@@ -449,12 +396,7 @@ describe('CheckboxInput', () => {
449
396
  it('submits under htmlName when checked', () => {
450
397
  const {container} = render(
451
398
  <form>
452
- <CheckboxInput
453
- label="Terms"
454
- htmlName="terms"
455
- value={true}
456
- onChange={() => {}}
457
- />
399
+ <CheckboxInput label="Terms" htmlName="terms" value={true} onChange={() => {}} />
458
400
  </form>,
459
401
  );
460
402
  const data = new FormData(container.querySelector('form')!);
@@ -474,25 +416,16 @@ describe('CheckboxInput', () => {
474
416
  />
475
417
  </form>,
476
418
  );
477
- expect([
478
- ...new FormData(container.querySelector('form')!).keys(),
479
- ]).toEqual([]);
419
+ expect([...new FormData(container.querySelector('form')!).keys()]).toEqual([]);
480
420
  });
481
421
 
482
422
  it('submits nothing when unchecked', () => {
483
423
  const {container} = render(
484
424
  <form>
485
- <CheckboxInput
486
- label="Terms"
487
- htmlName="terms"
488
- value={false}
489
- onChange={() => {}}
490
- />
425
+ <CheckboxInput label="Terms" htmlName="terms" value={false} onChange={() => {}} />
491
426
  </form>,
492
427
  );
493
- expect([
494
- ...new FormData(container.querySelector('form')!).keys(),
495
- ]).toEqual([]);
428
+ expect([...new FormData(container.querySelector('form')!).keys()]).toEqual([]);
496
429
  });
497
430
  });
498
431
  });
@@ -395,7 +395,6 @@ export function CheckboxInput({
395
395
  className,
396
396
  style,
397
397
  ref,
398
- ...rest
399
398
  }: CheckboxInputProps) {
400
399
  const id = useId();
401
400
  const descriptionID = useId();
@@ -485,7 +484,6 @@ export function CheckboxInput({
485
484
  )}>
486
485
  <div {...stylex.props(styles.checkboxWrapper, wrapperSizeStyles[size])}>
487
486
  <input
488
- {...rest}
489
487
  ref={mergeRefs(
490
488
  ref,
491
489
  indeterminateRef,
@@ -88,11 +88,6 @@ export const docs = {
88
88
  default: "'label'",
89
89
  },
90
90
  ],
91
- theming: {
92
- targets: [
93
- {className: 'astryx-citation', visualProps: ['variant']},
94
- ],
95
- },
96
91
  };
97
92
 
98
93
  /** @type {import('../docs-types').TranslationDoc} */
@@ -31,12 +31,7 @@
31
31
  import {type ReactNode, type MouseEvent, useRef, type Ref} from 'react';
32
32
  import * as stylex from '@stylexjs/stylex';
33
33
  import type {StyleXStyles} from '@stylexjs/stylex';
34
- import {
35
- borderVars,
36
- colorVars,
37
- durationVars,
38
- easeVars,
39
- } from '../theme/tokens.stylex';
34
+ import {colorVars, durationVars, easeVars} from '../theme/tokens.stylex';
40
35
  import type {SizeValue, SpacingStep} from '../utils/types';
41
36
  import {mergeProps, mergeRefs} from '../utils';
42
37
  import {Card} from '../Card/Card';
@@ -71,6 +66,7 @@ const styles = stylex.create({
71
66
  content: '""',
72
67
  position: 'absolute',
73
68
  inset: 0,
69
+ borderRadius: 'inherit',
74
70
  pointerEvents: 'none',
75
71
  transitionProperty: 'background-color',
76
72
  transitionDuration: durationVars['--duration-fast'],
@@ -88,38 +84,6 @@ const styles = stylex.create({
88
84
  },
89
85
  },
90
86
  },
91
- // Borderless variants (everything except `default`): drop the transparent
92
- // 1px border Card applies. The overlay is inset to the padding box — inside
93
- // that border — so a transparent border strip stays untinted on hover and
94
- // reads as a faint ring. With no border, the overlay covers the full box
95
- // edge-to-edge and the ring disappears.
96
- borderless: {
97
- borderWidth: 0,
98
- },
99
- // Bordered variant (`default`): draw the 1px border *within* the padding by
100
- // subtracting the border width from every side. Total inset (border +
101
- // padding) then equals the borderless variants' padding, so content geometry
102
- // and outer dimensions stay identical across all variants. The border rests
103
- // at the subtle token and emphasizes on hover.
104
- bordered: {
105
- borderColor: colorVars['--color-border'],
106
- paddingInlineStart: `calc(var(--container-padding-inline-start) - ${borderVars['--border-width']})`,
107
- paddingInlineEnd: `calc(var(--container-padding-inline-end) - ${borderVars['--border-width']})`,
108
- paddingBlockStart: `calc(var(--container-padding-block-start) - ${borderVars['--border-width']})`,
109
- paddingBlockEnd: `calc(var(--container-padding-block-end) - ${borderVars['--border-width']})`,
110
- transitionProperty: 'border-color',
111
- transitionDuration: durationVars['--duration-fast'],
112
- transitionTimingFunction: easeVars['--ease-standard'],
113
- },
114
- // Emphasize the bordered variant's border on hover. Guarded by
115
- // @media (hover: hover) so touch devices don't get a stuck hover state.
116
- borderedHoverOnPointer: {
117
- '@media (hover: hover)': {
118
- ':hover': {
119
- borderColor: colorVars['--color-border-emphasized'],
120
- },
121
- },
122
- },
123
87
  disabled: {
124
88
  cursor: 'not-allowed',
125
89
  opacity: 0.5,
@@ -284,11 +248,6 @@ export function ClickableCard({
284
248
 
285
249
  const isLink = href != null;
286
250
 
287
- // Only the `default` variant has a visible border. Card draws a transparent
288
- // 1px border on every other variant purely to avoid layout jitter; we drop
289
- // it here so the hover overlay covers the full box with no untinted ring.
290
- const hasBorder = variant === 'default';
291
-
292
251
  return (
293
252
  <Card
294
253
  ref={mergeRefs(ref, containerRef)}
@@ -305,10 +264,8 @@ export function ClickableCard({
305
264
  [
306
265
  styles.interactive,
307
266
  styles.focusWithin,
308
- hasBorder ? styles.bordered : styles.borderless,
309
267
  !isDisabled && styles.overlay,
310
268
  !isDisabled && styles.hoverOnPointer,
311
- !isDisabled && hasBorder && styles.borderedHoverOnPointer,
312
269
  isDisabled && styles.disabled,
313
270
  xstyleProp,
314
271
  ] as unknown as StyleXStyles
@@ -90,11 +90,6 @@ export const docs = {
90
90
  type: '(code: string, language: string) => Array<{type: string; start: number; end: number}>',
91
91
  description: 'Custom tokenizer override for unsupported languages.',
92
92
  },
93
- {
94
- name: 'syntaxTheme',
95
- type: 'SyntaxThemeDefinition',
96
- description: 'Per-instance syntax theme override. Shorthand for wrapping the block in <SyntaxTheme theme={...}>. Accepts a preset from @astryxdesign/core/theme/syntax or a theme created with defineSyntaxTheme(). Defaults to the nearest SyntaxTheme ancestor or the theme-level syntax colors.',
97
- },
98
93
  {
99
94
  name: 'isCollapsible',
100
95
  type: 'boolean',
@@ -140,8 +135,8 @@ export const docs = {
140
135
  },
141
136
  theming: {
142
137
  targets: [
143
- {className: 'astryx-code', visualProps: ['color']},
144
- {className: 'astryx-codeblock', visualProps: ['size', 'language', 'container']},
138
+ {className: 'astryx-code'},
139
+ {className: 'astryx-codeblock', visualProps: ['size', 'language']},
145
140
  ],
146
141
  },
147
142
  usage: {
@@ -3,21 +3,15 @@
3
3
  /**
4
4
  * @file CodeBlock.test.tsx
5
5
  * @input Uses vitest, @testing-library/react, CodeBlock component
6
- * @output Unit tests for CodeBlock (copy button, collapse, scroll region a11y, syntaxTheme)
6
+ * @output Unit tests for CodeBlock (copy button, collapse, scroll region a11y)
7
7
  * @position Testing; validates CodeBlock implementation
8
8
  *
9
9
  * SYNC: When CodeBlock.tsx changes, update tests to match new behavior
10
10
  */
11
11
 
12
- import {describe, it, expect, vi, beforeEach, afterEach} from 'vitest';
13
- import {render, screen, fireEvent, waitFor} from '@testing-library/react';
12
+ import {describe, it, expect, vi, beforeEach} from 'vitest';
13
+ import {render, screen, fireEvent} from '@testing-library/react';
14
14
  import {CodeBlock} from './CodeBlock';
15
- import {__resetLiveRegionsForTest} from '../hooks/useAnnounce';
16
- import {dracula} from '../theme/syntax';
17
-
18
- function politeRegion(): HTMLElement | null {
19
- return document.querySelector('[data-astryx-live-region="polite"]');
20
- }
21
15
 
22
16
  // A code sample long enough to exceed the default collapsible threshold (10).
23
17
  const LONG_CODE = Array.from(
@@ -33,10 +27,6 @@ describe('CodeBlock', () => {
33
27
  });
34
28
  });
35
29
 
36
- afterEach(() => {
37
- __resetLiveRegionsForTest();
38
- });
39
-
40
30
  it('renders the code', () => {
41
31
  render(<CodeBlock code="const x = 1;" language="javascript" />);
42
32
  expect(screen.getByText(/const/)).toBeInTheDocument();
@@ -63,15 +53,6 @@ describe('CodeBlock', () => {
63
53
  expect(navigator.clipboard.writeText).toHaveBeenCalledWith('const x = 1;');
64
54
  });
65
55
 
66
- it('announces "Copied" to a polite live region after copying', async () => {
67
- render(<CodeBlock code="const x = 1;" language="javascript" />);
68
- const copyButton = screen.getByRole('button', {name: 'Copy code'});
69
- fireEvent.click(copyButton);
70
- await waitFor(() => {
71
- expect(politeRegion()).toHaveTextContent('Copied');
72
- });
73
- });
74
-
75
56
  it('does NOT collapse the block when the copy button is clicked', () => {
76
57
  render(
77
58
  <CodeBlock
@@ -131,69 +112,4 @@ describe('CodeBlock', () => {
131
112
  fireEvent.click(header);
132
113
  expect(header).toHaveAttribute('aria-expanded', 'false');
133
114
  });
134
-
135
- it('links the collapsible header to its code region via aria-controls', () => {
136
- render(
137
- <CodeBlock
138
- code={LONG_CODE}
139
- language="javascript"
140
- title="example"
141
- isCollapsible
142
- />,
143
- );
144
- const header = screen
145
- .getAllByRole('button')
146
- .find(el => el.hasAttribute('aria-expanded'))!;
147
- const controlsId = header.getAttribute('aria-controls');
148
- // aria-controls must be present and point at the real code region.
149
- expect(controlsId).toBeTruthy();
150
- const region = document.getElementById(controlsId as string);
151
- expect(region).not.toBeNull();
152
- // The region contains the scrollable code body (role="group").
153
- expect(region).toContainElement(screen.getByRole('group'));
154
- });
155
-
156
- it('keeps aria-controls resolvable when collapsed (region stays mounted)', () => {
157
- render(
158
- <CodeBlock
159
- code={LONG_CODE}
160
- language="javascript"
161
- title="example"
162
- isCollapsible
163
- />,
164
- );
165
- const header = screen
166
- .getAllByRole('button')
167
- .find(el => el.hasAttribute('aria-expanded'))!;
168
- fireEvent.click(header);
169
- expect(header).toHaveAttribute('aria-expanded', 'false');
170
- // The code region uses a CSS grid animation to collapse, so it stays in
171
- // the DOM — aria-controls stays a valid, resolvable reference (unlike a
172
- // conditionally-mounted region, which would need a conditional attribute).
173
- const controlsId = header.getAttribute('aria-controls');
174
- expect(controlsId).toBeTruthy();
175
- expect(document.getElementById(controlsId as string)).not.toBeNull();
176
- });
177
-
178
- it('applies a per-instance syntax theme via the syntaxTheme prop', () => {
179
- const {container} = render(
180
- <CodeBlock
181
- code="const x = 1;"
182
- language="javascript"
183
- syntaxTheme={dracula}
184
- />,
185
- );
186
- const wrapper = container.querySelector('[data-astryx-syntax-theme]');
187
- expect(wrapper).not.toBeNull();
188
- expect(wrapper).toHaveAttribute('data-astryx-syntax-theme', 'dracula');
189
- expect(wrapper!.querySelector('pre')).not.toBeNull();
190
- });
191
-
192
- it('renders no syntax theme wrapper when syntaxTheme is not set', () => {
193
- const {container} = render(
194
- <CodeBlock code="const x = 1;" language="javascript" />,
195
- );
196
- expect(container.querySelector('[data-astryx-syntax-theme]')).toBeNull();
197
- expect(container.firstElementChild?.tagName).toBe('PRE');
198
- });
199
115
  });
@@ -3,7 +3,7 @@
3
3
  'use client';
4
4
  /**
5
5
  * @file CodeBlock.tsx
6
- * @input Uses React, StyleX, theme tokens, CSS Custom Highlight API, SyntaxTheme provider
6
+ * @input Uses React, StyleX, theme tokens, CSS Custom Highlight API
7
7
  * @output Exports CodeBlock component and CodeBlockProps
8
8
  * @position Core implementation; read-only syntax-highlighted code display
9
9
  */
@@ -11,7 +11,6 @@
11
11
  import {
12
12
  useInsertionEffect,
13
13
  useEffect,
14
- useId,
15
14
  useRef,
16
15
  useState,
17
16
  useCallback,
@@ -33,7 +32,6 @@ import {
33
32
  easeVars,
34
33
  } from '../theme/tokens.stylex';
35
34
  import {mergeProps} from '../utils';
36
- import {useAnnounce} from '../hooks/useAnnounce';
37
35
  import {Icon} from '../Icon';
38
36
  import {
39
37
  tokenize,
@@ -45,7 +43,6 @@ import type {SyntaxToken, TokenLine} from './tokenizer';
45
43
  import {ensureHighlightStyles} from './highlightStyles';
46
44
  import {applyHighlightRangesChunked} from './highlightRanges';
47
45
  import {themeProps} from '../utils/themeProps';
48
- import {SyntaxTheme, type SyntaxThemeDefinition} from '../theme/syntax';
49
46
 
50
47
  // ---------------------------------------------------------------------------
51
48
  // Styles
@@ -176,17 +173,6 @@ const styles = stylex.create({
176
173
  headerCollapsible: {
177
174
  cursor: 'pointer',
178
175
  userSelect: 'none',
179
- // Restore a keyboard-only focus ring with the standard token/offset so this
180
- // disclosure control matches the rest of the system (Collapsible, TabMenu);
181
- // otherwise it falls back to the inconsistent UA default outline.
182
- outline: {
183
- default: null,
184
- ':focus-visible': `2px solid ${colorVars['--color-accent']}`,
185
- },
186
- outlineOffset: {
187
- default: '0',
188
- ':focus-visible': '2px',
189
- },
190
176
  },
191
177
  gutter: {
192
178
  flexShrink: 0,
@@ -396,14 +382,6 @@ export interface CodeBlockProps extends BaseProps<HTMLPreElement> {
396
382
  language: string,
397
383
  ) => {type: string; start: number; end: number}[];
398
384
  highlightMode?: 'auto' | 'ranges' | 'spans';
399
- /**
400
- * Per-instance syntax theme override. Shorthand for wrapping this block in
401
- * `<SyntaxTheme theme={...}>` — accepts a preset from
402
- * `@astryxdesign/core/theme/syntax` or a theme created with
403
- * `defineSyntaxTheme()`. Without it, the block uses the theme-level syntax
404
- * colors from the nearest SyntaxTheme ancestor or `defineTheme({ syntax })`.
405
- */
406
- syntaxTheme?: SyntaxThemeDefinition;
407
385
  }
408
386
 
409
387
  // ---------------------------------------------------------------------------
@@ -655,7 +633,6 @@ export function CodeBlock({
655
633
  container = 'card',
656
634
  tokenizer: customTokenizer,
657
635
  highlightMode = 'auto',
658
- syntaxTheme,
659
636
  xstyle,
660
637
  className,
661
638
  style,
@@ -663,7 +640,6 @@ export function CodeBlock({
663
640
  ...props
664
641
  }: CodeBlockProps) {
665
642
  const [copied, setCopied] = useState(false);
666
- const announce = useAnnounce();
667
643
 
668
644
  const useSpans =
669
645
  highlightMode === 'spans' ||
@@ -689,15 +665,12 @@ export function CodeBlock({
689
665
  try {
690
666
  await navigator.clipboard.writeText(code);
691
667
  setCopied(true);
692
- // Swapping the button's aria-label alone isn't reliably announced by
693
- // screen readers, so confirm the copy via a polite live region.
694
- announce('Copied');
695
668
  onCopy?.();
696
669
  setTimeout(() => setCopied(false), 2000);
697
670
  } catch {
698
671
  // Clipboard failures leave the copied state unchanged.
699
672
  }
700
- }, [code, onCopy, announce]);
673
+ }, [code, onCopy]);
701
674
 
702
675
  const sizeStyle = size === 'sm' ? styles.sizeSm : styles.sizeMd;
703
676
  const gutterSizeStyle = size === 'sm' ? styles.gutterSm : styles.gutterMd;
@@ -707,11 +680,6 @@ export function CodeBlock({
707
680
 
708
681
  const canCollapse = isCollapsible && lines.length >= collapsibleThreshold;
709
682
  const [isCollapsed, setIsCollapsed] = useState(false);
710
- // Links the collapsible header to the code region it shows/hides so assistive
711
- // tech can move from the button to its controlled content (disclosure
712
- // pattern). The region stays mounted when collapsed (CSS grid animation), so
713
- // this is always a resolvable reference — aria-controls can be unconditional.
714
- const regionId = useId();
715
683
 
716
684
  const scrollContainerRef = useRef<HTMLDivElement>(null);
717
685
  const scrollStyle: CSSProperties | undefined = maxHeight
@@ -749,7 +717,6 @@ export function CodeBlock({
749
717
  role={canCollapse ? 'button' : undefined}
750
718
  tabIndex={canCollapse ? 0 : undefined}
751
719
  aria-expanded={canCollapse ? !isCollapsed : undefined}
752
- aria-controls={canCollapse ? regionId : undefined}
753
720
  onClick={canCollapse ? () => setIsCollapsed(prev => !prev) : undefined}
754
721
  onKeyDown={
755
722
  canCollapse
@@ -835,7 +802,7 @@ export function CodeBlock({
835
802
  </div>
836
803
  );
837
804
 
838
- const block = (
805
+ return (
839
806
  <pre
840
807
  ref={ref}
841
808
  {...mergeProps(
@@ -853,7 +820,6 @@ export function CodeBlock({
853
820
  {headerEl}
854
821
  {canCollapse ? (
855
822
  <div
856
- id={regionId}
857
823
  {...stylex.props(
858
824
  styles.collapseGrid,
859
825
  isCollapsed && styles.collapseGridCollapsed,
@@ -866,12 +832,6 @@ export function CodeBlock({
866
832
  {!showHeader && copyButtonEl}
867
833
  </pre>
868
834
  );
869
-
870
- return syntaxTheme ? (
871
- <SyntaxTheme theme={syntaxTheme}>{block}</SyntaxTheme>
872
- ) : (
873
- block
874
- );
875
835
  }
876
836
 
877
837
  CodeBlock.displayName = 'CodeBlock';
@@ -16,8 +16,7 @@ export const docs = {
16
16
  },
17
17
  theming: {
18
18
  targets: [
19
- {className: 'astryx-collapsible', visualProps: ['dividers', 'density']},
20
- {className: 'astryx-collapsible-group', visualProps: ['dividers', 'density']},
19
+ {className: 'astryx-collapsible'},
21
20
  ],
22
21
  },
23
22
  description: 'A primitive that makes any content collapsible: a trigger button toggles visibility of the content area, managing its own state or deferring to a parent CollapsibleGroup.',
@@ -70,8 +69,7 @@ export const docs = {
70
69
  usage: {
71
70
  description: 'Collapsible hides and reveals content behind a trigger button. Use it in settings panels, FAQ pages, or detail views to keep the page scannable while letting users drill into sections they care about. Wrap multiple collapsibles in CollapsibleGroup for accordion behavior. For custom collapsible components, use the `useCollapsible` hook directly (`astryx hook useCollapsible`).',
72
71
  bestPractices: [
73
- { guidance: true, description: 'Use dividers="between" on CollapsibleGroup for FAQ-style lists: built-in row hairlines with themed border tokens, no hand-rolled borders.' },
74
- { guidance: true, description: 'Wrap each Collapsible in an Card for visual separation in accordion layouts, or use CollapsibleGroup dividers for flat lists; don\'t combine both.' },
72
+ { guidance: true, description: 'Wrap each Collapsible in an Card for visual separation in accordion layouts.' },
75
73
  { guidance: true, description: 'Use CollapsibleGroup with type="single" for settings or FAQ pages where only one section should be open at a time.' },
76
74
  { guidance: true, description: 'Use type="multiple" when users need to compare content across sections, like feature lists or pricing tiers.' },
77
75
  { guidance: true, description: 'Start sections open (defaultIsOpen) when the content is likely needed on first view; don\'t make users click to see essential info.' },
@@ -92,8 +90,7 @@ export const docsZh = {
92
90
  usage: {
93
91
  description: 'Collapsible hides and reveals content behind a trigger button. Use it in settings panels, FAQ pages, or detail views to keep the page scannable while letting users drill into sections they care about. Wrap multiple collapsibles in CollapsibleGroup for accordion behavior.',
94
92
  bestPractices: [
95
- { guidance: true, description: 'Use dividers="between" on CollapsibleGroup for FAQ-style lists: built-in row hairlines with themed border tokens, no hand-rolled borders.' },
96
- { guidance: true, description: 'Wrap each Collapsible in an Card for visual separation in accordion layouts, or use CollapsibleGroup dividers for flat lists; don\'t combine both.' },
93
+ { guidance: true, description: 'Wrap each Collapsible in an Card for visual separation in accordion layouts.' },
97
94
  { guidance: true, description: 'Use CollapsibleGroup with type="single" for settings or FAQ pages where only one section should be open at a time.' },
98
95
  { guidance: true, description: 'Use type="multiple" when users need to compare content across sections, like feature lists or pricing tiers.' },
99
96
  { guidance: true, description: 'Start sections open (defaultIsOpen) when the content is likely needed on first view; don\'t make users click to see essential info.' },
@@ -110,8 +107,7 @@ export const docsDense = {
110
107
  usage: {
111
108
  description: 'Collapsible hides and reveals content behind a trigger button. Use in settings, FAQs, or detail views. Wrap in CollapsibleGroup for accordion behavior.',
112
109
  bestPractices: [
113
- { guidance: true, description: 'Use dividers="between" on CollapsibleGroup for FAQ-style lists: built-in row hairlines, no hand-rolled borders.' },
114
- { guidance: true, description: 'Wrap each Collapsible in an Card for visual separation, or use CollapsibleGroup dividers for flat lists; not both.' },
110
+ { guidance: true, description: 'Wrap each Collapsible in an Card for visual separation in accordion layouts.' },
115
111
  { guidance: true, description: 'Use CollapsibleGroup with type="single" for settings or FAQ pages where only one section should be open at a time.' },
116
112
  { guidance: true, description: 'Use type="multiple" when users need to compare across sections.' },
117
113
  { guidance: true, description: 'Start sections open (defaultIsOpen) when content is needed on first view.' },