@budibase/bbui 1.0.76-alpha.5 → 1.0.78

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.
@@ -3,8 +3,8 @@
3
3
  import "@spectrum-css/table/dist/index-vars.css"
4
4
  import CellRenderer from "./CellRenderer.svelte"
5
5
  import SelectEditRenderer from "./SelectEditRenderer.svelte"
6
- import { cloneDeep, deepGet } from "../helpers"
7
- import ProgressCircle from "../ProgressCircle/ProgressCircle.svelte"
6
+ import { cloneDeep } from "lodash"
7
+ import { deepGet } from "../helpers"
8
8
 
9
9
  /**
10
10
  * The expected schema is our normal couch schemas for our tables.
@@ -15,11 +15,6 @@
15
15
  * sortable: Set to false to disable sorting data by a certain column
16
16
  * editable: Set to false to disable editing a certain column if the
17
17
  * allowEditColumns prop is true
18
- * width: the width of the column
19
- * align: the alignment of the column
20
- * template: a HBS or JS binding to use as the value
21
- * background: the background color
22
- * color: the text color
23
18
  */
24
19
  export let data = []
25
20
  export let schema = {}
@@ -34,14 +29,13 @@
34
29
  export let editColumnTitle = "Edit"
35
30
  export let customRenderers = []
36
31
  export let disableSorting = false
37
- export let autoSortColumns = true
38
- export let compact = false
39
32
 
40
33
  const dispatch = createEventDispatcher()
41
34
 
42
35
  // Config
36
+ const rowHeight = 55
43
37
  const headerHeight = 36
44
- $: rowHeight = compact ? 46 : 55
38
+ const rowPreload = 5
45
39
 
46
40
  // Sorting state
47
41
  let sortColumn
@@ -52,20 +46,32 @@
52
46
  let loaded = false
53
47
  $: schema = fixSchema(schema)
54
48
  $: if (!loading) loaded = true
55
- $: fields = getFields(schema, showAutoColumns, autoSortColumns)
56
- $: rows = fields?.length ? data || [] : []
57
- $: visibleRowCount = getVisibleRowCount(
58
- loaded,
59
- height,
60
- rows.length,
61
- rowCount,
62
- rowHeight
63
- )
64
- $: contentStyle = getContentStyle(visibleRowCount, rowCount, rowHeight)
49
+ $: rows = data ?? []
50
+ $: visibleRowCount = getVisibleRowCount(loaded, height, rows.length, rowCount)
51
+ $: contentStyle = getContentStyle(visibleRowCount, rowCount)
65
52
  $: sortedRows = sortRows(rows, sortColumn, sortOrder)
66
- $: gridStyle = getGridStyle(fields, schema, showEditColumn)
53
+ $: fields = getFields(schema, showAutoColumns)
67
54
  $: showEditColumn = allowEditRows || allowSelectRows
68
- $: cellStyles = computeCellStyles(schema)
55
+
56
+ // Scrolling state
57
+ let timeout
58
+ let nextScrollTop = 0
59
+ let scrollTop = 0
60
+ $: firstVisibleRow = calculateFirstVisibleRow(scrollTop)
61
+ $: lastVisibleRow = calculateLastVisibleRow(
62
+ firstVisibleRow,
63
+ visibleRowCount,
64
+ rows.length
65
+ )
66
+
67
+ // Reset state when data changes
68
+ $: rows.length, reset()
69
+ const reset = () => {
70
+ nextScrollTop = 0
71
+ scrollTop = 0
72
+ clearTimeout(timeout)
73
+ timeout = null
74
+ }
69
75
 
70
76
  const fixSchema = schema => {
71
77
  let fixedSchema = {}
@@ -85,7 +91,7 @@
85
91
  return fixedSchema
86
92
  }
87
93
 
