@tcn/ui-table 2.3.4 → 2.3.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 (44) hide show
  1. package/dist/cell.css +1 -1
  2. package/dist/components/cells/data_cell.d.ts.map +1 -1
  3. package/dist/components/cells/data_cell.js +4 -3
  4. package/dist/components/cells/data_cell.js.map +1 -1
  5. package/dist/components/cells/footer_cell.d.ts.map +1 -1
  6. package/dist/components/cells/footer_cell.js +5 -4
  7. package/dist/components/cells/footer_cell.js.map +1 -1
  8. package/dist/components/cells/header_cell.d.ts +3 -5
  9. package/dist/components/cells/header_cell.d.ts.map +1 -1
  10. package/dist/components/cells/header_cell.js +49 -37
  11. package/dist/components/cells/header_cell.js.map +1 -1
  12. package/dist/components/cells/sort_control.d.ts +8 -0
  13. package/dist/components/cells/sort_control.d.ts.map +1 -0
  14. package/dist/components/cells/sort_control.js +27 -0
  15. package/dist/components/cells/sort_control.js.map +1 -0
  16. package/dist/components/cells/sticky_row_data_cell.d.ts.map +1 -1
  17. package/dist/components/cells/sticky_row_data_cell.js +14 -13
  18. package/dist/components/cells/sticky_row_data_cell.js.map +1 -1
  19. package/dist/components/cells/sticky_row_fill_cell.d.ts.map +1 -1
  20. package/dist/components/cells/sticky_row_fill_cell.js +4 -3
  21. package/dist/components/cells/sticky_row_fill_cell.js.map +1 -1
  22. package/dist/components/table/table.d.ts.map +1 -1
  23. package/dist/components/table/table.js +66 -64
  24. package/dist/components/table/table.js.map +1 -1
  25. package/dist/components/table_filter_panel/field_filters/string_field_filter.d.ts.map +1 -1
  26. package/dist/components/table_filter_panel/field_filters/string_field_filter.js +21 -20
  27. package/dist/components/table_filter_panel/field_filters/string_field_filter.js.map +1 -1
  28. package/dist/components/table_pager.d.ts.map +1 -1
  29. package/dist/components/table_pager.js +34 -16
  30. package/dist/components/table_pager.js.map +1 -1
  31. package/dist/table.css +1 -1
  32. package/package.json +4 -4
  33. package/src/__stories__/table.stories.tsx +232 -195
  34. package/src/components/cells/cell.module.css +7 -45
  35. package/src/components/cells/data_cell.tsx +3 -2
  36. package/src/components/cells/footer_cell.tsx +3 -2
  37. package/src/components/cells/header_cell.tsx +19 -28
  38. package/src/components/cells/sort_control.tsx +44 -0
  39. package/src/components/cells/sticky_row_data_cell.tsx +3 -2
  40. package/src/components/cells/sticky_row_fill_cell.tsx +3 -2
  41. package/src/components/table/table.module.css +24 -212
  42. package/src/components/table/table.tsx +35 -24
  43. package/src/components/table_filter_panel/field_filters/string_field_filter.tsx +1 -0
  44. package/src/components/table_pager.tsx +12 -2
@@ -9,7 +9,7 @@ import {
9
9
  } from '@tcn/resource-store';
10
10
  import { useSignalValue } from '@tcn/state';
11
11
  import { Button } from '@tcn/ui/actions';
12
- import { Box, HStack, Spacer, VStack } from '@tcn/ui/stacks';
12
+ import { Box, HStack, Spacer, VStack, ZStack } from '@tcn/ui/stacks';
13
13
  import { VPanel } from '@tcn/ui/surfaces';
14
14
  import { Title } from '@tcn/ui/typography';
15
15
  import { GlobalSearch } from '../components/global_search.js';
@@ -22,12 +22,22 @@ import { StringFieldFilter } from '../components/table_filter_panel/field_filter
22
22
  import { TableFilterPanel } from '../components/table_filter_panel/table_filter_panel.js';
23
23
  import { TablePager } from '../components/table_pager.js';
24
24
  import { DataItem, items, stickyItems } from './sample_data.js';
