@svelte-lean/table 0.1.0

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.
package/dist/style.css ADDED
@@ -0,0 +1,806 @@
1
+ /*
2
+ * @svelte-lean/table. Layer `slean.components`, selectors in :where(): unlayered application CSS
3
+ * wins without !important (only print uses it, against inline styles). `--slean-table-*` tokens
4
+ * read `--slean-*` from @svelte-lean/styles and fall back to the same defaults, light-dark() by the
5
+ * page's color-scheme. Rows and cells are reached through child combinators and controls through
6
+ * the table's own classes, so nested tables and primitives in cells keep their own look.
7
+ */
8
+ @layer slean.reset, slean.tokens, slean.base, slean.components, slean.compositions, slean.utilities;
9
+
10
+ /* Native checkbox fallback, one layer below `@svelte-lean/styles/checkbox.css`, which wins when loaded. */
11
+ @layer slean.base {
12
+ :where(.slean-table-check) {
13
+ inline-size: 1rem;
14
+ block-size: 1rem;
15
+ margin: 0;
16
+ accent-color: var(--slean-table-accent);
17
+ vertical-align: middle;
18
+ cursor: pointer;
19
+ }
20
+ }
21
+
22
+ @layer slean.components {
23
+ :where(.slean-table) {
24
+ --slean-table-bg: var(--slean-surface, light-dark(#fff, oklch(19.5% 0.009 260)));
25
+ --slean-table-fg: var(--slean-fg, light-dark(oklch(20.5% 0.012 260), oklch(95% 0.005 260)));
26
+ --slean-table-muted: var(
27
+ --slean-fg-muted,
28
+ light-dark(oklch(44.6% 0.014 260), oklch(74% 0.012 260))
29
+ );
30
+ --slean-table-border: var(
31
+ --slean-border,
32
+ light-dark(oklch(87.2% 0.007 260), oklch(33.5% 0.013 260))
33
+ );
34
+ --slean-table-soft: var(
35
+ --slean-muted,
36
+ light-dark(oklch(95.8% 0.004 260), oklch(26% 0.011 260))
37
+ );
38
+ --slean-table-accent: var(--slean-accent, light-dark(oklch(54% 0.19 258), oklch(56% 0.18 258)));
39
+ --slean-table-selected: var(
40
+ --slean-accent-soft,
41
+ light-dark(oklch(95% 0.03 258), oklch(28% 0.07 258))
42
+ );
43
+ --slean-table-danger: var(--slean-danger, light-dark(oklch(55% 0.2 25), oklch(58% 0.19 25)));
44
+ --slean-table-focus: var(--slean-focus-ring-color, var(--slean-table-accent));
45
+ --slean-table-shadow: var(
46
+ --slean-shadow-lg,
47
+ 0 16px 40px oklch(0% 0 0 / 0.18),
48
+ 0 2px 6px oklch(0% 0 0 / 0.08)
49
+ );
50
+ --slean-table-radius: var(--slean-radius-lg, 0.875rem);
51
+ --slean-table-control-radius: var(--slean-radius-sm, 0.375rem);
52
+ --slean-table-control-height: var(--slean-control-height-sm, 2rem);
53
+ --slean-table-font: var(--slean-font-sans, system-ui, sans-serif);
54
+ --slean-table-font-size: var(--slean-text-sm, 0.875rem);
55
+ --slean-table-duration: var(--slean-duration-fast, 100ms);
56
+ --slean-table-cell-padding-x: 0.75rem;
57
+ --slean-table-cell-padding-y: 0.5rem;
58
+ --slean-table-header-bg: color-mix(
59
+ in oklab,
60
+ var(--slean-table-soft) 55%,
61
+ var(--slean-table-bg)
62
+ );
63
+ --slean-table-header-fg: var(--slean-table-muted);
64
+ --slean-table-header-font-size: 0.8125rem;
65
+ --slean-table-header-font-weight: 500;
66
+ --slean-table-header-text-transform: none;
67
+ --slean-table-header-letter-spacing: normal;
68
+ --slean-table-row-hover: color-mix(
69
+ in oklab,
70
+ var(--slean-table-soft) 60%,
71
+ var(--slean-table-bg)
72
+ );
73
+ --slean-table-row-stripe: color-mix(
74
+ in oklab,
75
+ var(--slean-table-soft) 45%,
76
+ var(--slean-table-bg)
77
+ );
78
+ --slean-table-row-selected: var(--slean-table-selected);
79
+ --slean-table-pin-shadow: light-dark(oklch(0% 0 0 / 0.1), oklch(0% 0 0 / 0.45));
80
+ --slean-table-fetching-opacity: 0.55;
81
+ /* Set per row by hover, stripes, selection or `rowClass`; reset here so it never leaks into a
82
+ table nested in a detail row. */
83
+ --slean-table-row-bg: initial;
84
+ box-sizing: border-box;
85
+ color: var(--slean-table-fg);
86
+ background: var(--slean-table-bg);
87
+ font-family: var(--slean-table-font);
88
+ font-size: var(--slean-table-font-size);
89
+ line-height: 1.43;
90
+ border: 1px solid var(--slean-table-border);
91
+ border-radius: var(--slean-table-radius);
92
+ isolation: isolate;
93
+ }
94
+ :where(.slean-table[data-density='compact']) {
95
+ --slean-table-cell-padding-y: 0.25rem;
96
+ --slean-table-font-size: 0.8125rem;
97
+ }
98
+ :where(.slean-table[data-density='spacious']) {
99
+ --slean-table-cell-padding-y: 0.875rem;
100
+ }
101
+ :where(
102
+ .slean-table-button,
103
+ .slean-table-input,
104
+ .slean-table-sort,
105
+ .slean-table-resize,
106
+ .slean-table-column-panel,
107
+ .slean-table-scroll,
108
+ .slean-table-scroll > table
109
+ ) {
110
+ box-sizing: border-box;
111
+ }
112
+
113
+ /* Owned controls: 32px, outline, tokens. */
114
+ :where(.slean-table-button, .slean-table-columns > summary) {
115
+ display: inline-flex;
116
+ align-items: center;
117
+ justify-content: center;
118
+ gap: 0.375rem;
119
+ min-block-size: var(--slean-table-control-height);
120
+ min-inline-size: var(--slean-table-control-height);
121
+ margin: 0;
122
+ padding: 0 0.75rem;
123
+ border: 1px solid var(--slean-table-border);
124
+ border-radius: var(--slean-table-control-radius);
125
+ background: var(--slean-table-bg);
126
+ color: var(--slean-table-fg);
127
+ font: inherit;
128
+ font-size: 0.8125rem;
129
+ font-weight: 500;
130
+ line-height: 1;
131
+ white-space: nowrap;
132
+ cursor: pointer;
133
+ }
134
+ :where(.slean-table-button:hover:not(:disabled), .slean-table-columns > summary:hover) {
135
+ background: var(--slean-table-soft);
136
+ }
137
+ :where(.slean-table-button:disabled) {
138
+ opacity: 0.5;
139
+ cursor: default;
140
+ }
141
+ :where(.slean-table-input) {
142
+ min-block-size: var(--slean-table-control-height);
143
+ margin: 0;
144
+ padding: 0 0.625rem;
145
+ border: 1px solid
146
+ var(--slean-control-border, light-dark(oklch(80.8% 0.009 260), oklch(39.5% 0.014 260)));
147
+ border-radius: var(--slean-table-control-radius);
148
+ background: var(--slean-table-bg);
149
+ color: var(--slean-table-fg);
150
+ font: inherit;
151
+ font-size: 0.8125rem;
152
+ }
153
+ :where(.slean-table-input)::placeholder {
154
+ color: var(--slean-table-muted);
155
+ opacity: 1;
156
+ }
157
+ :where(.slean-table-input:focus-visible) {
158
+ border-color: var(--slean-table-focus);
159
+ outline: 2px solid transparent;
160
+ box-shadow: var(
161
+ --slean-control-ring,
162
+ 0 0 0 3px color-mix(in oklab, var(--slean-table-focus) 22%, transparent)
163
+ );
164
+ }
165
+ :where(
166
+ .slean-table-button,
167
+ .slean-table-sort,
168
+ .slean-table-resize,
169
+ .slean-table-group-toggle,
170
+ .slean-table-columns > summary,
171
+ .slean-table-scroll,
172
+ .slean-table-check
173
+ ):focus-visible {
174
+ outline: 2px solid var(--slean-table-focus);
175
+ outline-offset: 2px;
176
+ }
177
+ :where(.slean-table-scroll > table > tbody > tr > td[tabindex]):focus-visible,
178
+ :where(.slean-table-scroll > table > tbody > tr[tabindex]):focus-visible {
179
+ outline: 2px solid var(--slean-table-focus);
180
+ outline-offset: -2px;
181
+ }
182
+ :where(.slean-table-scroll > table > tbody > tr[data-clickable]) {
183
+ cursor: pointer;
184
+ }
185
+
186
+ /* Toolbar, title, column controls. */
187
+ :where(.slean-table-toolbar) {
188
+ display: flex;
189
+ align-items: center;
190
+ gap: 0.5rem;
191
+ padding: 0.75rem;
192
+ flex-wrap: wrap;
193
+ }
194
+ :where(.slean-table-title) {
195
+ padding: 0.75rem;
196
+ font-weight: 600;
197
+ border-bottom: 1px solid var(--slean-table-border);
198
+ }
199
+ :where(.slean-table-search) {
200
+ flex: 1 1 14rem;
201
+ min-inline-size: 10rem;
202
+ max-inline-size: 20rem;
203
+ font-size: 0.875rem;
204
+ }
205
+ :where(.slean-table-selected) {
206
+ font-size: 0.8125rem;
207
+ color: var(--slean-table-muted);
208
+ }
209
+ :where(.slean-table-columns) {
210
+ position: relative;
211
+ margin-inline-start: auto;
212
+ }
213
+ :where(.slean-table-columns > summary) {
214
+ list-style: none;
215
+ }
216
+ :where(.slean-table-columns > summary)::-webkit-details-marker {
217
+ display: none;
218
+ }
219
+ :where(.slean-table-column-panel) {
220
+ position: absolute;
221
+ inset-inline-end: 0;
222
+ top: calc(100% + 0.375rem);
223
+ z-index: 20;
224
+ min-inline-size: 22rem;
225
+ max-block-size: 25rem;
226
+ overflow: auto;
227
+ padding: 0.375rem 0.625rem;
228
+ background: var(--slean-table-bg);
229
+ border: 1px solid var(--slean-table-border);
230
+ border-radius: var(--slean-radius-md, 0.625rem);
231
+ box-shadow: var(--slean-table-shadow);
232
+ }
233
+ :where(.slean-table-column-panel > div) {
234
+ display: flex;
235
+ align-items: center;
236
+ gap: 0.25rem;
237
+ padding: 0.25rem 0;
238
+ }
239
+ :where(.slean-table-column-panel label) {
240
+ display: flex;
241
+ gap: 0.5rem;
242
+ align-items: center;
243
+ flex: 1;
244
+ }
245
+ :where(.slean-table-column-panel .slean-table-button) {
246
+ min-inline-size: 1.75rem;
247
+ min-block-size: 1.75rem;
248
+ padding: 0;
249
+ border-color: transparent;
250
+ background: transparent;
251
+ }
252
+ :where(.slean-table-column-panel .slean-table-input) {
253
+ min-block-size: 1.75rem;
254
+ }
255
+
256
+ /* Scroll region and table. */
257
+ :where(.slean-table-scroll) {
258
+ overflow: auto;
259
+ position: relative;
260
+ border-block: 1px solid var(--slean-table-border);
261
+ }
262
+ /* Nothing above or below the scroll region (no toolbar, no pager): the root's border is the
263
+ line, and the region clips its content to the root's rounded corners. */
264
+ :where(.slean-table > .slean-table-scroll:first-child) {
265
+ border-top: 0;
266
+ border-start-start-radius: calc(var(--slean-table-radius) - 1px);
267
+ border-start-end-radius: calc(var(--slean-table-radius) - 1px);
268
+ }
269
+ :where(.slean-table > .slean-table-scroll:last-child) {
270
+ border-bottom: 0;
271
+ border-end-start-radius: calc(var(--slean-table-radius) - 1px);
272
+ border-end-end-radius: calc(var(--slean-table-radius) - 1px);
273
+ }
274
+ :where(.slean-table-scroll > table) {
275
+ border-collapse: separate;
276
+ border-spacing: 0;
277
+ table-layout: fixed;
278
+ /* Not width: 100%: a percentage-width table reports an unbounded max-content size, which
279
+ blows up any shrink-to-fit container around it (a nested table, a grid or flex item). */
280
+ width: max-content;
281
+ min-width: 100%;
282
+ }
283
+ :where(.slean-table-scroll > table > caption) {
284
+ text-align: start;
285
+ padding: 0.75rem;
286
+ color: var(--slean-table-muted);
287
+ }
288
+ :where(.slean-table-scroll > table > * > tr > :is(th, td)) {
289
+ padding: var(--slean-table-cell-padding-y) var(--slean-table-cell-padding-x);
290
+ border-bottom: 1px solid var(--slean-table-border);
291
+ background: var(--slean-table-row-bg, var(--slean-table-bg));
292
+ overflow-wrap: anywhere;
293
+ vertical-align: middle;
294
+ }
295
+ :where(.slean-table-scroll > table > thead > tr > :is(th, td)) {
296
+ background: var(--slean-table-header-bg);
297
+ color: var(--slean-table-header-fg);
298
+ font-size: var(--slean-table-header-font-size);
299
+ font-weight: var(--slean-table-header-font-weight);
300
+ text-transform: var(--slean-table-header-text-transform);
301
+ letter-spacing: var(--slean-table-header-letter-spacing);
302
+ text-align: start;
303
+ position: relative;
304
+ }
305
+ /* The filter row: data cells inside the head, on the head's surface. */
306
+ :where(.slean-table-filters > td) {
307
+ padding-block: 0.375rem;
308
+ text-transform: none;
309
+ letter-spacing: normal;
310
+ }
311
+ :where(.slean-table-sticky > thead) {
312
+ position: sticky;
313
+ top: 0;
314
+ z-index: 5;
315
+ }
316
+ /* Page-sticky header (no `height`, the table fits its width): the region is no scroll container,
317
+ so the header sticks to the page, below `--slean-table-sticky-top`. The corner cells take over
318
+ the rounding the region no longer clips. */
319
+ :where(.slean-table-scroll[data-page-sticky]) {
320
+ overflow: visible;
321
+ }
322
+ :where(.slean-table-scroll[data-page-sticky] > .slean-table-sticky > thead) {
323
+ top: var(--slean-table-sticky-top, 0px);
324
+ }
325
+ :where(
326
+ .slean-table
327
+ > .slean-table-scroll[data-page-sticky]:first-child
328
+ > table
329
+ > thead
330
+ > tr:first-child
331
+ > :first-child
332
+ ) {
333
+ border-start-start-radius: calc(var(--slean-table-radius) - 1px);
334
+ }
335
+ :where(
336
+ .slean-table
337
+ > .slean-table-scroll[data-page-sticky]:first-child
338
+ > table
339
+ > thead
340
+ > tr:first-child
341
+ > :last-child
342
+ ) {
343
+ border-start-end-radius: calc(var(--slean-table-radius) - 1px);
344
+ }
345
+ :where(.slean-table-scroll > table > tbody > tr:last-child > td) {
346
+ border-bottom: 0;
347
+ }
348
+ :where(.slean-table-heading) {
349
+ display: flex;
350
+ align-items: center;
351
+ gap: 0.25rem;
352
+ min-height: 1.5rem;
353
+ }
354
+ :where(th[data-align='end'] > .slean-table-heading) {
355
+ justify-content: flex-end;
356
+ }
357
+ :where(th[data-align='center'] > .slean-table-heading) {
358
+ justify-content: center;
359
+ }
360
+ :where(.slean-table-sort) {
361
+ appearance: none;
362
+ display: inline-flex;
363
+ align-items: center;
364
+ gap: 0.375rem;
365
+ min-inline-size: 0;
366
+ margin: 0 0 0 -0.25rem;
367
+ padding: 0.125rem 0.25rem;
368
+ border: 0;
369
+ border-radius: var(--slean-table-control-radius);
370
+ background: transparent;
371
+ color: inherit;
372
+ font: inherit;
373
+ text-align: start;
374
+ text-transform: inherit;
375
+ letter-spacing: inherit;
376
+ cursor: pointer;
377
+ }
378
+ :where(.slean-table-sort:hover) {
379
+ color: var(--slean-table-fg);
380
+ }
381
+ :where(.slean-table-sort-icon) {
382
+ display: inline-flex;
383
+ align-items: center;
384
+ gap: 0.125rem;
385
+ font-size: 0.6875rem;
386
+ font-variant-numeric: tabular-nums;
387
+ opacity: 0.65;
388
+ }
389
+ /* Pointer devices see the icon on hover and focus; touch devices always. Sorted: always. */
390
+ @media (hover: hover) {
391
+ :where(.slean-table-sort-icon) {
392
+ opacity: 0;
393
+ }
394
+ :where(th:hover > .slean-table-heading > .slean-table-sort > .slean-table-sort-icon),
395
+ :where(.slean-table-sort:focus-visible > .slean-table-sort-icon) {
396
+ opacity: 0.65;
397
+ }
398
+ }
399
+ :where(th[aria-sort] > .slean-table-heading > .slean-table-sort) {
400
+ color: var(--slean-table-fg);
401
+ }
402
+ :where(th[aria-sort] > .slean-table-heading > .slean-table-sort > .slean-table-sort-icon) {
403
+ opacity: 1;
404
+ }
405
+ :where(.slean-table-resize) {
406
+ appearance: none;
407
+ position: absolute;
408
+ inset-inline-end: 0;
409
+ top: 0;
410
+ height: 100%;
411
+ width: 7px;
412
+ margin: 0;
413
+ padding: 0;
414
+ border: 0;
415
+ border-radius: 0;
416
+ background: transparent;
417
+ cursor: col-resize;
418
+ touch-action: none;
419
+ }
420
+ :where(.slean-table-resize:hover, .slean-table-resize:focus-visible) {
421
+ background: linear-gradient(var(--slean-table-accent), var(--slean-table-accent)) center / 2px
422
+ 100% no-repeat;
423
+ }
424
+ :where(.slean-table-filter) {
425
+ width: 100%;
426
+ min-width: 3rem;
427
+ font-weight: 400;
428
+ }
429
+ :where(.slean-table-cell) {
430
+ display: flex;
431
+ align-items: center;
432
+ gap: 0.5rem;
433
+ min-height: 1.5rem;
434
+ }
435
+ :where(td[data-align='end'] > .slean-table-cell) {
436
+ justify-content: flex-end;
437
+ }
438
+ :where(td[data-align='center'] > .slean-table-cell) {
439
+ justify-content: center;
440
+ }
441
+ :where(.slean-table-placeholder) {
442
+ color: var(--slean-table-muted);
443
+ }
444
+ :where(.slean-table-icon) {
445
+ inline-size: 1rem;
446
+ block-size: 1rem;
447
+ fill: none;
448
+ stroke: currentColor;
449
+ stroke-width: 1.5;
450
+ stroke-linecap: round;
451
+ stroke-linejoin: round;
452
+ flex-shrink: 0;
453
+ }
454
+ :where(.slean-table-sort-icon > .slean-table-icon) {
455
+ inline-size: 0.875rem;
456
+ block-size: 0.875rem;
457
+ }
458
+ :where(.slean-table-page-gap > .slean-table-icon) {
459
+ stroke-width: 2.5;
460
+ }
461
+
462
+ /* Row controls: 24px ghost icon buttons. */
463
+ :where(.slean-table-expand, .slean-table-edit, .slean-table-row-move > .slean-table-button) {
464
+ min-inline-size: 1.5rem;
465
+ min-block-size: 1.5rem;
466
+ padding: 0;
467
+ border-color: transparent;
468
+ background: transparent;
469
+ color: var(--slean-table-muted);
470
+ flex-shrink: 0;
471
+ }
472
+ :where(
473
+ .slean-table-expand:hover,
474
+ .slean-table-edit:hover,
475
+ .slean-table-row-move > .slean-table-button:hover
476
+ ) {
477
+ color: var(--slean-table-fg);
478
+ }
479
+ /* Keeps the text of rows without a toggle aligned with the rows that have one. */
480
+ :where(.slean-table-expand-spacer) {
481
+ inline-size: 1.5rem;
482
+ flex-shrink: 0;
483
+ }
484
+ :where(.slean-table-edit) {
485
+ margin-inline-start: auto;
486
+ opacity: 0.4;
487
+ }
488
+ :where(td:hover > .slean-table-cell > .slean-table-edit, .slean-table-edit:focus-visible) {
489
+ opacity: 1;
490
+ }
491
+ :where(.slean-table-row-move) {
492
+ display: flex;
493
+ gap: 0.125rem;
494
+ }
495
+ :where(.slean-table-ellipsis > .slean-table-cell) {
496
+ line-height: 1.5rem;
497
+ min-width: 0;
498
+ overflow: hidden;
499
+ white-space: nowrap;
500
+ text-overflow: ellipsis;
501
+ display: block;
502
+ }
503
+
504
+ /* Row states write one variable on the row; cells paint it (pinned cells included). Stripes
505
+ count data rows only, so an open detail row does not shift them. */
506
+ :where(
507
+ .slean-table[data-striped='true']
508
+ > .slean-table-scroll
509
+ > table
510
+ > tbody
511
+ > tr:nth-child(even of [data-row-id])
512
+ ) {
513
+ --slean-table-row-bg: var(--slean-table-row-stripe);
514
+ }
515
+ :where(
516
+ .slean-table[data-hoverable='true']
517
+ > .slean-table-scroll
518
+ > table
519
+ > tbody
520
+ > tr[data-row-id]:hover
521
+ ) {
522
+ --slean-table-row-bg: var(--slean-table-row-hover);
523
+ }
524
+ :where(.slean-table-scroll > table > tbody > tr[data-selected='true']) {
525
+ --slean-table-row-bg: var(--slean-table-row-selected);
526
+ }
527
+ :where(.slean-table[data-bordered='true'] > .slean-table-scroll > table > * > tr > :is(th, td)) {
528
+ border-inline-end: 1px solid var(--slean-table-border);
529
+ }
530
+ :where(.slean-table[data-bordered='true'] > .slean-table-scroll > table > * > tr > :last-child) {
531
+ border-inline-end: 0;
532
+ }
533
+
534
+ /* Leading control columns and pinned columns. */
535
+ :where(.slean-table-selection, .slean-table-expander) {
536
+ position: sticky;
537
+ inset-inline-start: 0;
538
+ z-index: 3;
539
+ text-align: center;
540
+ }
541
+ :where(.slean-table-selection) {
542
+ width: var(--slean-table-selection-width, 44px);
543
+ padding-inline: 0;
544
+ }
545
+ :where(.slean-table-expander) {
546
+ width: var(--slean-table-expand-width, 40px);
547
+ padding-inline: 0;
548
+ }
549
+ :where(thead .slean-table-selection, thead .slean-table-expander) {
550
+ z-index: 4;
551
+ }
552
+ :where(.slean-table-scroll > table > * > tr > [data-pin='left'][data-pin-edge]) {
553
+ border-inline-end: 1px solid var(--slean-table-border);
554
+ box-shadow: 6px 0 8px -6px var(--slean-table-pin-shadow);
555
+ }
556
+ :where(.slean-table-scroll > table > * > tr > [data-pin='right'][data-pin-edge]) {
557
+ border-inline-start: 1px solid var(--slean-table-border);
558
+ box-shadow: -6px 0 8px -6px var(--slean-table-pin-shadow);
559
+ }
560
+ :where(.slean-table-scroll > table > * > tr > [data-pin='left'][data-pin-edge]:dir(rtl)) {
561
+ box-shadow: -6px 0 8px -6px var(--slean-table-pin-shadow);
562
+ }
563
+ :where(.slean-table-scroll > table > * > tr > [data-pin='right'][data-pin-edge]:dir(rtl)) {
564
+ box-shadow: 6px 0 8px -6px var(--slean-table-pin-shadow);
565
+ }
566
+ :where(.slean-table-scroll > table > tbody > tr > td[data-range='true']) {
567
+ background: var(--slean-table-selected);
568
+ box-shadow: inset 0 0 0 1px var(--slean-table-accent);
569
+ }
570
+
571
+ /* Empty, loading, fetching, error. */
572
+ :where(.slean-table-scroll > table > tbody > tr > .slean-table-empty) {
573
+ padding: 3rem 1rem;
574
+ text-align: center;
575
+ color: var(--slean-table-muted);
576
+ }
577
+ :where(.slean-table-skeleton) {
578
+ display: block;
579
+ block-size: 0.75rem;
580
+ inline-size: 70%;
581
+ max-inline-size: 12rem;
582
+ border-radius: 999px;
583
+ background: var(--slean-table-soft);
584
+ }
585
+ :where(.slean-table-skeleton-row > td:nth-child(3n + 2) > .slean-table-skeleton) {
586
+ inline-size: 45%;
587
+ }
588
+ :where(.slean-table-skeleton-row > td:nth-child(3n) > .slean-table-skeleton) {
589
+ inline-size: 85%;
590
+ }
591
+ :where(.slean-table[data-fetching] > .slean-table-scroll > table > tbody) {
592
+ opacity: var(--slean-table-fetching-opacity);
593
+ }
594
+ :where(.slean-table-error) {
595
+ display: flex;
596
+ align-items: center;
597
+ gap: 0.75rem;
598
+ padding: 0.625rem 0.75rem;
599
+ color: var(--slean-table-danger);
600
+ background: color-mix(in oklab, var(--slean-table-danger) 8%, var(--slean-table-bg));
601
+ }
602
+ :where(.slean-table-editor) {
603
+ display: flex;
604
+ flex-wrap: wrap;
605
+ align-items: center;
606
+ gap: 0.375rem;
607
+ }
608
+ :where(.slean-table-editor > .slean-table-input) {
609
+ flex: 1 1 100%;
610
+ min-width: 4.5rem;
611
+ }
612
+ :where(.slean-table-editor > [role='alert']) {
613
+ color: var(--slean-table-danger);
614
+ width: 100%;
615
+ font-size: 0.75rem;
616
+ }
617
+
618
+ /* Detail rows, groups, footer. */
619
+ :where(.slean-table-scroll > table > tbody > .slean-table-detail > td) {
620
+ padding: 1rem;
621
+ background: var(--slean-table-row-stripe);
622
+ }
623
+ :where(.slean-table-scroll > table > tbody > .slean-table-group > th) {
624
+ background: var(--slean-table-header-bg);
625
+ text-align: start;
626
+ font-weight: 600;
627
+ }
628
+ :where(.slean-table-group-toggle) {
629
+ appearance: none;
630
+ display: inline-flex;
631
+ align-items: center;
632
+ gap: 0.375rem;
633
+ margin: 0;
634
+ padding: 0.125rem 0.25rem;
635
+ border: 0;
636
+ border-radius: var(--slean-table-control-radius);
637
+ background: transparent;
638
+ color: inherit;
639
+ font: inherit;
640
+ cursor: pointer;
641
+ }
642
+ :where(.slean-table-aggregate) {
643
+ margin-inline-start: 1.25rem;
644
+ font-weight: 400;
645
+ font-size: 0.75rem;
646
+ color: var(--slean-table-muted);
647
+ }
648
+ :where(.slean-table-scroll > table > tfoot > tr > td) {
649
+ font-weight: 600;
650
+ background: var(--slean-table-header-bg);
651
+ border-top: 1px solid var(--slean-table-border);
652
+ border-bottom: 0;
653
+ }
654
+
655
+ /* Pagination. */
656
+ /* The status takes the start; the controls keep to the end edge, also on a wrapped line. */
657
+ :where(.slean-table-pagination) {
658
+ display: flex;
659
+ align-items: center;
660
+ justify-content: flex-end;
661
+ gap: 0.5rem 1rem;
662
+ padding: 0.5rem 0.75rem;
663
+ font-size: 0.8125rem;
664
+ flex-wrap: wrap;
665
+ }
666
+ :where(.slean-table-page-status) {
667
+ margin-inline-end: auto;
668
+ color: var(--slean-table-muted);
669
+ }
670
+ :where(.slean-table-page-size) {
671
+ display: flex;
672
+ align-items: center;
673
+ gap: 0.5rem;
674
+ white-space: nowrap;
675
+ }
676
+ :where(.slean-table-pager, .slean-table-pages) {
677
+ display: flex;
678
+ align-items: center;
679
+ gap: 0.25rem;
680
+ }
681
+ :where(.slean-table-pager .slean-table-button) {
682
+ padding: 0 0.5rem;
683
+ font-variant-numeric: tabular-nums;
684
+ }
685
+ :where(.slean-table-pages > .slean-table-button) {
686
+ border-color: transparent;
687
+ background: transparent;
688
+ }
689
+ :where(.slean-table-pages > .slean-table-button[aria-current='page']) {
690
+ border-color: var(--slean-table-border);
691
+ background: var(--slean-table-bg);
692
+ font-weight: 600;
693
+ }
694
+ :where(.slean-table-page-gap) {
695
+ display: inline-flex;
696
+ justify-content: center;
697
+ min-inline-size: var(--slean-table-control-height);
698
+ color: var(--slean-table-muted);
699
+ }
700
+ /* Direction-bearing icons point the other way in right-to-left tables. */
701
+ :where(
702
+ .slean-table-pager .slean-table-icon,
703
+ [aria-expanded='false'] > .slean-table-icon,
704
+ .slean-table-column-panel .slean-table-icon
705
+ ):dir(rtl) {
706
+ scale: -1 1;
707
+ }
708
+
709
+ @media (prefers-reduced-motion: no-preference) {
710
+ :where(.slean-table-button, .slean-table-input, .slean-table-columns > summary) {
711
+ transition-property: background-color, border-color, box-shadow, color;
712
+ transition-duration: var(--slean-table-duration);
713
+ }
714
+ :where(.slean-table-sort-icon) {
715
+ transition: opacity var(--slean-table-duration);
716
+ }
717
+ :where(.slean-table-scroll > table > tbody) {
718
+ transition: opacity var(--slean-table-duration);
719
+ }
720
+ :where(.slean-table-skeleton) {
721
+ background: linear-gradient(
722
+ 90deg,
723
+ transparent 20%,
724
+ color-mix(in oklab, var(--slean-table-bg) 60%, transparent) 50%,
725
+ transparent 80%
726
+ )
727
+ 0 0 / 200% 100% var(--slean-table-soft);
728
+ animation: slean-table-shimmer 1.6s linear infinite;
729
+ }
730
+ }
731
+ @keyframes slean-table-shimmer {
732
+ from {
733
+ background-position: 200% 0;
734
+ }
735
+ to {
736
+ background-position: -200% 0;
737
+ }
738
+ }
739
+ @media (max-width: 600px) {
740
+ :where(.slean-table-column-panel) {
741
+ min-inline-size: 18rem;
742
+ }
743
+ :where(.slean-table-page-size, .slean-table-pages) {
744
+ display: none;
745
+ }
746
+ }
747
+ /* Text for assistive technology only (sort precedence, control column headers, status). */
748
+ :where(.slean-table-visually-hidden) {
749
+ position: absolute;
750
+ width: 1px;
751
+ height: 1px;
752
+ margin: -1px;
753
+ padding: 0;
754
+ overflow: hidden;
755
+ clip-path: inset(50%);
756
+ white-space: nowrap;
757
+ border: 0;
758
+ }
759
+ /* Forced colors replace backgrounds with Canvas and drop shadows; selection needs system colors. */
760
+ @media (forced-colors: active) {
761
+ :where(.slean-table-scroll > table > tbody > tr[data-selected='true'] > td),
762
+ :where(.slean-table-scroll > table > tbody > tr > td[data-range='true']) {
763
+ forced-color-adjust: none;
764
+ background: Highlight;
765
+ color: HighlightText;
766
+ }
767
+ :where(.slean-table-scroll > table > tbody > tr > td[data-range='true']) {
768
+ outline: 1px solid HighlightText;
769
+ outline-offset: -2px;
770
+ }
771
+ :where(.slean-table-pages > .slean-table-button[aria-current='page']) {
772
+ border-color: Highlight;
773
+ }
774
+ }
775
+ /* Print: inline sticky offsets and the scroll limit are inline styles, hence !important. */
776
+ @media print {
777
+ :where(
778
+ .slean-table-toolbar,
779
+ .slean-table-pagination,
780
+ .slean-table-resize,
781
+ .slean-table-edit,
782
+ .slean-table-row-move
783
+ ) {
784
+ display: none !important;
785
+ }
786
+ :where(.slean-table-scroll) {
787
+ overflow: visible;
788
+ max-height: none !important;
789
+ }
790
+ :where(.slean-table-scroll > table) {
791
+ min-width: 0;
792
+ width: 100%;
793
+ }
794
+ :where(.slean-table-scroll > table > * > tr > :is(th, td)) {
795
+ position: static !important;
796
+ box-shadow: none;
797
+ }
798
+ :where(.slean-table-scroll > table > thead) {
799
+ position: static !important;
800
+ display: table-header-group;
801
+ }
802
+ :where(.slean-table-scroll > table > * > tr) {
803
+ break-inside: avoid;
804
+ }
805
+ }
806
+ }