@orfium/ictinus 5.43.4 → 5.43.6

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 (68) hide show
  1. package/.turbo/turbo-build.log +18 -18
  2. package/CHANGELOG.md +12 -0
  3. package/dist/package.json.d.ts +1 -1
  4. package/dist/package.json.js +1 -1
  5. package/dist/sprinkles/properties.css.js +1 -1
  6. package/dist/sprinkles/properties.css.ts.vanilla.css +1 -1
  7. package/dist/src/actions/ActionsContent.d.ts +65 -64
  8. package/dist/src/actions/ActionsRoot.d.ts +65 -64
  9. package/dist/src/data-table/DataTable.d.ts +77 -64
  10. package/dist/src/data-table/DataTableBody.d.ts +67 -64
  11. package/dist/src/data-table/DataTableCounter.d.ts +2 -1
  12. package/dist/src/data-table/DataTableHeader.d.ts +65 -64
  13. package/dist/src/data-table/DataTableRow.d.ts +135 -133
  14. package/dist/src/data-table/DataTableRowContext.d.ts +28 -5
  15. package/dist/src/skeleton/Skeleton.css.d.ts +5 -0
  16. package/dist/src/skeleton/Skeleton.d.ts +427 -0
  17. package/dist/src/skeleton/index.d.ts +1 -0
  18. package/dist/src/sprinkles/properties.css.d.ts +280 -0
  19. package/dist/src/sprinkles/sprinkles.d.ts +597 -56
  20. package/dist/src/vanilla/Box/Box.d.ts +65 -64
  21. package/dist/src/vanilla/Box/extractBoxProps.d.ts +2 -2
  22. package/dist/src/vanilla/Table/Table.d.ts +65 -64
  23. package/dist/src/vanilla/Table/TableBody.d.ts +65 -64
  24. package/dist/src/vanilla/Table/TableCell.d.ts +65 -64
  25. package/dist/src/vanilla/Table/TableFooter.d.ts +65 -64
  26. package/dist/src/vanilla/Table/TableHeader.d.ts +65 -64
  27. package/dist/src/vanilla/Table/TableHeaderCell.d.ts +65 -64
  28. package/dist/src/vanilla/Table/TableRow.d.ts +65 -64
  29. package/dist/src/vanilla/Text/Text.d.ts +65 -64
  30. package/dist/src/vanilla/index.d.ts +2 -0
  31. package/dist/vanilla/Dropdown/Dropdown-css.js +2 -2
  32. package/dist/vanilla/Menu/Menu-css.js +3 -3
  33. package/dist/vanilla/Popover/Popover-css.js +2 -2
  34. package/dist/vanilla/Table/Table-css.js +3 -3
  35. package/dist/vanilla/Table/TableCell-css.js +3 -3
  36. package/dist/vanilla/Table/TableHeaderCell-css.js +3 -3
  37. package/dist/vanilla/Table/TableRow-css.js +2 -2
  38. package/dist/vanilla/Tooltip/Tooltip-css.js +2 -2
  39. package/dist/vanilla/assets/src/skeleton/Skeleton.css.ts.vanilla-CNzX69JK.css +6 -0
  40. package/dist/vanilla/assets/src/sprinkles/{properties.css.ts.vanilla-C8hqLKur.css → properties.css.ts.vanilla-CRlOneec.css} +3613 -3233
  41. package/dist/vanilla/index.d.ts +1308 -852
  42. package/dist/vanilla/index.js +2 -0
  43. package/dist/vanilla/package.json.js +1 -1
  44. package/dist/vanilla/src/actions/ActionsContent-css.js +2 -2
  45. package/dist/vanilla/src/data-table/DataTableBody-css.js +3 -3
  46. package/dist/vanilla/src/data-table/DataTableBody.js +123 -89
  47. package/dist/vanilla/src/data-table/DataTableCounter.js +5 -3
  48. package/dist/vanilla/src/data-table/DataTableHeaderCell-css.js +3 -3
  49. package/dist/vanilla/src/data-table/DataTableRowContext.js +29 -2
  50. package/dist/vanilla/src/skeleton/Skeleton-css.js +9 -0
  51. package/dist/vanilla/src/skeleton/Skeleton.js +26 -0
  52. package/dist/vanilla/src/sprinkles/properties-css.js +4 -4
  53. package/package.json +1 -1
  54. package/src/components/Controls/CheckBox/__snapshots__/CheckBox.test.tsx.snap +1 -1
  55. package/src/components/DatePicker/OverlayComponent/__snapshots__/OverlayComponent.test.tsx.snap +4 -4
  56. package/src/components/DatePicker/OverlayComponent/components/MonthWrapper/__snapshots__/MonthWrapper.test.tsx.snap +2 -2
  57. package/src/components/TopAppBar/__snapshots__/TopAppBar.test.tsx.snap +2 -2
  58. package/src/data-table/DataTable.tsx +16 -0
  59. package/src/data-table/DataTableBody.tsx +153 -109
  60. package/src/data-table/DataTableCounter.tsx +13 -4
  61. package/src/data-table/DataTableRow.tsx +4 -5
  62. package/src/data-table/DataTableRowContext.tsx +33 -4
  63. package/src/skeleton/Skeleton.css.ts +19 -0
  64. package/src/skeleton/Skeleton.tsx +34 -0
  65. package/src/skeleton/index.ts +1 -0
  66. package/src/sprinkles/properties.css.ts +87 -6
  67. package/src/vanilla/index.ts +2 -0
  68. package/src/data-table/react-table.d.ts +0 -12
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@orfium/ictinus",
3
- "version": "5.43.4",
3
+ "version": "5.43.6",
4
4
  "type": "module",