25
+ import { CrossIcon } from '@tcn/icons/cross_icon.js';
25
26
  import styles from './table.module.css';
27
+ import { Footer, Header, Main, Rail, Side, VBody } from '@tcn/ui/layouts';
26
28
 
27
29
  const meta: Meta = {
28
30
  title: 'Table',
29
31
  };
30
32
 
33
+ const StoryWrapper = ({ children }: { children: React.ReactNode }) => {
34
+ return (
35
+ <ZStack maxHeight="600px" padding="24px">
36
+ {children}
37
+ </ZStack>
38
+ );
39
+ };
40
+
31
41
  export function Basic() {
32
42
  const [source] = useState(() => {
33
43
  return new StaticDataSource<DataItem>(items, [
@@ -42,21 +52,23 @@ export function Basic() {
42
52
  });
43
53
 
44
54
  return (
45
- <Table
46
- dataSource={source}
47
- onRowClick={item => {
48
- alert(`Clicked ${item.name}`);
49
- }}
50
- >
51
- <TableColumn heading="Name" fieldName="name" />
52
- <TableColumn heading="Age" fieldName="age" />
53
- <TableColumn heading="Email" fieldName="email" />
54
- <TableColumn heading="City" fieldName="city" />
55
- <TableColumn heading="Country" fieldName="country" />
56
- <TableColumn heading="Occupation" fieldName="occupation" />
57
- <TableColumn heading="Active" fieldName="isActive" />
58
- <div>Other kinds of children don't render</div>
59
- </Table>
55
+ <StoryWrapper>
56
+ <Table
57
+ dataSource={source}
58
+ onRowClick={item => {
59
+ alert(`Clicked ${item.name}`);
60
+ }}
61
+ >
62
+ <TableColumn heading="Name" fieldName="name" />
63
+ <TableColumn heading="Age" fieldName="age" />
64
+ <TableColumn heading="Email" fieldName="email" />
65
+ <TableColumn heading="City" fieldName="city" />
66
+ <TableColumn heading="Country" fieldName="country" />
67
+ <TableColumn heading="Occupation" fieldName="occupation" />
68
+ <TableColumn heading="Active" fieldName="isActive" />
69
+ <div>Other kinds of children don't render</div>
70
+ </Table>
71
+ </StoryWrapper>
60
72
  );
61
73
  }
62
74
 
@@ -76,26 +88,28 @@ export function WithSort() {
76
88
  const currentResults = useSignalValue(source.broadcasts.currentResults);
77
89
 
78
90
  return (
79
- <Table
80
- dataSource={source}
81
- onRowClick={item => {
82
- alert(`Clicked ${item.name}`);
83
- }}
84
- >
85
- <TableColumn heading="Name" footer="Some Names" fieldName="name" canSort />
86
- <TableColumn
87
- heading="Age"
88
- footer={`Average Age: ${Math.round(currentResults.reduce((sum, i) => sum + i.age, 0) / currentResults.length)}`}
89
- fieldName="age"
90
- canSort
91
- width={120}
92
- />
93
- <TableColumn heading="Email" fieldName="email" canSort />
94
- <TableColumn heading="City" fieldName="city" canSort />
95
- <TableColumn heading="Country" fieldName="country" canSort />
96
- <TableColumn heading="Occupation" fieldName="occupation" canSort />
97
- <TableColumn heading="Active" fieldName="isActive" canSort />
98
- </Table>
91
+ <StoryWrapper>
92
+ <Table
93
+ dataSource={source}
94
+ onRowClick={item => {
95
+ alert(`Clicked ${item.name}`);
96
+ }}
97
+ >
98
+ <TableColumn heading="Name" footer="Some Names" fieldName="name" canSort />
99
+ <TableColumn
100
+ heading="Age"
101
+ footer={`Average Age: ${Math.round(currentResults.reduce((sum, i) => sum + i.age, 0) / currentResults.length)}`}
102
+ fieldName="age"
103
+ canSort
104
+ width={120}
105
+ />
106
+ <TableColumn heading="Email" fieldName="email" canSort />
107
+ <TableColumn heading="City" fieldName="city" canSort />
108
+ <TableColumn heading="Country" fieldName="country" canSort />
109
+ <TableColumn heading="Occupation" fieldName="occupation" canSort />
110
+ <TableColumn heading="Active" fieldName="isActive" canSort />
111
+ </Table>
112
+ </StoryWrapper>
99
113
  );
100
114
  }
101
115
 
@@ -116,7 +130,7 @@ export function WithRowHighlighting() {
116
130
  const [selectedRow, setSelectedRow] = useState<string | null>(null);
117
131
 
118
132
  return (
119
- <div>
133
+ <StoryWrapper>
120
134
  <Table
121
135
  dataSource={source}
122
136
  isRowHighlighted={row => {
@@ -132,7 +146,7 @@ export function WithRowHighlighting() {
132
146
  <TableColumn heading="Occupation" fieldName="occupation" />
133
147
  <TableColumn heading="Active" fieldName="isActive" />
134
148
  </Table>
135
- </div>
149
+ </StoryWrapper>
136
150
  );
137
151
  }
138
152
 
@@ -150,59 +164,65 @@ export function ComplexHeadersAndFooters() {
150
164
  });
151
165
 
152
166
  return (
153
- <Table dataSource={source}>
154
- <TableColumn
155
- heading={
156
- <div style={{ display: 'flex', alignItems: 'center', gap: '8px' }}>
157
- <span>👤</span>
158
- <span>Name</span>
159
- </div>
160
- }
161
- footer={
162
- <div style={{ display: 'flex', justifyContent: 'space-between' }}>
163
- <span>Total:</span>
164
- <span>{items.length}</span>
165
- </div>
166
- }
167
- fieldName="name"
168
- render={(i: DataItem) => i.name}
169
- />
170
- <TableColumn
171
- heading={
172
- <div style={{ display: 'flex', alignItems: 'center', gap: '8px' }}>
173
- <span>🎂</span>
174
- <span>Age</span>
175
- </div>
176
- }
177
- footer={
178
- <div style={{ display: 'flex', justifyContent: 'space-between' }}>
179
- <span>Average:</span>
180
- <span>
181
- {Math.round(items.reduce((sum, i) => sum + i.age, 0) / items.length)}
182
- </span>
183
- </div>
184
- }
185
- fieldName="age"
186
- render={(i: DataItem) => i.age}
187
- />
188
- <TableColumn heading="Email" fieldName="email" render={(i: DataItem) => i.email} />
189
- <TableColumn heading="City" fieldName="city" render={(i: DataItem) => i.city} />
190
- <TableColumn
191
- heading="Country"
192
- fieldName="country"
193
- render={(i: DataItem) => i.country}
194
- />
195
- <TableColumn
196
- heading="Occupation"
197
- fieldName="occupation"
198
- render={(i: DataItem) => i.occupation}
199
- />
200
- <TableColumn
201
- heading="Active"
202
- fieldName="isActive"
203
- render={(i: DataItem) => (i.isActive ? 'Yes' : 'No')}
204
- />
205
- </Table>
167
+ <StoryWrapper>
168
+ <Table dataSource={source}>
169
+ <TableColumn
170
+ heading={
171
+ <div style={{ display: 'flex', alignItems: 'center', gap: '8px' }}>
172
+ <span>👤</span>
173
+ <span>Name</span>
174
+ </div>
175
+ }
176
+ footer={
177
+ <div style={{ display: 'flex', justifyContent: 'space-between' }}>
178
+ <span>Total:</span>
179
+ <span>{items.length}</span>
180
+ </div>
181
+ }
182
+ fieldName="name"
183
+ render={(i: DataItem) => i.name}
184
+ />
185
+ <TableColumn
186
+ heading={
187
+ <div style={{ display: 'flex', alignItems: 'center', gap: '8px' }}>
188
+ <span>🎂</span>
189
+ <span>Age</span>
190
+ </div>
191
+ }
192
+ footer={
193
+ <div style={{ display: 'flex', justifyContent: 'space-between' }}>
194
+ <span>Average:</span>
195
+ <span>
196
+ {Math.round(items.reduce((sum, i) => sum + i.age, 0) / items.length)}
197
+ </span>
198
+ </div>
199
+ }
200
+ fieldName="age"
201
+ render={(i: DataItem) => i.age}
202
+ />
203
+ <TableColumn
204
+ heading="Email"
205
+ fieldName="email"
206
+ render={(i: DataItem) => i.email}
207
+ />
208
+ <TableColumn heading="City" fieldName="city" render={(i: DataItem) => i.city} />
209
+ <TableColumn
210
+ heading="Country"
211
+ fieldName="country"
212
+ render={(i: DataItem) => i.country}
213
+ />
214
+ <TableColumn
215
+ heading="Occupation"
216
+ fieldName="occupation"
217
+ render={(i: DataItem) => i.occupation}
218
+ />
219
+ <TableColumn
220
+ heading="Active"
221
+ fieldName="isActive"
222
+ render={(i: DataItem) => (i.isActive ? 'Yes' : 'No')}
223
+ />
224
+ </Table>
225
+ </StoryWrapper>
206
226
  );
207
227
  }
208
228
 
@@ -220,7 +240,7 @@ export function WithStickyActionsColumn() {
220
240
  });
221
241
 
222
242
  return (
223
- <div style={{ width: '600px', height: '400px' }}>
243
+ <StoryWrapper>
224
244
  <Table
225
245
  dataSource={source}
226
246
  onRowClick={item => {
@@ -237,47 +257,33 @@ export function WithStickyActionsColumn() {
237
257
  <TableColumn
238
258
  heading="Actions"
239
259
  sticky="end"
240
- width={120}
260
+ width={144}
241
261
  render={(item: DataItem) => (
242
- <div style={{ display: 'flex', gap: '4px', justifyContent: 'center' }}>
243
- <button
262
+ <HStack gap="4px">
263
+ <Button
264
+ size="sm"
244
265
  onClick={e => {
245
266
  e.stopPropagation();
246
- alert(`Edit ${item.name}`);
247
- }}
248
- style={{
249
- padding: '4px 8px',
250
- fontSize: '12px',
251
- border: '1px solid #ccc',
252
- borderRadius: '4px',
253
- background: '#f0f0f0',
254
- cursor: 'pointer',
267
+ alert(`Edit ${JSON.stringify(item)}`);
255
268
  }}
256
269
  >
257
270
  Edit
258
- </button>
259
- <button
271
+ </Button>
272
+ <Button
273
+ size="sm"
274
+ severity="dangerous"
260
275
  onClick={e => {
261
276
  e.stopPropagation();
262
- alert(`Delete ${item.name}`);
263
- }}
264
- style={{
265
- padding: '4px 8px',
266
- fontSize: '12px',
267
- border: '1px solid #ff6b6b',
268
- borderRadius: '4px',
269
- background: '#ff6b6b',
270
- color: 'white',
271
- cursor: 'pointer',
277
+ alert(`Delete ${JSON.stringify(item)}`);
272
278
  }}
273
279
  >
274
280
  Delete
275
- </button>
276
- </div>
281
+ </Button>
282
+ </HStack>
277
283
  )}
278
284
  />
279
285
  </Table>
280
- </div>
286
+ </StoryWrapper>
281
287
  );
282
288
  }
283
289
 
@@ -295,32 +301,34 @@ export function WithTableHeaderAndTableFooter() {
295
301
  });
296
302
 
297
303
  return (
298
- <VPanel>
299
- <HStack className={styles.header} padding="8px" vAlign="center">
300
- <Title>The Table</Title>
301
- <Spacer />
302
- <GlobalSearch dataSource={source} />
303
- </HStack>
304
- <VStack height="flex">
305
- <Table
306
- dataSource={source}
307
- onRowClick={item => {
308
- alert(`Clicked ${item.name}`);
309
- }}
310
- >
311
- <TableColumn heading="Name" fieldName="name" />
312
- <TableColumn heading="Age" fieldName="age" />
313
- <TableColumn heading="Email" fieldName="email" />
314
- <TableColumn heading="City" fieldName="city" />
315
- <TableColumn heading="Country" fieldName="country" />
316
- <TableColumn heading="Occupation" fieldName="occupation" />
317
- <TableColumn heading="Active" fieldName="isActive" />
318
- </Table>
319
- </VStack>
320
- <HStack padding="8px">
321
- <TablePager dataSource={source} />
322
- </HStack>
323
- </VPanel>
304
+ <StoryWrapper>
305
+ <VPanel>
306
+ <Header className={styles.header} padding="8px" vAlign="center">
307
+ <Title>The Table</Title>
308
+ <Spacer />
309
+ <GlobalSearch dataSource={source} />
310
+ </Header>
311
+ <VBody height="flex">
312
+ <Table
313
+ dataSource={source}
314
+ onRowClick={item => {
315
+ alert(`Clicked ${item.name}`);
316
+ }}
317
+ >
318
+ <TableColumn heading="Name" fieldName="name" />
319
+ <TableColumn heading="Age" fieldName="age" />
320
+ <TableColumn heading="Email" fieldName="email" />
321
+ <TableColumn heading="City" fieldName="city" />
322
+ <TableColumn heading="Country" fieldName="country" />
323
+ <TableColumn heading="Occupation" fieldName="occupation" />
324
+ <TableColumn heading="Active" fieldName="isActive" />
325
+ </Table>
326
+ </VBody>
327
+ <Footer>
328
+ <TablePager dataSource={source} />
329
+ </Footer>
330
+ </VPanel>
331
+ </StoryWrapper>
324
332
  );
325
333
  }
326
334
 
@@ -348,29 +356,39 @@ export function WithStickyItems() {
348
356
  }, []);
349
357
 
350
358
  return (
351
- <VStack height="100%">
352
- <Table dataSource={source} stickyItems={stickyThings}>
353
- <TableColumn heading="Name" fieldName="name" sticky="start" />
354
- <TableColumn heading="Age" fieldName="age" width={150} />
355
- <TableColumn heading="Email" fieldName="email" width={300} />
356
- <TableColumn heading="City" fieldName="city" width={300} />
357
- <TableColumn heading="Country" fieldName="country" width={200} />
358
- <TableColumn heading="Occupation" fieldName="occupation" width={200} />
359
- <TableColumn heading="Active" fieldName="isActive" />
360
- <TableColumn
361
- heading="Actions"
362
- sticky="end"
363
- width={120}
364
- render={(item: DataItem) => {
365
- if (stickyThings.includes(item)) {
366
- return <Button onClick={() => dismissStickyThing(item)}>x</Button>;
367
- }
368
- return null;
369
- }}
370
- />
371
- </Table>
372
- <TablePager dataSource={source} />
373
- </VStack>
359
+ <StoryWrapper>
360
+ <VStack height="100%" gap="8px">
361
+ <Table dataSource={source} stickyItems={stickyThings}>
362
+ <TableColumn heading="Name" fieldName="name" sticky="start" />
363
+ <TableColumn heading="Age" fieldName="age" width={150} />
364
+ <TableColumn heading="Email" fieldName="email" width={300} />
365
+ <TableColumn heading="City" fieldName="city" width={300} />
366
+ <TableColumn heading="Country" fieldName="country" width={200} />
367
+ <TableColumn heading="Occupation" fieldName="occupation" width={200} />
368
+ <TableColumn heading="Active" fieldName="isActive" />
369
+ <TableColumn
370
+ heading="Actions"
371
+ sticky="end"
372
+ width={120}
373
+ render={(item: DataItem) => {
374
+ if (stickyThings.includes(item)) {
375
+ return (
376
+ <Button
377
+ utility
378
+ hierarchy="tertiary"
379
+ onClick={() => dismissStickyThing(item)}
380
+ >
381
+ <CrossIcon />
382
+ </Button>
383
+ );
384
+ }
385
+ return null;
386
+ }}
387
+ />
388
+ </Table>
389
+ <TablePager dataSource={source} />
390
+ </VStack>
391
+ </StoryWrapper>
374
392
  );
375
393
  }
376
394
 
@@ -390,33 +408,52 @@ export function WithFilterPanel() {
390
408
  });
