@astryxdesign/core 0.1.1 → 0.1.2-canary.03536f1

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 (207) hide show
  1. package/CHANGELOG.md +105 -0
  2. package/README.md +119 -1
  3. package/dist/AvatarGroup/AvatarGroupOverflow.d.ts +1 -1
  4. package/dist/AvatarGroup/AvatarGroupOverflow.d.ts.map +1 -1
  5. package/dist/AvatarGroup/AvatarGroupOverflow.js +4 -1
  6. package/dist/Banner/Banner.d.ts +7 -0
  7. package/dist/Banner/Banner.d.ts.map +1 -1
  8. package/dist/Banner/Banner.js +9 -2
  9. package/dist/Button/Button.d.ts +12 -2
  10. package/dist/Button/Button.d.ts.map +1 -1
  11. package/dist/Button/Button.js +51 -13
  12. package/dist/Calendar/Calendar.d.ts +5 -4
  13. package/dist/Calendar/Calendar.d.ts.map +1 -1
  14. package/dist/Calendar/Calendar.js +6 -1
  15. package/dist/Calendar/index.d.ts +1 -1
  16. package/dist/Calendar/index.d.ts.map +1 -1
  17. package/dist/DateTimeInput/DateTimeInput.d.ts +7 -2
  18. package/dist/DateTimeInput/DateTimeInput.d.ts.map +1 -1
  19. package/dist/DateTimeInput/DateTimeInput.js +5 -4
  20. package/dist/EmptyState/EmptyState.d.ts.map +1 -1
  21. package/dist/EmptyState/EmptyState.js +7 -1
  22. package/dist/HoverCard/HoverCard.d.ts +2 -2
  23. package/dist/HoverCard/HoverCard.d.ts.map +1 -1
  24. package/dist/HoverCard/HoverCard.js +18 -6
  25. package/dist/HoverCard/useHoverCard.d.ts.map +1 -1
  26. package/dist/HoverCard/useHoverCard.js +7 -3
  27. package/dist/Kbd/Kbd.d.ts.map +1 -1
  28. package/dist/Kbd/Kbd.js +1 -1
  29. package/dist/Layer/anchorName.d.ts +20 -0
  30. package/dist/Layer/anchorName.d.ts.map +1 -0
  31. package/dist/Layer/anchorName.js +36 -0
  32. package/dist/Layer/useLayer.d.ts +19 -0
  33. package/dist/Layer/useLayer.d.ts.map +1 -1
  34. package/dist/Layer/useLayer.js +15 -6
  35. package/dist/Link/Link.d.ts +10 -1
  36. package/dist/Link/Link.d.ts.map +1 -1
  37. package/dist/Link/Link.js +7 -2
  38. package/dist/Link/LinkProvider.d.ts +1 -0
  39. package/dist/Link/LinkProvider.d.ts.map +1 -1
  40. package/dist/Link/LinkProvider.js +1 -0
  41. package/dist/Markdown/Markdown.d.ts.map +1 -1
  42. package/dist/Markdown/Markdown.js +13 -3
  43. package/dist/MobileNav/MobileNav.d.ts.map +1 -1
  44. package/dist/MobileNav/MobileNav.js +13 -0
  45. package/dist/Pagination/Pagination.d.ts.map +1 -1
  46. package/dist/Pagination/Pagination.js +31 -27
  47. package/dist/Slider/Slider.js +2 -2
  48. package/dist/Table/BaseTable.d.ts.map +1 -1
  49. package/dist/Table/BaseTable.js +38 -16
  50. package/dist/Table/Table.d.ts.map +1 -1
  51. package/dist/Table/Table.js +30 -7
  52. package/dist/Table/TableCell.d.ts +8 -1
  53. package/dist/Table/TableCell.d.ts.map +1 -1
  54. package/dist/Table/TableCell.js +10 -10
  55. package/dist/Table/TableHeaderCell.d.ts +8 -1
  56. package/dist/Table/TableHeaderCell.d.ts.map +1 -1
  57. package/dist/Table/TableHeaderCell.js +16 -16
  58. package/dist/Table/TableRow.d.ts +6 -1
  59. package/dist/Table/TableRow.d.ts.map +1 -1
  60. package/dist/Table/TableRow.js +15 -7
  61. package/dist/Table/index.d.ts +4 -1
  62. package/dist/Table/index.d.ts.map +1 -1
  63. package/dist/Table/index.js +2 -0
  64. package/dist/Table/plugins/sortable/useTableSortable.d.ts.map +1 -1
  65. package/dist/Table/plugins/sortable/useTableSortable.js +59 -3
  66. package/dist/Table/plugins/stickyColumns/index.d.ts +3 -0
  67. package/dist/Table/plugins/stickyColumns/index.d.ts.map +1 -0
  68. package/dist/Table/plugins/stickyColumns/index.js +3 -0
  69. package/dist/Table/plugins/stickyColumns/useTableStickyColumns.d.ts +25 -0
  70. package/dist/Table/plugins/stickyColumns/useTableStickyColumns.d.ts.map +1 -0
  71. package/dist/Table/plugins/stickyColumns/useTableStickyColumns.js +369 -0
  72. package/dist/Table/tableContextMenu.d.ts +33 -0
  73. package/dist/Table/tableContextMenu.d.ts.map +1 -0
  74. package/dist/Table/tableContextMenu.js +136 -0
  75. package/dist/Table/types.d.ts +161 -5
  76. package/dist/Table/types.d.ts.map +1 -1
  77. package/dist/Table/useBaseTablePlugins.d.ts.map +1 -1
  78. package/dist/Table/useBaseTablePlugins.js +1 -1
  79. package/dist/Text/text.stylex.d.ts +2 -2
  80. package/dist/Text/text.stylex.js +2 -2
  81. package/dist/Timestamp/Timestamp.d.ts +1 -1
  82. package/dist/Timestamp/Timestamp.d.ts.map +1 -1
  83. package/dist/Timestamp/Timestamp.js +28 -3
  84. package/dist/ToggleButton/ToggleButton.d.ts +7 -9
  85. package/dist/ToggleButton/ToggleButton.d.ts.map +1 -1
  86. package/dist/ToggleButton/ToggleButton.js +34 -57
  87. package/dist/Tokenizer/Tokenizer.d.ts.map +1 -1
  88. package/dist/Tokenizer/Tokenizer.js +1 -1
  89. package/dist/Tooltip/useTooltip.d.ts.map +1 -1
  90. package/dist/Tooltip/useTooltip.js +1 -0
  91. package/dist/astryx.css +30 -1
  92. package/dist/astryx.umd.js +147 -0
  93. package/dist/astryx.umd.js.map +7 -0
  94. package/dist/theme/generateThemeRules.js +1 -1
  95. package/dist/theme/syntax/SyntaxTheme.d.ts +1 -1
  96. package/dist/theme/syntax/SyntaxTheme.js +1 -1
  97. package/dist/theme/syntax/defineSyntaxTheme.d.ts.map +1 -1
  98. package/dist/theme/syntax/defineSyntaxTheme.js +2 -2
  99. package/dist/theme/syntax/presets.d.ts +1 -1
  100. package/dist/theme/syntax/presets.d.ts.map +1 -1
  101. package/dist/theme/syntax/presets.js +1 -1
  102. package/dist/theme/syntax/tokens.d.ts +1 -1
  103. package/dist/theme/syntax/tokens.js +1 -1
  104. package/dist/theme/types.d.ts +1 -1
  105. package/dist/utils/dateTypes.d.ts +12 -0
  106. package/dist/utils/dateTypes.d.ts.map +1 -1
  107. package/dist/utils/dateTypes.js +41 -1
  108. package/package.json +6 -2
  109. package/src/AvatarGroup/AvatarGroupOverflow.tsx +3 -0
  110. package/src/Banner/Banner.doc.mjs +8 -0
  111. package/src/Banner/Banner.test.tsx +16 -7
  112. package/src/Banner/Banner.tsx +9 -2
  113. package/src/Button/Button.doc.mjs +6 -0
  114. package/src/Button/Button.test.tsx +105 -11
  115. package/src/Button/Button.tsx +73 -5
  116. package/src/Calendar/Calendar.doc.mjs +4 -4
  117. package/src/Calendar/Calendar.test.tsx +21 -26
  118. package/src/Calendar/Calendar.tsx +21 -5
  119. package/src/Calendar/index.ts +1 -0
  120. package/src/Chat/ChatComposer.doc.mjs +3 -0
  121. package/src/Chat/ChatComposerDrawer.doc.mjs +12 -0
  122. package/src/CheckboxInput/CheckboxInput.doc.mjs +8 -0
  123. package/src/ClickableCard/ClickableCard.doc.mjs +15 -0
  124. package/src/DateTimeInput/DateTimeInput.doc.mjs +11 -3
  125. package/src/DateTimeInput/DateTimeInput.test.tsx +23 -3
  126. package/src/DateTimeInput/DateTimeInput.tsx +13 -10
  127. package/src/Dialog/Dialog.doc.mjs +2 -2
  128. package/src/EmptyState/EmptyState.test.tsx +4 -2
  129. package/src/EmptyState/EmptyState.tsx +6 -2
  130. package/src/HoverCard/HoverCard.doc.mjs +3 -0
  131. package/src/HoverCard/HoverCard.test.tsx +189 -2
  132. package/src/HoverCard/HoverCard.tsx +20 -16
  133. package/src/HoverCard/useHoverCard.tsx +13 -10
  134. package/src/Icon/Icon.doc.mjs +8 -0
  135. package/src/Kbd/Kbd.tsx +2 -9
  136. package/src/Layer/anchorName.test.ts +146 -0
  137. package/src/Layer/anchorName.ts +46 -0
  138. package/src/Layer/useLayer.doc.mjs +7 -2
  139. package/src/Layer/useLayer.tsx +33 -9
  140. package/src/Layout/Layout.doc.mjs +1 -1
  141. package/src/Lightbox/Lightbox.doc.mjs +0 -2
  142. package/src/Link/Link.test.tsx +20 -2
  143. package/src/Link/Link.tsx +12 -3
  144. package/src/Link/LinkProvider.tsx +1 -0
  145. package/src/List/List.doc.mjs +7 -0
  146. package/src/Markdown/Markdown.doc.mjs +2 -0
  147. package/src/Markdown/Markdown.test.tsx +17 -26
  148. package/src/Markdown/Markdown.tsx +16 -6
  149. package/src/MobileNav/MobileNav.doc.mjs +8 -8
  150. package/src/MobileNav/MobileNav.tsx +13 -0
  151. package/src/MobileNav/MobileNavReopen.test.tsx +118 -0
  152. package/src/OverflowList/OverflowList.doc.mjs +17 -0
  153. package/src/Pagination/Pagination.test.tsx +137 -13
  154. package/src/Pagination/Pagination.tsx +33 -28
  155. package/src/ProgressBar/ProgressBar.test.tsx +13 -3
  156. package/src/Resizable/Resizable.doc.mjs +1 -1
  157. package/src/Section/Section.doc.mjs +11 -0
  158. package/src/SelectableCard/SelectableCard.doc.mjs +15 -0
  159. package/src/Selector/Selector.doc.mjs +4 -0
  160. package/src/Skeleton/Skeleton.doc.mjs +11 -1
  161. package/src/Slider/Slider.doc.mjs +4 -0
  162. package/src/Slider/Slider.test.tsx +3 -16
  163. package/src/Slider/Slider.tsx +1 -1
  164. package/src/TabList/TabList.doc.mjs +6 -0
  165. package/src/Table/BaseTable.tsx +72 -41
  166. package/src/Table/Table.doc.mjs +12 -0
  167. package/src/Table/Table.test.tsx +29 -30
  168. package/src/Table/Table.tsx +22 -1
  169. package/src/Table/TableCell.tsx +25 -23
  170. package/src/Table/TableHeaderCell.tsx +28 -29
  171. package/src/Table/TableRow.tsx +37 -7
  172. package/src/Table/index.ts +6 -0
  173. package/src/Table/plugins/sortable/useTableSortable.test.tsx +91 -2
  174. package/src/Table/plugins/sortable/useTableSortable.tsx +53 -1
  175. package/src/Table/plugins/stickyColumns/index.ts +4 -0
  176. package/src/Table/plugins/stickyColumns/useTableStickyColumns.test.tsx +163 -0
  177. package/src/Table/plugins/stickyColumns/useTableStickyColumns.tsx +407 -0
  178. package/src/Table/tableContextMenu.test.tsx +157 -0
  179. package/src/Table/tableContextMenu.tsx +146 -0
  180. package/src/Table/types.ts +175 -4
  181. package/src/Table/useBaseTablePlugins.ts +1 -0
  182. package/src/Table/useTableColumnResize.doc.mjs +96 -0
  183. package/src/Table/useTableStickyColumns.doc.mjs +59 -0
  184. package/src/Text/Heading.doc.mjs +15 -2
  185. package/src/Text/Text.doc.mjs +7 -1
  186. package/src/Text/text.stylex.ts +2 -2
  187. package/src/Timestamp/Timestamp.doc.mjs +9 -0
  188. package/src/Timestamp/Timestamp.test.tsx +44 -18
  189. package/src/Timestamp/Timestamp.tsx +30 -10
  190. package/src/ToggleButton/ToggleButton.doc.mjs +9 -3
  191. package/src/ToggleButton/ToggleButton.test.tsx +39 -18
  192. package/src/ToggleButton/ToggleButton.tsx +46 -83
  193. package/src/Tokenizer/Tokenizer.tsx +4 -1
  194. package/src/Toolbar/Toolbar.doc.mjs +65 -5
  195. package/src/Tooltip/Tooltip.test.tsx +13 -0
  196. package/src/Tooltip/useTooltip.tsx +2 -3
  197. package/src/hooks/useImageMode.test.ts +133 -0
  198. package/src/theme/derivedVarRegistry.test.ts +4 -0
  199. package/src/theme/generateThemeRules.test.ts +7 -8
  200. package/src/theme/generateThemeRules.ts +1 -1
  201. package/src/theme/syntax/SyntaxTheme.tsx +1 -1
  202. package/src/theme/syntax/defineSyntaxTheme.ts +20 -11
  203. package/src/theme/syntax/presets.ts +5 -2
  204. package/src/theme/syntax/tokens.ts +1 -1
  205. package/src/theme/types.ts +1 -1
  206. package/src/utils/dateTypes.test.ts +40 -0
  207. package/src/utils/dateTypes.ts +40 -0
