@varialkit/table 0.1.1

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/package.json ADDED
@@ -0,0 +1,32 @@
1
+ {
2
+ "name": "@varialkit/table",
3
+ "version": "0.1.1",
4
+ "type": "module",
5
+ "main": "src/index.ts",
6
+ "types": "src/index.ts",
7
+ "exports": {
8
+ ".": "./src/index.ts",
9
+ "./examples": "./examples/index.tsx"
10
+ },
11
+ "files": [
12
+ "src",
13
+ "docs.md",
14
+ "examples",
15
+ "examples.tsx"
16
+ ],
17
+ "peerDependencies": {
18
+ "react": "^19.0.0"
19
+ },
20
+ "dependencies": {
21
+ "@tanstack/react-table": "^8.21.2",
22
+ "@varialkit/button": "0.1.1",
23
+ "@varialkit/checkbox": "0.1.1",
24
+ "@varialkit/dropdown": "0.1.1",
25
+ "@varialkit/icons": "0.1.1",
26
+ "@varialkit/menu": "0.1.1"
27
+ },
28
+ "devDependencies": {
29
+ "@types/react": "19.0.10",
30
+ "react": "19.0.0"
31
+ }
32
+ }
package/src/Table.scss ADDED
@@ -0,0 +1,531 @@
1
+ .solara-table {
2
+ width: 100%;
3
+ overflow-x: auto;
4
+ /* Map table presentation to the shared theme token system. */
5
+ --solara-table-text-primary: var(--color-text-primary, #0f172a);
6
+ --solara-table-text-secondary: var(--color-text-secondary, #475569);
7
+ --solara-table-text-tertiary: var(--color-text-tertiary, #94a3b8);
8
+ --solara-table-text-muted: var(--color-text-secondary, #64748b);
9
+ --solara-table-surface-base: var(--color-surface-0, #ffffff);
10
+ --solara-table-surface-header: var(--color-surface-100, #f8fafc);
11
+ --solara-table-surface-hover: var(--color-surface-100, #f8fafc);
12
+ --solara-table-border-color: var(--color-divider-primary, #e2e8f0);
13
+ color: var(--solara-table-text-primary);
14
+ /* Row state variables are theme-overridable so selection/expansion colors stay consistent app-wide. */
15
+ --solara-table-row-hover-bg: var(--color-surface-100, #f8fafc);
16
+ --solara-table-row-selected-bg: color-mix(
17
+ in srgb,
18
+ var(--color-accent-primary, #2563eb) 14%,
19
+ transparent
20
+ );
21
+ --solara-table-row-selected-hover-bg: color-mix(
22
+ in srgb,
23
+ var(--color-accent-primary, #2563eb) 18%,
24
+ transparent
25
+ );
26
+ --solara-table-row-expanded-bg: color-mix(
27
+ in srgb,
28
+ var(--color-accent-primary, #2563eb) 8%,
29
+ transparent
30
+ );
31
+ --solara-table-row-expanded-hover-bg: color-mix(
32
+ in srgb,
33
+ var(--color-accent-primary, #2563eb) 12%,
34
+ transparent
35
+ );
36
+ --solara-table-row-expanded-selected-bg: color-mix(
37
+ in srgb,
38
+ var(--color-accent-primary, #2563eb) 22%,
39
+ transparent
40
+ );
41
+ --solara-table-row-subrow-bg: color-mix(
42
+ in srgb,
43
+ var(--color-surface-200, #f1f5f9) 65%,
44
+ transparent
45
+ );
46
+ --solara-table-row-subrow-expanded-bg: color-mix(
47
+ in srgb,
48
+ var(--color-accent-primary, #2563eb) 10%,
49
+ var(--color-surface-100, #f8fafc)
50
+ );
51
+ --solara-table-row-subrow-selected-bg: color-mix(
52
+ in srgb,
53
+ var(--color-accent-primary, #2563eb) 20%,
54
+ transparent
55
+ );
56
+ --solara-table-row-expanded-accent: color-mix(
57
+ in srgb,
58
+ var(--color-accent-primary, #2563eb) 40%,
59
+ transparent
60
+ );
61
+ /* Grid layout tokens are density-aware and can be overridden per surface. */
62
+ --solara-table-grid-gap: 0.75rem;
63
+ --solara-table-grid-row-gap: var(--solara-table-grid-gap);
64
+ --solara-table-grid-column-gap: var(--solara-table-grid-gap);
65
+ --solara-table-grid-details-gap: 0.5rem;
66
+ --solara-table-grid-details-padding: 0.75rem;
67
+ --solara-table-grid-media-min-height: 180px;
68
+ }
69
+
70
+ .solara-table--split-sticky {
71
+ /* Split layout handles horizontal scroll inside the center pane. */
72
+ overflow-x: visible;
73
+ }
74
+ .solara-table--split-sticky {
75
+ overflow-x: visible;
76
+ }
77
+
78
+ .solara-table__table {
79
+ width: 100%;
80
+ border-collapse: collapse;
81
+ border-spacing: 0;
82
+ }
83
+
84
+ .solara-table__head th {
85
+ text-align: left;
86
+ font-weight: 600;
87
+ color: var(--solara-table-text-secondary);
88
+ background: var(--solara-table-header-bg, var(--solara-table-surface-header));
89
+ }
90
+
91
+ .solara-table__cell,
92
+ .solara-table__header-cell {
93
+ padding: 0.75rem 1rem;
94
+ border-bottom: 1px solid var(--solara-table-border-color);
95
+ font-size: 0.875rem;
96
+ }
97
+
98
+ .solara-table__row:hover {
99
+ /* Hover sets the default row background; explicit state classes below can override it. */
100
+ --solara-table-row-bg: var(
101
+ --solara-table-row-hover-bg,
102
+ var(--solara-table-surface-hover)
103
+ );
104
+ }
105
+
106
+ .solara-table__row > .solara-table__cell,
107
+ .solara-table__row > .solara-table__actions-cell {
108
+ /* Apply a single resolved row color to each cell so pinning/split panes stay visually aligned. */
109
+ background: var(--solara-table-row-bg, transparent);
110
+ }
111
+
112
+ .solara-table__row--selected {
113
+ --solara-table-row-bg: var(--solara-table-row-selected-bg);
114
+ }
115
+
116
+ .solara-table__row--selected:hover {
117
+ --solara-table-row-bg: var(--solara-table-row-selected-hover-bg);
118
+ }
119
+
120
+ .solara-table__row--expanded {
121
+ --solara-table-row-bg: var(--solara-table-row-expanded-bg);
122
+ }
123
+
124
+ .solara-table__row--expanded:hover {
125
+ --solara-table-row-bg: var(--solara-table-row-expanded-hover-bg);
126
+ }
127
+
128
+ .solara-table__row--expanded.solara-table__row--selected {
129
+ --solara-table-row-bg: var(--solara-table-row-expanded-selected-bg);
130
+ }
131
+
132
+ .solara-table__row--subrow {
133
+ --solara-table-row-bg: var(--solara-table-row-subrow-bg);
134
+ }
135
+
136
+ .solara-table__row--subrow.solara-table__row--in-expanded-group {
137
+ --solara-table-row-bg: var(--solara-table-row-subrow-expanded-bg);
138
+ }
139
+
140
+ .solara-table__row--subrow.solara-table__row--selected {
141
+ --solara-table-row-bg: var(--solara-table-row-subrow-selected-bg);
142
+ }
143
+
144
+ .solara-table__row--expanded > .solara-table__cell:first-child,
145
+ .solara-table__row--expanded > .solara-table__actions-cell:first-child {
146
+ /* Subtle leading edge to indicate the parent row controls expanded content. */
147
+ box-shadow: inset 2px 0 0 var(--solara-table-row-expanded-accent);
148
+ }
149
+
150
+ .solara-table__row--clickable {
151
+ cursor: pointer;
152
+ }
153
+
154
+ .solara-table__cell--pinned,
155
+ .solara-table__header-cell--pinned {
156
+ position: sticky;
157
+ left: 0;
158
+ /* Prefer row background when set so pinned cells inherit selected/expanded states. */
159
+ background: var(
160
+ --solara-table-row-bg,
161
+ var(
162
+ --solara-table-pinned-bg,
163
+ var(--solara-table-header-bg, var(--solara-table-surface-header))
164
+ )
165
+ );
166
+ z-index: 2;
167
+ box-shadow: var(--solara-table-pinned-shadow, 1px 0 0 var(--solara-table-border-color));
168
+ }
169
+
170
+ .solara-table__header-cell--pinned {
171
+ z-index: 3;
172
+ }
173
+
174
+ .solara-table__empty td {
175
+ padding: 2rem 1rem;
176
+ text-align: center;
177
+ color: var(--solara-table-text-muted);
178
+ }
179
+
180
+ .solara-table__sort {
181
+ width: 100%;
182
+ display: inline-flex;
183
+ align-items: center;
184
+ justify-content: space-between;
185
+ gap: 0.5rem;
186
+ background: none;
187
+ border: none;
188
+ padding: 0;
189
+ font: inherit;
190
+ color: inherit;
191
+ cursor: pointer;
192
+ }
193
+
194
+ .solara-table__sort-indicator {
195
+ font-size: 0.75rem;
196
+ color: var(--solara-table-text-tertiary);
197
+ display: inline-flex;
198
+ align-items: center;
199
+ }
200
+
201
+ .solara-table--sticky-header .solara-table__head th {
202
+ position: sticky;
203
+ top: 0;
204
+ z-index: 1;
205
+ background: var(
206
+ --solara-table-sticky-header-bg,
207
+ var(--solara-table-header-bg, var(--solara-table-surface-header))
208
+ );
209
+ box-shadow: var(--solara-table-sticky-header-shadow, 0 1px 0 var(--solara-table-border-color));
210
+ }
211
+
212
+ .solara-table--transparent-sticky .solara-table__head th,
213
+ .solara-table--transparent-sticky .solara-table__cell--pinned,
214
+ .solara-table--transparent-sticky .solara-table__header-cell--pinned {
215
+ background: transparent !important;
216
+ box-shadow: none;
217
+ }
218
+
219
+ .solara-table--transparent-background .solara-table__table,
220
+ .solara-table--transparent-background .solara-table__head,
221
+ .solara-table--transparent-background .solara-table__body,
222
+ .solara-table--transparent-background tr,
223
+ .solara-table--transparent-background th,
224
+ .solara-table--transparent-background td {
225
+ background: transparent !important;
226
+ background-color: transparent !important;
227
+ }
228
+
229
+ .solara-table__header-actions-cell {
230
+ width: 1%;
231
+ white-space: nowrap;
232
+ text-align: right;
233
+ vertical-align: middle;
234
+ padding: 0.75rem 1rem;
235
+ border-bottom: 1px solid var(--solara-table-border-color);
236
+ }
237
+
238
+ .solara-table__header-action-button {
239
+ appearance: none;
240
+ border: none;
241
+ background: transparent;
242
+ padding: 0;
243
+ display: inline-flex;
244
+ align-items: center;
245
+ cursor: pointer;
246
+ color: inherit;
247
+ }
248
+
249
+ .solara-table__header-actions-stack {
250
+ display: inline-flex;
251
+ align-items: center;
252
+ gap: 0.5rem;
253
+ }
254
+
255
+ .solara-table__actions-cell {
256
+ width: 1%;
257
+ border-bottom: 1px solid var(--solara-table-border-color);
258
+ }
259
+
260
+ .solara-table__actions-col {
261
+ width: 1%;
262
+ }
263
+
264
+ .solara-table__grid-toolbar {
265
+ display: flex;
266
+ justify-content: flex-end;
267
+ align-items: center;
268
+ margin-bottom: 0.75rem;
269
+ }
270
+
271
+ .solara-table__grid {
272
+ display: grid;
273
+ row-gap: var(--solara-table-grid-row-gap);
274
+ column-gap: var(--solara-table-grid-column-gap);
275
+ }
276
+
277
+ .solara-table__grid--masonry {
278
+ display: block;
279
+ column-gap: var(--solara-table-grid-column-gap);
280
+ }
281
+
282
+ .solara-table__grid--masonry > * {
283
+ /* Keep each card intact so media/details don't split across columns. */
284
+ -webkit-column-break-inside: avoid;
285
+ page-break-inside: avoid;
286
+ break-inside: avoid;
287
+ margin-bottom: var(--solara-table-grid-row-gap);
288
+ }
289
+
290
+ .solara-table__grid--masonry > *:last-child {
291
+ margin-bottom: 0;
292
+ }
293
+
294
+ .solara-table__grid--masonry .solara-table__grid-cell--media {
295
+ min-height: 0;
296
+ }
297
+
298
+ .solara-table__grid--masonry .solara-table__grid-cell--media > .solara-table__grid-cell-value {
299
+ height: auto;
300
+ }
301
+
302
+ .solara-table__grid--masonry .solara-table__grid-cell--media > .solara-table__grid-cell-value > img,
303
+ .solara-table__grid--masonry .solara-table__grid-cell--media > .solara-table__grid-cell-value > video {
304
+ height: auto;
305
+ object-fit: contain;
306
+ }
307
+
308
+ .solara-table__grid-row {
309
+ border: 1px solid var(--solara-table-border-color);
310
+ border-radius: 12px;
311
+ overflow: hidden;
312
+ display: grid;
313
+ gap: 0;
314
+ background: var(--solara-table-row-bg, var(--solara-table-surface-base));
315
+ }
316
+
317
+ .solara-table__grid-cell {
318
+ display: grid;
319
+ gap: 0.125rem;
320
+ }
321
+
322
+ .solara-table__grid-row-details {
323
+ display: grid;
324
+ gap: var(--solara-table-grid-details-gap);
325
+ padding: var(--solara-table-grid-details-padding);
326
+ }
327
+
328
+ .solara-table__grid-cell--media {
329
+ min-height: var(--solara-table-grid-media-min-height);
330
+ }
331
+
332
+ .solara-table__grid-cell--unpadded {
333
+ padding: 0;
334
+ }
335
+
336
+ .solara-table__grid-cell--media > .solara-table__grid-cell-value {
337
+ height: 100%;
338
+ /* Prevent inline-media baseline whitespace artifacts in media-first cards. */
339
+ line-height: 0;
340
+ }
341
+
342
+ .solara-table__grid-cell--media > .solara-table__grid-cell-value > img,
343
+ .solara-table__grid-cell--media > .solara-table__grid-cell-value > video {
344
+ display: block;
345
+ width: 100%;
346
+ height: 100%;
347
+ object-fit: cover;
348
+ }
349
+
350
+ .solara-table__grid-cell-label {
351
+ font-size: 0.75rem;
352
+ color: var(--solara-table-text-tertiary);
353
+ text-transform: uppercase;
354
+ letter-spacing: 0.02em;
355
+ }
356
+
357
+ .solara-table__grid-cell-value {
358
+ font-size: 0.875rem;
359
+ color: var(--solara-table-text-primary);
360
+ }
361
+
362
+ .solara-table__grid-empty {
363
+ padding: 2rem 1rem;
364
+ text-align: center;
365
+ color: var(--solara-table-text-muted);
366
+ }
367
+
368
+ .solara-table__split-header,
369
+ .solara-table__split-body {
370
+ display: flex;
371
+ align-items: stretch;
372
+ width: 100%;
373
+ }
374
+
375
+ .solara-table__pane {
376
+ /* Let panes size to their content; center pane flexes to fill. */
377
+ width: max-content;
378
+ }
379
+
380
+ .solara-table__pane--left,
381
+ .solara-table__pane--right {
382
+ flex: 0 0 auto;
383
+ }
384
+
385
+ .solara-table__pane--center {
386
+ width: 100%;
387
+ }
388
+
389
+ .solara-table__header-scroll {
390
+ /* Header scroll is synced with the center body scroll. */
391
+ overflow: hidden;
392
+ flex: 1 1 auto;
393
+ min-width: 0;
394
+ }
395
+
396
+ .solara-table__body-center {
397
+ /* The only horizontally scrollable pane. */
398
+ overflow: auto;
399
+ flex: 1 1 auto;
400
+ min-width: 0;
401
+ }
402
+
403
+ .solara-table__body-side {
404
+ /* Pinned panes: vertical scroll only, no horizontal scroll. */
405
+ overflow-y: auto;
406
+ overflow-x: hidden;
407
+ flex: 0 0 auto;
408
+ scrollbar-width: none;
409
+ }
410
+
411
+ .solara-table__body-side::-webkit-scrollbar {
412
+ display: none;
413
+ }
414
+
415
+ .solara-table__menu-row {
416
+ display: grid;
417
+ grid-template-columns: minmax(0, 1fr) auto;
418
+ align-items: center;
419
+ gap: 0.5rem;
420
+ padding: 0;
421
+ }
422
+
423
+ .solara-table__menu-row--simple {
424
+ grid-template-columns: minmax(0, 1fr);
425
+ }
426
+
427
+ .solara-table__menu-toggle {
428
+ appearance: none;
429
+ border: 0;
430
+ background: transparent;
431
+ padding: 0;
432
+ display: inline-flex;
433
+ align-items: center;
434
+ justify-content: space-between;
435
+ gap: 0.5rem;
436
+ width: 100%;
437
+ color: inherit;
438
+ font: inherit;
439
+ cursor: pointer;
440
+ padding: 0.35rem 0.5rem;
441
+ border-radius: 8px;
442
+ }
443
+
444
+ .solara-table__menu-toggle:disabled {
445
+ opacity: 0.5;
446
+ cursor: not-allowed;
447
+ }
448
+
449
+ .solara-table__menu-toggle-label {
450
+ overflow: hidden;
451
+ text-overflow: ellipsis;
452
+ white-space: nowrap;
453
+ }
454
+
455
+ .solara-table__menu-row-actions {
456
+ display: inline-flex;
457
+ align-items: center;
458
+ gap: 0.25rem;
459
+ }
460
+
461
+ .solara-table__menu-icon-button {
462
+ appearance: none;
463
+ border: 0;
464
+ background: transparent;
465
+ padding: 0;
466
+ display: inline-flex;
467
+ align-items: center;
468
+ justify-content: center;
469
+ cursor: pointer;
470
+ color: inherit;
471
+ }
472
+
473
+ .solara-table__menu-icon-button:disabled {
474
+ opacity: 0.4;
475
+ cursor: not-allowed;
476
+ }
477
+
478
+ .solara-table__menu-visibility {
479
+ font-size: 0.75rem;
480
+ color: var(--solara-table-text-secondary);
481
+ }
482
+
483
+ .solara-table__menu-visibility--hidden {
484
+ color: var(--solara-table-text-tertiary);
485
+ }
486
+
487
+ .solara-table--density-compact .solara-table__cell,
488
+ .solara-table--density-compact .solara-table__header-cell {
489
+ padding: 0.5rem 0.75rem;
490
+ font-size: 0.8125rem;
491
+ }
492
+
493
+ .solara-table--density-compact {
494
+ /* Compact mode tightens list padding and grid card rhythm together. */
495
+ --solara-table-grid-gap: 0.5rem;
496
+ --solara-table-grid-details-gap: 0.375rem;
497
+ --solara-table-grid-details-padding: 0.625rem;
498
+ --solara-table-grid-media-min-height: 160px;
499
+ }
500
+
501
+ .solara-table--density-compact .solara-table__header-actions-cell,
502
+ .solara-table--density-compact .solara-table__actions-cell {
503
+ padding: 0.5rem 0.75rem;
504
+ }
505
+
506
+ .solara-table--density-compact .solara-table__grid-cell-value {
507
+ font-size: 0.8125rem;
508
+ }
509
+
510
+ .solara-table--density-spacious .solara-table__cell,
511
+ .solara-table--density-spacious .solara-table__header-cell {
512
+ padding: 1rem 1.25rem;
513
+ font-size: 0.9375rem;
514
+ }
515
+
516
+ .solara-table--density-spacious {
517
+ /* Spacious mode increases both table breathing room and grid card spacing. */
518
+ --solara-table-grid-gap: 1rem;
519
+ --solara-table-grid-details-gap: 0.625rem;
520
+ --solara-table-grid-details-padding: 1rem;
521
+ --solara-table-grid-media-min-height: 220px;
522
+ }
523
+
524
+ .solara-table--density-spacious .solara-table__header-actions-cell,
525
+ .solara-table--density-spacious .solara-table__actions-cell {
526
+ padding: 1rem 1.25rem;
527
+ }
528
+
529
+ .solara-table--density-spacious .solara-table__grid-cell-value {
530
+ font-size: 0.9375rem;
531
+ }