391
409
 
392
410
  return (
393
- <VStack height="100%">
394
- <HStack height="100%" vAlign="start" gap="8px">
395
- <Box width="300px" height="100%" enableResizeOnEnd>
396
- <TableFilterPanel dataSource={source}>
397
- <StringFieldFilter fieldName="name" label="Name (string)" />
398
- <NumberFieldFilter fieldName="age" label="Age (number)" />
399
- <DateFieldFilter fieldName="birthdate" label="Birthdate (date range)" />
400
- <NumberRangeFieldFilter fieldName="age" label="Age (number range)" />
401
- </TableFilterPanel>
402
- </Box>
403
- <Table dataSource={source} height="100%" width="flex">
404
- <TableColumn heading="Name" fieldName="name" sticky="start" />
405
- <TableColumn heading="Age" fieldName="age" width={150} canSort />
406
- <TableColumn heading="Email" fieldName="email" width={300} />
407
- <TableColumn heading="City" fieldName="city" width={300} />
408
- <TableColumn
409
- heading="Birthdate"
410
- fieldName="birthdate"
411
- width={300}
412
- render={(i: DataItem) => i.birthdate.toLocaleDateString()}
413
- />
414
- <TableColumn heading="Occupation" fieldName="occupation" width={200} />
415
- <TableColumn heading="Active" fieldName="isActive" />
416
- </Table>
417
- </HStack>
418
- <TablePager dataSource={source} />
419
- </VStack>
411
+ <StoryWrapper>
412
+ <VPanel height="100%">
413
+ <Header>The Table</Header>
414
+ <VBody>
415
+ <Rail>
416
+ <Side>
417
+ <Box
418
+ minWidth="300px"
419
+ enableResizeOnEnd
420
+ overflowY="auto"
421
+ height="100%"
422
+ style={{
423
+ scrollbarGutter: 'stable', // Not sure if there is a better way to prevent the scrollbar appearing causing a horizontal scroll - to to resizing, we fix the width of the content, so adding a vertical scrollbar causing a horizontal overflow.
424
+ }}
425
+ >
426
+ <TableFilterPanel dataSource={source}>
427
+ <StringFieldFilter fieldName="name" label="Name (string)" />
428
+ <NumberFieldFilter fieldName="age" label="Age (number)" />
429
+ <DateFieldFilter fieldName="birthdate" label="Birthdate (date range)" />
430
+ <NumberRangeFieldFilter fieldName="age" label="Age (number range)" />
431
+ </TableFilterPanel>
432
+ </Box>
433
+ </Side>
434
+ <Main>
435
+ <Table dataSource={source} height="100%" width="flex">
436
+ <TableColumn heading="Name" fieldName="name" sticky="start" />
437
+ <TableColumn heading="Age" fieldName="age" width={150} canSort />
438
+ <TableColumn heading="Email" fieldName="email" width={300} />
439
+ <TableColumn heading="City" fieldName="city" width={300} />
440
+ <TableColumn
441
+ heading="Birthdate"
442
+ fieldName="birthdate"
443
+ width={300}
444
+ render={(i: DataItem) => i.birthdate.toLocaleDateString()}
445
+ />
446
+ <TableColumn heading="Occupation" fieldName="occupation" width={200} />
447
+ <TableColumn heading="Active" fieldName="isActive" />
448
+ </Table>
449
+ </Main>
450
+ </Rail>
451
+ </VBody>
452
+ <Footer>
453
+ <TablePager dataSource={source} />
454
+ </Footer>
455
+ </VPanel>
456
+ </StoryWrapper>
420
457
  );