5
5
  "main": "./dist/index.umd.cjs",
6
6
  "module": "./dist/index.js",
@@ -125,7 +125,7 @@ exports[`Checkbox Component > it renders the Checkbox correctly 1`] = `
125
125
  >
126
126
  <div>
127
127
  <svg
128
- class="properties_color_inverted.primary_base__146hxcf23u properties_height_5_base__146hxcf74 properties_width_5_base__146hxcf4c"
128
+ class="properties_color_inverted.primary_base__146hxcf27a properties_height_5_base__146hxcf7q properties_width_5_base__146hxcf4e"
129
129
  data-ictinus="test-version"
130
130
  data-testid="test_test_unselected"
131
131
  viewBox="0 0 20 20"
@@ -603,7 +603,7 @@ exports[`OverlayComponent > should render correctly 1`] = `
603
603
  type="button"
604
604
  >
605
605
  <svg
606
- class="properties_color_active_base__146hxcf23a properties_height_5_base__146hxcf74 properties_width_5_base__146hxcf4c"
606
+ class="properties_color_active_base__146hxcf26q properties_height_5_base__146hxcf7q properties_width_5_base__146hxcf4e"
607
607
  data-ictinus="test-version"
608
608
  viewBox="0 0 20 20"
609
609
  xmlns="http://www.w3.org/2000/svg"
@@ -660,7 +660,7 @@ exports[`OverlayComponent > should render correctly 1`] = `
660
660
  type="button"
661
661
  >
662
662
  <svg
663
- class="properties_color_active_base__146hxcf23a properties_height_5_base__146hxcf74 properties_width_5_base__146hxcf4c"
663
+ class="properties_color_active_base__146hxcf26q properties_height_5_base__146hxcf7q properties_width_5_base__146hxcf4e"
664
664
  data-ictinus="test-version"
665
665
  viewBox="0 0 20 20"
666
666
  xmlns="http://www.w3.org/2000/svg"
@@ -1945,7 +1945,7 @@ exports[`OverlayComponent > should render datepicker correctly 1`] = `
1945
1945
  type="button"
1946
1946
  >
1947
1947
  <svg
1948
- class="properties_color_active_base__146hxcf23a properties_height_5_base__146hxcf74 properties_width_5_base__146hxcf4c"
1948
+ class="properties_color_active_base__146hxcf26q properties_height_5_base__146hxcf7q properties_width_5_base__146hxcf4e"
1949
1949
  data-ictinus="test-version"
