@shotleybuilder/svelte-gridlite-kit 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.
Files changed (43) hide show
  1. package/README.md +260 -0
  2. package/dist/GridLite.svelte +1361 -0
  3. package/dist/GridLite.svelte.d.ts +42 -0
  4. package/dist/components/CellContextMenu.svelte +209 -0
  5. package/dist/components/CellContextMenu.svelte.d.ts +28 -0
  6. package/dist/components/ColumnMenu.svelte +234 -0
  7. package/dist/components/ColumnMenu.svelte.d.ts +29 -0
  8. package/dist/components/ColumnPicker.svelte +403 -0
  9. package/dist/components/ColumnPicker.svelte.d.ts +29 -0
  10. package/dist/components/FilterBar.svelte +390 -0
  11. package/dist/components/FilterBar.svelte.d.ts +38 -0
  12. package/dist/components/FilterCondition.svelte +643 -0
  13. package/dist/components/FilterCondition.svelte.d.ts +35 -0
  14. package/dist/components/GroupBar.svelte +463 -0
  15. package/dist/components/GroupBar.svelte.d.ts +33 -0
  16. package/dist/components/RowDetailModal.svelte +213 -0
  17. package/dist/components/RowDetailModal.svelte.d.ts +25 -0
  18. package/dist/components/SortBar.svelte +232 -0
  19. package/dist/components/SortBar.svelte.d.ts +30 -0
  20. package/dist/components/SortCondition.svelte +129 -0
  21. package/dist/components/SortCondition.svelte.d.ts +30 -0
  22. package/dist/index.d.ts +23 -0
  23. package/dist/index.js +29 -0
  24. package/dist/query/builder.d.ts +160 -0
  25. package/dist/query/builder.js +432 -0
  26. package/dist/query/live.d.ts +50 -0
  27. package/dist/query/live.js +118 -0
  28. package/dist/query/schema.d.ts +30 -0
  29. package/dist/query/schema.js +75 -0
  30. package/dist/state/migrations.d.ts +29 -0
  31. package/dist/state/migrations.js +113 -0
  32. package/dist/state/views.d.ts +54 -0
  33. package/dist/state/views.js +130 -0
  34. package/dist/styles/gridlite.css +966 -0
  35. package/dist/types.d.ts +164 -0
  36. package/dist/types.js +2 -0
  37. package/dist/utils/filters.d.ts +14 -0
  38. package/dist/utils/filters.js +49 -0
  39. package/dist/utils/formatters.d.ts +16 -0
  40. package/dist/utils/formatters.js +39 -0
  41. package/dist/utils/fuzzy.d.ts +47 -0
  42. package/dist/utils/fuzzy.js +142 -0
  43. package/package.json +76 -0