421
458
  }
422
459
 
@@ -7,13 +7,13 @@
7
7
  .table-cell[data-stick-to="end"] {
8
8
  position: sticky;
9
9
  top: 0;
10
- right: var(--end-offset, -1px);
10
+ right: var(--end-offset, 0);
11
11
  }
12
12
 
13
13
  .table-cell[data-stick-to="start"]:dir(rtl) {
14
14
  position: sticky;
15
15
  top: 0;
16
- right: var(--start-offset, -1px);
16
+ right: var(--start-offset, 0);
17
17
  }
18
18
 
19
19
  .table-cell[data-stick-to="end"]:dir(rtl) {
@@ -22,38 +22,20 @@
22
22
  left: var(--end-offset, 0);
23
23
  }
24
24
 
25
- .table-cell[data-is-last-sticky-start="true"] > div {
26
- border-inline-end: 1px solid #ccc;
27
- }
28
-
29
- :global(.dark-mode) .table-cell[data-is-last-sticky-start="true"] > div {
30
- border-inline-end: 1px solid #202020;
31
- }
32
-
33
- .table-cell[data-is-last-sticky-end="true"] > div {
34
- border-inline-start: 1px solid #ccc;
35
- }
36
-
37
- :global(.dark-mode) .table-cell[data-is-last-sticky-end="true"] div {
38
- border-inline-start: 1px solid #202020;
39
- }
40
-
41
- .table-cell[data-no-border="true"] {
42
- border-inline: none;
43
- }
44
-
45
25
  /* Sticky row cells */
