@dxos/react-ui-table 0.8.1-main.ba2dec9 → 0.8.1-staging.31c3ee1

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 (191) hide show
  1. package/dist/lib/browser/{chunk-3FR6NHPD.mjs → chunk-YWNRUF4J.mjs} +8 -6
  2. package/dist/lib/browser/chunk-YWNRUF4J.mjs.map +7 -0
  3. package/dist/lib/browser/index.mjs +625 -225
  4. package/dist/lib/browser/index.mjs.map +4 -4
  5. package/dist/lib/browser/meta.json +1 -1
  6. package/dist/lib/browser/types/index.mjs +1 -1
  7. package/dist/lib/node/{chunk-NB3SFHGA.cjs → chunk-TGG6OZ54.cjs} +10 -8
  8. package/dist/lib/node/chunk-TGG6OZ54.cjs.map +7 -0
  9. package/dist/lib/node/index.cjs +618 -220
  10. package/dist/lib/node/index.cjs.map +4 -4
  11. package/dist/lib/node/meta.json +1 -1
  12. package/dist/lib/node/types/index.cjs +3 -3
  13. package/dist/lib/node/types/index.cjs.map +1 -1
  14. package/dist/lib/node-esm/{chunk-RLVVOZW5.mjs → chunk-KKLP54L3.mjs} +8 -6
  15. package/dist/lib/node-esm/chunk-KKLP54L3.mjs.map +7 -0
  16. package/dist/lib/node-esm/index.mjs +625 -225
  17. package/dist/lib/node-esm/index.mjs.map +4 -4
  18. package/dist/lib/node-esm/meta.json +1 -1
  19. package/dist/lib/node-esm/types/index.mjs +1 -1
  20. package/dist/types/src/components/Table/ColumnActionsMenu.d.ts.map +1 -1
  21. package/dist/types/src/components/Table/ColumnSettings.d.ts.map +1 -1
  22. package/dist/types/src/components/Table/DynamicTable.d.ts +24 -0
  23. package/dist/types/src/components/Table/DynamicTable.d.ts.map +1 -0
  24. package/dist/types/src/components/Table/DynamicTable.stories.d.ts +10 -0
  25. package/dist/types/src/components/Table/DynamicTable.stories.d.ts.map +1 -0
  26. package/dist/types/src/components/Table/RowActionsMenu.d.ts.map +1 -1
  27. package/dist/types/src/components/Table/Table.d.ts +1 -0
  28. package/dist/types/src/components/Table/Table.d.ts.map +1 -1
  29. package/dist/types/src/components/Table/Table.stories.d.ts +4 -3
  30. package/dist/types/src/components/Table/Table.stories.d.ts.map +1 -1
  31. package/dist/types/src/components/Table/index.d.ts +1 -0
  32. package/dist/types/src/components/Table/index.d.ts.map +1 -1
  33. package/dist/types/src/components/Table/relations.stories.d.ts +9 -0
  34. package/dist/types/src/components/Table/relations.stories.d.ts.map +1 -0
  35. package/dist/types/src/components/TableCellEditor/TableCellEditor.d.ts.map +1 -1
  36. package/dist/types/src/components/TableCellEditor/TableCellEditor.stories.d.ts.map +1 -1
  37. package/dist/types/src/components/testing.d.ts +7 -7
  38. package/dist/types/src/components/testing.d.ts.map +1 -1
  39. package/dist/types/src/hooks/useTableModel.d.ts +8 -9
  40. package/dist/types/src/hooks/useTableModel.d.ts.map +1 -1
  41. package/dist/types/src/model/index.d.ts +1 -0
  42. package/dist/types/src/model/index.d.ts.map +1 -1
  43. package/dist/types/src/model/selection-model.d.ts +6 -3
  44. package/dist/types/src/model/selection-model.d.ts.map +1 -1
  45. package/dist/types/src/model/table-model.d.ts +42 -16
  46. package/dist/types/src/model/table-model.d.ts.map +1 -1
  47. package/dist/types/src/model/table-presentation.d.ts +4 -4
  48. package/dist/types/src/model/table-presentation.d.ts.map +1 -1
  49. package/dist/types/src/model/table-sorting.d.ts +2 -2
  50. package/dist/types/src/model/table-sorting.d.ts.map +1 -1
  51. package/dist/types/src/types/table.d.ts +7 -32
  52. package/dist/types/src/types/table.d.ts.map +1 -1
  53. package/dist/types/src/util/dynamic-table.d.ts +31 -0
  54. package/dist/types/src/util/dynamic-table.d.ts.map +1 -0
  55. package/dist/types/src/util/index.d.ts +1 -0
  56. package/dist/types/src/util/index.d.ts.map +1 -1
  57. package/dist/types/src/util/table-controls.d.ts +2 -2
  58. package/dist/types/src/util/table-controls.d.ts.map +1 -1
  59. package/dist/types/src/util/table.d.ts +5 -3
  60. package/dist/types/src/util/table.d.ts.map +1 -1
  61. package/package.json +38 -37
  62. package/src/components/Table/ColumnActionsMenu.tsx +6 -4
  63. package/src/components/Table/ColumnSettings.tsx +5 -6
  64. package/src/components/Table/CreateRefPanel.tsx +3 -3
  65. package/src/components/Table/DynamicTable.stories.tsx +155 -0
  66. package/src/components/Table/DynamicTable.tsx +104 -0
  67. package/src/components/Table/RefPanel.tsx +3 -3
  68. package/src/components/Table/RowActionsMenu.tsx +18 -3
  69. package/src/components/Table/Table.stories.tsx +170 -115
  70. package/src/components/Table/Table.tsx +71 -26
  71. package/src/components/Table/index.ts +1 -0
  72. package/src/components/Table/relations.stories.tsx +113 -0
  73. package/src/components/TableCellEditor/TableCellEditor.stories.tsx +15 -5
  74. package/src/components/TableCellEditor/TableCellEditor.tsx +102 -4
  75. package/src/components/testing.ts +1 -1
  76. package/src/hooks/useTableModel.ts +35 -14
  77. package/src/model/index.ts +1 -0
  78. package/src/model/selection-model.ts +12 -2
  79. package/src/model/table-model.test.ts +2 -2
  80. package/src/model/table-model.ts +117 -32
  81. package/src/model/table-presentation.test.ts +2 -2
  82. package/src/model/table-presentation.ts +94 -22
  83. package/src/model/table-sorting.ts +3 -2
  84. package/src/playwright/smoke.spec.ts +2 -3
  85. package/src/types/table.ts +9 -10
  86. package/src/util/dynamic-table.ts +103 -0
  87. package/src/util/index.ts +1 -0
  88. package/src/util/table-controls.ts +4 -4
  89. package/src/util/table.ts +68 -65
  90. package/dist/lib/browser/_deprecated/index.mjs +0 -1483
  91. package/dist/lib/browser/_deprecated/index.mjs.map +0 -7
  92. package/dist/lib/browser/chunk-3FR6NHPD.mjs.map +0 -7
  93. package/dist/lib/node/_deprecated/index.cjs +0 -1511
  94. package/dist/lib/node/_deprecated/index.cjs.map +0 -7
  95. package/dist/lib/node/chunk-NB3SFHGA.cjs.map +0 -7
  96. package/dist/lib/node-esm/_deprecated/index.mjs +0 -1485
  97. package/dist/lib/node-esm/_deprecated/index.mjs.map +0 -7
  98. package/dist/lib/node-esm/chunk-RLVVOZW5.mjs.map +0 -7
  99. package/dist/types/src/_deprecated/components/Cell/Cell.d.ts +0 -12
  100. package/dist/types/src/_deprecated/components/Cell/Cell.d.ts.map +0 -1
  101. package/dist/types/src/_deprecated/components/Cell/CellCombobox.d.ts +0 -13
  102. package/dist/types/src/_deprecated/components/Cell/CellCombobox.d.ts.map +0 -1
  103. package/dist/types/src/_deprecated/components/Cell/index.d.ts +0 -2
  104. package/dist/types/src/_deprecated/components/Cell/index.d.ts.map +0 -1
  105. package/dist/types/src/_deprecated/components/ColumnMenu/ColumnMenu.d.ts +0 -23
  106. package/dist/types/src/_deprecated/components/ColumnMenu/ColumnMenu.d.ts.map +0 -1
  107. package/dist/types/src/_deprecated/components/ColumnMenu/ColumnMenu.stories.d.ts +0 -36
  108. package/dist/types/src/_deprecated/components/ColumnMenu/ColumnMenu.stories.d.ts.map +0 -1
  109. package/dist/types/src/_deprecated/components/ColumnMenu/ColumnSettings.d.ts +0 -15
  110. package/dist/types/src/_deprecated/components/ColumnMenu/ColumnSettings.d.ts.map +0 -1
  111. package/dist/types/src/_deprecated/components/ColumnMenu/ColumnSettings.stories.d.ts +0 -84
  112. package/dist/types/src/_deprecated/components/ColumnMenu/ColumnSettings.stories.d.ts.map +0 -1
  113. package/dist/types/src/_deprecated/components/ColumnMenu/index.d.ts +0 -3
  114. package/dist/types/src/_deprecated/components/ColumnMenu/index.d.ts.map +0 -1
  115. package/dist/types/src/_deprecated/components/Table/Table.d.ts +0 -20
  116. package/dist/types/src/_deprecated/components/Table/Table.d.ts.map +0 -1
  117. package/dist/types/src/_deprecated/components/Table/Table.stories.d.ts +0 -116
  118. package/dist/types/src/_deprecated/components/Table/Table.stories.d.ts.map +0 -1
  119. package/dist/types/src/_deprecated/components/Table/TableBody.d.ts +0 -12
  120. package/dist/types/src/_deprecated/components/Table/TableBody.d.ts.map +0 -1
  121. package/dist/types/src/_deprecated/components/Table/TableContext.d.ts +0 -13
  122. package/dist/types/src/_deprecated/components/Table/TableContext.d.ts.map +0 -1
  123. package/dist/types/src/_deprecated/components/Table/TableHead.d.ts +0 -9
  124. package/dist/types/src/_deprecated/components/Table/TableHead.d.ts.map +0 -1
  125. package/dist/types/src/_deprecated/components/Table/TableRootContext.d.ts +0 -17
  126. package/dist/types/src/_deprecated/components/Table/TableRootContext.d.ts.map +0 -1
  127. package/dist/types/src/_deprecated/components/Table/index.d.ts +0 -5
  128. package/dist/types/src/_deprecated/components/Table/index.d.ts.map +0 -1
  129. package/dist/types/src/_deprecated/components/Table/props.d.ts +0 -42
  130. package/dist/types/src/_deprecated/components/Table/props.d.ts.map +0 -1
  131. package/dist/types/src/_deprecated/components/index.d.ts +0 -4
  132. package/dist/types/src/_deprecated/components/index.d.ts.map +0 -1
  133. package/dist/types/src/_deprecated/helpers.d.ts +0 -91
  134. package/dist/types/src/_deprecated/helpers.d.ts.map +0 -1
  135. package/dist/types/src/_deprecated/hooks/index.d.ts +0 -5
  136. package/dist/types/src/_deprecated/hooks/index.d.ts.map +0 -1
  137. package/dist/types/src/_deprecated/hooks/useColumnSizing.d.ts +0 -12
  138. package/dist/types/src/_deprecated/hooks/useColumnSizing.d.ts.map +0 -1
  139. package/dist/types/src/_deprecated/hooks/useColumnSorting.d.ts +0 -15
  140. package/dist/types/src/_deprecated/hooks/useColumnSorting.d.ts.map +0 -1
  141. package/dist/types/src/_deprecated/hooks/usePinLastRow.d.ts +0 -3
  142. package/dist/types/src/_deprecated/hooks/usePinLastRow.d.ts.map +0 -1
  143. package/dist/types/src/_deprecated/hooks/useRowSelection.d.ts +0 -7
  144. package/dist/types/src/_deprecated/hooks/useRowSelection.d.ts.map +0 -1
  145. package/dist/types/src/_deprecated/index.d.ts +0 -8
  146. package/dist/types/src/_deprecated/index.d.ts.map +0 -1
  147. package/dist/types/src/_deprecated/schema/Schema.stories.d.ts +0 -11
  148. package/dist/types/src/_deprecated/schema/Schema.stories.d.ts.map +0 -1
  149. package/dist/types/src/_deprecated/schema/column-utils.d.ts +0 -7
  150. package/dist/types/src/_deprecated/schema/column-utils.d.ts.map +0 -1
  151. package/dist/types/src/_deprecated/schema/index.d.ts +0 -3
  152. package/dist/types/src/_deprecated/schema/index.d.ts.map +0 -1
  153. package/dist/types/src/_deprecated/schema/types.d.ts +0 -27
  154. package/dist/types/src/_deprecated/schema/types.d.ts.map +0 -1
  155. package/dist/types/src/_deprecated/theme.d.ts +0 -29
  156. package/dist/types/src/_deprecated/theme.d.ts.map +0 -1
  157. package/dist/types/src/_deprecated/translations.d.ts +0 -21
  158. package/dist/types/src/_deprecated/translations.d.ts.map +0 -1
  159. package/dist/types/src/_deprecated/types.d.ts +0 -26
  160. package/dist/types/src/_deprecated/types.d.ts.map +0 -1
  161. package/src/_deprecated/components/Cell/Cell.tsx +0 -88
  162. package/src/_deprecated/components/Cell/CellCombobox.tsx +0 -103
  163. package/src/_deprecated/components/Cell/index.ts +0 -5
  164. package/src/_deprecated/components/ColumnMenu/ColumnMenu.stories.tsx +0 -129
  165. package/src/_deprecated/components/ColumnMenu/ColumnMenu.tsx +0 -182
  166. package/src/_deprecated/components/ColumnMenu/ColumnSettings.stories.tsx +0 -108
  167. package/src/_deprecated/components/ColumnMenu/ColumnSettings.tsx +0 -207
  168. package/src/_deprecated/components/ColumnMenu/index.ts +0 -6
  169. package/src/_deprecated/components/Table/Table.stories.tsx +0 -508
  170. package/src/_deprecated/components/Table/Table.tsx +0 -301
  171. package/src/_deprecated/components/Table/TableBody.tsx +0 -82
  172. package/src/_deprecated/components/Table/TableContext.tsx +0 -34
  173. package/src/_deprecated/components/Table/TableHead.tsx +0 -78
  174. package/src/_deprecated/components/Table/TableRootContext.ts +0 -39
  175. package/src/_deprecated/components/Table/index.ts +0 -8
  176. package/src/_deprecated/components/Table/props.ts +0 -60
  177. package/src/_deprecated/components/index.ts +0 -7
  178. package/src/_deprecated/helpers.tsx +0 -526
  179. package/src/_deprecated/hooks/index.ts +0 -8
  180. package/src/_deprecated/hooks/useColumnSizing.ts +0 -46
  181. package/src/_deprecated/hooks/useColumnSorting.ts +0 -64
  182. package/src/_deprecated/hooks/usePinLastRow.ts +0 -47
  183. package/src/_deprecated/hooks/useRowSelection.ts +0 -40
  184. package/src/_deprecated/index.ts +0 -12
  185. package/src/_deprecated/schema/Schema.stories.tsx +0 -59
  186. package/src/_deprecated/schema/column-utils.ts +0 -54
  187. package/src/_deprecated/schema/index.ts +0 -6
  188. package/src/_deprecated/schema/types.ts +0 -40
  189. package/src/_deprecated/theme.ts +0 -82
  190. package/src/_deprecated/translations.ts +0 -26
  191. package/src/_deprecated/types.ts +0 -38
