@extable/core 0.3.2 → 0.3.4

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/src/styles.css ADDED
@@ -0,0 +1,885 @@
1
+ /* Component root */
2
+ .extable-root {
3
+ --extable-border: 1px solid #dadce0;
4
+ --extable-accent: #3b82f6;
5
+ --extable-invalid: #ef4444;
6
+ --extable-header-bg: #e5e7eb;
7
+ --extable-formula-readonly-fg: #99aaff;
8
+
9
+ border: 1px solid #d0d7de;
10
+ box-sizing: border-box;
11
+
12
+ /* Layout primitives */
13
+ & .extable-shell {
14
+ display: flex;
15
+ width: 100%;
16
+ height: 100%;
17
+ min-width: 0;
18
+ min-height: 0;
19
+ position: relative;
20
+ font-family: "Inter", "Segoe UI", system-ui, -apple-system, "Helvetica Neue", sans-serif;
21
+ overflow: visible;
22
+ }
23
+
24
+ & .extable-viewport {
25
+ flex: 1;
26
+ flex-basis: 0;
27
+ min-width: 0;
28
+ min-height: 0;
29
+ overflow: auto;
30
+ position: relative;
31
+ overscroll-behavior: contain;
32
+ background: transparent;
33
+ border: none;
34
+ box-sizing: border-box;
35
+ }
36
+
37
+ & .extable-overlay-layer {
38
+ position: sticky;
39
+ top: 0;
40
+ left: 0;
41
+ width: 0;
42
+ height: 0;
43
+ pointer-events: none;
44
+ z-index: 20;
45
+ }
46
+
47
+ /* Loading overlay (defaultData === null) */
48
+ &.extable-loading .extable-shell::after {
49
+ content: "";
50
+ position: absolute;
51
+ inset: 0;
52
+ background: rgba(255, 255, 255, 0.65);
53
+ backdrop-filter: blur(1px);
54
+ z-index: 20;
55
+ }
56
+
57
+ &.extable-loading .extable-shell::before {
58
+ content: "";
59
+ position: absolute;
60
+ left: 50%;
61
+ top: 50%;
62
+ width: 28px;
63
+ height: 28px;
64
+ margin-left: -14px;
65
+ margin-top: -14px;
66
+ border-radius: 9999px;
67
+ border: 3px solid rgba(148, 163, 184, 0.5);
68
+ border-top-color: rgba(59, 130, 246, 0.9);
69
+ animation: extable-spin 0.9s linear infinite;
70
+ z-index: 21;
71
+ }
72
+
73
+ /* Spreadsheet table styles (HTML renderer + overlay table) */
74
+ & table[data-extable-renderer="html"],
75
+ & table[data-extable-renderer="canvas-html-overlay"] {
76
+ border-collapse: collapse;
77
+ width: 100%;
78
+ background: transparent;
79
+ table-layout: fixed;
80
+ font-size: 14px;
81
+ line-height: 16px;
82
+
83
+ & thead th {
84
+ position: sticky;
85
+ top: 0;
86
+ z-index: 5;
87
+ }
88
+
89
+ /* Ensure the top-left corner stays visible on both axes scroll. */
90
+ & thead th.extable-corner {
91
+ left: 0;
92
+ z-index: 7;
93
+ }
94
+
95
+ & th {
96
+ position: relative;
97
+ background: var(--extable-header-bg);
98
+ border: 1px solid #d0d7de;
99
+ padding: 4px 8px;
100
+ font-weight: 700;
101
+ text-align: left;
102
+ }
103
+
104
+ /* Column resize handle only for column headers (not row headers / corner). */
105
+ & thead th:not(.extable-row-header)::after {
106
+ content: "";
107
+ position: absolute;
108
+ top: 0;
109
+ right: -3px;
110
+ width: 6px;
111
+ height: 100%;
112
+ cursor: col-resize;
113
+ }
114
+
115
+ & td {
116
+ border: 1px solid #d0d7de;
117
+ padding: 4px 8px;
118
+ min-width: 80px;
119
+ cursor: cell;
120
+ font-weight: 400;
121
+
122
+ &:focus-within {
123
+ outline: 2px solid #2b7fff;
124
+ outline-offset: -1px;
125
+ }
126
+
127
+ &.pending {
128
+ color: #b91c1c;
129
+ }
130
+ }
131
+
132
+ & input {
133
+ border: none;
134
+ padding: 2px 4px;
135
+ width: 100%;
136
+ box-sizing: border-box;
137
+ background: #fff;
138
+ font: inherit;
139
+
140
+ &:focus {
141
+ outline: none;
142
+ }
143
+ }
144
+
145
+ /* Ensure row headers stay fixed on horizontal scroll and match Canvas alignment. */
146
+ & th.extable-row-header {
147
+ position: sticky;
148
+ left: 0;
149
+ text-align: center;
150
+ z-index: 6;
151
+ }
152
+ }
153
+
154
+ & table[data-extable-renderer="canvas-html-overlay"] {
155
+ opacity: 0;
156
+ }
157
+
158
+ /* Special cells */
159
+ & .extable-cell {
160
+ border: var(--extable-border);
161
+ padding: 4px 8px;
162
+ position: relative;
163
+
164
+ &.invalid {
165
+ outline: 1px solid var(--extable-invalid);
166
+ }
167
+ }
168
+
169
+ & .extable-diag-warning::before,
170
+ & .extable-diag-error::before {
171
+ content: "";
172
+ position: absolute;
173
+ top: 0;
174
+ right: 0;
175
+ width: 10px;
176
+ height: 10px;
177
+ background: linear-gradient(225deg, #f59e0b 50%, transparent 50%);
178
+ }
179
+
180
+ & .extable-diag-error::before {
181
+ background: linear-gradient(225deg, #ef4444 50%, transparent 50%);
182
+ }
183
+
184
+ & .extable-row-header {
185
+ position: sticky;
186
+ left: 0;
187
+ background: var(--extable-header-bg);
188
+ text-align: center;
189
+ vertical-align: middle;
190
+ line-height: 16px;
191
+ padding: 0;
192
+ border: var(--extable-border);
193
+ font-weight: 600;
194
+ color: #334155;
195
+ z-index: 4;
196
+ cursor: default;
197
+ }
198
+
199
+ & .extable-corner {
200
+ position: sticky;
201
+ top: 0;
202
+ left: 0;
203
+ z-index: 6;
204
+ background: var(--extable-header-bg);
205
+ padding: 0;
206
+
207
+ &::after {
208
+ content: "";
209
+ position: absolute;
210
+ top: 4px;
211
+ left: 4px;
212
+ width: 12px;
213
+ height: 12px;
214
+ background: linear-gradient(135deg, #9ca3af 50%, transparent 50%);
215
+ }
216
+ }
217
+
218
+ /* Selection + active cell */
219
+ & .extable-active-row-header,
220
+ & .extable-active-col-header {
221
+ background: rgba(59, 130, 246, 0.16);
222
+ }
223
+
224
+ & .extable-selected {
225
+ background: rgba(59, 130, 246, 0.12) !important;
226
+ }
227
+
228
+ /* Selected but non-active cells keep spreadsheet-like cursor (cell). */
229
+ & td.extable-selected {
230
+ cursor: cell;
231
+ }
232
+
233
+ /* Active editable cell shows text cursor, even when selected. */
234
+ & td.extable-active-cell.extable-editable {
235
+ cursor: text;
236
+ }
237
+
238
+ /* Active readonly/boolean cells should not look editable. */
239
+ & td.extable-active-cell.extable-readonly,
240
+ & td.extable-active-cell.extable-boolean {
241
+ cursor: default;
242
+ }
243
+
244
+ & .extable-all-selected td,
245
+ & .extable-all-selected th {
246
+ background: rgba(59, 130, 246, 0.08) !important;
247
+ }
248
+
249
+ & .extable-active-cell {
250
+ outline: 2px solid var(--extable-accent);
251
+ outline-offset: -2px;
252
+ position: relative;
253
+
254
+ &::after {
255
+ content: "";
256
+ position: absolute;
257
+ width: 12px;
258
+ height: 12px;
259
+ right: 1px;
260
+ bottom: 1px;
261
+ background: var(--extable-accent);
262
+ border: 1px solid #ffffff;
263
+ cursor: crosshair;
264
+ opacity: 0;
265
+ }
266
+ }
267
+
268
+ &[data-extable-fill-handle="1"] {
269
+ & .extable-active-cell::after {
270
+ opacity: 1;
271
+ }
272
+ }
273
+
274
+ /* Data-driven readonly (row/column/formula) cells are visually muted. */
275
+ & .extable-readonly-muted {
276
+ background: #f3f4f6 !important;
277
+ color: #94a3b8 !important;
278
+ }
279
+
280
+ /* Formula-driven readonly cells are shown with a subtle blue text color. */
281
+ & .extable-readonly-formula {
282
+ color: var(--extable-formula-readonly-fg);
283
+ }
284
+
285
+ & td.extable-disabled {
286
+ cursor: default;
287
+ }
288
+
289
+ & .extable-action-button,
290
+ & .extable-action-link {
291
+ display: inline-flex;
292
+ align-items: center;
293
+ gap: 4px;
294
+ max-width: 100%;
295
+ font: inherit;
296
+ color: inherit;
297
+ background: transparent;
298
+ border: none;
299
+ padding: 0;
300
+ cursor: pointer;
301
+ text-decoration: none;
302
+ }
303
+
304
+ & .extable-action-button {
305
+ padding: 4px 10px;
306
+ border-radius: 8px;
307
+ border: 1px solid #94a3b8;
308
+ background: linear-gradient(180deg, #f8fafc 0%, #e2e8f0 100%);
309
+ color: #0f172a;
310
+ box-shadow:
311
+ 0 1px 0 rgba(15, 23, 42, 0.08),
312
+ inset 0 1px 0 rgba(255, 255, 255, 0.9);
313
+ transition:
314
+ background 140ms ease,
315
+ border-color 140ms ease,
316
+ box-shadow 140ms ease,
317
+ transform 80ms ease;
318
+
319
+ &:hover,
320
+ &:focus-visible {
321
+ background: linear-gradient(180deg, #ffffff 0%, #e2e8f0 100%);
322
+ border-color: #64748b;
323
+ box-shadow:
324
+ 0 2px 0 rgba(15, 23, 42, 0.12),
325
+ inset 0 1px 0 rgba(255, 255, 255, 0.95);
326
+ outline: none;
327
+ }
328
+
329
+ &:active {
330
+ transform: translateY(1px);
331
+ box-shadow:
332
+ 0 0 0 rgba(15, 23, 42, 0.12),
333
+ inset 0 1px 0 rgba(255, 255, 255, 0.85);
334
+ }
335
+ }
336
+
337
+ & .extable-action-link {
338
+ color: #2563eb;
339
+ text-decoration: underline;
340
+ text-underline-offset: 2px;
341
+ }
342
+
343
+ & .extable-action-disabled {
344
+ color: #94a3b8;
345
+ border-color: #e2e8f0;
346
+ background: linear-gradient(180deg, #f8fafc 0%, #e5e7eb 100%);
347
+ cursor: default;
348
+ text-decoration: none;
349
+ box-shadow: none;
350
+ }
351
+
352
+ & .extable-tag-list {
353
+ display: flex;
354
+ flex-wrap: wrap;
355
+ align-items: center;
356
+ gap: 4px;
357
+ }
358
+
359
+ & .extable-tag {
360
+ display: inline-flex;
361
+ align-items: center;
362
+ gap: 6px;
363
+ padding: 2px 8px;
364
+ border-radius: 999px;
365
+ border: 1px solid #cbd5e1;
366
+ background: #e2e8f0;
367
+ color: #0f172a;
368
+ font-size: 12px;
369
+ line-height: 1.2;
370
+ white-space: nowrap;
371
+ }
372
+
373
+ & .extable-tag-remove {
374
+ display: inline-flex;
375
+ align-items: center;
376
+ justify-content: center;
377
+ width: 16px;
378
+ height: 16px;
379
+ border-radius: 999px;
380
+ border: none;
381
+ background: transparent;
382
+ color: #475569;
383
+ cursor: pointer;
384
+ padding: 0;
385
+
386
+ &:hover,
387
+ &:focus-visible {
388
+ outline: none;
389
+ background: rgba(148, 163, 184, 0.4);
390
+ color: #0f172a;
391
+ }
392
+
393
+ &:disabled {
394
+ opacity: 0.6;
395
+ cursor: default;
396
+ }
397
+ }
398
+
399
+ /* Selection highlight must remain visible even on readonly cells. */
400
+ & td.extable-selected.extable-readonly-muted {
401
+ background: rgba(59, 130, 246, 0.12) !important;
402
+ }
403
+
404
+ & .extable-all-selected td.extable-readonly-muted,
405
+ & .extable-all-selected th.extable-readonly-muted {
406
+ background: rgba(59, 130, 246, 0.08) !important;
407
+ }
408
+
409
+ /* In global readonly mode, keep normal look (viewer style). */
410
+ &.extable-readonly-all .extable-readonly-muted {
411
+ background: inherit !important;
412
+ color: inherit !important;
413
+ }
414
+
415
+ &.extable-readonly-all .extable-readonly-formula {
416
+ color: inherit !important;
417
+ }
418
+
419
+ /* In readonly mode, body cells should keep a spreadsheet-like cursor (cell). */
420
+ &.extable-readonly-all table[data-extable-renderer="html"] tbody td,
421
+ &.extable-readonly-all table[data-extable-renderer="canvas-html-overlay"] tbody td {
422
+ cursor: cell;
423
+ }
424
+
425
+ &.extable-readonly-all td.extable-active-cell {
426
+ cursor: cell !important;
427
+ }
428
+
429
+ &.extable-readonly-all .extable-active-cell::after {
430
+ cursor: cell;
431
+ }
432
+
433
+ /* Column header inner layout */
434
+ & .extable-col-header {
435
+ position: relative;
436
+ display: block;
437
+ min-width: 0;
438
+ cursor: default;
439
+ }
440
+
441
+ & .extable-col-header-text {
442
+ min-width: 0;
443
+ overflow: hidden;
444
+ text-overflow: ellipsis;
445
+ white-space: nowrap;
446
+ }
447
+
448
+ & .extable-filter-sort-trigger {
449
+ position: absolute;
450
+ right: 4px;
451
+ top: 50%;
452
+ transform: translateY(-50%);
453
+ width: 22px;
454
+ height: 22px;
455
+ padding: 0;
456
+ border: 1px solid rgba(148, 163, 184, 0.55);
457
+ border-radius: 6px;
458
+ background: rgba(255, 255, 255, 0.7);
459
+ cursor: pointer;
460
+ opacity: 0;
461
+ display: none;
462
+ align-items: center;
463
+ justify-content: center;
464
+ z-index: 1;
465
+ line-height: 1;
466
+ color: rgba(15, 23, 42, 0.75);
467
+
468
+ &:hover,
469
+ &:focus-visible {
470
+ opacity: 1;
471
+ outline: none;
472
+ background: rgba(255, 255, 255, 0.92);
473
+ border-color: rgba(59, 130, 246, 0.7);
474
+ color: rgba(15, 23, 42, 0.92);
475
+ }
476
+ }
477
+
478
+ & th:hover .extable-filter-sort-trigger {
479
+ display: inline-flex;
480
+ opacity: 0.55;
481
+ }
482
+
483
+ & th[data-extable-fs-active="1"] .extable-filter-sort-trigger,
484
+ & th[data-extable-sort-dir] .extable-filter-sort-trigger {
485
+ display: inline-flex;
486
+ opacity: 0.75;
487
+ }
488
+
489
+ & th:hover[data-extable-fs-active="1"] .extable-filter-sort-trigger,
490
+ & th:hover[data-extable-sort-dir] .extable-filter-sort-trigger {
491
+ display: inline-flex;
492
+ opacity: 1;
493
+ }
494
+
495
+ /* When the button is visible, reserve space so it doesn't cover the text. */
496
+ & th:hover .extable-col-header,
497
+ & th[data-extable-fs-active="1"] .extable-col-header,
498
+ & th[data-extable-sort-dir] .extable-col-header {
499
+ padding-right: 28px;
500
+ }
501
+
502
+ /* Text helpers */
503
+ & .cell-nowrap {
504
+ white-space: nowrap;
505
+ text-overflow: ellipsis;
506
+ overflow: hidden;
507
+ }
508
+
509
+ & .cell-wrap {
510
+ white-space: pre-wrap;
511
+ text-overflow: clip;
512
+ overflow-wrap: anywhere;
513
+ }
514
+
515
+ & .align-left {
516
+ text-align: left;
517
+ }
518
+
519
+ & .align-right {
520
+ text-align: right;
521
+ }
522
+
523
+ /* HTML-only: show tooltip on cell hover (anchored to the cell, no JS). */
524
+ & td[data-extable-diag-message]:hover::after {
525
+ content: attr(data-extable-diag-message);
526
+ position: absolute;
527
+ top: 6px;
528
+ left: calc(100% + 10px);
529
+ max-width: 360px;
530
+ padding: 8px 10px;
531
+ border-radius: 10px;
532
+ background: #111827;
533
+ color: #f8fafc;
534
+ font-size: 12px;
535
+ line-height: 1.25;
536
+ box-shadow: 0 12px 28px rgba(0, 0, 0, 0.28);
537
+ border: 1px solid rgba(148, 163, 184, 0.35);
538
+ white-space: pre-wrap;
539
+ z-index: 20;
540
+ }
541
+
542
+ & td[data-extable-diag-message]:hover::before {
543
+ content: "";
544
+ position: absolute;
545
+ top: 14px;
546
+ left: calc(100% + 2px);
547
+ width: 0;
548
+ height: 0;
549
+ border: 7px solid transparent;
550
+ border-right-color: #111827;
551
+ z-index: 21;
552
+ }
553
+
554
+ /* Context menu */
555
+ & .extable-context-menu {
556
+ border: none;
557
+ padding: 6px 0;
558
+ border-radius: 8px;
559
+ background: rgba(255, 255, 255, 0.98);
560
+ box-shadow: 0 18px 38px rgba(0, 0, 0, 0.25), 0 8px 12px rgba(0, 0, 0, 0.18);
561
+ backdrop-filter: blur(6px);
562
+ min-width: 200px;
563
+ position: fixed;
564
+ margin: 0;
565
+ inset: auto;
566
+ z-index: 1000;
567
+ pointer-events: auto;
568
+
569
+ &::backdrop {
570
+ background: transparent;
571
+ }
572
+
573
+ & hr.extable-context-sep {
574
+ border: 0;
575
+ border-top: 1px solid #e5e7eb;
576
+ margin: 6px 0;
577
+ }
578
+
579
+ & button {
580
+ display: flex;
581
+ gap: 8px;
582
+ align-items: center;
583
+ width: 100%;
584
+ padding: 8px 14px;
585
+ background: transparent;
586
+ border: none;
587
+ font: inherit;
588
+ text-align: left;
589
+ cursor: pointer;
590
+
591
+ &:hover,
592
+ &:focus-visible {
593
+ background: rgba(59, 130, 246, 0.12);
594
+ outline: none;
595
+ }
596
+ }
597
+ }
598
+
599
+ /* Sidebars */
600
+ & .extable-filter-sort-sidebar {
601
+ flex: 0 0 0px;
602
+ width: 0px;
603
+ min-width: 0;
604
+ border: 1px solid rgba(148, 163, 184, 0.45);
605
+ background: rgba(255, 255, 255, 0.98);
606
+ backdrop-filter: none;
607
+ -webkit-backdrop-filter: none;
608
+ box-shadow: none;
609
+ flex-direction: column;
610
+ gap: 10px;
611
+ padding: 0px;
612
+ transform: translateX(12px);
613
+ opacity: 0;
614
+ pointer-events: none;
615
+ overflow: hidden;
616
+ visibility: hidden;
617
+ transition:
618
+ flex-basis 180ms ease-out,
619
+ width 180ms ease-out,
620
+ padding 180ms ease-out,
621
+ border-width 180ms ease-out,
622
+ opacity 180ms ease-out,
623
+ transform 180ms ease-out,
624
+ visibility 0s linear 180ms;
625
+ border-width: 0;
626
+ }
627
+
628
+ &.extable-filter-sort-open .extable-filter-sort-sidebar {
629
+ flex-basis: 440px;
630
+ width: 440px;
631
+ padding: 12px;
632
+ opacity: 1;
633
+ transform: translateX(0);
634
+ pointer-events: auto;
635
+ visibility: visible;
636
+ border-width: 1px;
637
+ transition:
638
+ flex-basis 180ms ease-out,
639
+ width 180ms ease-out,
640
+ padding 180ms ease-out,
641
+ border-width 180ms ease-out,
642
+ opacity 180ms ease-out,
643
+ transform 180ms ease-out,
644
+ visibility 0s linear 0s;
645
+ }
646
+
647
+ & .extable-filter-sort-sidebar input[type="checkbox"] {
648
+ width: 16px;
649
+ height: 16px;
650
+ accent-color: #0f172a;
651
+ vertical-align: middle;
652
+ }
653
+ }
654
+
655
+ @keyframes extable-spin {
656
+ to {
657
+ transform: rotate(360deg);
658
+ }
659
+ }
660
+
661
+ .extable-root {
662
+ /* Filter/Sort sidebar contents */
663
+ & .extable-filter-sort-header {
664
+ display: flex;
665
+ flex-direction: column;
666
+ gap: 8px;
667
+ }
668
+
669
+ & .extable-filter-sort-row {
670
+ display: flex;
671
+ align-items: center;
672
+ gap: 10px;
673
+ justify-content: space-between;
674
+ flex-wrap: wrap;
675
+ }
676
+
677
+ & .extable-filter-sort-title {
678
+ font-weight: 700;
679
+ color: #0f172a;
680
+ }
681
+
682
+ & .extable-filter-sort-close {
683
+ width: 28px;
684
+ height: 28px;
685
+ border-radius: 8px;
686
+ border: 1px solid rgba(148, 163, 184, 0.5);
687
+ background: rgba(255, 255, 255, 0.8);
688
+ cursor: pointer;
689
+
690
+ &:hover,
691
+ &:focus-visible {
692
+ outline: none;
693
+ border-color: rgba(59, 130, 246, 0.7);
694
+ background: rgba(226, 232, 240, 0.9);
695
+ }
696
+ }
697
+
698
+ & .extable-filter-sort-body {
699
+ display: flex;
700
+ flex-direction: column;
701
+ gap: 12px;
702
+ min-height: 0;
703
+ flex: 1;
704
+ overflow: hidden;
705
+ border: 1px solid rgba(148, 163, 184, 0.35);
706
+ border-radius: 0;
707
+ padding: 10px;
708
+ background: rgba(248, 250, 252, 0.7);
709
+ }
710
+
711
+ & .extable-filter-sort-section {
712
+ display: flex;
713
+ flex-direction: column;
714
+ gap: 8px;
715
+ border: 1px solid rgba(148, 163, 184, 0.25);
716
+ border-radius: 10px;
717
+ padding: 10px;
718
+ background: #ffffff;
719
+ }
720
+
721
+ & .extable-filter-sort-section-filter {
722
+ flex: 1;
723
+ min-height: 0;
724
+ }
725
+
726
+ & .extable-filter-sort-section-sort {
727
+ flex: 0 0 auto;
728
+ }
729
+
730
+ & .extable-filter-sort-section-title {
731
+ font-weight: 700;
732
+ color: #0f172a;
733
+ }
734
+
735
+ & .extable-filter-sort-values {
736
+ min-height: 0;
737
+ flex: 1;
738
+ overflow: auto;
739
+ border: 1px solid rgba(148, 163, 184, 0.35);
740
+ border-radius: 10px;
741
+ padding: 8px;
742
+ background: rgba(255, 255, 255, 0.9);
743
+
744
+ & label {
745
+ display: grid;
746
+ grid-template-columns: 26px 1fr;
747
+ gap: 8px;
748
+ align-items: center;
749
+ padding: 6px 6px;
750
+ border-radius: 8px;
751
+ }
752
+
753
+ & label:hover {
754
+ background: rgba(59, 130, 246, 0.08);
755
+ }
756
+ }
757
+
758
+ & .extable-filter-sort-actions {
759
+ display: flex;
760
+ gap: 8px;
761
+ flex-wrap: nowrap;
762
+
763
+ & label {
764
+ display: inline-flex;
765
+ align-items: center;
766
+ gap: 6px;
767
+ white-space: nowrap;
768
+ }
769
+
770
+ &[data-align="split"] {
771
+ justify-content: space-between;
772
+
773
+ & button[data-extable-fs="select-none"] {
774
+ margin-right: auto;
775
+ }
776
+ }
777
+
778
+ &[data-align="right"] {
779
+ justify-content: flex-end;
780
+ }
781
+
782
+ & button {
783
+ padding: 6px 12px;
784
+ border-radius: 10px;
785
+ border: 1px solid rgba(100, 116, 139, 0.6);
786
+ background: linear-gradient(180deg, #ffffff 0%, #e2e8f0 100%);
787
+ box-shadow:
788
+ 0 1px 0 rgba(15, 23, 42, 0.08),
789
+ inset 0 1px 0 rgba(255, 255, 255, 0.9);
790
+ cursor: pointer;
791
+ transition:
792
+ background 140ms ease,
793
+ border-color 140ms ease,
794
+ box-shadow 140ms ease,
795
+ transform 80ms ease;
796
+
797
+ &:hover,
798
+ &:focus-visible {
799
+ outline: none;
800
+ border-color: rgba(59, 130, 246, 0.7);
801
+ background: linear-gradient(180deg, #ffffff 0%, #dbeafe 100%);
802
+ box-shadow:
803
+ 0 2px 0 rgba(15, 23, 42, 0.12),
804
+ inset 0 1px 0 rgba(255, 255, 255, 0.95);
805
+ }
806
+
807
+ &:active {
808
+ transform: translateY(1px);
809
+ box-shadow:
810
+ 0 0 0 rgba(15, 23, 42, 0.12),
811
+ inset 0 1px 0 rgba(255, 255, 255, 0.85);
812
+ }
813
+ }
814
+
815
+ & button[data-extable-fs="apply-filter"],
816
+ & button[data-active="1"] {
817
+ background: linear-gradient(180deg, #0f172a 0%, #1e293b 100%);
818
+ color: #f8fafc;
819
+ border-color: #0f172a;
820
+ box-shadow:
821
+ 0 2px 0 rgba(15, 23, 42, 0.3),
822
+ inset 0 1px 0 rgba(255, 255, 255, 0.08);
823
+ }
824
+ }
825
+ }
826
+
827
+ .extable-tooltip {
828
+ position: absolute;
829
+ pointer-events: none;
830
+ z-index: 9999;
831
+ display: none;
832
+ max-width: 360px;
833
+ padding: 8px 10px;
834
+ border-radius: 10px;
835
+ background: #111827;
836
+ color: #f8fafc;
837
+ font-size: 12px;
838
+ line-height: 1.25;
839
+ box-shadow: 0 12px 28px rgba(0, 0, 0, 0.28);
840
+ border: 1px solid rgba(148, 163, 184, 0.35);
841
+ white-space: pre-wrap;
842
+ }
843
+
844
+ .extable-tooltip[data-visible="1"] {
845
+ display: block;
846
+ }
847
+
848
+ .extable-tooltip::after {
849
+ content: "";
850
+ position: absolute;
851
+ top: 10px;
852
+ width: 0;
853
+ height: 0;
854
+ border: 7px solid transparent;
855
+ }
856
+
857
+ .extable-tooltip[data-side="right"]::after {
858
+ left: -14px;
859
+ border-right-color: #111827;
860
+ }
861
+
862
+ .extable-tooltip[data-side="left"]::after {
863
+ right: -14px;
864
+ border-left-color: #111827;
865
+ }
866
+
867
+ /* Tooltip is defined at top-level to apply even when appended to <body>. */
868
+
869
+ .extable-root {
870
+ /* Toasts */
871
+ & .extable-toast {
872
+ border-radius: 8px;
873
+ padding: 10px 14px;
874
+ background: rgba(25, 25, 28, 0.92);
875
+ color: #f8fafc;
876
+ box-shadow: 0 12px 30px rgba(0, 0, 0, 0.28), 0 6px 12px rgba(0, 0, 0, 0.18);
877
+ font-size: 13px;
878
+ max-width: 320px;
879
+ line-height: 1.4;
880
+
881
+ &[data-variant="error"] {
882
+ background: rgba(220, 38, 38, 0.92);
883
+ }
884
+ }
885
+ }