1950
1950
  viewBox="0 0 20 20"
1951
1951
  xmlns="http://www.w3.org/2000/svg"
@@ -2585,7 +2585,7 @@ exports[`OverlayComponent > should render datepicker correctly 1`] = `
2585
2585
  type="button"
2586
2586
  >
2587
2587
  <svg
2588
- class="properties_color_active_base__146hxcf23a properties_height_5_base__146hxcf74 properties_width_5_base__146hxcf4c"
2588
+ class="properties_color_active_base__146hxcf26q properties_height_5_base__146hxcf7q properties_width_5_base__146hxcf4e"
2589
2589
  data-ictinus="test-version"
2590
2590
  viewBox="0 0 20 20"
2591
2591
  xmlns="http://www.w3.org/2000/svg"
@@ -474,7 +474,7 @@ exports[`MonthWrapper > should render correctly 1`] = `
474
474
  type="button"
475
475
  >
476
476
  <svg
477
- class="properties_color_active_base__146hxcf23a properties_height_5_base__146hxcf74 properties_width_5_base__146hxcf4c"
477
+ class="properties_color_active_base__146hxcf26q properties_height_5_base__146hxcf7q properties_width_5_base__146hxcf4e"
478
478
  data-ictinus="test-version"
479
479
  viewBox="0 0 20 20"
480
480
  xmlns="http://www.w3.org/2000/svg"
@@ -531,7 +531,7 @@ exports[`MonthWrapper > should render correctly 1`] = `
531
531
  type="button"
532
532
  >
533
533
  <svg
534
- class="properties_color_active_base__146hxcf23a properties_height_5_base__146hxcf74 properties_width_5_base__146hxcf4c"
534
+ class="properties_color_active_base__146hxcf26q properties_height_5_base__146hxcf7q properties_width_5_base__146hxcf4e"
535
535
  data-ictinus="test-version"
536
536
  viewBox="0 0 20 20"
537
537
  xmlns="http://www.w3.org/2000/svg"
@@ -367,7 +367,7 @@ exports[`TopAppBar > should render correctly 1`] = `
367
367
  Tom Cruise
368
368
  </span>
369
369
  <svg
370
- class="properties_color_active_base__146hxcf23a properties_height_5_base__146hxcf74 properties_width_5_base__146hxcf4c"
370
+ class="properties_color_active_base__146hxcf26q properties_height_5_base__146hxcf7q properties_width_5_base__146hxcf4e"
371
371
  data-ictinus="test-version"
372
372
  viewBox="0 0 20 20"
373
373
  xmlns="http://www.w3.org/2000/svg"