46
-
47
26
  .sticky-row-table-cell {
27
+ /* FIXME: vvv should be on theme ideally. */
28
+ --material: #cccccc;
29
+ background-color: #cccccc;
30
+ /* FIXME: ^^^ Hack to make ergo theme happy. -- will refactor into ui/theme in a future issue */
48
31
  position: sticky;
49
- top: 22px; /* The header row height */
50
32
  z-index: 1;
51
33
  }
52
34
 
53
35
  .sticky-row-table-cell[data-stick-to="start"] {
54
36
  position: sticky;
55
37
  top: 0;
56
- left: var(--start-offset, 0);
38
+ left: var(--start-offset, -1px);
57
39
  z-index: 2;
58
40
  }
59
41
 
@@ -77,23 +59,3 @@
77
59
  left: var(--end-offset, 0);
78
60
  z-index: 2;
79
61
  }
80
-
81
- .sticky-row-table-cell[data-is-last-sticky-start="true"] > div {
82
- border-inline-end: 1px solid #ccc;
83
- }
84
-
85
- :global(.dark-mode) .sticky-row-table-cell[data-is-last-sticky-start="true"] > div {
86
- border-inline-end: 1px solid #202020;
87
- }
88
-
89
- .sticky-row-table-cell[data-is-last-sticky-end="true"] > div {
90
- border-inline-start: 1px solid #ccc;
91
- }
92
-
93
- :global(.dark-mode) .sticky-row-table-cell[data-is-last-sticky-end="true"] {
94
- border-inline-start: 1px solid #202020;
95
- }
96
-
97
- .sticky-row-table-cell[data-no-border="true"] {
98
- border-inline: none;
99
- }
@@ -1,6 +1,7 @@
1
1
  import React from 'react';