@@ -0,0 +1,966 @@
1
+ /* GridLite — Base Styles */
2
+
3
+ /* ─── Container ──────────────────────────────────────────────────────────── */
4
+
5
+ .gridlite-container {
6
+ width: 100%;
7
+ font-family:
8
+ -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
9
+ font-size: 14px;
10
+ color: #1a1a1a;
11
+ }
12
+
13
+ .gridlite-table-wrap {
14
+ width: 100%;
15
+ overflow-x: auto;
16
+ }
17
+
18
+ /* ─── Table ──────────────────────────────────────────────────────────────── */
19
+
20
+ .gridlite-table {
21
+ width: 100%;
22
+ border-collapse: collapse;
23
+ border-spacing: 0;
24
+ }
25
+
26
+ /* ─── Header ─────────────────────────────────────────────────────────────── */
27
+
28
+ .gridlite-thead {
29
+ position: sticky;
30
+ top: 0;
31
+ z-index: 1;
32
+ }
33
+
34
+ .gridlite-th {
35
+ background: #f8f9fa;
36
+ border-bottom: 2px solid #dee2e6;
37
+ font-weight: 600;
38
+ text-align: left;
39
+ white-space: nowrap;
40
+ user-select: none;
41
+ }
42
+
43
+ /* ─── Body ───────────────────────────────────────────────────────────────── */
44
+
45
+ .gridlite-td {
46
+ border-bottom: 1px solid #e9ecef;
47
+ white-space: nowrap;
48
+ overflow: hidden;
49
+ text-overflow: ellipsis;
50
+ }
51
+
52
+ .gridlite-tr:hover {
53
+ background: #f1f3f5;
54
+ }
55
+
56
+ .gridlite-tr:focus-within {
57
+ outline: 2px solid #4c6ef5;
58
+ outline-offset: -2px;
59
+ }
60
+
61
+ /* ─── Row Height Variants ────────────────────────────────────────────────── */
62
+
63
+ .gridlite-row-short .gridlite-th,
64
+ .gridlite-row-short .gridlite-td {
65
+ padding-top: 4px;
66
+ padding-bottom: 4px;
67
+ }
68
+
69
+ .gridlite-row-medium .gridlite-th,
70
+ .gridlite-row-medium .gridlite-td {
71
+ padding-top: 8px;
72
+ padding-bottom: 8px;
73
+ }
74
+
75
+ .gridlite-row-tall .gridlite-th,
76
+ .gridlite-row-tall .gridlite-td {
77
+ padding-top: 12px;
78
+ padding-bottom: 12px;
79
+ }
80
+
81
+ .gridlite-row-extra_tall .gridlite-th,
82
+ .gridlite-row-extra_tall .gridlite-td {
83
+ padding-top: 16px;
84
+ padding-bottom: 16px;
85
+ }
86
+
87
+ /* ─── Column Spacing Variants ────────────────────────────────────────────── */
88
+
89
+ .gridlite-spacing-narrow .gridlite-th,
90
+ .gridlite-spacing-narrow .gridlite-td {
91
+ padding-left: 6px;
92
+ padding-right: 6px;
93
+ }
94
+
95
+ .gridlite-spacing-normal .gridlite-th,
96
+ .gridlite-spacing-normal .gridlite-td {
97
+ padding-left: 12px;
98
+ padding-right: 12px;
99
+ }
100
+
101
+ .gridlite-spacing-wide .gridlite-th,
102
+ .gridlite-spacing-wide .gridlite-td {
103
+ padding-left: 20px;
104
+ padding-right: 20px;
105
+ }
106
+
107
+ /* ─── Toolbar ────────────────────────────────────────────────────────────── */
108
+
109
+ .gridlite-toolbar {
110
+ display: flex;
111
+ align-items: center;
112
+ gap: 8px;
113
+ padding: 8px 0;
114
+ flex-wrap: wrap;
115
+ }
116
+
117
+ /* Button label — hidden in some layouts */
118
+ .gridlite-btn-label {
119
+ /* visible by default */
120
+ }
121
+
122
+ /* ─── Layout: Airtable ───────────────────────────────────────────────────── */
123
+ /* Right-aligned: Columns → Filter → Group → Sort → Row Height → Spacing → Search */
124
+
125
+ .gridlite-layout-airtable .gridlite-toolbar {
126
+ justify-content: flex-end;
127
+ }
128
+
129
+ .gridlite-layout-airtable .gridlite-toolbar-columns {
130
+ order: 1;
131
+ }
132
+ .gridlite-layout-airtable .gridlite-toolbar-filter {
133
+ order: 2;
134
+ }
135
+ .gridlite-layout-airtable .gridlite-toolbar-group {
136
+ order: 3;
137
+ }
138
+ .gridlite-layout-airtable .gridlite-toolbar-sort {
139
+ order: 4;
140
+ }
141
+ .gridlite-layout-airtable .gridlite-toolbar-view {
142
+ order: 5;
143
+ }
144
+ .gridlite-layout-airtable .gridlite-toolbar-search {
145
+ order: 6;
146
+ }
147
+
148
+ /* ─── Layout: Excel ──────────────────────────────────────────────────────── */
149
+ /* Two rows: top = data controls + search, bottom = view controls */
150
+
151
+ .gridlite-layout-excel .gridlite-toolbar {
152
+ flex-wrap: wrap;
153
+ justify-content: flex-start;
154
+ }
155
+
156
+ .gridlite-layout-excel .gridlite-toolbar-filter {
157
+ order: 1;
158
+ }
159
+ .gridlite-layout-excel .gridlite-toolbar-sort {
160
+ order: 2;
161
+ }
162
+ .gridlite-layout-excel .gridlite-toolbar-group {
163
+ order: 3;
164
+ }
165
+ .gridlite-layout-excel .gridlite-toolbar-search {
166
+ order: 4;
167
+ margin-left: auto;
168
+ }
169
+ .gridlite-layout-excel .gridlite-toolbar-columns {
170
+ order: 6;
171
+ }
172
+ .gridlite-layout-excel .gridlite-toolbar-view {
173
+ order: 7;
174
+ }
175
+
176
+ /* Force second row via a full-width break */
177
+ .gridlite-layout-excel .gridlite-toolbar::after {
178
+ content: "";
179
+ width: 100%;
180
+ order: 5;
181
+ }
182
+
183
+ /* ─── Layout: Shadcn ─────────────────────────────────────────────────────── */
184
+ /* Search left, data controls middle, view controls right */
185
+
186
+ .gridlite-layout-shadcn .gridlite-toolbar {
187
+ justify-content: flex-start;
188
+ }
189
+
190
+ .gridlite-layout-shadcn .gridlite-toolbar-search {
191
+ order: 1;
192
+ margin-right: auto;
193
+ }
194
+ .gridlite-layout-shadcn .gridlite-toolbar-filter {
195
+ order: 2;
196
+ }
197
+ .gridlite-layout-shadcn .gridlite-toolbar-sort {
198
+ order: 3;
199
+ }
200
+ .gridlite-layout-shadcn .gridlite-toolbar-group {
201
+ order: 4;
202
+ }
203
+ .gridlite-layout-shadcn .gridlite-toolbar-columns {
204
+ order: 5;
205
+ }
206
+ .gridlite-layout-shadcn .gridlite-toolbar-view {
207
+ order: 6;
208
+ }
209
+
210
+ /* ─── Layout: AG Grid ────────────────────────────────────────────────────── */
211
+ /* TODO(#1): aggrid layout is experimental — not production-ready. Needs debugging. */
212
+ /* Minimal top bar + sidebar on right */
213
+
214
+ .gridlite-layout-aggrid .gridlite-toolbar-aggrid-top {
215
+ justify-content: flex-start;
216
+ }
217
+
218
+ .gridlite-aggrid-body {
219
+ display: flex;
220
+ gap: 0;
221
+ min-height: 400px;
222
+ }
223
+
224
+ .gridlite-aggrid-body > .gridlite-table-wrap {
225
+ flex: 1;
226
+ min-width: 0;
227
+ overflow-x: auto;
228
+ }
229
+
230
+ .gridlite-aggrid-body > .gridlite-aggrid-sidebar {
231
+ flex-shrink: 0;
232
+ width: 260px;
233
+ border-left: 1px solid #dee2e6;
234
+ background: #f8f9fa;
235
+ overflow-y: auto;
236
+ max-height: 600px;
237
+ }
238
+
239
+ .gridlite-aggrid-sidebar-section {
240
+ border-bottom: 1px solid #dee2e6;
241
+ }
242
+
243
+ .gridlite-aggrid-sidebar-header {
244
+ padding: 8px 12px;
245
+ font-size: 0.6875rem;
246
+ font-weight: 600;
247
+ color: #868e96;
248
+ text-transform: uppercase;
249
+ letter-spacing: 0.05em;
250
+ background: #f1f3f5;
251
+ border-bottom: 1px solid #dee2e6;
252
+ }
253
+
254
+ /* Override ColumnPicker positioning when inside aggrid sidebar */
255
+ .gridlite-aggrid-sidebar .gridlite-column-picker {
256
+ position: static;
257
+ min-width: unset;
258
+ border: none;
259
+ border-radius: 0;
260
+ box-shadow: none;
261
+ background: transparent;
262
+ }
263
+
264
+ /* Override FilterBar styling when inside aggrid sidebar */
265
+ .gridlite-aggrid-sidebar .gridlite-filter-bar {
266
+ border: none;
267
+ border-radius: 0;
268
+ margin-bottom: 0;
269
+ background: transparent;
270
+ }
271
+
272
+ /* Pagination also inside the aggrid body */
273
+ .gridlite-layout-aggrid .gridlite-aggrid-body ~ .gridlite-pagination {
274
+ /* pagination stays below the body flex container */
275
+ }
276
+
277
+ /* ─── Global Search ──────────────────────────────────────────────────────── */
278
+
279
+ .gridlite-search {
280
+ display: flex;
281
+ align-items: center;
282
+ position: relative;
283
+ margin-left: auto;
284
+ }
285
+
286
+ .gridlite-search-icon {
287
+ position: absolute;
288
+ left: 8px;
289
+ width: 16px;
290
+ height: 16px;
291
+ color: #9ca3af;
292
+ pointer-events: none;
293
+ }
294
+
295
+ .gridlite-search-input {
296
+ padding: 0.5rem 28px 0.5rem 28px;
297
+ font-size: 0.875rem;
298
+ border: 1px solid #d1d5db;
299
+ border-radius: 0.375rem;
300
+ background: white;
301
+ min-width: 200px;
302
+ transition:
303
+ border-color 0.15s,
304
+ box-shadow 0.15s;
305
+ }
306
+
307
+ .gridlite-search-input:focus {
308
+ outline: none;
309
+ border-color: #4c6ef5;
310
+ box-shadow: 0 0 0 3px rgba(76, 110, 245, 0.1);
311
+ }
312
+
313
+ .gridlite-search-input::placeholder {
314
+ color: #9ca3af;
315
+ }
316
+
317
+ .gridlite-search-clear {
318
+ position: absolute;
319
+ right: 6px;
320
+ display: inline-flex;
321
+ align-items: center;
322
+ justify-content: center;
323
+ padding: 2px;
324
+ background: none;
325
+ border: none;
326
+ border-radius: 3px;
327
+ cursor: pointer;
328
+ color: #9ca3af;
329
+ transition: color 0.15s;
330
+ }
331
+
332
+ .gridlite-search-clear:hover {
333
+ color: #374151;
334
+ }
335
+
336
+ /* ─── Pagination ─────────────────────────────────────────────────────────── */
337
+
338
+ .gridlite-pagination {
339
+ display: flex;
340
+ align-items: center;
341
+ justify-content: space-between;
342
+ padding: 8px 0;
343
+ font-size: 13px;
344
+ color: #495057;
345
+ }
346
+
347
+ .gridlite-pagination-controls {
348
+ display: flex;
349
+ align-items: center;
350
+ gap: 4px;
351
+ }
352
+
353
+ .gridlite-pagination button {
354
+ padding: 4px 12px;
355
+ border: 1px solid #dee2e6;
356
+ border-radius: 4px;
357
+ background: #fff;
358
+ cursor: pointer;
359
+ font-size: 13px;
360
+ }
361
+
362
+ .gridlite-pagination button:hover:not(:disabled) {
363
+ background: #f1f3f5;
364
+ }
365
+
366
+ .gridlite-pagination button:disabled {
367
+ opacity: 0.5;
368
+ cursor: not-allowed;
369
+ }
370
+
371
+ .gridlite-page-size-select {
372
+ padding: 4px 8px;
373
+ border: 1px solid #dee2e6;
374
+ border-radius: 4px;
375
+ font-size: 13px;
376
+ background: #fff;
377
+ margin-right: 8px;
378
+ }
379
+
380
+ /* ─── View Controls ──────────────────────────────────────────────────────── */
381
+
382
+ .gridlite-view-controls {
383
+ display: flex;
384
+ align-items: center;
385
+ gap: 4px;
386
+ }
387
+
388
+ .gridlite-view-control {
389
+ position: relative;
390
+ }
391
+
392
+ .gridlite-view-control-btn {
393
+ display: inline-flex;
394
+ align-items: center;
395
+ gap: 0.5rem;
396
+ padding: 0.5rem 1rem;
397
+ font-size: 0.875rem;
398
+ font-weight: 500;
399
+ border: 1px solid #d1d5db;
400
+ border-radius: 0.375rem;
401
+ background: #fff;
402
+ cursor: pointer;
403
+ color: #374151;
404
+ white-space: nowrap;
405
+ transition:
406
+ border-color 0.15s,
407
+ background 0.15s;
408
+ }
409
+
410
+ .gridlite-view-control-btn:hover {
411
+ background: #f8f9fa;
412
+ border-color: #adb5bd;
413
+ }
414
+
415
+ .gridlite-view-control-btn.active {
416
+ border-color: #4c6ef5;
417
+ color: #4c6ef5;
418
+ background: #edf2ff;
419
+ }
420
+
421
+ .gridlite-view-dropdown {
422
+ position: absolute;
423
+ top: calc(100% + 4px);
424
+ right: 0;
425
+ min-width: 160px;
426
+ background: #fff;
427
+ border: 1px solid #dee2e6;
428
+ border-radius: 0.375rem;
429
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
430
+ z-index: 50;
431
+ padding: 4px 0;
432
+ }
433
+
434
+ .gridlite-view-dropdown-title {
435
+ padding: 6px 12px;
436
+ font-size: 0.75rem;
437
+ font-weight: 600;
438
+ color: #868e96;
439
+ text-transform: uppercase;
440
+ letter-spacing: 0.05em;
441
+ }
442
+
443
+ .gridlite-view-dropdown-item {
444
+ display: block;
445
+ width: 100%;
446
+ padding: 6px 12px;
447
+ font-size: 0.8125rem;
448
+ text-align: left;
449
+ border: none;
450
+ background: none;
451
+ cursor: pointer;
452
+ color: #1a1a1a;
453
+ transition: background 0.1s;
454
+ }
455
+
456
+ .gridlite-view-dropdown-item:hover {
457
+ background: #f1f3f5;
458
+ }
459
+
460
+ .gridlite-view-dropdown-item.selected {
461
+ color: #4c6ef5;
462
+ font-weight: 600;
463
+ background: #edf2ff;
464
+ }
465
+
466
+ /* Column Picker */
467
+
468
+ .gridlite-column-picker {
469
+ position: absolute;
470
+ top: calc(100% + 4px);
471
+ right: 0;
472
+ min-width: 260px;
473
+ background: #fff;
474
+ border: 1px solid #dee2e6;
475
+ border-radius: 0.375rem;
476
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
477
+ z-index: 50;
478
+ padding: 0;
479
+ }
480
+
481
+ /* Search */
482
+
483
+ .gridlite-column-picker-search {
484
+ display: flex;
485
+ align-items: center;
486
+ position: relative;
487
+ padding: 8px 10px;
488
+ border-bottom: 1px solid #e9ecef;
489
+ }
490
+
491
+ .gridlite-column-picker-search-icon {
492
+ position: absolute;
493
+ left: 18px;
494
+ width: 14px;
495
+ height: 14px;
496
+ color: #9ca3af;
497
+ pointer-events: none;
498
+ }
499
+
500
+ .gridlite-column-picker-search-input {
501
+ width: 100%;
502
+ padding: 5px 24px 5px 26px;
503
+ font-size: 0.8125rem;
504
+ border: 1px solid #d1d5db;
505
+ border-radius: 4px;
506
+ background: #fff;
507
+ transition: border-color 0.15s;
508
+ }
509
+
510
+ .gridlite-column-picker-search-input:focus {
511
+ outline: none;
512
+ border-color: #4c6ef5;
513
+ box-shadow: 0 0 0 2px rgba(76, 110, 245, 0.1);
514
+ }
515
+
516
+ .gridlite-column-picker-search-input::placeholder {
517
+ color: #9ca3af;
518
+ }
519
+
520
+ .gridlite-column-picker-search-clear {
521
+ position: absolute;
522
+ right: 16px;
523
+ display: inline-flex;
524
+ align-items: center;
525
+ justify-content: center;
526
+ padding: 2px;
527
+ background: none;
528
+ border: none;
529
+ cursor: pointer;
530
+ color: #9ca3af;
531
+ border-radius: 3px;
532
+ transition: color 0.15s;
533
+ }
534
+
535
+ .gridlite-column-picker-search-clear:hover {
536
+ color: #374151;
537
+ }
538
+
539
+ /* Actions */
540
+
541
+ .gridlite-column-picker-actions {
542
+ display: flex;
543
+ gap: 8px;
544
+ padding: 6px 10px;
545
+ border-bottom: 1px solid #e9ecef;
546
+ }
547
+
548
+ .gridlite-column-picker-actions button {
549
+ padding: 3px 8px;
550
+ font-size: 0.75rem;
551
+ border: 1px solid #d1d5db;
552
+ border-radius: 4px;
553
+ background: #fff;
554
+ cursor: pointer;
555
+ color: #495057;
556
+ transition: background 0.1s;
557
+ }
558
+
559
+ .gridlite-column-picker-actions button:hover {
560
+ background: #f1f3f5;
561
+ }
562
+
563
+ /* List */
564
+
565
+ .gridlite-column-picker-list {
566
+ max-height: 360px;
567
+ overflow-y: auto;
568
+ padding: 4px 0;
569
+ }
570
+
571
+ /* Sections */
572
+
573
+ .gridlite-column-picker-section {
574
+ padding: 0;
575
+ }
576
+
577
+ .gridlite-column-picker-section + .gridlite-column-picker-section {
578
+ border-top: 1px solid #e9ecef;
579
+ }
580
+
581
+ .gridlite-column-picker-section-header {
582
+ display: flex;
583
+ align-items: center;
584
+ gap: 6px;
585
+ padding: 6px 10px;
586
+ font-size: 0.6875rem;
587
+ font-weight: 600;
588
+ color: #868e96;
589
+ text-transform: uppercase;
590
+ letter-spacing: 0.05em;
591
+ }
592
+
593
+ .gridlite-column-picker-section-count {
594
+ display: inline-flex;
595
+ align-items: center;
596
+ justify-content: center;
597
+ min-width: 16px;
598
+ height: 16px;
599
+ padding: 0 4px;
600
+ font-size: 0.625rem;
601
+ font-weight: 500;
602
+ color: #6c757d;
603
+ background: #e9ecef;
604
+ border-radius: 8px;
605
+ }
606
+
607
+ /* Items */
608
+
609
+ .gridlite-column-picker-item {
610
+ display: flex;
611
+ align-items: center;
612
+ gap: 6px;
613
+ padding: 5px 10px;
614
+ font-size: 0.8125rem;
615
+ cursor: pointer;
616
+ color: #1a1a1a;
617
+ transition: background 0.1s;
618
+ }
619
+
620
+ .gridlite-column-picker-item:hover {
621
+ background: #f1f3f5;
622
+ }
623
+
624
+ .gridlite-column-picker-item-hidden {
625
+ color: #868e96;
626
+ }
627
+
628
+ .gridlite-column-picker-item input[type="checkbox"] {
629
+ margin: 0;
630
+ accent-color: #4c6ef5;
631
+ flex-shrink: 0;
632
+ }
633
+
634
+ .gridlite-column-picker-item-label {
635
+ flex: 1;
636
+ min-width: 0;
637
+ overflow: hidden;
638
+ text-overflow: ellipsis;
639
+ white-space: nowrap;
640
+ }
641
+
642
+ /* Drag handle */
643
+
644
+ .gridlite-column-picker-drag-handle {
645
+ display: inline-flex;
646
+ align-items: center;
647
+ justify-content: center;
648
+ width: 14px;
649
+ flex-shrink: 0;
650
+ color: #ced4da;
651
+ cursor: grab;
652
+ border-radius: 2px;
653
+ padding: 2px 0;
654
+ transition: color 0.15s;
655
+ }
656
+
657
+ .gridlite-column-picker-drag-handle:active {
658
+ cursor: grabbing;
659
+ }
660
+
661
+ .gridlite-column-picker-item:hover .gridlite-column-picker-drag-handle {
662
+ color: #868e96;
663
+ }
664
+
665
+ /* Selection */
666
+
667
+ .gridlite-column-picker-item.selected {
668
+ background: #edf2ff;
669
+ }
670
+
671
+ .gridlite-column-picker-item.selected:hover {
672
+ background: #dbe4ff;
673
+ }
674
+
675
+ .gridlite-column-picker-item.focused {
676
+ outline: 2px solid #4c6ef5;
677
+ outline-offset: -2px;
678
+ }
679
+
680
+ /* Drag feedback */
681
+
682
+ .gridlite-column-picker-item.dragged {
683
+ opacity: 0.35;
684
+ }
685
+
686
+ /* Drop indicator lines */
687
+
688
+ .gridlite-column-picker-item.drop-before {
689
+ box-shadow: inset 0 2px 0 0 #4c6ef5;
690
+ }
691
+
692
+ .gridlite-column-picker-item.drop-after {
693
+ box-shadow: inset 0 -2px 0 0 #4c6ef5;
694
+ }
695
+
696
+ /* Selection count badge */
697
+
698
+ .gridlite-column-picker-selection-count {
699
+ margin-left: auto;
700
+ font-size: 0.6875rem;
701
+ color: #4c6ef5;
702
+ font-weight: 500;
703
+ }
704
+
705
+ /* Drag ghost (multi-column) */
706
+
707
+ .gridlite-column-picker-drag-ghost {
708
+ position: fixed;
709
+ top: -1000px;
710
+ left: -1000px;
711
+ padding: 4px 10px;
712
+ font-size: 0.75rem;
713
+ font-weight: 600;
714
+ color: #fff;
715
+ background: #4c6ef5;
716
+ border-radius: 4px;
717
+ white-space: nowrap;
718
+ pointer-events: none;
719
+ z-index: 9999;
720
+ }
721
+
722
+ /* Empty state within sections */
723
+
724
+ .gridlite-column-picker-empty {
725
+ padding: 8px 10px;
726
+ font-size: 0.75rem;
727
+ color: #868e96;
728
+ font-style: italic;
729
+ }
730
+
731
+ /* ─── Filter Bar ─────────────────────────────────────────────────────────── */
732
+
733
+ .gridlite-filter-bar {
734
+ padding: 8px;
735
+ background: #f8f9fa;
736
+ border: 1px solid #dee2e6;
737
+ border-radius: 6px;
738
+ margin-bottom: 8px;
739
+ }
740
+
741
+ /* ─── Column Header Interactive ──────────────────────────────────────────── */
742
+
743
+ .gridlite-th-interactive {
744
+ position: relative;
745
+ }
746
+
747
+ .gridlite-th-content {
748
+ display: flex;
749
+ align-items: center;
750
+ gap: 4px;
751
+ }
752
+
753
+ .gridlite-th-label {
754
+ flex: 1;
755
+ }
756
+
757
+ .gridlite-th-menu-btn {
758
+ display: inline-flex;
759
+ align-items: center;
760
+ justify-content: center;
761
+ padding: 2px;
762
+ background: none;
763
+ border: none;
764
+ border-radius: 3px;
765
+ cursor: pointer;
766
+ color: #adb5bd;
767
+ opacity: 0;
768
+ transition:
769
+ opacity 0.15s,
770
+ color 0.15s,
771
+ background 0.15s;
772
+ }
773
+
774
+ .gridlite-th-interactive:hover .gridlite-th-menu-btn {
775
+ opacity: 1;
776
+ }
777
+
778
+ .gridlite-th-menu-btn:hover {
779
+ color: #495057;
780
+ background: #e9ecef;
781
+ }
782
+
783
+ /* ─── Column Reorder Drag Feedback ───────────────────────────────────────── */
784
+
785
+ .gridlite-th.dragging {
786
+ opacity: 0.4;
787
+ }
788
+
789
+ .gridlite-th.drag-over {
790
+ border-left: 2px solid #4c6ef5;
791
+ }
792
+
793
+ /* ─── Column Resize Handle ───────────────────────────────────────────────── */
794
+
795
+ .gridlite-resize-handle {
796
+ position: absolute;
797
+ top: 0;
798
+ right: -6px;
799
+ height: 100%;
800
+ width: 12px;
801
+ cursor: col-resize;
802
+ user-select: none;
803
+ touch-action: none;
804
+ background: transparent;
805
+ z-index: 10;
806
+ transition: background 0.15s;
807
+ }
808
+
809
+ .gridlite-resize-handle:hover {
810
+ background: rgba(76, 110, 245, 0.1);
811
+ }
812
+
813
+ .gridlite-resize-handle:hover::after,
814
+ .gridlite-resize-handle.resizing::after {
815
+ content: "";
816
+ position: absolute;
817
+ top: 0;
818
+ left: 50%;
819
+ transform: translateX(-50%);
820
+ height: 100%;
821
+ width: 2px;
822
+ background: #4c6ef5;
823
+ }
824
+
825
+ .gridlite-resize-handle.resizing {
826
+ background: rgba(76, 110, 245, 0.08);
827
+ }
828
+
829
+ /* ─── Row Detail (default layout) ────────────────────────────────────────── */
830
+
831
+ .gridlite-row-detail {
832
+ margin: 0;
833
+ }
834
+
835
+ .gridlite-row-detail-field {
836
+ display: flex;
837
+ padding: 8px 0;
838
+ border-bottom: 1px solid #f1f3f5;
839
+ }
840
+
841
+ .gridlite-row-detail-field:last-child {
842
+ border-bottom: none;
843
+ }
844
+
845
+ .gridlite-row-detail-field dt {
846
+ width: 140px;
847
+ flex-shrink: 0;
848
+ font-weight: 600;
849
+ color: #495057;
850
+ font-size: 0.8125rem;
851
+ }
852
+
853
+ .gridlite-row-detail-field dd {
854
+ margin: 0;
855
+ color: #1a1a1a;
856
+ }
857
+
858
+ /* ─── Grouped View ───────────────────────────────────────────────────────── */
859
+
860
+ .gridlite-group-row {
861
+ cursor: pointer;
862
+ }
863
+
864
+ .gridlite-group-row:hover {
865
+ background: #f1f3f5;
866
+ }
867
+
868
+ .gridlite-group-td {
869
+ background: #f8f9fa;
870
+ border-bottom: 1px solid #dee2e6;
871
+ padding: 0 !important;
872
+ }
873
+
874
+ .gridlite-group-header {
875
+ display: flex;
876
+ align-items: center;
877
+ gap: 8px;
878
+ padding: 8px 12px;
879
+ font-weight: 600;
880
+ font-size: 0.875rem;
881
+ }
882
+
883
+ /* Nesting indentation */
884
+ .gridlite-group-level-0 {
885
+ padding-left: 12px;
886
+ }
887
+
888
+ .gridlite-group-level-1 {
889
+ padding-left: 32px;
890
+ }
891
+
892
+ .gridlite-group-level-2 {
893
+ padding-left: 52px;
894
+ }
895
+
896
+ .gridlite-group-chevron {
897
+ flex-shrink: 0;
898
+ color: #6c757d;
899
+ transition: transform 0.15s ease;
900
+ transform: rotate(0deg);
901
+ }
902
+
903
+ .gridlite-group-chevron.expanded {
904
+ transform: rotate(90deg);
905
+ }
906
+
907
+ .gridlite-group-label {
908
+ color: #1a1a1a;
909
+ }
910
+
911
+ .gridlite-group-count {
912
+ display: inline-flex;
913
+ align-items: center;
914
+ justify-content: center;
915
+ min-width: 20px;
916
+ height: 20px;
917
+ padding: 0 6px;
918
+ font-size: 0.75rem;
919
+ font-weight: 500;
920
+ color: #6c757d;
921
+ background: #e9ecef;
922
+ border-radius: 10px;
923
+ }
924
+
925
+ .gridlite-group-agg {
926
+ display: inline-flex;
927
+ align-items: center;
928
+ padding: 2px 8px;
929
+ font-size: 0.75rem;
930
+ font-weight: 400;
931
+ color: #495057;
932
+ background: #e8f4fd;
933
+ border-radius: 4px;
934
+ }
935
+
936
+ .gridlite-group-loading {
937
+ font-size: 0.75rem;
938
+ font-weight: 400;
939
+ color: #868e96;
940
+ font-style: italic;
941
+ }
942
+
943
+ .gridlite-group-child {
944
+ background: #fff;
945
+ }
946
+
947
+ .gridlite-group-child:hover {
948
+ background: #f8f9fa;
949
+ }
950
+
951
+ /* ─── Empty State ────────────────────────────────────────────────────────── */
952
+
953
+ .gridlite-empty {
954
+ text-align: center;
955
+ padding: 24px;
956
+ color: #868e96;
957
+ font-style: italic;
958
+ }
959
+
960
+ /* ─── Loading State ──────────────────────────────────────────────────────── */
961
+
962
+ .gridlite-loading {
963
+ text-align: center;
964
+ padding: 24px;
965
+ color: #868e96;
966
+ }