@@ -751,7 +751,7 @@ exports[`TopAppBar > should render correctly on dark 1`] = `
751
751
  Tom Cruise
752
752
  </span>
753
753
  <svg
754
- class="properties_color_active_base__146hxcf23a properties_height_5_base__146hxcf74 properties_width_5_base__146hxcf4c"
754
+ class="properties_color_active_base__146hxcf26q properties_height_5_base__146hxcf7q properties_width_5_base__146hxcf4e"
755
755
  data-ictinus="test-version"
756
756
  viewBox="0 0 20 20"
757
757
  xmlns="http://www.w3.org/2000/svg"
@@ -1,3 +1,4 @@
1
+ import type { Row, RowData } from '@tanstack/react-table';
1
2
  import type { Table } from '@tanstack/table-core';
2
3
 
3
4
  import { forwardRef, useState } from 'react';
@@ -34,3 +35,18 @@ export const DataTable = forwardRef<HTMLDivElement, DataTableProps>(
34
35
  );
35
36
 
36
37
  DataTable.displayName = 'DataTable';
38
+
39
+ declare module '@tanstack/react-table' {
40
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars, unused-imports/no-unused-vars
41
+ interface ColumnMeta<TData extends RowData, TValue> {
42
+ align?: 'flex-start' | 'center' | 'flex-end';
43
+ label?: string;
44
+ tooltip?: string;
45
+ // backward compatibility with old v5 table
46
+ contentAlign?: 'left' | 'center' | 'right';
47
+ }
48
+
49
+ interface TableMeta<TData extends RowData> {
50
+ getCellProps?: (row: Row<TData>) => Omit<BoxProps<'td'>, 'size'>;
51
+ }
52
+ }
@@ -1,7 +1,7 @@
1
- import { flexRender } from '@tanstack/react-table';
1
+ import { flexRender, type Row } from '@tanstack/react-table';
2
2
  import { useVirtualizer } from '@tanstack/react-virtual';
3
3
  import { assignInlineVars } from '@vanilla-extract/dynamic';
4
- import { forwardRef, type RefObject, useEffect, useRef } from 'react';
4
+ import { forwardRef, type RefObject, useEffect, useMemo, useRef } from 'react';
5
5
  import { useDOMRef } from '~/components/utils/useDOMRef';
6
6
  import { cn } from '../utils/cn';
7
7
  import { Box, type BoxProps } from '../vanilla/Box';
@@ -9,20 +9,26 @@ import { Table, TableBody, TableCell, TableHeader, TableRow } from '../vanilla/T
9
9
  import { useDataTableContext } from './DataTableContext';
10
10
  import { DataTableHeaderCell } from './DataTableHeaderCell';
11
11
  import { DataTableRow } from './DataTableRow';
12
+ import { fakeRow } from './DataTableRowContext';
12
13
 
13
14
  import * as styles from './DataTableBody.css';
14
15
 
16
+ function isTableRow(row: Row<unknown> | ReturnType<typeof fakeRow>): row is Row<unknown> {
17
+ return 'original' in row;
18
+ }
19
+
15
20
  export type DataTableBodyProps = BoxProps<
16
21
  'div',
17
22
  {
18
23
  estimatedRowHeight?: number;
19
24
  bordered?: boolean;
20
25
  size?: 'sm' | 'md' | 'lg';
26
+ loading?: boolean | Record<string, 'sub-rows' | false>;
21
27
  }
22
28
  >;
23
29
 
24
- const COL_VIRTUALIZATION_THRESHOLD = 20;
25
- const ROW_VIRTUALIZATION_THRESHOLD = 20;
30
+ const COL_VIRTUALIZATION_THRESHOLD = 25;
31
+ const ROW_VIRTUALIZATION_THRESHOLD = 25;
26
32
 
27
33
  export const DataTableBody = forwardRef<HTMLDivElement, DataTableBodyProps>(
28
34
  (
@@ -31,6 +37,7 @@ export const DataTableBody = forwardRef<HTMLDivElement, DataTableBodyProps>(
31
37
  estimatedRowHeight = 44,
32
38
  bordered = false,
33
39
  size = 'sm',
40
+ loading,
34
41
  style,
35
42
  ...props
36
43
  }: DataTableBodyProps,
@@ -40,7 +47,24 @@ export const DataTableBody = forwardRef<HTMLDivElement, DataTableBodyProps>(
40
47
 
41
48
  const { table } = useDataTableContext();
42
49
 
43
- const rows = table.getRowModel().rows;
50
+ const { rows: rawRows } = table.getRowModel();
51
+ const rows = useMemo(() => {
52
+ let index = 0;
53
+
54
+ return rawRows.reduce<Array<(typeof rawRows)[number] | ReturnType<typeof fakeRow>>>(
55
+ (result, row) => {
56
+ result.push(row);
57
+ index++;
58
+ if (loading && typeof loading === 'object' && loading[row.id] === 'sub-rows') {
59
+ result.push(fakeRow(table, index++), fakeRow(table, index++));
60
+ }
61
+
62
+ return result;
63
+ },
64
+ []
65
+ );
66
+ }, [loading, rawRows, table]);
67
+
44
68
  const previousRowsRef = useRef(rows);
45
69
  useEffect(() => {
46
70
  previousRowsRef.current = rows;
@@ -163,115 +187,135 @@ export const DataTableBody = forwardRef<HTMLDivElement, DataTableBodyProps>(
163
187
  : undefined
164
188
  }
165
189
  >
166
- {(rowVirtualizer.options.enabled
167
- ? virtualRows.length === 0 && rows.length > 0
168
- ? previousRowsRef.current.map((row) => ({
169
- row,
170
- virtualRow: undefined,
171
- }))
172
- : virtualRows.map((virtualRow) => ({
173
- row: rows[virtualRow.index],
174
- virtualRow,
175
- }))
176
- : rows.map((row) => ({ row, virtualRow: undefined }))
177
- ).map(({ row, virtualRow }, index) => (
178
- <DataTableRow
179
- data-index={virtualRow?.index}
180
- display="flex"
181
- key={row.id}
182
- index={virtualRow?.index ?? index}
183
- row={row}
184
- ref={virtualRow ? rowVirtualizer.measureElement : undefined}
185
- style={
186
- virtualRow
187
- ? {
188
- position: 'absolute',
189
- transform: `translateY(${virtualRow.start}px)`,
190
- }
191
- : undefined
192
- }
193
- >
194
- {row.getLeftVisibleCells().map((cell) => (
195
- <TableCell
196
- bordered={bordered}
197
- size={size}
198
- justifyContent={cell.column.columnDef.meta?.align}
199
- key={cell.id}
200
- pinned
201
- style={{
202
- ...assignInlineVars({
203
- [styles.cellOffsetVar]: `${cell.column.getStart('left')}px`,
204
- [styles.cellSizeVar]: `${cell.column.getSize()}`,
205
- }),
206
- }}
207
- className={cn(
208
- styles.cell({
209
- pinned: 'left',
210
- resizable: cell.column.getCanResize(),
211
- })
212
- )}
213
- >
214
- {flexRender(cell.column.columnDef.cell, cell.getContext())}
215
- </TableCell>
216
- ))}
190
+ {(loading === true
191
+ ? Array.from({ length: 10 }, (__, rowIndex) => ({
192
+ row: fakeRow(table, rowIndex),
193
+ virtualRow: undefined,
194
+ }))
195
+ : rowVirtualizer.options.enabled
196
+ ? virtualRows.length === 0 && rows.length > 0
197
+ ? previousRowsRef.current.map((row) => ({
198
+ row,
199
+ virtualRow: undefined,
200
+ }))
201
+ : virtualRows.map((virtualRow) => ({
202
+ row: rows[virtualRow.index],
203
+ virtualRow,
204
+ }))
205
+ : rows.map((row) => ({ row, virtualRow: undefined }))
206
+ ).map(({ row, virtualRow }, index) => {
207
+ const cellProps = isTableRow(row)
208
+ ? table.options.meta?.getCellProps?.(row)
209
+ : undefined;
217
210
 
218
- {columnVirtualizer.options.enabled && virtualColumnsOffset > 0 && (
219
- <TableCell style={{ width: virtualColumnsOffset }} />
220
- )}
211
+ return (
212
+ <DataTableRow
213
+ data-index={virtualRow?.index}
214
+ display="flex"
215
+ key={row.id}
216
+ index={virtualRow?.index ?? index}
217
+ row={row}
218
+ ref={virtualRow ? rowVirtualizer.measureElement : undefined}
219
+ style={
220
+ virtualRow
221
+ ? {
222
+ position: 'absolute',
223
+ transform: `translateY(${virtualRow.start}px)`,
224
+ }
225
+ : undefined
226
+ }
227
+ >
228
+ {row.getLeftVisibleCells().map((cell) => (
229
+ <TableCell
230
+ bordered={bordered}
231
+ size={size}
232
+ justifyContent={cell.column.columnDef.meta?.align}
233
+ key={cell.id}
234
+ pinned
235
+ {...cellProps}
236
+ style={{
237
+ ...assignInlineVars({
238
+ [styles.cellOffsetVar]: `${cell.column.getStart('left')}px`,
239
+ [styles.cellSizeVar]: `${cell.column.getSize()}`,
240
+ }),
241
+ ...cellProps?.style,
242
+ }}
243
+ className={cn(
244
+ styles.cell({
245
+ pinned: 'left',
246
+ resizable: cell.column.getCanResize(),
247
+ }),
248
+ cellProps?.className
249
+ )}
250
+ >
251
+ {flexRender(cell.column.columnDef.cell, cell.getContext())}
252
+ </TableCell>
253
+ ))}
221
254
 
222
- {(columnVirtualizer.options.enabled
223
- ? virtualColumns.map((virtualCell) => {
224
- const cells = row.getCenterVisibleCells();
255
+ {columnVirtualizer.options.enabled && virtualColumnsOffset > 0 && (
256
+ <TableCell style={{ width: virtualColumnsOffset }} />
257
+ )}
225
258
 
226
- return cells[virtualCell.index];
227
- })
228
- : row.getCenterVisibleCells()
229
- ).map((cell) => (
230
- <TableCell
231
- key={cell.id}
232
- size={size}
233
- bordered={bordered}
234
- justifyContent={cell.column.columnDef.meta?.align}
235
- style={{
236
- ...assignInlineVars({
237
- [styles.cellSizeVar]: `${cell.column.getSize()}`,
238
- }),
239
- }}
240
- className={cn(
241
- styles.cell({
242
- resizable: cell.column.getCanResize(),
243
- })
244
- )}
245
- >
246
- {flexRender(cell.column.columnDef.cell, cell.getContext())}
247
- </TableCell>
248
- ))}
259
+ {(columnVirtualizer.options.enabled
260
+ ? virtualColumns.map((virtualCell) => {
261
+ const cells = row.getCenterVisibleCells();
249
262
 
250
- {row.getRightVisibleCells().map((cell) => (
251
- <TableCell
252
- key={cell.id}
253
- size={size}
254
- bordered={bordered}
255
- justifyContent={cell.column.columnDef.meta?.align}
256
- pinned
257
- style={{
258
- ...assignInlineVars({
259
- [styles.cellOffsetVar]: `${cell.column.getStart('right')}px`,
260
- [styles.cellSizeVar]: `${cell.column.getSize()}`,
261
- }),
262
- }}
263
- className={cn(
264
- styles.cell({
265
- pinned: 'right',
266
- resizable: cell.column.getCanResize(),
263
+ return cells[virtualCell.index];
267
264
  })
268
- )}
269
- >
270
- {flexRender(cell.column.columnDef.cell, cell.getContext())}
271
- </TableCell>
272
- ))}
273
- </DataTableRow>
274
- ))}
265
+ : row.getCenterVisibleCells()
266
+ ).map((cell) => (
267
+ <TableCell
268
+ key={cell.id}
269
+ size={size}
270
+ bordered={bordered}
271
+ justifyContent={cell.column.columnDef.meta?.align}
272
+ {...cellProps}
273
+ style={{
274
+ ...assignInlineVars({
275
+ [styles.cellSizeVar]: `${cell.column.getSize()}`,
276
+ }),
277
+ ...cellProps?.style,
278
+ }}
279
+ className={cn(
280
+ styles.cell({
281
+ resizable: cell.column.getCanResize(),
282
+ }),
283
+ cellProps?.className
284
+ )}
285
+ >
286
+ {flexRender(cell.column.columnDef.cell, cell.getContext())}
287
+ </TableCell>
288
+ ))}
289
+
290
+ {row.getRightVisibleCells().map((cell) => (
291
+ <TableCell
292
+ key={cell.id}
293
+ size={size}
294
+ bordered={bordered}
295
+ justifyContent={cell.column.columnDef.meta?.align}
296
+ pinned
297
+ {...cellProps}
298
+ style={{
299
+ ...assignInlineVars({
300
+ [styles.cellOffsetVar]: `${cell.column.getStart('right')}px`,
301
+ [styles.cellSizeVar]: `${cell.column.getSize()}`,
302
+ }),
303
+ ...cellProps?.style,
304
+ }}
305
+ className={cn(
306
+ styles.cell({
307
+ pinned: 'right',
308
+ resizable: cell.column.getCanResize(),
309
+ }),
310
+ cellProps?.className
311
+ )}
312
+ >
313
+ {flexRender(cell.column.columnDef.cell, cell.getContext())}
314
+ </TableCell>
315
+ ))}
316
+ </DataTableRow>
317
+ );
318
+ })}
275
319
  </TableBody>
276
320
  </Table>
277
321
  </Box>
@@ -1,3 +1,4 @@
1
+ import { Skeleton } from '../skeleton';
1
2
  import { Box, type BoxProps } from '../vanilla/Box';
2
3
  import { Text } from '../vanilla/Text';
3
4
  import { useDataTableContext } from './DataTableContext';
@@ -6,6 +7,7 @@ export type DataTableCounterProps = BoxProps<
6
7
  'div',
7
8
  {
8
9
  count?: number;
10
+ loading?: boolean;
9
11
  singular?: string;
10
12
  plural?: string;
11
13
  }
@@ -13,6 +15,7 @@ export type DataTableCounterProps = BoxProps<
13
15
 
14
16
  export function DataTableCounter({
15
17
  count: countProp,
18
+ loading = false,
16
19
  singular = 'item',
17
20
  plural = 'items',
18
21
  ...props
@@ -28,10 +31,16 @@ export function DataTableCounter({
28
31
 
29
32
  return (
30
33
  <Box display="flex" alignItems="center" gap="sm" {...props}>
31
- <Text typography="label02" color="active">
32
- {count.toLocaleString()}
33
- </Text>
34
- <Text typography="label02">{hasSelection ? `${label} selected` : label}</Text>
34
+ {loading ? (
35
+ <Skeleton w="20" />
36
+ ) : (
37
+ <>
38
+ <Text typography="label02" color="active">
39
+ {count.toLocaleString()}
40
+ </Text>
41
+ <Text typography="label02">{hasSelection ? `${label} selected` : label}</Text>
42
+ </>
43
+ )}
35
44
  </Box>
36
45
  );
37
46
  }
@@ -1,4 +1,3 @@
1
- import type { Row } from '@tanstack/table-core';
2
1
  import {
3
2
  forwardRef,
4
3
  type MouseEvent,
@@ -12,9 +11,9 @@ import { useDOMRef } from '../components/utils/useDOMRef';
12
11
  import type { BoxProps } from '../vanilla/Box';
13
12
  import { TableRow } from '../vanilla/Table';
14
13
  import { useDataTableContext } from './DataTableContext';
15
- import { DataTableRowProvider } from './DataTableRowContext';
14
+ import { DataTableRowProvider, type fakeRow } from './DataTableRowContext';
16
15
 
17
- export type DataTableRowProps<TData> = BoxProps<
16
+ export type DataTableRowProps = BoxProps<
18
17
  typeof TableRow,
19
18
  {
20
19
  /**
@@ -24,11 +23,11 @@ export type DataTableRowProps<TData> = BoxProps<
24
23
  /**
25
24
  * The Row instance to render.
26
25
  */
27
- row: Row<TData>;
26
+ row: ReturnType<typeof fakeRow>;
28
27
  }
29
28
  >;
30
29
 
31
- export const DataTableRow = forwardRef<HTMLTableRowElement, DataTableRowProps<unknown>>(
30
+ export const DataTableRow = forwardRef<HTMLTableRowElement, DataTableRowProps>(
32
31
  ({ children, index, row, ...props }, ref: RefObject<HTMLTableRowElement>) => {
33
32
  const { highlightedIndex, setHighlightedIndex, table } = useDataTableContext();
34
33
 
@@ -1,7 +1,8 @@
1
- import type { Row } from '@tanstack/table-core';
2
- import { createContext, useContext, type RefObject } from 'react';
1
+ import type { CellContext, Column, Table } from '@tanstack/table-core';
2
+ import { createContext, createElement, useContext, type RefObject } from 'react';
3
+ import { Skeleton } from '../skeleton';
3
4
 
4
- export type DataTableRowContextValue<TData = unknown> = {
5
+ export type DataTableRowContextValue = {
5
6
  actions: Array<RefObject<HTMLDivElement>>;
6
7
  focusManaged: boolean | undefined;
7
8
  highlightedIndex: number;
@@ -9,7 +10,7 @@ export type DataTableRowContextValue<TData = unknown> = {
9
10
  onActionMount:
10
11
  | ((params: { primary: boolean | undefined; ref: RefObject<HTMLDivElement> }) => () => void)
11
12
  | undefined;
12
- row: Row<TData> | undefined;
13
+ row: ReturnType<typeof fakeRow> | undefined;
13
14
  setHighlightedIndex: ((highlightedIndex: number) => void) | undefined;
14
15
  setSelector: ((ref: RefObject<HTMLLabelElement> | undefined) => void) | undefined;
15
16
  };
@@ -36,3 +37,31 @@ export function useDataTableRowContext() {
36
37
 
37
38
  return context;
38
39
  }
40
+
41
+ const fakeCellsFactory = (columns: Column<unknown, unknown>[], rowIndex: number) => () =>
42
+ columns.map((column, columnIndex) => ({
43
+ column: {
44
+ ...column,
45
+ columnDef: {
46
+ ...column.columnDef,
47
+ cell: () =>
48
+ createElement(Skeleton, {
49
+ w: (['1/2', 'full', '3/4'] as const)[(rowIndex + columnIndex) % 3],
50
+ }),
51
+ },
52
+ } as Column<unknown, unknown>,
53
+ getContext: () => ({}) as CellContext<unknown, unknown>,
54
+ id: column.id,
55
+ }));
56
+
57
+ export const fakeRow = (table: Table<unknown>, rowIndex: number) => ({
58
+ getCanMultiSelect: () => false,
59
+ getCanSelect: () => false,
60
+ getCenterVisibleCells: fakeCellsFactory(table.getCenterVisibleLeafColumns(), rowIndex),
61
+ getIsSelected: () => false,
62
+ getLeftVisibleCells: fakeCellsFactory(table.getLeftVisibleLeafColumns(), rowIndex),
63
+ getRightVisibleCells: fakeCellsFactory(table.getRightVisibleLeafColumns(), rowIndex),
64
+ getToggleSelectedHandler: () => (__event: unknown) => {},
65
+ id: 'loading' + rowIndex,
66
+ toggleSelected: (__value?: boolean) => {},
67
+ });
@@ -0,0 +1,19 @@
1
+ import { recipe } from '@vanilla-extract/recipes';
2
+ import { sprinkles } from '../sprinkles';
3
+ import { style } from '../vanilla-extract';
4
+
5
+ export const skeleton = recipe({
6
+ base: [
7
+ sprinkles({
8
+ animation: 'pulse',
9
+ bg: 'alt',
10
+ color: 'secondary',
11
+ display: 'block',
12
+ }),
13
+ style({
14
+ selectors: {
15
+ '&:empty:before': { content: '"\\00a0"' },
16
+ },
17
+ }),
18
+ ],
19
+ });
@@ -0,0 +1,34 @@
1
+ import { createSlot } from '@radix-ui/react-slot';
2
+ import { forwardRef, type ReactElement } from 'react';
3
+
4
+ import { cn } from '../utils/cn';
5
+ import { Box, type BoxProps } from '../vanilla/Box';
6
+ import * as styles from './Skeleton.css';
7
+
8
+ const Slot = createSlot('@orfium/ictinus/Skeleton');
9
+
10
+ export type SkeletonProps = BoxProps<
11
+ 'span',
12
+ {
13
+ children?: ReactElement;
14
+ circle?: boolean;
15
+ rounded?: BoxProps['rounded'];
16
+ }
17
+ >;
18
+
19
+ export const Skeleton = forwardRef<HTMLSpanElement, SkeletonProps>(
20
+ ({ asChild = true, children, circle, className, rounded = '2', ...props }, ref) => {
21
+ return (
22
+ <Box
23
+ asChild={asChild}
24
+ rounded={circle || rounded === '7' ? '7' : rounded}
25
+ className={cn(styles.skeleton({}), className)}
26
+ {...props}
27
+ >
28
+ <Slot ref={ref}>{children ?? <span />}</Slot>
29
+ </Box>
30
+ );
31
+ }
32
+ );
33
+
34
+ Skeleton.displayName = 'Skeleton';
@@ -0,0 +1 @@
1
+ export * from './Skeleton';