2
2
 
3
3
  import cellStyles from './cell.module.css';
4
+ import { TD } from '@tcn/ui/layouts';
4
5
 
5
6
  export type DataCellProps = {
6
7
  content: React.ReactNode;
@@ -10,7 +11,7 @@ export type DataCellProps = {
10
11
 
11
12
  export function DataCell({ content, sticky, width }: DataCellProps) {
12
13
  return (
13
- <td className={cellStyles['table-cell']} data-stick-to={sticky}>
14
+ <TD className={cellStyles['table-cell']} data-stick-to={sticky}>
14
15
  <div
15
16
  style={{
16
17
  width: `${width}px`,
@@ -20,6 +21,6 @@ export function DataCell({ content, sticky, width }: DataCellProps) {
20
21
  >
21
22
  {content}
22
23
  </div>
23
- </td>
24
+ </TD>
24
25
  );
25
26
  }
@@ -1,6 +1,7 @@
1
1
  import React from 'react';
2
2
 
3
3
  import cellStyles from './cell.module.css';
4
+ import { TD } from '@tcn/ui/layouts';
4
5
 
5
6
  export type FooterCellProps = {
6
7
  content: React.ReactNode;
@@ -10,7 +11,7 @@ export type FooterCellProps = {
10
11
 
11
12
  export function FooterCell({ content, sticky, width }: FooterCellProps) {
12
13
  return (
13
- <td className={cellStyles['table-cell']} data-stick-to={sticky}>
14
+ <TD className={cellStyles['table-cell']} data-stick-to={sticky}>
14
15
  <div
15
16
  style={{
16
17
  width: `${width}px`,
@@ -20,6 +21,6 @@ export function FooterCell({ content, sticky, width }: FooterCellProps) {
20
21
  >
21
22
  {content}
22
23
  </div>
23
- </td>
24
+ </TD>
24
25
  );
25
26
  }