@@ -18,7 +18,7 @@
18
18
  * pageSize, pageSizeOptions, onPageSizeChange, variant, siblingCount, size, isDisabled,
19
19
  * label, data-testid, xstyle
20
20
  */
21
- import { useTransition } from 'react';
21
+ import { useOptimistic, useTransition } from 'react';
22
22
  import * as stylex from '@stylexjs/stylex';
23
23
  import "../theme/tokens.stylex.js";
24
24
  import { colorVars, fontWeightVars, sizeVars, spacingVars, durationVars, easeVars, typeScaleVars } from "../theme/tokens.stylex.js";
@@ -173,12 +173,16 @@ export function Pagination({
173
173
  style,
174
174
  ref
175
175
  }) {
176
- const [isPending, startTransition] = useTransition();
176
+ const [, startTransition] = useTransition();
177
+
178
+ // Track the page optimistically so rapid prev/next clicks advance from the
179
+ // in-flight target instead of stalling on the last committed page.
180
+ const [optimisticPage, setOptimisticPage] = useOptimistic(page);
177
181
 
178
182
  // Compute pagination state
179
183
  const computedTotalPages = totalPagesProp ?? (totalItems != null ? Math.ceil(totalItems / pageSize) : undefined);
180
- const hasPrevious = page > 1;
181
- const hasNext = computedTotalPages != null ? page < computedTotalPages : hasMore ?? false;
184
+ const hasPrevious = optimisticPage > 1;
185
+ const hasNext = computedTotalPages != null ? optimisticPage < computedTotalPages : hasMore ?? false;
182
186
 
183
187
  // Return null for empty state
184
188
  if (totalItems != null && totalItems <= 0) {
@@ -187,42 +191,42 @@ export function Pagination({
187
191
  if (computedTotalPages != null && computedTotalPages <= 0) {
188
192
  return null;
189
193
  }
194
+
195
+ // Interruptible: re-clicking before the transition settles starts a fresh one
196
+ // with the next optimistic page rather than being dropped, so there is no
197
+ // re-entry guard.
190
198
  const handlePageChange = newPage => {
191
- if (isDisabled || isPending) {
199
+ if (isDisabled) {
192
200
  return;
193
201
  }
202
+ // Keep onChange urgent so controlled page state updates in the same commit
203
+ // as the click; only the optimistic indicator and changeAction defer.
194
204
  onChange(newPage);
195
- if (changeAction) {
196
- startTransition(async () => {
197
- await changeAction(newPage);
198
- });
199
- }
205
+ startTransition(async () => {
206
+ setOptimisticPage(newPage);
207
+ await changeAction?.(newPage);
208
+ });
200
209
  };
201
210
  const handlePrevious = () => {
202
211
  if (hasPrevious) {
203
- handlePageChange(page - 1);
212
+ handlePageChange(optimisticPage - 1);
204
213
  }
205
214
  };
206
215
  const handleNext = () => {
207
216
  if (hasNext) {
208
- handlePageChange(page + 1);
217
+ handlePageChange(optimisticPage + 1);
209
218
  }
210
219
  };
211
220
  const handlePageSizeChange = value => {
212
221
  const newSize = Number(value);
213
222
  onPageSizeChange?.(newSize);
214
- // Reset to page 1 when page size changes
215
- onChange(1);
216
- if (changeAction) {
217
- startTransition(async () => {
218
- await changeAction(1);
219
- });
220
- }
223
+ // Reset to page 1 when page size changes.
224
+ handlePageChange(1);
221
225
  };
222
226
 
223
227
  // Item range for count display
224
- const rangeStart = (page - 1) * pageSize + 1;
225
- const rangeEnd = totalItems != null ? Math.min(page * pageSize, totalItems) : page * pageSize;
228
+ const rangeStart = (optimisticPage - 1) * pageSize + 1;
229
+ const rangeEnd = totalItems != null ? Math.min(optimisticPage * pageSize, totalItems) : optimisticPage * pageSize;
226
230
  const buttonSize = size === 'sm' ? 'sm' : 'md';
227
231
  const isSm = size === 'sm';
228
232
  const renderIndicator = () => {
@@ -232,7 +236,7 @@ export function Pagination({
232
236
  if (computedTotalPages == null) {
233
237
  return null;
234
238
  }
235
- const pageRange = generatePageRange(page, computedTotalPages, siblingCount);
239
+ const pageRange = generatePageRange(optimisticPage, computedTotalPages, siblingCount);
236
240
  return /*#__PURE__*/_jsx(_Fragment, {
237
241
  children: pageRange.map((item, index) => {
238
242
  if (item === '...') {
@@ -251,7 +255,7 @@ export function Pagination({
251
255
  children: "\u2026"
252
256
  }, `ellipsis-${previousPage}-${nextPage}`);
253
257
  }
254
- const isActive = item === page;
258
+ const isActive = item === optimisticPage;
255
259
  return /*#__PURE__*/_jsx(Button, {
256
260
  label: `Go to page ${item}`,
257
261
  "aria-label": `Go to page ${item}`,
@@ -296,7 +300,7 @@ export function Pagination({
296
300
  type: "body",
297
301
  size: "sm",
298
302
  color: "secondary",
299
- children: `Page ${page} of ${computedTotalPages}`
303
+ children: `Page ${optimisticPage} of ${computedTotalPages}`
300
304
  })
301
305
  });
302
306
  }
@@ -316,11 +320,11 @@ export function Pagination({
316
320
  }, (_, i) => /*#__PURE__*/_jsx("button", {
317
321
  type: "button",
318
322
  "aria-label": `Go to page ${i + 1}`,
319
- "aria-current": i + 1 === page ? 'page' : undefined,
323
+ "aria-current": i + 1 === optimisticPage ? 'page' : undefined,
320
324
  onClick: () => handlePageChange(i + 1),
321
325
  disabled: isDisabled,
322
326
  ...mergeProps(themeProps('pagination-dot', {
323
- active: i + 1 === page ? 'active' : null,
327
+ active: i + 1 === optimisticPage ? 'active' : null,
324
328
  size
325
329
  }), {
326
330
  0: {
@@ -347,7 +351,7 @@ export function Pagination({
347
351
  7: {
348
352
  className: "xc342km xng3xce x1717udv x16rqkct x15406qy xuedmi6 xlr8y92 x1a2a7pz x17nn4n9 x1wfwxd8 x7s97pk x1wu31ai xcenk2v x1ewilqj x1h6gzvc xbyyjgo"
349
353
  }
350
- }[!!isSm << 2 | !!(i + 1 === page) << 1 | !!isDisabled << 0])
354
+ }[!!isSm << 2 | !!(i + 1 === optimisticPage) << 1 | !!isDisabled << 0])
351
355
  }, i + 1))
352
356
  });
353
357
  }
@@ -484,10 +484,10 @@ export function Slider({
484
484
  orientation
485
485
  }), {
486
486
  0: {
487
- className: "x10l6tqk xwmxj5m xjspbzw x13vifvy x1ey2m1c x51ohtg x1nrll8i xuuh30"
487
+ className: "x10l6tqk xdsb6cv xjspbzw x13vifvy x1ey2m1c x51ohtg x1nrll8i xuuh30"
488
488
  },
489
489
  1: {
490
- className: "x10l6tqk xwmxj5m xjspbzw xu96u03 x3m8u43 xqu0tyb xwa60dl x1cb1t30"
490
+ className: "x10l6tqk xdsb6cv xjspbzw xu96u03 x3m8u43 xqu0tyb xwa60dl x1cb1t30"
491
491
  }
492
492
  }[!!isHorizontal << 0])
493
493
  }), /*#__PURE__*/_jsx("div", {
@@ -1 +1 @@
1
- {"version":3,"file":"BaseTable.d.ts","sourceRoot":"","sources":["../../src/Table/BaseTable.tsx"],"names":[],"mappings":"AAGA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAe,KAAK,YAAY,EAAkB,KAAK,GAAG,EAAC,MAAM,OAAO,CAAC;AAGhF,OAAO,KAAK,EACV,cAAc,EAWf,MAAM,SAAS,CAAC;AA6fjB;;;;;;;;;;;;;;;;;GAiBG;AACH,eAAO,MAAM,SAAS,EAAqB,CACzC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAEjC,KAAK,EAAE,cAAc,CAAC,CAAC,CAAC,GAAG;IAAC,GAAG,CAAC,EAAE,GAAG,CAAC,gBAAgB,CAAC,CAAA;CAAC,KACrD,YAAY,CAAC"}
1
+ {"version":3,"file":"BaseTable.d.ts","sourceRoot":"","sources":["../../src/Table/BaseTable.tsx"],"names":[],"mappings":"AAGA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAe,KAAK,YAAY,EAAkB,KAAK,GAAG,EAAC,MAAM,OAAO,CAAC;AAGhF,OAAO,KAAK,EACV,cAAc,EAYf,MAAM,SAAS,CAAC;AA6hBjB;;;;;;;;;;;;;;;;;GAiBG;AACH,eAAO,MAAM,SAAS,EAAqB,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC3E,KAAK,EAAE,cAAc,CAAC,CAAC,CAAC,GAAG;IAAC,GAAG,CAAC,EAAE,GAAG,CAAC,gBAAgB,CAAC,CAAA;CAAC,KACrD,YAAY,CAAC"}
@@ -105,7 +105,7 @@ function TableRowInner({
105
105
  CellComponent
106
106
  }) {
107
107
  // Build cells first
108
- const cells = columns.map(col => {
108
+ const cells = columns.map((col, columnIndex) => {
109
109
  // Apply column alignment to body cells
110
110
  const initialCellHtmlProps = {};
111
111
  if (col.align) {
@@ -113,10 +113,13 @@ function TableRowInner({
113
113
  textAlign: col.align
114
114
  };
115
115
  }
116
- const cellRenderProps = applyPlugins(plugins, p => p.transformBodyCell, {
116
+ const initialBodyCellRenderProps = {
117
117
  htmlProps: initialCellHtmlProps,
118
- styles: []
119
- }, col, item);
118
+ styles: [],
119
+ columnIndex,
120
+ columns: columns
121
+ };
122
+ const cellRenderProps = applyPlugins(plugins, p => p.transformBodyCell, initialBodyCellRenderProps, col, item, columnIndex, columns);
120
123
  const isDefaultRenderer = !col.renderCell;
121
124
  const rawContent = isDefaultRenderer ? defaultCellRenderer(item, col.key) : col.renderCell?.(item) ?? null;
122
125
 
@@ -136,6 +139,7 @@ function TableRowInner({
136
139
  }
137
140
  return /*#__PURE__*/_jsx(CellComponent, {
138
141
  ...cellRenderProps.htmlProps,
142
+ contextMenuActions: cellRenderProps.contextMenuActions,
139
143
  xstyle: cellRenderProps.styles,
140
144
  children: content
141
145
  }, col.key);
@@ -265,7 +269,7 @@ function BaseTableInner({
265
269
  });
266
270
 
267
271
  // --- Plugin pipeline: header cells ---
268
- const headerCells = resolvedColumns.map(col => {
272
+ const headerCells = resolvedColumns.map((col, columnIndex) => {
269
273
  const headerContent = col.header ?? col.key;
270
274
 
271
275
  // Build initial htmlProps with column alignment if specified
@@ -277,11 +281,14 @@ function BaseTableInner({
277
281
  textAlign: col.align
278
282
  };
279
283
  }
280
- const cellRenderProps = applyPlugins(plugins, p => p.transformHeaderCell, {
284
+ const initialHeaderRenderProps = {
281
285
  htmlProps: initialHeaderHtmlProps,
282
286
  styles: [],
283
- content: headerContent
284
- }, col);
287
+ content: headerContent,
288
+ columnIndex,
289
+ columns: resolvedColumns
290
+ };
291
+ const cellRenderProps = applyPlugins(plugins, p => p.transformHeaderCell, initialHeaderRenderProps, col, columnIndex, resolvedColumns);
285
292
 
286
293
  // Apply pre-computed column width styles on the <th>.
287
294
  // With table-layout: fixed, header cell sizing controls column widths.
@@ -308,18 +315,20 @@ function BaseTableInner({
308
315
  below
309
316
  } = cellRenderProps;
310
317
  const hasSlots = before != null || after != null || overlay != null || below != null;
318
+ const headerInner = hasSlots ? /*#__PURE__*/_jsxs(_Fragment, {
319
+ children: [before, after != null ? /*#__PURE__*/_jsxs("div", {
320
+ ...{
321
+ className: "x3nfvp2 x6s0dn4 xzye2dw xeuugli"
322
+ },
323
+ children: [resolvedContent, after]
324
+ }) : resolvedContent, overlay, below]
325
+ }) : resolvedContent;
311
326
  return /*#__PURE__*/_jsx(HeaderCellComponent, {
312
327
  ...mergedHtmlProps,
313
328
  ...headerTitleProp,
329
+ contextMenuActions: cellRenderProps.contextMenuActions,
314
330
  xstyle: cellRenderProps.styles,
315
- children: hasSlots ? /*#__PURE__*/_jsxs(_Fragment, {
316
- children: [before, after != null ? /*#__PURE__*/_jsxs("div", {
317
- ...{
318
- className: "x3nfvp2 x6s0dn4 xzye2dw xeuugli"
319
- },
320
- children: [resolvedContent, after]
321
- }) : resolvedContent, overlay, below]
322
- }) : resolvedContent
331
+ children: headerInner
323
332
  }, col.key);
324
333
  });
325
334
 
@@ -348,6 +357,7 @@ function BaseTableInner({
348
357
  children: [hasColumns && /*#__PURE__*/_jsx(TableHeader, {
349
358
  children: /*#__PURE__*/_jsx(RowComponent, {
350
359
  ...headerRowRenderProps.htmlProps,
360
+ isHeaderRow: true,
351
361
  xstyle: headerRowRenderProps.styles,
352
362
  children: headerRowRenderProps.children
353
363
  })
@@ -381,8 +391,20 @@ function BaseTableInner({
381
391
  // when columns exceed the container width. This wrapper sits between
382
392
  // the <table> and transformTableContext, so plugin chrome (pagination,
383
393
  // toolbars) renders outside the scroll area.
394
+ //
395
+ // Before rendering the wrapper, run the plugin `transformScrollWrapper`
396
+ // pipeline so plugins can attach a ref to the scroll container (scroll-aware
397
+ // sticky shadows, virtualization) and inject before/after chrome.
384
398
  if (ScrollWrapper) {
399
+ const scrollWrapperRenderProps = applyPlugins(plugins, p => p.transformScrollWrapper, {
400
+ htmlProps: {},
401
+ styles: []
402
+ });
385
403
  tableElement = /*#__PURE__*/_jsx(ScrollWrapper, {
404
+ htmlProps: scrollWrapperRenderProps.htmlProps,
405
+ styles: scrollWrapperRenderProps.styles,
406
+ beforeTable: scrollWrapperRenderProps.beforeTable,
407
+ afterTable: scrollWrapperRenderProps.afterTable,
386
408
  children: tableElement
387
409
  });
388
410
  }
@@ -1 +1 @@
1
- {"version":3,"file":"Table.d.ts","sourceRoot":"","sources":["../../src/Table/Table.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAU,KAAK,YAAY,EAAE,KAAK,GAAG,EAAC,MAAM,OAAO,CAAC;AAQ3D,OAAO,KAAK,EACV,cAAc,EACd,kBAAkB,EAClB,WAAW,EAEZ,MAAM,SAAS,CAAC;AAMjB,oDAAoD;AAEpD,MAAM,MAAM,YAAY,GAAG,SAAS,GAAG,UAAU,GAAG,UAAU,CAAC;AAE/D,kCAAkC;AAElC,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,MAAM,CAAC;AAEjE,8DAA8D;AAE9D,MAAM,MAAM,iBAAiB,GAAG,MAAM,GAAG,UAAU,CAAC;AAEpD;;;;;GAKG;AAEH,MAAM,WAAW,UAAU,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAE,SAAQ,IAAI,CACzE,cAAc,CAAC,CAAC,CAAC,EACjB,SAAS,GAAG,YAAY,CACzB;IACC,uCAAuC;IACvC,OAAO,CAAC,EAAE,YAAY,CAAC;IACvB,qCAAqC;IACrC,QAAQ,CAAC,EAAE,aAAa,CAAC;IACzB,wCAAwC;IACxC,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,8CAA8C;IAC9C,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;;;;;;;;;;OAUG;IACH,aAAa,CAAC,EAAE,kBAAkB,CAAC;IACnC;;;;;;;;;;;;;;;OAeG;IACH,YAAY,CAAC,EAAE,MAAM,GAAG,UAAU,CAAC;IACnC,6CAA6C;IAC7C,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC;CAC1C;AA6HD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AACH,eAAO,MAAM,KAAK,EAAiB,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACnE,KAAK,EAAE,UAAU,CAAC,CAAC,CAAC,GAAG;IAAC,GAAG,CAAC,EAAE,GAAG,CAAC,gBAAgB,CAAC,CAAA;CAAC,KACjD,YAAY,CAAC"}
1
+ {"version":3,"file":"Table.d.ts","sourceRoot":"","sources":["../../src/Table/Table.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAU,KAAK,YAAY,EAAE,KAAK,GAAG,EAAC,MAAM,OAAO,CAAC;AAQ3D,OAAO,KAAK,EACV,cAAc,EACd,kBAAkB,EAClB,WAAW,EAEZ,MAAM,SAAS,CAAC;AAOjB,oDAAoD;AAEpD,MAAM,MAAM,YAAY,GAAG,SAAS,GAAG,UAAU,GAAG,UAAU,CAAC;AAE/D,kCAAkC;AAElC,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,MAAM,CAAC;AAEjE,8DAA8D;AAE9D,MAAM,MAAM,iBAAiB,GAAG,MAAM,GAAG,UAAU,CAAC;AAEpD;;;;;GAKG;AAEH,MAAM,WAAW,UAAU,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAE,SAAQ,IAAI,CACzE,cAAc,CAAC,CAAC,CAAC,EACjB,SAAS,GAAG,YAAY,CACzB;IACC,uCAAuC;IACvC,OAAO,CAAC,EAAE,YAAY,CAAC;IACvB,qCAAqC;IACrC,QAAQ,CAAC,EAAE,aAAa,CAAC;IACzB,wCAAwC;IACxC,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,8CAA8C;IAC9C,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;;;;;;;;;;OAUG;IACH,aAAa,CAAC,EAAE,kBAAkB,CAAC;IACnC;;;;;;;;;;;;;;;OAeG;IACH,YAAY,CAAC,EAAE,MAAM,GAAG,UAAU,CAAC;IACnC,6CAA6C;IAC7C,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC;CAC1C;AAiJD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AACH,eAAO,MAAM,KAAK,EAAiB,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACnE,KAAK,EAAE,UAAU,CAAC,CAAC,CAAC,GAAG;IAAC,GAAG,CAAC,EAAE,GAAG,CAAC,gBAAgB,CAAC,CAAA;CAAC,KACjD,YAAY,CAAC"}
@@ -41,7 +41,7 @@ import { themeProps } from "../utils/themeProps.js";
41
41
  *
42
42
  * @template T - The row data type
43
43
  */
44
- import { jsx as _jsx } from "react/jsx-runtime";
44
+ import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
45
45
  // =============================================================================
46
46
  // StyleX Styles (table-level only; cell/row/header styles owned by components)
47
47
  // =============================================================================
@@ -53,14 +53,37 @@ const tableStyles = {
53
53
  $$css: true
54
54
  }
55
55
  };
56
+ const scrollWrapperStyles = {
57
+ base: {
58
+ kXHlph: "xw2csxc",
59
+ kuHK5b: "x5lxg6s",
60
+ $$css: true
61
+ },
62
+ containerBleed: {
63
+ keTefX: "xojxgvx",
64
+ k71WvV: "x1fcf3bl",
65
+ kzqmXN: "xx6qvi6",
66
+ keoZOQ: "xkibk3",
67
+ k1K539: "xlayyun",
68
+ $$css: true
69
+ }
70
+ };
56
71
  function TableScrollWrapper({
57
- children
72
+ children,
73
+ htmlProps,
74
+ styles: pluginStyles,
75
+ beforeTable,
76
+ afterTable
58
77
  }) {
59
- return /*#__PURE__*/_jsx("div", {
60
- ...mergeProps(themeProps('table-scroll-wrapper'), {
61
- className: "xw2csxc x5lxg6s xojxgvx x1fcf3bl xx6qvi6 xkibk3 xlayyun"
62
- }),
63
- children: children
78
+ const {
79
+ ref,
80
+ ...restHtmlProps
81
+ } = htmlProps ?? {};
82
+ return /*#__PURE__*/_jsxs("div", {
83
+ ref: ref,
84
+ ...restHtmlProps,
85
+ ...mergeProps(themeProps('table-scroll-wrapper'), stylex.props(scrollWrapperStyles.base, scrollWrapperStyles.containerBleed, ...(pluginStyles ?? []))),
86
+ children: [beforeTable, children, afterTable]
64
87
  });
65
88
  }
66
89
 
@@ -12,6 +12,7 @@
12
12
  import type { ReactNode } from 'react';
13
13
  import type { BaseProps } from '../BaseProps';
14
14
  import type { StyleXStyles } from '../theme/types';
15
+ import type { TableContextActions } from './types';
15
16
  /** Props for TableCell — thin `<td>` wrapper */
16
17
  export interface TableCellProps extends BaseProps<HTMLTableCellElement> {
17
18
  /** Ref forwarded to the root element */
@@ -30,6 +31,12 @@ export interface TableCellProps extends BaseProps<HTMLTableCellElement> {
30
31
  * Must be a `stylex.create()` value — not an inline style object.
31
32
  */
32
33
  xstyle?: StyleXStyles | StyleXStyles[];
34
+ /**
35
+ * Right-click actions rendered as a context menu around the cell content.
36
+ * The cell owns the wrapper so it controls how the menu interacts with its
37
+ * padding / content. Empty or undefined renders no menu.
38
+ */
39
+ contextMenuActions?: TableContextActions;
33
40
  }
34
41
  /**
35
42
  * TableCell — a `<td>` wrapper for children/streaming mode.
@@ -45,7 +52,7 @@ export interface TableCellProps extends BaseProps<HTMLTableCellElement> {
45
52
  * </TableRow>
46
53
  * ```
47
54
  */
48
- export declare function TableCell({ children, xstyle, ref, className: incomingClassName, style: incomingStyle, ...props }: TableCellProps): import("react").JSX.Element;
55
+ export declare function TableCell({ children, xstyle, ref, className: incomingClassName, style: incomingStyle, contextMenuActions, ...props }: TableCellProps): import("react").JSX.Element;
49
56
  export declare namespace TableCell {
50
57
  var displayName: string;
51
58
  }
@@ -1 +1 @@
1
- {"version":3,"file":"TableCell.d.ts","sourceRoot":"","sources":["../../src/Table/TableCell.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,OAAO,CAAC;AACrC,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AAQ5C,OAAO,KAAK,EAAC,YAAY,EAAC,MAAM,gBAAgB,CAAC;AAejD,gDAAgD;AAChD,MAAM,WAAW,cAAe,SAAQ,SAAS,CAAC,oBAAoB,CAAC;IACrE,wCAAwC;IACxC,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAC;IACtC,0FAA0F;IAC1F,KAAK,CAAC,EAAE,KAAK,GAAG,KAAK,GAAG,UAAU,GAAG,UAAU,CAAC;IAChD,yEAAyE;IACzE,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,yEAAyE;IACzE,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,sEAAsE;IACtE,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB;;;OAGG;IACH,MAAM,CAAC,EAAE,YAAY,GAAG,YAAY,EAAE,CAAC;CACxC;AA8DD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,SAAS,CAAC,EACxB,QAAQ,EACR,MAAM,EACN,GAAG,EACH,SAAS,EAAE,iBAAiB,EAC5B,KAAK,EAAE,aAAa,EACpB,GAAG,KAAK,EACT,EAAE,cAAc,+BAwChB;yBA/Ce,SAAS"}
1
+ {"version":3,"file":"TableCell.d.ts","sourceRoot":"","sources":["../../src/Table/TableCell.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,OAAO,CAAC;AACrC,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AAQ5C,OAAO,KAAK,EAAC,YAAY,EAAC,MAAM,gBAAgB,CAAC;AACjD,OAAO,KAAK,EAAC,mBAAmB,EAAC,MAAM,SAAS,CAAC;AAgBjD,gDAAgD;AAChD,MAAM,WAAW,cAAe,SAAQ,SAAS,CAAC,oBAAoB,CAAC;IACrE,wCAAwC;IACxC,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAC;IACtC,0FAA0F;IAC1F,KAAK,CAAC,EAAE,KAAK,GAAG,KAAK,GAAG,UAAU,GAAG,UAAU,CAAC;IAChD,yEAAyE;IACzE,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,yEAAyE;IACzE,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,sEAAsE;IACtE,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB;;;OAGG;IACH,MAAM,CAAC,EAAE,YAAY,GAAG,YAAY,EAAE,CAAC;IACvC;;;;OAIG;IACH,kBAAkB,CAAC,EAAE,mBAAmB,CAAC;CAC1C;AA8DD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,SAAS,CAAC,EACxB,QAAQ,EACR,MAAM,EACN,GAAG,EACH,SAAS,EAAE,iBAAiB,EAC5B,KAAK,EAAE,aAAa,EACpB,kBAAkB,EAClB,GAAG,KAAK,EACT,EAAE,cAAc,+BAiChB;yBAzCe,SAAS"}
@@ -16,6 +16,7 @@
16
16
  import * as stylex from '@stylexjs/stylex';
17
17
  import "../theme/tokens.stylex.js";
18
18
  import { borderVars, colorVars, spacingVars, typeScaleVars } from "../theme/tokens.stylex.js";
19
+ import { wrapInTableContextMenu } from "./tableContextMenu.js";
19
20
  import "./table.stylex.js";
20
21
  import { overflowStyles, wrapStyles, containerEdgeStyles, tableRowMarker } from "./table.stylex.js";
21
22
  import { useTableContext, buildDividerStyles, mergeXStyle } from "./useTableCellStyles.js";
@@ -98,23 +99,22 @@ export function TableCell({
98
99
  ref,
99
100
  className: incomingClassName,
100
101
  style: incomingStyle,
102
+ contextMenuActions,
101
103
  ...props
102
104
  }) {
103
105
  const ctx = useTableContext();
104
- if (!ctx) {
105
- return /*#__PURE__*/_jsx("td", {
106
- ref: ref,
107
- ...props,
108
- ...mergeProps(themeProps('table-cell'), stylex.props(xstyle), incomingClassName, incomingStyle),
109
- children: children
110
- });
111
- }
112
- const cellStyles = [densityStyles[ctx.density], ctx.textOverflow === 'truncate' ? overflowStyles.cell : wrapStyles.cell, containerEdgeStyles[ctx.density], verticalAlignStyles[ctx.verticalAlign], ...buildDividerStyles(ctx, dividerRowStyles.cell, dividerColumnStyles.cell)];
106
+
107
+ // Standalone (no table context) renders plain, with no density/divider styles.
108
+ const cellStyles = ctx ? [densityStyles[ctx.density], ctx.textOverflow === 'truncate' ? overflowStyles.cell : wrapStyles.cell, containerEdgeStyles[ctx.density], verticalAlignStyles[ctx.verticalAlign], ...buildDividerStyles(ctx, dividerRowStyles.cell, dividerColumnStyles.cell)] : [];
109
+
110
+ // The cell owns the context-menu wrapper so it controls how the menu
111
+ // interacts with its padding / content. No-op when no actions.
112
+ const content = wrapInTableContextMenu(children, contextMenuActions);
113
113
  return /*#__PURE__*/_jsx("td", {
114
114
  ref: ref,
115
115
  ...props,
116
116
  ...mergeProps(themeProps('table-cell'), stylex.props(...mergeXStyle(cellStyles, xstyle)), incomingClassName, incomingStyle),
117
- children: children
117
+ children: content
118
118
  });
119
119
  }
120
120
  TableCell.displayName = 'TableCell';
@@ -12,6 +12,7 @@
12
12
  import type { ReactNode } from 'react';
13
13
  import type { BaseProps } from '../BaseProps';
14
14
  import type { StyleXStyles } from '../theme/types';
15
+ import type { TableContextActions } from './types';
15
16
  /** Props for TableHeaderCell — `<th>` wrapper with context-aware styling */
16
17
  export interface TableHeaderCellProps extends BaseProps<HTMLTableCellElement> {
17
18
  /** Ref forwarded to the root element */
@@ -24,6 +25,12 @@ export interface TableHeaderCellProps extends BaseProps<HTMLTableCellElement> {
24
25
  * Must be a `stylex.create()` value — not an inline style object.
25
26
  */
26
27
  xstyle?: StyleXStyles | StyleXStyles[];
28
+ /**
29
+ * Right-click actions rendered as a context menu around the cell content.
30
+ * The cell owns the wrapper so it controls how the menu interacts with its
31
+ * padding / content. Empty or undefined renders no menu.
32
+ */
33
+ contextMenuActions?: TableContextActions;
27
34
  }
28
35
  /**
29
36
  * TableHeaderCell — a `<th>` wrapper for header cells.
@@ -44,7 +51,7 @@ export interface TableHeaderCellProps extends BaseProps<HTMLTableCellElement> {
44
51
  * </thead>
45
52
  * ```
46
53
  */
47
- export declare function TableHeaderCell({ children, xstyle, ref, className: incomingClassName, style: incomingStyle, ...props }: TableHeaderCellProps): import("react").JSX.Element;
54
+ export declare function TableHeaderCell({ children, xstyle, ref, className: incomingClassName, style: incomingStyle, contextMenuActions, ...props }: TableHeaderCellProps): import("react").JSX.Element;
48
55
  export declare namespace TableHeaderCell {
49
56
  var displayName: string;
50
57
  }
@@ -1 +1 @@
1
- {"version":3,"file":"TableHeaderCell.d.ts","sourceRoot":"","sources":["../../src/Table/TableHeaderCell.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,OAAO,CAAC;AACrC,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AAS5C,OAAO,KAAK,EAAC,YAAY,EAAC,MAAM,gBAAgB,CAAC;AAMjD,4EAA4E;AAC5E,MAAM,WAAW,oBAAqB,SAAQ,SAAS,CAAC,oBAAoB,CAAC;IAC3E,wCAAwC;IACxC,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAC;IACtC,oDAAoD;IACpD,KAAK,CAAC,EAAE,KAAK,GAAG,KAAK,GAAG,UAAU,GAAG,UAAU,CAAC;IAChD,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB;;;OAGG;IACH,MAAM,CAAC,EAAE,YAAY,GAAG,YAAY,EAAE,CAAC;CACxC;AAkDD;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,eAAe,CAAC,EAC9B,QAAQ,EACR,MAAM,EACN,GAAG,EACH,SAAS,EAAE,iBAAiB,EAC5B,KAAK,EAAE,aAAa,EACpB,GAAG,KAAK,EACT,EAAE,oBAAoB,+BAgDtB;yBAvDe,eAAe"}
1
+ {"version":3,"file":"TableHeaderCell.d.ts","sourceRoot":"","sources":["../../src/Table/TableHeaderCell.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,OAAO,CAAC;AACrC,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AAS5C,OAAO,KAAK,EAAC,YAAY,EAAC,MAAM,gBAAgB,CAAC;AACjD,OAAO,KAAK,EAAC,mBAAmB,EAAC,MAAM,SAAS,CAAC;AAOjD,4EAA4E;AAC5E,MAAM,WAAW,oBAAqB,SAAQ,SAAS,CAAC,oBAAoB,CAAC;IAC3E,wCAAwC;IACxC,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAC;IACtC,oDAAoD;IACpD,KAAK,CAAC,EAAE,KAAK,GAAG,KAAK,GAAG,UAAU,GAAG,UAAU,CAAC;IAChD,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB;;;OAGG;IACH,MAAM,CAAC,EAAE,YAAY,GAAG,YAAY,EAAE,CAAC;IACvC;;;;OAIG;IACH,kBAAkB,CAAC,EAAE,mBAAmB,CAAC;CAC1C;AAkDD;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,eAAe,CAAC,EAC9B,QAAQ,EACR,MAAM,EACN,GAAG,EACH,SAAS,EAAE,iBAAiB,EAC5B,KAAK,EAAE,aAAa,EACpB,kBAAkB,EAClB,GAAG,KAAK,EACT,EAAE,oBAAoB,+BAsCtB;yBA9Ce,eAAe"}
@@ -18,6 +18,7 @@ import "../theme/tokens.stylex.js";
18
18
  import { colorVars, spacingVars, fontWeightVars, typeScaleVars, borderVars } from "../theme/tokens.stylex.js";
19
19
  import { overflowStyles, containerEdgeStyles } from "./table.stylex.js";
20
20
  import { useTableContext, mergeXStyle } from "./useTableCellStyles.js";
21
+ import { wrapInTableContextMenu } from "./tableContextMenu.js";
21
22
  import { mergeProps } from "../utils/index.js";
22
23
  import { themeProps } from "../utils/themeProps.js";
23
24
 
@@ -96,32 +97,31 @@ export function TableHeaderCell({
96
97
  ref,
97
98
  className: incomingClassName,
98
99
  style: incomingStyle,
100
+ contextMenuActions,
99
101
  ...props
100
102
  }) {
101
103
  const ctx = useTableContext();
102
- if (!ctx) {
103
- return /*#__PURE__*/_jsx("th", {
104
- ref: ref,
105
- ...props,
106
- ...mergeProps(themeProps('table-header-cell'), stylex.props(xstyle), incomingClassName, incomingStyle),
107
- children: children
108
- });
109
- }
110
104
 
111
105
  // Header cells always get the bottom divider (separates header from body).
112
- // Column dividers use the shared buildDividerStyles — but only for
113
- // the column axis, since the row divider is the headerDividerStyles.
114
- const cellStyles = [headerStyles.cell, densityStyles[ctx.density], headerDividerStyles.cell, overflowStyles.cell, containerEdgeStyles[ctx.density]];
115
-
116
- // Only add column dividers from the shared builder
117
- if (ctx.dividers === 'columns' || ctx.dividers === 'grid') {
118
- cellStyles.push(dividerColumnStyles.cell);
106
+ // When used standalone (no table context) the cell renders plain, with no
107
+ // density/divider styles.
108
+ const cellStyles = [];
109
+ if (ctx) {
110
+ cellStyles.push(headerStyles.cell, densityStyles[ctx.density], headerDividerStyles.cell, overflowStyles.cell, containerEdgeStyles[ctx.density]);
111
+ // Column dividers come from the shared builder (column axis only).
112
+ if (ctx.dividers === 'columns' || ctx.dividers === 'grid') {
113
+ cellStyles.push(dividerColumnStyles.cell);
114
+ }
119
115
  }
116
+
117
+ // The cell owns the context-menu wrapper so it controls how the menu
118
+ // interacts with its padding / content. No-op when no actions.
119
+ const content = wrapInTableContextMenu(children, contextMenuActions);
120
120
  return /*#__PURE__*/_jsx("th", {
121
121
  ref: ref,
122
122
  ...props,
123
123
  ...mergeProps(themeProps('table-header-cell'), stylex.props(...mergeXStyle(cellStyles, xstyle)), incomingClassName, incomingStyle),
124
- children: children
124
+ children: content
125
125
  });
126
126
  }
127
127
  TableHeaderCell.displayName = 'TableHeaderCell';
@@ -22,6 +22,11 @@ export interface TableRowProps extends BaseProps<HTMLTableRowElement> {
22
22
  * Must be a `stylex.create()` value — not an inline style object.
23
23
  */
24
24
  xstyle?: StyleXStyles[];
25
+ /**
26
+ * Whether this row is the header row. Header rows skip the striped/hover
27
+ * row styling (which is only meant for body rows).
28
+ */
29
+ isHeaderRow?: boolean;
25
30
  }
26
31
  /**
27
32
  * TableRow — a `<tr>` wrapper for children/streaming mode.
@@ -39,7 +44,7 @@ export interface TableRowProps extends BaseProps<HTMLTableRowElement> {
39
44
  * </Table>
40
45
  * ```
41
46
  */
42
- export declare function TableRow({ children, xstyle, ref, ...props }: TableRowProps): import("react").JSX.Element;
47
+ export declare function TableRow({ children, xstyle, ref, isHeaderRow, ...props }: TableRowProps): import("react").JSX.Element;
43
48
  export declare namespace TableRow {
44
49
  var displayName: string;
45
50
  }
@@ -1 +1 @@
1
- {"version":3,"file":"TableRow.d.ts","sourceRoot":"","sources":["../../src/Table/TableRow.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;GAUG;AAEH,OAAO,EAAM,KAAK,SAAS,EAAC,MAAM,OAAO,CAAC;AAC1C,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AAG5C,OAAO,KAAK,EAAC,YAAY,EAAC,MAAM,gBAAgB,CAAC;AAMjD,+CAA+C;AAC/C,MAAM,WAAW,aAAc,SAAQ,SAAS,CAAC,mBAAmB,CAAC;IACnE,wCAAwC;IACxC,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAC;IACrC,QAAQ,EAAE,SAAS,CAAC;IACpB;;;OAGG;IACH,MAAM,CAAC,EAAE,YAAY,EAAE,CAAC;CACzB;AAwCD;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,QAAQ,CAAC,EACvB,QAAQ,EACR,MAAM,EACN,GAAG,EACH,GAAG,KAAK,EACT,EAAE,aAAa,+BAgDf;yBArDe,QAAQ"}
1
+ {"version":3,"file":"TableRow.d.ts","sourceRoot":"","sources":["../../src/Table/TableRow.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;GAUG;AAEH,OAAO,EAAM,KAAK,SAAS,EAAC,MAAM,OAAO,CAAC;AAC1C,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AAG5C,OAAO,KAAK,EAAC,YAAY,EAAC,MAAM,gBAAgB,CAAC;AAMjD,+CAA+C;AAC/C,MAAM,WAAW,aAAc,SAAQ,SAAS,CAAC,mBAAmB,CAAC;IACnE,wCAAwC;IACxC,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAC;IACrC,QAAQ,EAAE,SAAS,CAAC;IACpB;;;OAGG;IACH,MAAM,CAAC,EAAE,YAAY,EAAE,CAAC;IACxB;;;OAGG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AA4DD;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,QAAQ,CAAC,EACvB,QAAQ,EACR,MAAM,EACN,GAAG,EACH,WAAmB,EACnB,GAAG,KAAK,EACT,EAAE,aAAa,+BAoDf;yBA1De,QAAQ"}
@@ -27,12 +27,14 @@ import { jsx as _jsx } from "react/jsx-runtime";
27
27
  const stripedRowStyles = {
28
28
  row: {
29
29
  kWkggS: "x1dnou9g",
30
+ "--table-row-overlay": "x1rht92",
30
31
  $$css: true
31
32
  }
32
33
  };
33
34
  const hoverRowStyles = {
34
35
  row: {
35
36
  kWkggS: "xe9uy6x",
37
+ "--table-row-overlay": "x1pkcbo2",
36
38
  k1ekBW: "x15406qy",
37
39
  kIyJzY: "xuedmi6",
38
40
  kAMwcw: "xlr8y92",
@@ -42,6 +44,7 @@ const hoverRowStyles = {
42
44
  const stripedHoverRowStyles = {
43
45
  row: {
44
46
  kWkggS: "x1dnou9g xe9uy6x",
47
+ "--table-row-overlay": "x1rht92 x1pkcbo2",
45
48
  k1ekBW: "x15406qy",
46
49
  kIyJzY: "xuedmi6",
47
50
  kAMwcw: "xlr8y92",
@@ -69,6 +72,7 @@ export function TableRow({
69
72
  children,
70
73
  xstyle,
71
74
  ref,
75
+ isHeaderRow = false,
72
76
  ...props
73
77
  }) {
74
78
  const ctx = use(TableContext);
@@ -82,13 +86,17 @@ export function TableRow({
82
86
  }
83
87
  const rowStyles = [];
84
88
 
85
- // Handle striped + hover combination to avoid backgroundColor conflicts
86
- if (ctx.isStriped && ctx.hasHover) {
87
- rowStyles.push(stripedHoverRowStyles.row);
88
- } else if (ctx.isStriped) {
89
- rowStyles.push(stripedRowStyles.row);
90
- } else if (ctx.hasHover) {
91
- rowStyles.push(hoverRowStyles.row);
89
+ // Striped + hover styling is for body rows only — the header row must not
90
+ // pick up the hover highlight (or striping) even when hasHover/isStriped.
91
+ if (!isHeaderRow) {
92
+ // Handle striped + hover combination to avoid backgroundColor conflicts
93
+ if (ctx.isStriped && ctx.hasHover) {
94
+ rowStyles.push(stripedHoverRowStyles.row);
95
+ } else if (ctx.isStriped) {
96
+ rowStyles.push(stripedRowStyles.row);
97
+ } else if (ctx.hasHover) {
98
+ rowStyles.push(hoverRowStyles.row);
99
+ }
92
100
  }
93
101
  if (ctx.dividers === 'rows' || ctx.dividers === 'grid') {
94
102
  // Note: last-body-row border removal is handled by TableCell
@@ -22,10 +22,12 @@ export { useTablePagination, paginateData } from './plugins/pagination';
22
22
  export { useTableColumnSettings } from './plugins/columnSettings';
23
23
  export { useTableColumnSettingsState } from './plugins/columnSettings';
24
24
  export { useTableColumnResize } from './plugins/columnResize';
25
+ export { useTableStickyColumns } from './plugins/stickyColumns';
26
+ export { resolveContextActions } from './tableContextMenu';
25
27
  export { useTableFiltering, useTableFilterState, toSearchFilters, } from './plugins/filtering';
26
28
  export { useBaseTablePlugins } from './useBaseTablePlugins';
27
29
  export { proportional, pixel, generateColumns, resolveColumnWidths, DEFAULT_MIN_COLUMN_WIDTH, } from './columnUtils';
28
- export type { TableColumn, TableColumnAlign, TableVerticalAlign, ColumnWidth, ProportionalWidth, PixelWidth, TablePlugin, TableRenderProps, HeaderRowRenderProps, HeaderCellRenderProps, BodyRowRenderProps, BodyCellRenderProps, BaseTableProps, } from './types';
30
+ export type { TableColumn, TableColumnAlign, TableVerticalAlign, ColumnWidth, ProportionalWidth, PixelWidth, TablePlugin, TableContextAction, TableContextActions, TableRenderProps, HeaderRowRenderProps, HeaderCellRenderProps, BodyRowRenderProps, BodyCellRenderProps, ScrollWrapperRenderProps, BaseTableProps, } from './types';
29
31
  export type { TableProps, TableDensity, TableDividers, TableTextOverflow, } from './Table';
30
32
  export type { TableRowProps } from './TableRow';
31
33
  export type { TableCellProps } from './TableCell';
@@ -42,5 +44,6 @@ export type { UseTablePaginationConfig } from './plugins/pagination';
42
44
  export type { UseTableColumnSettingsConfig, ColumnSettingsOption, } from './plugins/columnSettings';
43
45
  export type { UseTableColumnSettingsStateConfig, UseTableColumnSettingsStateReturn, } from './plugins/columnSettings';
44
46
  export type { UseTableColumnResizeConfig } from './plugins/columnResize';
47
+ export type { UseTableStickyColumnsConfig } from './plugins/stickyColumns';
45
48
  export type { UseTableFilteringConfig, TableFilterState, TableFilterVariant, TableFilterValue, TableFilterFieldRef, } from './plugins/filtering';
46
49
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/Table/index.ts"],"names":[],"mappings":"AAIA;;;;;;;GAOG;AAEH,OAAO,EAAC,KAAK,EAAC,MAAM,SAAS,CAAC;AAC9B,OAAO,EAAC,QAAQ,EAAC,MAAM,YAAY,CAAC;AACpC,OAAO,EAAC,SAAS,EAAC,MAAM,aAAa,CAAC;AACtC,OAAO,EAAC,eAAe,EAAC,MAAM,mBAAmB,CAAC;AAClD,OAAO,EAAC,WAAW,EAAC,MAAM,eAAe,CAAC;AAC1C,OAAO,EAAC,SAAS,EAAC,MAAM,aAAa,CAAC;AACtC,OAAO,EAAC,WAAW,EAAC,MAAM,eAAe,CAAC;AAC1C,OAAO,EAAC,YAAY,EAAC,MAAM,gBAAgB,CAAC;AAC5C,OAAO,EAAC,iBAAiB,EAAC,MAAM,qBAAqB,CAAC;AACtD,OAAO,EAAC,sBAAsB,EAAC,MAAM,qBAAqB,CAAC;AAC3D,OAAO,EAAC,gBAAgB,EAAC,MAAM,oBAAoB,CAAC;AACpD,OAAO,EAAC,qBAAqB,EAAC,MAAM,oBAAoB,CAAC;AACzD,OAAO,EAAC,kBAAkB,EAAE,YAAY,EAAC,MAAM,sBAAsB,CAAC;AACtE,OAAO,EAAC,sBAAsB,EAAC,MAAM,0BAA0B,CAAC;AAChE,OAAO,EAAC,2BAA2B,EAAC,MAAM,0BAA0B,CAAC;AACrE,OAAO,EAAC,oBAAoB,EAAC,MAAM,wBAAwB,CAAC;AAC5D,OAAO,EACL,iBAAiB,EACjB,mBAAmB,EACnB,eAAe,GAChB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAC,mBAAmB,EAAC,MAAM,uBAAuB,CAAC;AAC1D,OAAO,EACL,YAAY,EACZ,KAAK,EACL,eAAe,EACf,mBAAmB,EACnB,wBAAwB,GACzB,MAAM,eAAe,CAAC;AACvB,YAAY,EACV,WAAW,EACX,gBAAgB,EAChB,kBAAkB,EAClB,WAAW,EACX,iBAAiB,EACjB,UAAU,EACV,WAAW,EACX,gBAAgB,EAChB,oBAAoB,EACpB,qBAAqB,EACrB,kBAAkB,EAClB,mBAAmB,EACnB,cAAc,GACf,MAAM,SAAS,CAAC;AACjB,YAAY,EACV,UAAU,EACV,YAAY,EACZ,aAAa,EACb,iBAAiB,GAClB,MAAM,SAAS,CAAC;AACjB,YAAY,EAAC,aAAa,EAAC,MAAM,YAAY,CAAC;AAC9C,YAAY,EAAC,cAAc,EAAC,MAAM,aAAa,CAAC;AAChD,YAAY,EAAC,oBAAoB,EAAC,MAAM,mBAAmB,CAAC;AAC5D,YAAY,EAAC,gBAAgB,EAAC,MAAM,eAAe,CAAC;AACpD,YAAY,EAAC,cAAc,EAAC,MAAM,aAAa,CAAC;AAChD,YAAY,EAAC,gBAAgB,EAAC,MAAM,eAAe,CAAC;AACpD,YAAY,EAAC,iBAAiB,EAAC,MAAM,gBAAgB,CAAC;AACtD,YAAY,EAAC,uBAAuB,EAAC,MAAM,qBAAqB,CAAC;AACjE,YAAY,EACV,4BAA4B,EAC5B,4BAA4B,GAC7B,MAAM,qBAAqB,CAAC;AAC7B,YAAY,EACV,sBAAsB,EACtB,2BAA2B,EAC3B,2BAA2B,EAC3B,mBAAmB,EACnB,kBAAkB,EAClB,cAAc,EACd,cAAc,GACf,MAAM,oBAAoB,CAAC;AAC5B,YAAY,EAAC,yBAAyB,EAAC,MAAM,SAAS,CAAC;AACvD,YAAY,EAAC,wBAAwB,EAAC,MAAM,sBAAsB,CAAC;AACnE,YAAY,EACV,4BAA4B,EAC5B,oBAAoB,GACrB,MAAM,0BAA0B,CAAC;AAClC,YAAY,EACV,iCAAiC,EACjC,iCAAiC,GAClC,MAAM,0BAA0B,CAAC;AAClC,YAAY,EAAC,0BAA0B,EAAC,MAAM,wBAAwB,CAAC;AACvE,YAAY,EACV,uBAAuB,EACvB,gBAAgB,EAChB,kBAAkB,EAClB,gBAAgB,EAChB,mBAAmB,GACpB,MAAM,qBAAqB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/Table/index.ts"],"names":[],"mappings":"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"}
@@ -26,6 +26,8 @@ export { useTablePagination, paginateData } from "./plugins/pagination/index.js"
26
26
  export { useTableColumnSettings } from "./plugins/columnSettings/index.js";
27
27
  export { useTableColumnSettingsState } from "./plugins/columnSettings/index.js";
28
28
  export { useTableColumnResize } from "./plugins/columnResize/index.js";
29
+ export { useTableStickyColumns } from "./plugins/stickyColumns/index.js";
30
+ export { resolveContextActions } from "./tableContextMenu.js";
29
31
  export { useTableFiltering, useTableFilterState, toSearchFilters } from "./plugins/filtering/index.js";
30
32
  export { useBaseTablePlugins } from "./useBaseTablePlugins.js";
31
33
  export { proportional, pixel, generateColumns, resolveColumnWidths, DEFAULT_MIN_COLUMN_WIDTH } from "./columnUtils.js";