@@ -1,508 +0,0 @@
1
- //
2
- // Copyright 2023 DXOS.org
3
- //
4
-
5
- import '@dxos-theme';
6
-
7
- import { Plugs, PlugsConnected } from '@phosphor-icons/react';
8
- import { type StoryObj } from '@storybook/react';
9
- import React, { useCallback, useEffect, useMemo, useState } from 'react';
10
-
11
- import { PublicKey } from '@dxos/keys';
12
- import { create } from '@dxos/live-object';
13
- import { log } from '@dxos/log';
14
- import { faker } from '@dxos/random';
15
- import { Button } from '@dxos/react-ui';
16
- import { withSignals, withTheme } from '@dxos/storybook-utils';
17
- import { range } from '@dxos/util';
18
-
19
- import { Table } from './Table';
20
- import { createColumnBuilder, type SearchListQueryModel, type ValueUpdater } from '../../helpers';
21
- import { type TableColumnDef } from '../../types';
22
-
23
- // TODO(burdon): Header menu builder.
24
- // TODO(burdon): Expand width if not all columns have explicit size.
25
-
26
- type Item = {
27
- publicKey: PublicKey;
28
- name: string;
29
- company?: string;
30
- count?: number;
31
- started?: Date;
32
- complete?: boolean;
33
- };
34
-
35
- faker.seed(911);
36
-
37
- const createItems = (count: number) =>
38
- range(count).map(
39
- () =>
40
- create<Item>({
41
- publicKey: PublicKey.random(),
42
- name: faker.commerce.productName(),
43
- count: faker.datatype.boolean({ probability: 0.9 }) ? faker.number.int({ min: 0, max: 10_000 }) : undefined,
44
- started: faker.date.recent(),
45
- complete: faker.datatype.boolean() ? true : faker.datatype.boolean() ? false : undefined,
46
- }) as Item,
47
- );
48
-
49
- const updateItems = <TValue = any,>(items: Item[], key: PublicKey, id: string, value: TValue) => {
50
- return items.map((item) => (item.publicKey.equals(key) ? { ...item, [id]: value } : item));
51
- };
52
-
53
- const tableStorySelectItems: Record<string, Item> = range(128).reduce((acc: Record<string, Item>, _i) => {
54
- const id = PublicKey.random();
55
- acc[id.toHex()] = {
56
- publicKey: id,
57
- name: faker.company.name(),
58
- };
59
- return acc;
60
- }, {});
61
-
62
- const timeout = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms));
63
-
64
- const tableStorySelectModel: SearchListQueryModel<Item> = {
65
- getId: (object) => object?.publicKey?.toHex() ?? 'never',
66
- getText: (object) => object?.name ?? 'never',
67
- query: async (search: string) => {
68
- await timeout(400);
69
- return Object.values(tableStorySelectItems).filter((item) => {
70
- return item.name.toLowerCase().includes(search.toLowerCase());
71
- });
72
- },
73
- };
74
-
75
- const { helper, builder } = createColumnBuilder<Item>();
76
-
77
- const makeColumns = (onUpdate?: ValueUpdater<Item, any>): TableColumnDef<Item, any>[] => [
78
- helper.display(builder.selectRow()),
79
- helper.accessor((item) => item.publicKey, { id: 'key', ...builder.key({ tooltip: true }) }),
80
- helper.accessor(
81
- 'name',
82
- builder.string({
83
- label: 'Name',
84
- onUpdate,
85
- meta: { expand: true },
86
- footer: (props) => props.table.getRowModel().rows.length,
87
- }),
88
- ),
89
- helper.accessor('started', builder.date({ label: 'Started', relative: true, meta: { resizable: true } })),
90
- helper.accessor(
91
- 'count',
92
- builder.number({
93
- label: 'Count',
94
- meta: { resizable: true },
95
- onUpdate,
96
- getGroupingValue: (row) => (row.count ? (row.count < 2000 ? 'A' : row.count < 5000 ? 'B' : 'C') : 'D'),
97
- }),
98
- ),
99
- helper.accessor('company', builder.combobox({ label: 'Company', model: tableStorySelectModel, onUpdate })),
100
- helper.accessor(
101
- 'complete',
102
- builder.switch({ getGroupingValue: (row) => row.complete === true, label: '', onUpdate }),
103
- ),
104
- helper.accessor('complete', builder.icon({ id: 'done', label: '' })),
105
- helper.accessor(
106
- 'complete',
107
- builder.icon({
108
- id: 'connected',
109
- label: '',
110
- on: { Icon: PlugsConnected, className: 'text-blue-500' },
111
- off: { Icon: Plugs, className: 'text-blue-200' },
112
- }),
113
- ),
114
- ];
115
-
116
- //
117
- // Tests
118
- //
119
-
120
- const MinimalTable = (props: any) => {
121
- return (
122
- <Table.Root>
123
- <Table.Viewport classNames='fixed inset-0'>
124
- <Table.Main<any> {...props} />
125
- </Table.Viewport>
126
- </Table.Root>
127
- );
128
- };
129
-
130
- export default {
131
- title: 'ui/react-ui-table/deprecated/Table',
132
- component: MinimalTable,
133
- args: {
134
- header: true,
135
- keyAccessor: (item: Item) => item.publicKey.toHex(),
136
- },
137
- argTypes: {
138
- header: { control: 'boolean' },
139
- footer: { control: 'boolean' },
140
- border: { control: 'boolean' },
141
- fullWidth: { control: 'boolean' },
142
- grouping: {
143
- control: 'select',
144
- options: ['none', 'complete', 'count'],
145
- mapping: {
146
- none: undefined,
147
- complete: ['complete'],
148
- count: ['count'],
149
- },
150
- },
151
- columnVisibility: {
152
- control: 'select',
153
- options: ['all', 'limited'],
154
- mapping: {
155
- all: undefined,
156
- limited: { key: false, started: false },
157
- },
158
- },
159
- rowsSelectable: { control: 'select', options: [false, true, 'multi'] },
160
- },
161
- decorators: [withTheme],
162
- };
163
-
164
- export const Default = {
165
- args: {
166
- columns: makeColumns(),
167
- data: createItems(20),
168
- },
169
- };
170
-
171
- export const Scrolling = {
172
- args: {
173
- columns: makeColumns(),
174
- data: createItems(200),
175
- },
176
- };
177
-
178
- export const Visibility = {
179
- args: {
180
- columns: makeColumns(),
181
- data: createItems(10),
182
- columnVisibility: { key: false, started: false },
183
- },
184
- };
185
-
186
- export const Empty = {
187
- args: {
188
- columns: makeColumns(),
189
- },
190
- };
191
-
192
- export const Dynamic = {
193
- render: () => {
194
- const [items, setItems] = useState<Item[]>(createItems(50));
195
-
196
- useEffect(() => {
197
- const interval = setInterval(() => {
198
- setItems((items) => {
199
- if (items.length >= 200) {
200
- clearInterval(interval);
201
- }
202
- return [...items, ...createItems(1)];
203
- });
204
- }, 500);
205
- return () => clearInterval(interval);
206
- }, []);
207
-
208
- const columns = useMemo(() => makeColumns(), []);
209
-
210
- return (
211
- <Table.Root>
212
- <Table.Viewport classNames='fixed inset-0'>
213
- <Table.Main<Item>
214
- role='grid'
215
- rowsSelectable='multi'
216
- keyAccessor={(row) => row.publicKey.toHex()}
217
- columns={columns}
218
- data={items}
219
- fullWidth
220
- stickyHeader
221
- border
222
- pinLastRow
223
- />
224
- </Table.Viewport>
225
- </Table.Root>
226
- );
227
- },
228
- };
229
-
230
- export const Editable = {
231
- render: () => {
232
- const [items, setItems] = useState<Item[]>(createItems(200));
233
-
234
- const onUpdate: ValueUpdater<Item, any> = useCallback(
235
- (item, prop, value) => setItems((items) => updateItems(items, item.publicKey, prop, value)),
236
- [setItems],
237
- );
238
-
239
- const columns = useMemo(() => makeColumns(onUpdate), [onUpdate]);
240
-
241
- return (
242
- <Table.Root>
243
- <Table.Viewport classNames='fixed inset-0'>
244
- <Table.Main<Item>
245
- role='grid'
246
- rowsSelectable='multi'
247
- keyAccessor={(row) => row.publicKey.toHex()}
248
- columns={columns}
249
- data={items}
250
- fullWidth
251
- stickyHeader
252
- border
253
- pinLastRow
254
- />
255
- </Table.Viewport>
256
- </Table.Root>
257
- );
258
- },
259
- };
260
-
261
- export const PinnedLastRow = {
262
- render: () => {
263
- const [items, setItems] = useState<Item[]>(createItems(200));
264
-
265
- const onUpdate: ValueUpdater<Item, any> = useCallback(
266
- (item, prop, value) => setItems((items) => updateItems(items, item.publicKey, prop, value)),
267
- [setItems],
268
- );
269
-
270
- const columns = useMemo(() => makeColumns(onUpdate), [onUpdate]);
271
-
272
- return (
273
- <Table.Root>
274
- <Table.Viewport classNames='fixed inset-0'>
275
- <Table.Main<Item>
276
- role='grid'
277
- rowsSelectable='multi'
278
- keyAccessor={(row) => row.publicKey.toHex()}
279
- columns={columns}
280
- data={items}
281
- fullWidth
282
- stickyHeader
283
- border
284
- pinLastRow
285
- />
286
- </Table.Viewport>
287
- </Table.Root>
288
- );
289
- },
290
- };
291
-
292
- export const InsertDelete = {
293
- render: () => {
294
- const [items, setItems] = useState<Item[]>(createItems(10));
295
-
296
- const onUpdate: ValueUpdater<Item, any> = useCallback(
297
- (item, prop, value) => setItems((items) => updateItems(items, item.publicKey, prop, value)),
298
- [setItems],
299
- );
300
-
301
- const columns = useMemo(() => makeColumns(onUpdate), [onUpdate]);
302
-
303
- const onInsertFirst = () => {
304
- setItems((items) => [...createItems(1), ...items]);
305
- };
306
-
307
- const onInsertLast = () => {
308
- setItems((items) => [...items, ...createItems(1)]);
309
- };
310
-
311
- const onDeleteFirst = () => {
312
- setItems(([_first, ...rest]) => rest);
313
- };
314
-
315
- const onDeleteLast = () => {
316
- setItems((items) => [...items.slice(0, items.length - 1)]);
317
- };
318
-
319
- return (
320
- <div className='space-y-4'>
321
- <div className='flex flex-row gap-2'>
322
- <Button onClick={onInsertFirst}>Insert first</Button>
323
- <Button onClick={onInsertLast}>Insert last</Button>
324
- <Button onClick={onDeleteFirst}>Delete first</Button>
325
- <Button onClick={onDeleteLast}>Delete last</Button>
326
- </div>
327
- <Table.Root>
328
- <Table.Viewport>
329
- <Table.Main<Item>
330
- role='grid'
331
- rowsSelectable='multi'
332
- keyAccessor={(row) => row.publicKey.toHex()}
333
- columns={columns}
334
- data={items}
335
- fullWidth
336
- stickyHeader
337
- border
338
- pinLastRow
339
- />
340
- </Table.Viewport>
341
- </Table.Root>
342
- </div>
343
- );
344
- },
345
- };
346
-
347
- export const Resizable = {
348
- render: () => {
349
- const [items, setItems] = useState<Item[]>(createItems(10));
350
-
351
- const onUpdate: ValueUpdater<Item, any> = useCallback(
352
- (item, prop, value) => setItems((items) => updateItems(items, item.publicKey, prop, value)),
353
- [setItems],
354
- );
355
-
356
- return (
357
- <Table.Root>
358
- <Table.Viewport classNames='fixed inset-0'>
359
- <Table.Main<Item>
360
- rowsSelectable='multi'
361
- keyAccessor={(row) => row.publicKey.toHex()}
362
- columns={makeColumns(onUpdate)}
363
- data={items}
364
- fullWidth
365
- stickyHeader
366
- />
367
- </Table.Viewport>
368
- </Table.Root>
369
- );
370
- },
371
- };
372
-
373
- export const TenThousandRows = {
374
- render: () => {
375
- const [items, setItems] = useState<Item[]>(createItems(10000));
376
-
377
- const onUpdate: ValueUpdater<Item, any> = useCallback(
378
- (item, prop, value) => setItems((items) => updateItems(items, item.publicKey, prop, value)),
379
- [setItems],
380
- );
381
-
382
- const columns = useMemo(() => makeColumns(onUpdate), [onUpdate]);
383
-
384
- return (
385
- <Table.Root>
386
- <Table.Viewport classNames='fixed inset-0'>
387
- <Table.Main<Item>
388
- role='grid'
389
- rowsSelectable='multi'
390
- keyAccessor={(row) => row.publicKey.toHex()}
391
- columns={columns}
392
- data={items}
393
- fullWidth
394
- stickyHeader
395
- border
396
- />{' '}
397
- </Table.Viewport>
398
- </Table.Root>
399
- );
400
- },
401
- };
402
-
403
- // TODO(burdon): Warning: Encountered two children with the same key.
404
-
405
- type StoryProps = {
406
- periodicMutations: boolean;
407
- mutationInterval: number;
408
- periodicDeletions: boolean;
409
- deletionInterval: number;
410
- periodicInsertions: boolean;
411
- insertionInterval: number;
412
- };
413
-
414
- const DefaultStory = ({
415
- periodicMutations,
416
- mutationInterval,
417
- periodicDeletions,
418
- deletionInterval,
419
- periodicInsertions,
420
- insertionInterval,
421
- }: StoryProps) => {
422
- const [state] = useState(() => create({ items: createItems(10) }));
423
-
424
- useEffect(() => {
425
- if (!periodicMutations) {
426
- return;
427
- }
428
-
429
- const i = setInterval(() => {
430
- if (state.items.length === 0) {
431
- return;
432
- }
433
-
434
- const idx = Math.floor(Math.random() * state.items.length);
435
- log('mutating', { idx });
436
- state.items[idx].name = faker.commerce.productName();
437
- state.items[idx].count = Math.floor(Math.random() * 1000);
438
- state.items[idx].started = new Date();
439
- }, mutationInterval);
440
-
441
- return () => clearInterval(i);
442
- }, [periodicMutations, mutationInterval, state.items]);
443
-
444
- useEffect(() => {
445
- if (!periodicInsertions) {
446
- return;
447
- }
448
-
449
- const i = setInterval(() => {
450
- log('inserting...');
451
- state.items.push(createItems(1)[0]);
452
- }, insertionInterval);
453
-
454
- return () => clearInterval(i);
455
- }, [periodicInsertions, insertionInterval, state.items]);
456
-
457
- useEffect(() => {
458
- if (!periodicDeletions) {
459
- return;
460
- }
461
-
462
- const i = setInterval(() => {
463
- if (state.items.length === 0) {
464
- return;
465
- }
466
-
467
- log('deleting...');
468
- const randomIndex = Math.floor(Math.random() * state.items.length);
469
- state.items.splice(randomIndex, 1);
470
- }, deletionInterval);
471
-
472
- return () => clearInterval(i);
473
- }, [periodicDeletions, deletionInterval, state.items]);
474
-
475
- const onUpdate = useCallback((...args: any[]) => {}, []);
476
- const columns = useMemo(() => makeColumns(onUpdate), []);
477
-
478
- return (
479
- <Table.Root>
480
- <Table.Viewport classNames='fixed inset-0'>
481
- <Table.Main<Item>
482
- role='grid'
483
- rowsSelectable='multi'
484
- keyAccessor={(row) => row.publicKey.toHex()}
485
- columns={columns}
486
- data={state.items}
487
- fullWidth
488
- stickyHeader
489
- border
490
- pinLastRow
491
- />
492
- </Table.Viewport>
493
- </Table.Root>
494
- );
495
- };
496
-
497
- export const RealTimeUpdates: StoryObj<StoryProps> = {
498
- render: DefaultStory,
499
- decorators: [withSignals],
500
- args: {
501
- periodicMutations: true,
502
- mutationInterval: 1000,
503
- periodicDeletions: false,
504
- deletionInterval: 5000,
505
- periodicInsertions: false,
506
- insertionInterval: 3000,
507
- },
508
- };