88
- const getVisibleRowCount = (loaded, height, allRows, rowCount, rowHeight) => {
94
+ const getVisibleRowCount = (loaded, height, allRows, rowCount) => {
89
95
  if (!loaded) {
90
96
  return rowCount || 0
91
97
  }
@@ -95,28 +101,11 @@
95
101
  return Math.min(allRows, Math.ceil(height / rowHeight))
96
102
  }
97
103
 
98
- const getContentStyle = (visibleRows, rowCount, rowHeight) => {
104
+ const getContentStyle = (visibleRows, rowCount) => {
99
105
  if (!rowCount || !visibleRows) {
100
106
  return ""
101
107
  }
102
- return `height: ${headerHeight + visibleRows * rowHeight}px;`
103
- }
104
-
105
- const getGridStyle = (fields, schema, showEditColumn) => {
106
- let style = "grid-template-columns:"
107
- if (showEditColumn) {
108
- style += " auto"
109
- }
110
- fields?.forEach(field => {
111
- const fieldSchema = schema[field]
112
- if (fieldSchema.width) {
113
- style += ` ${fieldSchema.width}`
114
- } else {
115
- style += " minmax(auto, 1fr)"
116
- }
117
- })
118
- style += ";"
119
- return style
108
+ return `height: ${headerHeight + visibleRows * (rowHeight + 1)}px;`
120
109
  }
121
110
 
122
111
  const sortRows = (rows, sortColumn, sortOrder) => {
@@ -155,14 +144,14 @@
155
144
  return name || ""
156
145
  }
157
146
 
158
- const getFields = (schema, showAutoColumns, autoSortColumns) => {
147
+ const getFields = (schema, showAutoColumns) => {
159
148
  let columns = []
160
149
  let autoColumns = []
161
150
  Object.entries(schema || {}).forEach(([field, fieldSchema]) => {
162
151
  if (!field || !fieldSchema) {
163
152
  return
164
153
  }
165
- if (!autoSortColumns || !fieldSchema?.autocolumn) {
154
+ if (!fieldSchema?.autocolumn) {
166
155
  columns.push(fieldSchema)
167
156
  } else if (showAutoColumns) {
168
157
  autoColumns.push(fieldSchema)
@@ -183,6 +172,28 @@
183
172
  .map(column => column.name)
184
173
  }
185
174
 
175
+ const onScroll = event => {
176
+ nextScrollTop = event.target.scrollTop
177
+ if (timeout) {
178
+ return
179
+ }
180
+ timeout = setTimeout(() => {
181
+ scrollTop = nextScrollTop
182
+ timeout = null
183
+ }, 50)
184
+ }
185
+
186
+ const calculateFirstVisibleRow = scrollTop => {
187
+ return Math.max(Math.floor(scrollTop / (rowHeight + 1)) - rowPreload, 0)
188
+ }
189
+
190
+ const calculateLastVisibleRow = (firstRow, visibleRowCount, allRowCount) => {
191
+ if (visibleRowCount === 0) {
192
+ return -1
193
+ }
194
+ return Math.min(firstRow + visibleRowCount + 2 * rowPreload, allRowCount)
195
+ }
196
+
186
197
  const editColumn = (e, field) => {
187
198
  e.stopPropagation()
188
199
  dispatch("editcolumn", field)
@@ -203,233 +214,170 @@
203
214
  selectedRows = [...selectedRows, row]
204
215
  }
205
216
  }
206
-
207
- const computeCellStyles = schema => {
208
- let styles = {}
209
- Object.keys(schema || {}).forEach(field => {
210
- styles[field] = ""
211
- if (schema[field].color) {
212
- styles[field] += `color: ${schema[field].color};`
213
- }
214
- if (schema[field].background) {
215
- styles[field] += `background-color: ${schema[field].background};`
216
- }
217
- if (schema[field].align === "Center") {
218
- styles[field] += "justify-content: center; text-align: center;"
219
- }
220
- if (schema[field].align === "Right") {
221
- styles[field] += "justify-content: flex-end; text-align: right;"
222
- }
223
- })
224
- return styles
225
- }
226
217
  </script>
227
218
 
228
- <div
229
- class="wrapper"
230
- class:wrapper--quiet={quiet}
231
- class:wrapper--compact={compact}
232
- bind:offsetHeight={height}
233
- style={`--row-height: ${rowHeight}px; --header-height: ${headerHeight}px;`}
234
- >
219
+ <div class="wrapper" bind:offsetHeight={height}>
235
220
  {#if !loaded}
236
- <div class="loading" style={contentStyle}>
237
- <ProgressCircle />
238
- </div>
221
+ <div class="loading" style={contentStyle} />
239
222
  {:else}
240
- <div class="spectrum-Table" style={`${contentStyle}${gridStyle}`}>
241
- {#if fields.length}
242
- <div class="spectrum-Table-head">
243
- {#if showEditColumn}
244
- <div
245
- class="spectrum-Table-headCell spectrum-Table-headCell--divider spectrum-Table-headCell--edit"
246
- >
247
- {editColumnTitle || ""}
248
- </div>
223
+ <div
224
+ on:scroll={onScroll}
225
+ class:quiet
226
+ style={`--row-height: ${rowHeight}px; --header-height: ${headerHeight}px;`}
227
+ class="container"
228
+ >
229
+ <div style={contentStyle}>
230
+ <table class="spectrum-Table" class:spectrum-Table--quiet={quiet}>
231
+ {#if fields.length}
232
+ <thead class="spectrum-Table-head">
233
+ <tr>
234
+ {#if showEditColumn}
235
+ <th class="spectrum-Table-headCell">
236
+ <div class="spectrum-Table-headCell-content">
237
+ {editColumnTitle || ""}
238
+ </div>
239
+ </th>
240
+ {/if}
241
+ {#each fields as field}
242
+ <th
243
+ class="spectrum-Table-headCell"
244
+ class:is-sortable={schema[field].sortable !== false}
245
+ class:is-sorted-desc={sortColumn === field &&
246
+ sortOrder === "Descending"}
247
+ class:is-sorted-asc={sortColumn === field &&
248
+ sortOrder === "Ascending"}
249
+ on:click={() => sortBy(schema[field])}
250
+ >
251
+ <div class="spectrum-Table-headCell-content">
252
+ <div class="title">{getDisplayName(schema[field])}</div>
253
+ {#if schema[field]?.autocolumn}
254
+ <svg
255
+ class="spectrum-Icon spectrum-Table-autoIcon"
256
+ focusable="false"
257
+ >
258
+ <use xlink:href="#spectrum-icon-18-MagicWand" />
259
+ </svg>
260
+ {/if}
261
+ {#if sortColumn === field}
262
+ <svg
263
+ class="spectrum-Icon spectrum-UIIcon-ArrowDown100 spectrum-Table-sortedIcon"
264
+ focusable="false"
265
+ aria-hidden="true"
266
+ >
267
+ <use xlink:href="#spectrum-css-icon-Arrow100" />
268
+ </svg>
269
+ {/if}
270
+ {#if allowEditColumns && schema[field]?.editable !== false}
271
+ <svg
272
+ class="spectrum-Icon spectrum-Table-editIcon"
273
+ focusable="false"
274
+ on:click={e => editColumn(e, field)}
275
+ >
276
+ <use xlink:href="#spectrum-icon-18-Edit" />
277
+ </svg>
278
+ {/if}
279
+ </div>
280
+ </th>
281
+ {/each}
282
+ </tr>
283
+ </thead>
249
284
  {/if}
250
- {#each fields as field}
251
- <div
252
- class="spectrum-Table-headCell"
253
- class:spectrum-Table-headCell--alignCenter={schema[field]
254
- .align === "Center"}
255
- class:spectrum-Table-headCell--alignRight={schema[field].align ===
256
- "Right"}
257
- class:is-sortable={schema[field].sortable !== false}
258
- class:is-sorted-desc={sortColumn === field &&
259
- sortOrder === "Descending"}
260
- class:is-sorted-asc={sortColumn === field &&
261
- sortOrder === "Ascending"}
262
- on:click={() => sortBy(schema[field])}
263
- >
264
- <div class="title">{getDisplayName(schema[field])}</div>
265
- {#if schema[field]?.autocolumn}
266
- <svg
267
- class="spectrum-Icon spectrum-Table-autoIcon"
268
- focusable="false"
269
- >
270
- <use xlink:href="#spectrum-icon-18-MagicWand" />
271
- </svg>
272
- {/if}
273
- {#if sortColumn === field}
274
- <svg
275
- class="spectrum-Icon spectrum-UIIcon-ArrowDown100 spectrum-Table-sortedIcon"
276
- focusable="false"
277
- aria-hidden="true"
285
+ <tbody class="spectrum-Table-body">
286
+ {#if sortedRows?.length && fields.length}
287
+ {#each sortedRows as row, idx}
288
+ <tr
289
+ on:click={() => dispatch("click", row)}
290
+ on:click={() => toggleSelectRow(row)}
291
+ class="spectrum-Table-row"
292
+ class:hidden={idx < firstVisibleRow || idx > lastVisibleRow}
278
293
  >
279
- <use xlink:href="#spectrum-css-icon-Arrow100" />
280
- </svg>
281
- {/if}
282
- {#if allowEditColumns && schema[field]?.editable !== false}
283
- <svg
284
- class="spectrum-Icon spectrum-Table-editIcon"
285
- focusable="false"
286
- on:click={e => editColumn(e, field)}
287
- >
288
- <use xlink:href="#spectrum-icon-18-Edit" />
289
- </svg>
290
- {/if}
291
- </div>
292
- {/each}
293
- </div>
294
- {/if}
295
- {#if sortedRows?.length}
296
- {#each sortedRows as row, idx}
297
- <div
298
- class="spectrum-Table-row"
299
- on:click={() => dispatch("click", row)}
300
- on:click={() => toggleSelectRow(row)}
301
- >
302
- {#if showEditColumn}
303
- <div
304
- class="spectrum-Table-cell spectrum-Table-cell--divider spectrum-Table-cell--edit"
305
- >
306
- <SelectEditRenderer
307
- data={row}
308
- selected={selectedRows.includes(row)}
309
- onToggleSelection={() => toggleSelectRow(row)}
310
- onEdit={e => editRow(e, row)}
311
- {allowSelectRows}
312
- {allowEditRows}
313
- />
314
- </div>
294
+ {#if idx >= firstVisibleRow && idx <= lastVisibleRow}
295
+ {#if showEditColumn}
296
+ <td
297
+ class="spectrum-Table-cell spectrum-Table-cell--divider"
298
+ >
299
+ <div class="spectrum-Table-cell-content">
300
+ <SelectEditRenderer
301
+ data={row}
302
+ selected={selectedRows.includes(row)}
303
+ onToggleSelection={() => toggleSelectRow(row)}
304
+ onEdit={e => editRow(e, row)}
305
+ {allowSelectRows}
306
+ {allowEditRows}
307
+ />
308
+ </div>
309
+ </td>
310
+ {/if}
311
+ {#each fields as field}
312
+ <td
313
+ class="spectrum-Table-cell"
314
+ class:spectrum-Table-cell--divider={!!schema[field]
315
+ .divider}
316
+ >
317
+ <div class="spectrum-Table-cell-content">
318
+ <CellRenderer
319
+ {customRenderers}
320
+ {row}
321
+ schema={schema[field]}
322
+ value={deepGet(row, field)}
323
+ on:clickrelationship
324
+ >
325
+ <slot />
326
+ </CellRenderer>
327
+ </div>
328
+ </td>
329
+ {/each}
330
+ {/if}
331
+ </tr>
332
+ {/each}
333
+ {:else}
334
+ <tr class="placeholder-row">
335
+ {#if showEditColumn}
336
+ <td class="placeholder-offset" />
337
+ {/if}
338
+ {#each fields as field}
339
+ <td />
340
+ {/each}
341
+ <div class="placeholder" class:has-fields={fields.length > 0}>
342
+ <div class="placeholder-content">
343
+ <svg
344
+ class="spectrum-Icon spectrum-Icon--sizeXXL"
345
+ focusable="false"
346
+ >
347
+ <use xlink:href="#spectrum-icon-18-Table" />
348
+ </svg>
349
+ <div>No rows found</div>
350
+ </div>
351
+ </div>
352
+ </tr>
315
353
  {/if}
316
- {#each fields as field}
317
- <div
318
- class="spectrum-Table-cell"
319
- class:spectrum-Table-cell--divider={!!schema[field].divider}
320
- style={cellStyles[field]}
321
- >
322
- <CellRenderer
323
- {customRenderers}
324
- {row}
325
- schema={schema[field]}
326
- value={deepGet(row, field)}
327
- on:clickrelationship
328
- >
329
- <slot />
330
- </CellRenderer>
331
- </div>
332
- {/each}
333
- </div>
334
- {/each}
335
- {:else}
336
- <div class="placeholder" class:placeholder--no-fields={!fields?.length}>
337
- <div class="placeholder-content">
338
- <svg class="spectrum-Icon spectrum-Icon--sizeXXL" focusable="false">
339
- <use xlink:href="#spectrum-icon-18-Table" />
340
- </svg>
341
- <div>No rows found</div>
342
- </div>
343
- </div>
344
- {/if}
354
+ </tbody>
355
+ </table>
356
+ </div>
345
357
  </div>
346
358
  {/if}
347
359
  </div>
348
360
 
349
361
  <style>
350
- /* Wrapper */
351
362
  .wrapper {
363
+ background-color: var(--spectrum-alias-background-color-secondary);
364
+ overflow: hidden;
352
365
  position: relative;
353
366
  z-index: 0;
354
- --table-bg: var(--spectrum-global-color-gray-50);
355
- --table-border: 1px solid var(--spectrum-alias-border-color-mid);
356
- --cell-padding: var(--spectrum-global-dimension-size-250);
357
- }
358
- .wrapper--quiet {
359
- --table-bg: var(--spectrum-alias-background-color-transparent);
360
- }
361
- .wrapper--compact {
362
- --cell-padding: var(--spectrum-global-dimension-size-150);
363
367
  }
364
368
 
365
- /* Loading */
366
- .loading {
367
- display: grid;
368
- place-items: center;
369
- min-height: 100px;
370
- }
371
-
372
- /* Table */
373
- .spectrum-Table {
374
- width: 100%;
375
- border-radius: 0;
376
- display: grid;
369
+ .container {
370
+ height: 100%;
371
+ position: relative;
377
372
  overflow: auto;
378
373
  }
379
-
380
- /* Header */
381
- .spectrum-Table-head {
382
- display: contents;
383
- }
384
- .spectrum-Table-head > :first-child {
385
- border-left: 1px solid transparent;
386
- padding-left: var(--cell-padding);
387
- }
388
- .spectrum-Table-head > :last-child {
389
- border-right: 1px solid transparent;
390
- padding-right: var(--cell-padding);
391
- }
392
- .spectrum-Table-headCell {
393
- height: var(--header-height);
394
- position: sticky;
395
- top: 0;
396
- text-overflow: ellipsis;
397
- white-space: nowrap;
398
- background-color: var(--spectrum-alias-background-color-secondary);
399
- z-index: 2;
400
- border-bottom: var(--table-border);
401
- padding: 0 calc(var(--cell-padding) / 1.33);
402
- display: flex;
403
- flex-direction: row;
404
- justify-content: flex-start;
405
- align-items: center;
406
- user-select: none;
407
- }
408
- .spectrum-Table-headCell--alignCenter {
409
- justify-content: center;
410
- }
411
- .spectrum-Table-headCell--alignRight {
412
- justify-content: flex-end;
413
- }
414
- .spectrum-Table-headCell--divider {
415
- padding-right: var(--cell-padding);
374
+ .container.quiet {
375
+ border: none;
416
376
  }
417
- .spectrum-Table-headCell--divider + .spectrum-Table-headCell {
418
- padding-left: var(--cell-padding);
419
- }
420
- .spectrum-Table-headCell--edit {
421
- position: sticky;
422
- left: 0;
423
- z-index: 3;
424
- }
425
- .spectrum-Table-headCell .title {
426
- overflow: hidden;
427
- text-overflow: ellipsis;
428
- }
429
- .spectrum-Table-headCell:hover .spectrum-Table-editIcon {
430
- opacity: 1;
431
- transition: opacity 0.2s ease;
377
+ table {
378
+ width: 100%;
432
379
  }
380
+
433
381
  .spectrum-Table-headCell .spectrum-Icon {
434
382
  pointer-events: all;
435
383
  margin-left: var(
@@ -445,93 +393,63 @@
445
393
  .spectrum-Table-editIcon {
446
394
  opacity: 0;
447
395
  }
448
-
449
- /* Table rows */
450
- .spectrum-Table-row {
451
- display: contents;
452
- }
453
- .spectrum-Table-row:hover .spectrum-Table-cell {
454
- /*background-color: var(--hover-bg) !important;*/
455
- }
456
- .spectrum-Table-row:hover .spectrum-Table-cell:after {
457
- background-color: var(--spectrum-alias-highlight-hover);
458
- }
459
- .wrapper--quiet .spectrum-Table-row {
460
- border-left: none;
461
- border-right: none;
462
- }
463
- .spectrum-Table-row > :first-child {
464
- border-left: var(--table-border);
465
- padding-left: var(--cell-padding);
466
- }
467
- .spectrum-Table-row > :last-child {
468
- border-right: var(--table-border);
469
- padding-right: var(--cell-padding);
396
+ .spectrum-Table-headCell:hover .spectrum-Table-editIcon {
397
+ opacity: 1;
398
+ transition: opacity 0.2s ease;
470
399
  }
471
400
 
472
- /* Table cells */
473
- .spectrum-Table-cell {
474
- flex: 1 1 auto;
475
- padding: 0 calc(var(--cell-padding) / 1.33);
476
- border-top: none;
477
- border-bottom: none;
478
- border-radius: 0;
479
- text-overflow: ellipsis;
401
+ th {
402
+ vertical-align: middle;
403
+ height: var(--header-height);
404
+ position: sticky;
405
+ top: 0;
406
+ z-index: 2;
407
+ background-color: var(--spectrum-alias-background-color-secondary);
408
+ border-bottom: 1px solid
409
+ var(--spectrum-table-border-color, var(--spectrum-alias-border-color-mid));
410
+ }
411
+ .spectrum-Table-headCell-content {
480
412
  white-space: nowrap;
481
- height: var(--row-height);
482
413
  display: flex;
483
414
  flex-direction: row;
484
415
  justify-content: flex-start;
485
416
  align-items: center;
486
- gap: 4px;
487
- border-bottom: 1px solid var(--spectrum-alias-border-color-mid);
488
- background-color: var(--table-bg);
489
- z-index: 1;
417
+ user-select: none;
490
418
  }
491
- .spectrum-Table-cell--divider {
492
- padding-right: var(--cell-padding);
419
+ .spectrum-Table-headCell-content .title {
420
+ overflow: hidden;
421
+ text-overflow: ellipsis;
493
422
  }
494
- .spectrum-Table-cell--divider + .spectrum-Table-cell {
495
- padding-left: var(--cell-padding);
423
+
424
+ .placeholder-row {
425
+ position: relative;
426
+ height: 150px;
496
427
  }
497
- .spectrum-Table-cell--edit {
498
- position: sticky;
499
- left: 0;
500
- z-index: 2;
428
+ .placeholder-row td {
429
+ border-top: none !important;
430
+ border-bottom: none !important;
501
431
  }
502
- .spectrum-Table-cell:after {
503
- content: "";
504
- position: absolute;
505
- width: 100%;
506
- height: 100%;
507
- background-color: transparent;
508
- top: 0;
509
- left: 0;
510
- pointer-events: none;
511
- transition: background-color
512
- var(--spectrum-global-animation-duration-100, 0.13s) ease-in-out;
432
+ .placeholder-offset {
433
+ width: 1px;
513
434
  }
514
-
515
- /* Placeholder */
516
435
  .placeholder {
436
+ top: 0;
437
+ height: 100%;
438
+ left: 0;
439
+ width: 100%;
440
+ position: absolute;
517
441
  display: flex;
518
442
  flex-direction: row;
519
443
  justify-content: center;
520
444
  align-items: center;
521
- border: var(--table-border);
522
- border-top: none;
523
- grid-column: 1 / -1;
524
- background-color: var(--table-bg);
525
445
  }
526
- .placeholder--no-fields {
527
- border-top: var(--table-border);
528
- }
529
- .wrapper--quiet .placeholder {
530
- border-left: none;
531
- border-right: none;
446
+ .placeholder.has-fields {
447
+ top: var(--header-height);
448
+ height: calc(100% - var(--header-height));
532
449
  }
450
+
533
451
  .placeholder-content {
534
- padding: 40px;
452
+ padding: 20px;
535
453
  display: flex;
536
454
  flex-direction: column;
537
455
  justify-content: center;
@@ -549,4 +467,41 @@
549
467
  );
550
468
  text-align: center;
551
469
  }
470
+
471
+ tbody {
472
+ z-index: 1;
473
+ }
474
+ tbody tr {
475
+ height: var(--row-height);
476
+ }
477
+ tbody tr.hidden {
478
+ height: calc(var(--row-height) + 1px);
479
+ }
480
+ td {
481
+ padding-top: 0;
482
+ padding-bottom: 0;
483
+ border-bottom: none;
484
+ border-top: 1px solid
485
+ var(--spectrum-table-border-color, var(--spectrum-alias-border-color-mid));
486
+ border-radius: 0;
487
+ }
488
+ tr:first-child td {
489
+ border-top: none;
490
+ }
491
+ tr:last-child td {
492
+ border-bottom: 1px solid
493
+ var(--spectrum-table-border-color, var(--spectrum-alias-border-color-mid));
494
+ }
495
+ td.spectrum-Table-cell--divider {
496
+ width: 1px;
497
+ }
498
+ .spectrum-Table-cell-content {
499
+ height: var(--row-height);
500
+ white-space: nowrap;
501
+ display: flex;
502
+ flex-direction: row;
503
+ justify-content: flex-start;
504
+ align-items: center;
505
+ gap: 4px;
506
+ }
552
507
  </style>