react-restyle-components 0.4.40 → 0.4.42

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.
@@ -0,0 +1,1794 @@
1
+ /**
2
+ * AG Grid Styled Components
3
+ * Beautiful, responsive styled components for the AG Grid-like table
4
+ */
5
+ import { styled, css, keyframes } from 'styled-components';
6
+ // ============================================================================
7
+ // Theme Definitions
8
+ // ============================================================================
9
+ const themes = {
10
+ alpine: {
11
+ backgroundColor: '#ffffff',
12
+ headerBackgroundColor: '#f8f8f8',
13
+ oddRowBackgroundColor: '#fcfcfc',
14
+ borderColor: '#dde2eb',
15
+ selectedRowBackgroundColor: '#b7e4ff',
16
+ hoverRowBackgroundColor: '#ecf0f1',
17
+ textColor: '#181d1f',
18
+ headerTextColor: '#181d1f',
19
+ accentColor: '#2196f3',
20
+ cellPadding: '0 12px',
21
+ headerPadding: '0 12px',
22
+ fontFamily: '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif',
23
+ fontSize: '13px',
24
+ headerFontSize: '13px',
25
+ headerFontWeight: '600',
26
+ borderRadius: '0',
27
+ cellBorderWidth: '1px',
28
+ },
29
+ 'alpine-dark': {
30
+ backgroundColor: '#181d1f',
31
+ headerBackgroundColor: '#222628',
32
+ oddRowBackgroundColor: '#1f2426',
33
+ borderColor: '#3d4749',
34
+ selectedRowBackgroundColor: '#005880',
35
+ hoverRowBackgroundColor: '#2d3436',
36
+ textColor: '#f0f0f0',
37
+ headerTextColor: '#f0f0f0',
38
+ accentColor: '#2196f3',
39
+ cellPadding: '0 12px',
40
+ headerPadding: '0 12px',
41
+ fontFamily: '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif',
42
+ fontSize: '13px',
43
+ headerFontSize: '13px',
44
+ headerFontWeight: '600',
45
+ borderRadius: '0',
46
+ cellBorderWidth: '1px',
47
+ },
48
+ balham: {
49
+ backgroundColor: '#ffffff',
50
+ headerBackgroundColor: '#f5f7f7',
51
+ oddRowBackgroundColor: '#fcfdfd',
52
+ borderColor: '#bdc3c7',
53
+ selectedRowBackgroundColor: '#b7e4ff',
54
+ hoverRowBackgroundColor: '#ecf0f1',
55
+ textColor: '#000000',
56
+ headerTextColor: '#000000',
57
+ accentColor: '#0091ea',
58
+ cellPadding: '0 4px',
59
+ headerPadding: '0 4px',
60
+ fontFamily: '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif',
61
+ fontSize: '12px',
62
+ headerFontSize: '12px',
63
+ headerFontWeight: '600',
64
+ borderRadius: '0',
65
+ cellBorderWidth: '1px',
66
+ },
67
+ 'balham-dark': {
68
+ backgroundColor: '#2d3436',
69
+ headerBackgroundColor: '#1e272c',
70
+ oddRowBackgroundColor: '#32393c',
71
+ borderColor: '#424a4d',
72
+ selectedRowBackgroundColor: '#005880',
73
+ hoverRowBackgroundColor: '#3d4749',
74
+ textColor: '#f0f0f0',
75
+ headerTextColor: '#f0f0f0',
76
+ accentColor: '#0091ea',
77
+ cellPadding: '0 4px',
78
+ headerPadding: '0 4px',
79
+ fontFamily: '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif',
80
+ fontSize: '12px',
81
+ headerFontSize: '12px',
82
+ headerFontWeight: '600',
83
+ borderRadius: '0',
84
+ cellBorderWidth: '1px',
85
+ },
86
+ material: {
87
+ backgroundColor: '#ffffff',
88
+ headerBackgroundColor: '#fafafa',
89
+ oddRowBackgroundColor: '#ffffff',
90
+ borderColor: '#e0e0e0',
91
+ selectedRowBackgroundColor: '#e3f2fd',
92
+ hoverRowBackgroundColor: '#f5f5f5',
93
+ textColor: 'rgba(0, 0, 0, 0.87)',
94
+ headerTextColor: 'rgba(0, 0, 0, 0.54)',
95
+ accentColor: '#3f51b5',
96
+ cellPadding: '0 24px 0 24px',
97
+ headerPadding: '0 24px 0 24px',
98
+ fontFamily: 'Roboto, "Helvetica Neue", sans-serif',
99
+ fontSize: '14px',
100
+ headerFontSize: '12px',
101
+ headerFontWeight: '500',
102
+ borderRadius: '0',
103
+ cellBorderWidth: '1px',
104
+ },
105
+ quartz: {
106
+ backgroundColor: '#ffffff',
107
+ headerBackgroundColor: '#ffffff',
108
+ oddRowBackgroundColor: '#fafafa',
109
+ borderColor: '#e2e8f0',
110
+ selectedRowBackgroundColor: '#dbeafe',
111
+ hoverRowBackgroundColor: '#f1f5f9',
112
+ textColor: '#1e293b',
113
+ headerTextColor: '#475569',
114
+ accentColor: '#3b82f6',
115
+ cellPadding: '0 16px',
116
+ headerPadding: '0 16px',
117
+ fontFamily: 'Inter, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif',
118
+ fontSize: '14px',
119
+ headerFontSize: '12px',
120
+ headerFontWeight: '600',
121
+ borderRadius: '8px',
122
+ cellBorderWidth: '1px',
123
+ },
124
+ 'quartz-dark': {
125
+ backgroundColor: '#0f172a',
126
+ headerBackgroundColor: '#1e293b',
127
+ oddRowBackgroundColor: '#1e293b',
128
+ borderColor: '#334155',
129
+ selectedRowBackgroundColor: '#1e3a5f',
130
+ hoverRowBackgroundColor: '#334155',
131
+ textColor: '#e2e8f0',
132
+ headerTextColor: '#94a3b8',
133
+ accentColor: '#3b82f6',
134
+ cellPadding: '0 16px',
135
+ headerPadding: '0 16px',
136
+ fontFamily: 'Inter, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif',
137
+ fontSize: '14px',
138
+ headerFontSize: '12px',
139
+ headerFontWeight: '600',
140
+ borderRadius: '8px',
141
+ cellBorderWidth: '1px',
142
+ },
143
+ };
144
+ export const getTheme = (variant, custom) => ({
145
+ ...themes[variant],
146
+ ...custom,
147
+ });
148
+ // ============================================================================
149
+ // Animations
150
+ // ============================================================================
151
+ const fadeIn = keyframes `
152
+ from { opacity: 0; }
153
+ to { opacity: 1; }
154
+ `;
155
+ const slideInRight = keyframes `
156
+ from { transform: translateX(10px); opacity: 0; }
157
+ to { transform: translateX(0); opacity: 1; }
158
+ `;
159
+ const pulse = keyframes `
160
+ 0%, 100% { opacity: 1; }
161
+ 50% { opacity: 0.5; }
162
+ `;
163
+ const shimmer = keyframes `
164
+ 0% { background-position: -200% 0; }
165
+ 100% { background-position: 200% 0; }
166
+ `;
167
+ const spin = keyframes `
168
+ from { transform: rotate(0deg); }
169
+ to { transform: rotate(360deg); }
170
+ `;
171
+ const rowEnter = keyframes `
172
+ from {
173
+ opacity: 0;
174
+ transform: translateY(-4px);
175
+ }
176
+ to {
177
+ opacity: 1;
178
+ transform: translateY(0);
179
+ }
180
+ `;
181
+ const cellFlash = keyframes `
182
+ 0% { background-color: rgba(76, 175, 80, 0.4); }
183
+ 100% { background-color: transparent; }
184
+ `;
185
+ // ============================================================================
186
+ // Grid Container
187
+ // ============================================================================
188
+ export const GridRoot = styled.div `
189
+ display: flex;
190
+ flex-direction: column;
191
+ width: 100%;
192
+ height: 100%;
193
+ background-color: ${({ $theme }) => $theme.backgroundColor};
194
+ font-family: ${({ $theme }) => $theme.fontFamily};
195
+ font-size: ${({ $theme }) => $theme.fontSize};
196
+ color: ${({ $theme }) => $theme.textColor};
197
+ border: 1px solid ${({ $theme }) => $theme.borderColor};
198
+ border-radius: ${({ $theme }) => $theme.borderRadius};
199
+ overflow: hidden;
200
+ position: relative;
201
+
202
+ *, *::before, *::after {
203
+ box-sizing: border-box;
204
+ }
205
+
206
+ /* Responsive styles */
207
+ ${({ $responsive }) => $responsive &&
208
+ css `
209
+ @media (max-width: 768px) {
210
+ border-radius: 0;
211
+ border-left: none;
212
+ border-right: none;
213
+ }
214
+ `}
215
+ `;
216
+ export const GridWrapper = styled.div `
217
+ display: flex;
218
+ flex-direction: column;
219
+ flex: 1;
220
+ min-height: 0;
221
+ overflow: hidden;
222
+ `;
223
+ // ============================================================================
224
+ // Toolbar / Header Area
225
+ // ============================================================================
226
+ export const GridToolbar = styled.div `
227
+ display: flex;
228
+ align-items: center;
229
+ justify-content: space-between;
230
+ gap: 12px;
231
+ padding: 8px 12px;
232
+ background: ${({ $theme }) => $theme.headerBackgroundColor};
233
+ border-bottom: 1px solid ${({ $theme }) => $theme.borderColor};
234
+ flex-wrap: wrap;
235
+
236
+ @media (max-width: 640px) {
237
+ flex-direction: column;
238
+ align-items: stretch;
239
+ gap: 8px;
240
+ }
241
+ `;
242
+ export const ToolbarGroup = styled.div `
243
+ display: flex;
244
+ align-items: center;
245
+ gap: 8px;
246
+ flex-wrap: wrap;
247
+ `;
248
+ export const ToolbarButton = styled.button `
249
+ display: inline-flex;
250
+ align-items: center;
251
+ justify-content: center;
252
+ gap: 6px;
253
+ padding: 6px 12px;
254
+ font-size: 13px;
255
+ font-weight: 500;
256
+ border-radius: 4px;
257
+ border: 1px solid ${({ $theme }) => $theme.borderColor};
258
+ background: ${({ $theme, $active }) => ($active ? $theme.accentColor : $theme.backgroundColor)};
259
+ color: ${({ $theme, $active }) => ($active ? '#ffffff' : $theme.textColor)};
260
+ cursor: pointer;
261
+ transition: all 0.15s ease;
262
+ white-space: nowrap;
263
+
264
+ ${({ $variant, $theme }) => $variant === 'primary' &&
265
+ css `
266
+ background: ${$theme.accentColor};
267
+ border-color: ${$theme.accentColor};
268
+ color: #ffffff;
269
+
270
+ &:hover {
271
+ filter: brightness(1.1);
272
+ }
273
+ `}
274
+
275
+ ${({ $variant }) => $variant === 'danger' &&
276
+ css `
277
+ background: #ef4444;
278
+ border-color: #ef4444;
279
+ color: #ffffff;
280
+
281
+ &:hover {
282
+ background: #dc2626;
283
+ border-color: #dc2626;
284
+ }
285
+ `}
286
+
287
+ &:hover:not(:disabled) {
288
+ background: ${({ $theme, $active }) => ($active ? $theme.accentColor : $theme.hoverRowBackgroundColor)};
289
+ }
290
+
291
+ &:disabled {
292
+ opacity: 0.5;
293
+ cursor: not-allowed;
294
+ }
295
+
296
+ svg {
297
+ width: 16px;
298
+ height: 16px;
299
+ }
300
+ `;
301
+ export const QuickFilter = styled.div `
302
+ position: relative;
303
+ display: flex;
304
+ align-items: center;
305
+
306
+ input {
307
+ width: 220px;
308
+ padding: 6px 12px 6px 32px;
309
+ font-size: 13px;
310
+ border: 1px solid ${({ $theme }) => $theme.borderColor};
311
+ border-radius: 4px;
312
+ background: ${({ $theme }) => $theme.backgroundColor};
313
+ color: ${({ $theme }) => $theme.textColor};
314
+ outline: none;
315
+ transition: border-color 0.15s ease, box-shadow 0.15s ease;
316
+
317
+ &::placeholder {
318
+ color: ${({ $theme }) => $theme.headerTextColor};
319
+ opacity: 0.6;
320
+ }
321
+
322
+ &:focus {
323
+ border-color: ${({ $theme }) => $theme.accentColor};
324
+ box-shadow: 0 0 0 3px ${({ $theme }) => $theme.accentColor}20;
325
+ }
326
+
327
+ @media (max-width: 640px) {
328
+ width: 100%;
329
+ }
330
+ }
331
+
332
+ svg {
333
+ position: absolute;
334
+ left: 10px;
335
+ width: 14px;
336
+ height: 14px;
337
+ color: ${({ $theme }) => $theme.headerTextColor};
338
+ opacity: 0.6;
339
+ }
340
+ `;
341
+ // ============================================================================
342
+ // Table Container
343
+ // ============================================================================
344
+ export const TableContainer = styled.div `
345
+ flex: 1;
346
+ overflow: auto;
347
+ position: relative;
348
+ min-height: 0;
349
+
350
+ ${({ $maxHeight }) => $maxHeight &&
351
+ css `
352
+ max-height: ${typeof $maxHeight === 'number' ? `${$maxHeight}px` : $maxHeight};
353
+ `}
354
+ `;
355
+ export const StyledTable = styled.table `
356
+ width: 100%;
357
+ border-collapse: collapse;
358
+ table-layout: ${({ $fixedLayout }) => ($fixedLayout ? 'fixed' : 'auto')};
359
+ color: ${({ $theme }) => $theme.textColor};
360
+ `;
361
+ // ============================================================================
362
+ // Header
363
+ // ============================================================================
364
+ export const TableHead = styled.thead `
365
+ ${({ $sticky, $theme }) => $sticky &&
366
+ css `
367
+ position: sticky;
368
+ top: 0;
369
+ z-index: 10;
370
+ background: ${$theme.headerBackgroundColor};
371
+ `}
372
+ `;
373
+ export const HeaderRow = styled.tr `
374
+ background: ${({ $theme }) => $theme.headerBackgroundColor};
375
+ height: ${({ $height }) => ($height ? `${$height}px` : '42px')};
376
+ `;
377
+ export const HeaderCell = styled.th `
378
+ padding: ${({ $theme }) => $theme.headerPadding};
379
+ text-align: ${({ $align }) => $align || 'left'};
380
+ font-size: ${({ $theme }) => $theme.headerFontSize};
381
+ font-weight: ${({ $theme }) => $theme.headerFontWeight};
382
+ color: ${({ $theme }) => $theme.headerTextColor};
383
+ border-bottom: 2px solid ${({ $theme }) => $theme.borderColor};
384
+ border-right: 1px solid ${({ $theme }) => $theme.borderColor};
385
+ white-space: nowrap;
386
+ overflow: hidden;
387
+ text-overflow: ellipsis;
388
+ position: relative;
389
+ user-select: none;
390
+ vertical-align: middle;
391
+ text-transform: uppercase;
392
+ letter-spacing: 0.5px;
393
+
394
+ ${({ $width }) => $width && css `width: ${$width}px;`}
395
+ ${({ $minWidth }) => $minWidth && css `min-width: ${$minWidth}px;`}
396
+ ${({ $maxWidth }) => $maxWidth && css `max-width: ${$maxWidth}px;`}
397
+
398
+ ${({ $sortable, $theme }) => $sortable &&
399
+ css `
400
+ cursor: pointer;
401
+
402
+ &:hover {
403
+ background: ${$theme.hoverRowBackgroundColor};
404
+ }
405
+ `}
406
+
407
+ ${({ $sorted, $theme }) => $sorted &&
408
+ css `
409
+ background: ${$theme.selectedRowBackgroundColor}40;
410
+ `}
411
+
412
+ ${({ $pinned, $theme }) => $pinned &&
413
+ css `
414
+ position: sticky;
415
+ ${$pinned === 'left' ? 'left: 0;' : 'right: 0;'}
416
+ z-index: 11;
417
+ background: ${$theme.headerBackgroundColor};
418
+ box-shadow: ${$pinned === 'left' ? '2px 0 4px rgba(0,0,0,0.1)' : '-2px 0 4px rgba(0,0,0,0.1)'};
419
+ `}
420
+
421
+ &:last-child {
422
+ border-right: none;
423
+ }
424
+ `;
425
+ export const HeaderCellContent = styled.div `
426
+ display: flex;
427
+ align-items: center;
428
+ gap: 6px;
429
+ min-height: 24px;
430
+ `;
431
+ export const HeaderText = styled.span `
432
+ flex: 1;
433
+ overflow: hidden;
434
+ text-overflow: ellipsis;
435
+ `;
436
+ export const SortIndicator = styled.span `
437
+ display: flex;
438
+ align-items: center;
439
+ justify-content: center;
440
+ width: 18px;
441
+ height: 18px;
442
+ opacity: ${({ $active }) => ($active ? 1 : 0.3)};
443
+ transition: opacity 0.15s ease, transform 0.2s ease;
444
+
445
+ svg {
446
+ width: 14px;
447
+ height: 14px;
448
+ transition: transform 0.2s ease;
449
+ transform: ${({ $direction }) => ($direction === 'desc' ? 'rotate(180deg)' : 'rotate(0deg)')};
450
+ }
451
+ `;
452
+ export const FilterIndicator = styled.span `
453
+ display: flex;
454
+ align-items: center;
455
+ justify-content: center;
456
+ width: 18px;
457
+ height: 18px;
458
+ border-radius: 3px;
459
+ color: ${({ $active, $theme }) => ($active ? $theme.accentColor : $theme.headerTextColor)};
460
+ opacity: ${({ $active }) => ($active ? 1 : 0.4)};
461
+ transition: all 0.15s ease;
462
+
463
+ &:hover {
464
+ opacity: 1;
465
+ background: ${({ $theme }) => $theme.hoverRowBackgroundColor};
466
+ }
467
+
468
+ svg {
469
+ width: 12px;
470
+ height: 12px;
471
+ }
472
+ `;
473
+ export const ResizeHandle = styled.div `
474
+ position: absolute;
475
+ right: 0;
476
+ top: 0;
477
+ bottom: 0;
478
+ width: 6px;
479
+ cursor: col-resize;
480
+ z-index: 1;
481
+ transition: background-color 0.15s ease;
482
+
483
+ ${({ $resizing, $theme }) => $resizing &&
484
+ css `
485
+ background: ${$theme.accentColor};
486
+ `}
487
+
488
+ &:hover {
489
+ background: ${({ $theme }) => $theme.accentColor}60;
490
+ }
491
+
492
+ &::after {
493
+ content: '';
494
+ position: absolute;
495
+ right: 2px;
496
+ top: 25%;
497
+ height: 50%;
498
+ width: 2px;
499
+ background: ${({ $theme }) => $theme.borderColor};
500
+ border-radius: 1px;
501
+ }
502
+ `;
503
+ // ============================================================================
504
+ // Column Group Header
505
+ // ============================================================================
506
+ export const GroupHeaderRow = styled.tr `
507
+ background: ${({ $theme }) => $theme.headerBackgroundColor};
508
+ `;
509
+ export const GroupHeaderCell = styled.th `
510
+ padding: ${({ $theme }) => $theme.headerPadding};
511
+ text-align: center;
512
+ font-size: ${({ $theme }) => $theme.headerFontSize};
513
+ font-weight: ${({ $theme }) => $theme.headerFontWeight};
514
+ color: ${({ $theme }) => $theme.headerTextColor};
515
+ border-bottom: 1px solid ${({ $theme }) => $theme.borderColor};
516
+ border-right: 1px solid ${({ $theme }) => $theme.borderColor};
517
+ background: ${({ $theme }) => $theme.headerBackgroundColor};
518
+ text-transform: uppercase;
519
+ letter-spacing: 0.5px;
520
+
521
+ &:last-child {
522
+ border-right: none;
523
+ }
524
+ `;
525
+ // ============================================================================
526
+ // Floating Filter Row
527
+ // ============================================================================
528
+ export const FloatingFilterRow = styled.tr `
529
+ background: ${({ $theme }) => $theme.headerBackgroundColor};
530
+ height: ${({ $height }) => ($height ? `${$height}px` : '32px')};
531
+ `;
532
+ export const FloatingFilterCell = styled.td `
533
+ padding: 4px 8px;
534
+ border-bottom: 1px solid ${({ $theme }) => $theme.borderColor};
535
+ border-right: 1px solid ${({ $theme }) => $theme.borderColor};
536
+ vertical-align: middle;
537
+
538
+ &:last-child {
539
+ border-right: none;
540
+ }
541
+
542
+ input,
543
+ select {
544
+ width: 100%;
545
+ padding: 4px 8px;
546
+ font-size: 12px;
547
+ border: 1px solid ${({ $theme }) => $theme.borderColor};
548
+ border-radius: 3px;
549
+ background: ${({ $theme }) => $theme.backgroundColor};
550
+ color: ${({ $theme }) => $theme.textColor};
551
+ outline: none;
552
+
553
+ &:focus {
554
+ border-color: ${({ $theme }) => $theme.accentColor};
555
+ }
556
+ }
557
+ `;
558
+ // ============================================================================
559
+ // Body
560
+ // ============================================================================
561
+ export const TableBody = styled.tbody `
562
+ color: ${({ $theme }) => $theme.textColor};
563
+ `;
564
+ export const TableRow = styled.tr `
565
+ height: ${({ $height }) => ($height ? `${$height}px` : '42px')};
566
+ color: ${({ $theme }) => $theme.textColor};
567
+ background: ${({ $theme, $selected, $highlighted, $striped, $even, $group }) => {
568
+ if ($selected)
569
+ return $theme.selectedRowBackgroundColor;
570
+ if ($highlighted)
571
+ return `${$theme.accentColor}20`;
572
+ if ($group)
573
+ return $theme.headerBackgroundColor;
574
+ if ($striped && $even)
575
+ return $theme.oddRowBackgroundColor;
576
+ return $theme.backgroundColor;
577
+ }};
578
+ transition: background-color 0.15s ease;
579
+
580
+ ${({ $animate }) => $animate &&
581
+ css `
582
+ animation: ${rowEnter} 0.2s ease;
583
+ `}
584
+
585
+ ${({ $dragging }) => $dragging &&
586
+ css `
587
+ opacity: 0.5;
588
+ `}
589
+
590
+ ${({ $dragOver, $theme }) => $dragOver &&
591
+ css `
592
+ background: ${$theme.selectedRowBackgroundColor}60;
593
+ box-shadow: inset 0 -2px 0 ${$theme.accentColor};
594
+ `}
595
+
596
+ &:hover {
597
+ background: ${({ $theme, $selected }) => $selected ? $theme.selectedRowBackgroundColor : $theme.hoverRowBackgroundColor};
598
+ }
599
+
600
+ ${({ $group }) => $group &&
601
+ css `
602
+ cursor: pointer;
603
+ font-weight: 600;
604
+ `}
605
+ `;
606
+ export const TableCell = styled.td `
607
+ padding: ${({ $theme }) => $theme.cellPadding};
608
+ text-align: ${({ $align }) => $align || 'left'};
609
+ border-bottom: ${({ $theme }) => $theme.cellBorderWidth} solid ${({ $theme }) => $theme.borderColor};
610
+ border-right: ${({ $theme }) => $theme.cellBorderWidth} solid ${({ $theme }) => $theme.borderColor};
611
+ vertical-align: middle;
612
+ overflow: hidden;
613
+ text-overflow: ellipsis;
614
+ white-space: nowrap;
615
+ color: ${({ $theme }) => $theme.textColor};
616
+
617
+ ${({ $width }) => $width && css `width: ${$width}px;`}
618
+
619
+ ${({ $pinned, $theme }) => $pinned &&
620
+ css `
621
+ position: sticky;
622
+ ${$pinned === 'left' ? 'left: 0;' : 'right: 0;'}
623
+ z-index: 5;
624
+ background: inherit;
625
+ box-shadow: ${$pinned === 'left' ? '2px 0 4px rgba(0,0,0,0.1)' : '-2px 0 4px rgba(0,0,0,0.1)'};
626
+ `}
627
+
628
+ ${({ $editing, $theme }) => $editing &&
629
+ css `
630
+ padding: 0;
631
+ background: ${$theme.backgroundColor};
632
+ box-shadow: inset 0 0 0 2px ${$theme.accentColor};
633
+ `}
634
+
635
+ ${({ $flashing }) => $flashing &&
636
+ css `
637
+ animation: ${cellFlash} 0.5s ease;
638
+ `}
639
+
640
+ &:last-child {
641
+ border-right: none;
642
+ }
643
+ `;
644
+ export const CellContent = styled.div `
645
+ display: flex;
646
+ align-items: center;
647
+ gap: 8px;
648
+ min-height: 20px;
649
+ color: inherit;
650
+
651
+ ${({ $wrapText }) => $wrapText &&
652
+ css `
653
+ white-space: normal;
654
+ word-break: break-word;
655
+ `}
656
+ `;
657
+ // ============================================================================
658
+ // Checkbox
659
+ // ============================================================================
660
+ export const Checkbox = styled.input `
661
+ width: 16px;
662
+ height: 16px;
663
+ margin: 0;
664
+ cursor: pointer;
665
+ accent-color: ${({ $theme }) => $theme.accentColor};
666
+ flex-shrink: 0;
667
+
668
+ &:disabled {
669
+ opacity: 0.5;
670
+ cursor: not-allowed;
671
+ }
672
+ `;
673
+ export const CheckboxCell = styled.div `
674
+ display: flex;
675
+ align-items: center;
676
+ justify-content: center;
677
+ width: 100%;
678
+ `;
679
+ // ============================================================================
680
+ // Expand / Group
681
+ // ============================================================================
682
+ export const ExpandButton = styled.button `
683
+ display: flex;
684
+ align-items: center;
685
+ justify-content: center;
686
+ width: 20px;
687
+ height: 20px;
688
+ padding: 0;
689
+ margin-left: ${({ $level }) => ($level ? `${$level * 16}px` : '0')};
690
+ margin-right: 8px;
691
+ border: none;
692
+ border-radius: 3px;
693
+ background: transparent;
694
+ cursor: pointer;
695
+ transition: all 0.15s ease;
696
+ flex-shrink: 0;
697
+
698
+ &:hover {
699
+ background: ${({ $theme }) => $theme.hoverRowBackgroundColor};
700
+ }
701
+
702
+ svg {
703
+ width: 14px;
704
+ height: 14px;
705
+ transition: transform 0.2s ease;
706
+ transform: ${({ $expanded }) => ($expanded ? 'rotate(90deg)' : 'rotate(0deg)')};
707
+ }
708
+ `;
709
+ export const GroupCell = styled.div `
710
+ display: flex;
711
+ align-items: center;
712
+ padding-left: ${({ $level }) => ($level ? `${$level * 20}px` : '0')};
713
+ `;
714
+ // ============================================================================
715
+ // Row Drag Handle
716
+ // ============================================================================
717
+ export const DragHandle = styled.div `
718
+ display: flex;
719
+ align-items: center;
720
+ justify-content: center;
721
+ width: 20px;
722
+ height: 20px;
723
+ cursor: grab;
724
+ opacity: 0.4;
725
+ transition: opacity 0.15s ease;
726
+ flex-shrink: 0;
727
+
728
+ &:hover {
729
+ opacity: 1;
730
+ }
731
+
732
+ ${({ $dragging }) => $dragging &&
733
+ css `
734
+ cursor: grabbing;
735
+ opacity: 1;
736
+ `}
737
+
738
+ svg {
739
+ width: 14px;
740
+ height: 14px;
741
+ }
742
+ `;
743
+ // ============================================================================
744
+ // Cell Editor
745
+ // ============================================================================
746
+ export const CellEditor = styled.div `
747
+ width: 100%;
748
+ height: 100%;
749
+ display: flex;
750
+ align-items: center;
751
+
752
+ input,
753
+ textarea,
754
+ select {
755
+ width: 100%;
756
+ height: 100%;
757
+ padding: 8px 12px;
758
+ font-size: inherit;
759
+ font-family: inherit;
760
+ border: none;
761
+ background: ${({ $theme }) => $theme.backgroundColor};
762
+ color: ${({ $theme }) => $theme.textColor};
763
+ outline: none;
764
+ }
765
+
766
+ textarea {
767
+ resize: vertical;
768
+ min-height: 80px;
769
+ }
770
+ `;
771
+ // ============================================================================
772
+ // Footer
773
+ // ============================================================================
774
+ export const TableFooter = styled.tfoot `
775
+ background: ${({ $theme }) => $theme.headerBackgroundColor};
776
+ `;
777
+ export const FooterRow = styled.tr `
778
+ height: 42px;
779
+ `;
780
+ export const FooterCell = styled.td `
781
+ padding: ${({ $theme }) => $theme.cellPadding};
782
+ text-align: ${({ $align }) => $align || 'left'};
783
+ font-weight: 600;
784
+ border-top: 2px solid ${({ $theme }) => $theme.borderColor};
785
+ color: ${({ $theme }) => $theme.headerTextColor};
786
+ `;
787
+ // ============================================================================
788
+ // Pagination
789
+ // ============================================================================
790
+ export const PaginationBar = styled.div `
791
+ display: flex;
792
+ align-items: center;
793
+ justify-content: space-between;
794
+ padding: 8px 16px;
795
+ background: ${({ $theme }) => $theme.headerBackgroundColor};
796
+ border-top: 1px solid ${({ $theme }) => $theme.borderColor};
797
+ gap: 16px;
798
+ flex-wrap: wrap;
799
+
800
+ @media (max-width: 640px) {
801
+ flex-direction: column;
802
+ gap: 12px;
803
+ }
804
+ `;
805
+ export const PaginationInfo = styled.div `
806
+ font-size: 13px;
807
+ color: ${({ $theme }) => $theme.headerTextColor};
808
+ `;
809
+ export const PaginationControls = styled.div `
810
+ display: flex;
811
+ align-items: center;
812
+ gap: 4px;
813
+ `;
814
+ export const PageButton = styled.button `
815
+ display: flex;
816
+ align-items: center;
817
+ justify-content: center;
818
+ min-width: 32px;
819
+ height: 32px;
820
+ padding: 0 8px;
821
+ font-size: 13px;
822
+ font-weight: 500;
823
+ border: 1px solid ${({ $theme, $active }) => ($active ? $theme.accentColor : $theme.borderColor)};
824
+ border-radius: 4px;
825
+ background: ${({ $theme, $active }) => ($active ? $theme.accentColor : $theme.backgroundColor)};
826
+ color: ${({ $theme, $active }) => ($active ? '#ffffff' : $theme.textColor)};
827
+ cursor: pointer;
828
+ transition: all 0.15s ease;
829
+
830
+ &:hover:not(:disabled) {
831
+ background: ${({ $theme, $active }) => ($active ? $theme.accentColor : $theme.hoverRowBackgroundColor)};
832
+ }
833
+
834
+ &:disabled {
835
+ opacity: 0.5;
836
+ cursor: not-allowed;
837
+ }
838
+
839
+ svg {
840
+ width: 16px;
841
+ height: 16px;
842
+ }
843
+ `;
844
+ export const PageSizeSelect = styled.select `
845
+ padding: 6px 8px;
846
+ font-size: 13px;
847
+ border: 1px solid ${({ $theme }) => $theme.borderColor};
848
+ border-radius: 4px;
849
+ background: ${({ $theme }) => $theme.backgroundColor};
850
+ color: ${({ $theme }) => $theme.textColor};
851
+ cursor: pointer;
852
+ outline: none;
853
+
854
+ &:focus {
855
+ border-color: ${({ $theme }) => $theme.accentColor};
856
+ }
857
+ `;
858
+ // ============================================================================
859
+ // Status Bar
860
+ // ============================================================================
861
+ export const StatusBar = styled.div `
862
+ display: flex;
863
+ align-items: center;
864
+ justify-content: space-between;
865
+ padding: 6px 16px;
866
+ background: ${({ $theme }) => $theme.headerBackgroundColor};
867
+ border-top: 1px solid ${({ $theme }) => $theme.borderColor};
868
+ font-size: 12px;
869
+ color: ${({ $theme }) => $theme.headerTextColor};
870
+ gap: 16px;
871
+ `;
872
+ export const StatusItem = styled.div `
873
+ display: flex;
874
+ align-items: center;
875
+ gap: 6px;
876
+
877
+ strong {
878
+ color: inherit;
879
+ }
880
+ `;
881
+ // ============================================================================
882
+ // Side Bar / Tool Panels
883
+ // ============================================================================
884
+ export const SideBar = styled.div `
885
+ width: ${({ $width }) => ($width ? `${$width}px` : '250px')};
886
+ min-width: 200px;
887
+ max-width: 400px;
888
+ background: ${({ $theme }) => $theme.backgroundColor};
889
+ border-${({ $position }) => ($position === 'left' ? 'right' : 'left')}: 1px solid ${({ $theme }) => $theme.borderColor};
890
+ display: flex;
891
+ flex-direction: column;
892
+ overflow: hidden;
893
+ `;
894
+ export const SideBarTabs = styled.div `
895
+ display: flex;
896
+ border-bottom: 1px solid ${({ $theme }) => $theme.borderColor};
897
+ `;
898
+ export const SideBarTab = styled.button `
899
+ flex: 1;
900
+ padding: 10px 12px;
901
+ font-size: 12px;
902
+ font-weight: 500;
903
+ border: none;
904
+ background: ${({ $theme, $active }) => ($active ? $theme.backgroundColor : $theme.headerBackgroundColor)};
905
+ color: ${({ $theme, $active }) => ($active ? $theme.accentColor : $theme.headerTextColor)};
906
+ cursor: pointer;
907
+ transition: all 0.15s ease;
908
+ border-bottom: 2px solid ${({ $theme, $active }) => ($active ? $theme.accentColor : 'transparent')};
909
+
910
+ &:hover {
911
+ background: ${({ $theme }) => $theme.backgroundColor};
912
+ }
913
+ `;
914
+ export const SideBarContent = styled.div `
915
+ flex: 1;
916
+ overflow: auto;
917
+ padding: 12px;
918
+ `;
919
+ // ============================================================================
920
+ // Overlays
921
+ // ============================================================================
922
+ export const Overlay = styled.div `
923
+ position: absolute;
924
+ inset: 0;
925
+ display: flex;
926
+ align-items: center;
927
+ justify-content: center;
928
+ background: ${({ $theme }) => $theme.backgroundColor}e6;
929
+ z-index: 100;
930
+ animation: ${fadeIn} 0.2s ease;
931
+ `;
932
+ export const LoadingOverlay = styled(Overlay) `
933
+ flex-direction: column;
934
+ gap: 16px;
935
+ `;
936
+ export const Spinner = styled.div `
937
+ width: ${({ $size }) => ($size ? `${$size}px` : '40px')};
938
+ height: ${({ $size }) => ($size ? `${$size}px` : '40px')};
939
+ border: 3px solid ${({ $theme }) => $theme.borderColor};
940
+ border-top-color: ${({ $theme }) => $theme.accentColor};
941
+ border-radius: 50%;
942
+ animation: ${spin} 0.8s linear infinite;
943
+ `;
944
+ export const NoRowsOverlay = styled(Overlay) `
945
+ flex-direction: column;
946
+ gap: 12px;
947
+ color: ${({ $theme }) => $theme.headerTextColor};
948
+
949
+ svg {
950
+ width: 48px;
951
+ height: 48px;
952
+ opacity: 0.5;
953
+ }
954
+ `;
955
+ // ============================================================================
956
+ // Context Menu
957
+ // ============================================================================
958
+ export const ContextMenu = styled.div `
959
+ position: fixed;
960
+ top: ${({ $y }) => $y}px;
961
+ left: ${({ $x }) => $x}px;
962
+ min-width: 180px;
963
+ background: ${({ $theme }) => $theme.backgroundColor};
964
+ border: 1px solid ${({ $theme }) => $theme.borderColor};
965
+ border-radius: 6px;
966
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
967
+ z-index: 1000;
968
+ overflow: hidden;
969
+ animation: ${slideInRight} 0.15s ease;
970
+ `;
971
+ export const ContextMenuItem = styled.div `
972
+ display: flex;
973
+ align-items: center;
974
+ gap: 10px;
975
+ padding: 8px 14px;
976
+ font-size: 13px;
977
+ cursor: ${({ $disabled }) => ($disabled ? 'not-allowed' : 'pointer')};
978
+ opacity: ${({ $disabled }) => ($disabled ? 0.5 : 1)};
979
+ color: ${({ $danger, $theme }) => ($danger ? '#ef4444' : $theme.textColor)};
980
+ transition: background-color 0.1s ease;
981
+
982
+ &:hover {
983
+ background: ${({ $disabled, $theme }) => ($disabled ? 'transparent' : $theme.hoverRowBackgroundColor)};
984
+ }
985
+
986
+ svg {
987
+ width: 16px;
988
+ height: 16px;
989
+ opacity: 0.7;
990
+ }
991
+
992
+ span.shortcut {
993
+ margin-left: auto;
994
+ font-size: 11px;
995
+ opacity: 0.5;
996
+ }
997
+ `;
998
+ export const ContextMenuDivider = styled.div `
999
+ height: 1px;
1000
+ background: ${({ $theme }) => $theme.borderColor};
1001
+ margin: 4px 0;
1002
+ `;
1003
+ // ============================================================================
1004
+ // Column Menu
1005
+ // ============================================================================
1006
+ export const ColumnMenu = styled.div `
1007
+ position: absolute;
1008
+ top: 100%;
1009
+ right: 0;
1010
+ min-width: 200px;
1011
+ background: ${({ $theme }) => $theme.backgroundColor};
1012
+ border: 1px solid ${({ $theme }) => $theme.borderColor};
1013
+ border-radius: 6px;
1014
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
1015
+ z-index: 100;
1016
+ overflow: hidden;
1017
+ animation: ${fadeIn} 0.15s ease;
1018
+ `;
1019
+ // ============================================================================
1020
+ // Mobile Card View
1021
+ // ============================================================================
1022
+ export const MobileCardContainer = styled.div `
1023
+ display: flex;
1024
+ flex-direction: column;
1025
+ gap: 12px;
1026
+ padding: 12px;
1027
+ `;
1028
+ export const MobileCard = styled.div `
1029
+ background: ${({ $theme }) => $theme.backgroundColor};
1030
+ border: 1px solid ${({ $theme, $selected }) => ($selected ? $theme.accentColor : $theme.borderColor)};
1031
+ border-radius: 8px;
1032
+ padding: 16px;
1033
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
1034
+ transition: all 0.15s ease;
1035
+
1036
+ ${({ $selected, $theme }) => $selected &&
1037
+ css `
1038
+ background: ${$theme.selectedRowBackgroundColor};
1039
+ `}
1040
+ `;
1041
+ export const MobileCardHeader = styled.div `
1042
+ display: flex;
1043
+ align-items: center;
1044
+ justify-content: space-between;
1045
+ margin-bottom: 12px;
1046
+ padding-bottom: 12px;
1047
+ border-bottom: 1px solid ${({ $theme }) => $theme.borderColor};
1048
+ `;
1049
+ export const MobileCardRow = styled.div `
1050
+ display: flex;
1051
+ justify-content: space-between;
1052
+ padding: 6px 0;
1053
+ font-size: 13px;
1054
+
1055
+ &:not(:last-child) {
1056
+ border-bottom: 1px solid ${({ $theme }) => $theme.borderColor}50;
1057
+ }
1058
+ `;
1059
+ export const MobileCardLabel = styled.span `
1060
+ color: ${({ $theme }) => $theme.headerTextColor};
1061
+ font-weight: 500;
1062
+ `;
1063
+ export const MobileCardValue = styled.span `
1064
+ color: ${({ $theme }) => $theme.textColor};
1065
+ text-align: right;
1066
+ `;
1067
+ // ============================================================================
1068
+ // Skeleton Loading
1069
+ // ============================================================================
1070
+ export const SkeletonRow = styled.tr `
1071
+ height: 42px;
1072
+ `;
1073
+ export const SkeletonCell = styled.td `
1074
+ padding: 8px 12px;
1075
+ border-bottom: 1px solid ${({ $theme }) => $theme.borderColor};
1076
+ border-right: 1px solid ${({ $theme }) => $theme.borderColor};
1077
+
1078
+ &:last-child {
1079
+ border-right: none;
1080
+ }
1081
+ `;
1082
+ export const SkeletonBlock = styled.div `
1083
+ height: 16px;
1084
+ width: ${({ $width }) => $width || '80%'};
1085
+ background: linear-gradient(
1086
+ 90deg,
1087
+ ${({ $theme }) => $theme.borderColor}40 25%,
1088
+ ${({ $theme }) => $theme.borderColor}80 50%,
1089
+ ${({ $theme }) => $theme.borderColor}40 75%
1090
+ );
1091
+ background-size: 200% 100%;
1092
+ animation: ${shimmer} 1.5s ease-in-out infinite;
1093
+ border-radius: 4px;
1094
+ `;
1095
+ // ============================================================================
1096
+ // Tooltip
1097
+ // ============================================================================
1098
+ export const TooltipContainer = styled.div `
1099
+ position: fixed;
1100
+ top: ${({ $y }) => $y}px;
1101
+ left: ${({ $x }) => $x}px;
1102
+ max-width: 300px;
1103
+ padding: 8px 12px;
1104
+ font-size: 12px;
1105
+ background: ${({ $theme }) => ($theme.textColor.includes('f0') ? '#333' : '#fff')};
1106
+ color: ${({ $theme }) => ($theme.textColor.includes('f0') ? '#fff' : '#333')};
1107
+ border-radius: 4px;
1108
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);
1109
+ z-index: 1001;
1110
+ pointer-events: none;
1111
+ animation: ${fadeIn} 0.1s ease;
1112
+ `;
1113
+ // ============================================================================
1114
+ // Drag Ghost
1115
+ // ============================================================================
1116
+ export const DragGhost = styled.div `
1117
+ position: fixed;
1118
+ pointer-events: none;
1119
+ z-index: 10000;
1120
+ padding: 8px 16px;
1121
+ background: ${({ $theme }) => $theme.accentColor};
1122
+ color: #ffffff;
1123
+ font-size: 13px;
1124
+ font-weight: 500;
1125
+ border-radius: 6px;
1126
+ box-shadow: 0 4px 16px rgba(0, 0, 0, 0.3);
1127
+ opacity: ${({ $visible }) => ($visible ? 0.9 : 0)};
1128
+ transform: translate(-50%, -50%);
1129
+ transition: opacity 0.15s ease;
1130
+ `;
1131
+ // ============================================================================
1132
+ // Selection Info Bar
1133
+ // ============================================================================
1134
+ export const SelectionBar = styled.div `
1135
+ display: flex;
1136
+ align-items: center;
1137
+ justify-content: space-between;
1138
+ padding: 8px 16px;
1139
+ background: ${({ $theme }) => $theme.accentColor};
1140
+ color: #ffffff;
1141
+ font-size: 13px;
1142
+ font-weight: 500;
1143
+ transform: translateY(${({ $visible }) => ($visible ? '0' : '-100%')});
1144
+ opacity: ${({ $visible }) => ($visible ? 1 : 0)};
1145
+ transition: all 0.2s ease;
1146
+ position: absolute;
1147
+ top: 0;
1148
+ left: 0;
1149
+ right: 0;
1150
+ z-index: 50;
1151
+ `;
1152
+ export const SelectionActions = styled.div `
1153
+ display: flex;
1154
+ align-items: center;
1155
+ gap: 8px;
1156
+ `;
1157
+ // ============================================================================
1158
+ // Side Panel (Right Panel with Columns & Filters tabs)
1159
+ // ============================================================================
1160
+ export const SidePanel = styled.div `
1161
+ width: ${({ $open, $width }) => ($open ? ($width ? `${$width}px` : '280px') : '40px')};
1162
+ min-width: ${({ $open }) => ($open ? '200px' : '40px')};
1163
+ max-width: ${({ $open }) => ($open ? '400px' : '40px')};
1164
+ background: ${({ $theme }) => $theme.backgroundColor};
1165
+ border-left: 1px solid ${({ $theme }) => $theme.borderColor};
1166
+ display: flex;
1167
+ flex-direction: column;
1168
+ overflow: hidden;
1169
+ transition: width 0.2s ease;
1170
+ flex-shrink: 0;
1171
+ `;
1172
+ export const SidePanelTabs = styled.div `
1173
+ display: flex;
1174
+ flex-direction: ${({ $collapsed }) => ($collapsed ? 'column' : 'row')};
1175
+ border-bottom: ${({ $collapsed }) => ($collapsed ? 'none' : '1px solid')};
1176
+ border-color: ${({ $theme }) => $theme.borderColor};
1177
+ background: ${({ $theme }) => $theme.headerBackgroundColor};
1178
+ `;
1179
+ export const SidePanelTab = styled.button `
1180
+ flex: ${({ $collapsed }) => ($collapsed ? 'none' : '1')};
1181
+ padding: ${({ $collapsed }) => ($collapsed ? '12px 10px' : '10px 12px')};
1182
+ font-size: 11px;
1183
+ font-weight: 600;
1184
+ text-transform: uppercase;
1185
+ letter-spacing: 0.5px;
1186
+ border: none;
1187
+ background: ${({ $theme, $active }) => ($active ? $theme.backgroundColor : 'transparent')};
1188
+ color: ${({ $theme, $active }) => ($active ? $theme.accentColor : $theme.headerTextColor)};
1189
+ cursor: pointer;
1190
+ transition: all 0.15s ease;
1191
+ border-bottom: 2px solid ${({ $theme, $active }) => ($active ? $theme.accentColor : 'transparent')};
1192
+ display: flex;
1193
+ align-items: center;
1194
+ justify-content: center;
1195
+ gap: 6px;
1196
+ white-space: nowrap;
1197
+
1198
+ &:hover {
1199
+ background: ${({ $theme }) => $theme.hoverRowBackgroundColor};
1200
+ color: ${({ $theme }) => $theme.accentColor};
1201
+ }
1202
+
1203
+ svg {
1204
+ width: 14px;
1205
+ height: 14px;
1206
+ }
1207
+ `;
1208
+ export const SidePanelContent = styled.div `
1209
+ flex: 1;
1210
+ overflow-y: auto;
1211
+ overflow-x: hidden;
1212
+ `;
1213
+ export const SidePanelSearch = styled.div `
1214
+ padding: 10px 12px;
1215
+ border-bottom: 1px solid ${({ $theme }) => $theme.borderColor};
1216
+
1217
+ input {
1218
+ width: 100%;
1219
+ padding: 8px 10px;
1220
+ font-size: 12px;
1221
+ border: 1px solid ${({ $theme }) => $theme.borderColor};
1222
+ border-radius: 4px;
1223
+ background: ${({ $theme }) => $theme.backgroundColor};
1224
+ color: ${({ $theme }) => $theme.textColor};
1225
+ outline: none;
1226
+
1227
+ &::placeholder {
1228
+ color: ${({ $theme }) => $theme.headerTextColor};
1229
+ opacity: 0.6;
1230
+ }
1231
+
1232
+ &:focus {
1233
+ border-color: ${({ $theme }) => $theme.accentColor};
1234
+ }
1235
+ }
1236
+ `;
1237
+ export const SidePanelSection = styled.div `
1238
+ border-bottom: 1px solid ${({ $theme }) => $theme.borderColor};
1239
+ `;
1240
+ export const SidePanelSectionHeader = styled.div `
1241
+ display: flex;
1242
+ align-items: center;
1243
+ gap: 8px;
1244
+ padding: 10px 12px;
1245
+ font-size: 11px;
1246
+ font-weight: 600;
1247
+ text-transform: uppercase;
1248
+ letter-spacing: 0.5px;
1249
+ color: ${({ $theme }) => $theme.headerTextColor};
1250
+ background: ${({ $theme }) => $theme.headerBackgroundColor};
1251
+ cursor: ${({ $collapsible }) => ($collapsible ? 'pointer' : 'default')};
1252
+ user-select: none;
1253
+
1254
+ &:hover {
1255
+ background: ${({ $collapsible, $theme }) => ($collapsible ? $theme.hoverRowBackgroundColor : $theme.headerBackgroundColor)};
1256
+ }
1257
+
1258
+ svg {
1259
+ width: 12px;
1260
+ height: 12px;
1261
+ transition: transform 0.2s ease;
1262
+ }
1263
+ `;
1264
+ export const SidePanelColumnItem = styled.div `
1265
+ display: flex;
1266
+ align-items: center;
1267
+ gap: 8px;
1268
+ padding: 6px 12px;
1269
+ padding-left: ${({ $indent }) => ($indent ? `${12 + $indent * 16}px` : '12px')};
1270
+ font-size: 13px;
1271
+ color: ${({ $theme }) => $theme.textColor};
1272
+ cursor: pointer;
1273
+ user-select: none;
1274
+ transition: background-color 0.1s ease;
1275
+ border-left: 2px solid transparent;
1276
+
1277
+ ${({ $selected, $theme }) => $selected &&
1278
+ css `
1279
+ background: ${$theme.selectedRowBackgroundColor}40;
1280
+ border-left-color: ${$theme.accentColor};
1281
+ `}
1282
+
1283
+ ${({ $dragging, $theme }) => $dragging &&
1284
+ css `
1285
+ opacity: 0.5;
1286
+ background: ${$theme.accentColor}20;
1287
+ `}
1288
+
1289
+ &:hover {
1290
+ background: ${({ $theme }) => $theme.hoverRowBackgroundColor};
1291
+ }
1292
+ `;
1293
+ export const SidePanelDragHandle = styled.span `
1294
+ display: flex;
1295
+ align-items: center;
1296
+ justify-content: center;
1297
+ width: 14px;
1298
+ height: 14px;
1299
+ cursor: grab;
1300
+ opacity: 0.4;
1301
+ flex-shrink: 0;
1302
+
1303
+ &:hover {
1304
+ opacity: 1;
1305
+ }
1306
+
1307
+ &:active {
1308
+ cursor: grabbing;
1309
+ }
1310
+
1311
+ svg {
1312
+ width: 12px;
1313
+ height: 12px;
1314
+ }
1315
+ `;
1316
+ export const SidePanelGroupLabel = styled.span `
1317
+ flex: 1;
1318
+ overflow: hidden;
1319
+ text-overflow: ellipsis;
1320
+ white-space: nowrap;
1321
+ `;
1322
+ // ============================================================================
1323
+ // Row Groups Drop Zone
1324
+ // ============================================================================
1325
+ export const RowGroupsZone = styled.div `
1326
+ display: flex;
1327
+ align-items: center;
1328
+ gap: 8px;
1329
+ padding: 8px 12px;
1330
+ min-height: 36px;
1331
+ background: ${({ $theme, $dragOver }) => ($dragOver ? `${$theme.accentColor}15` : $theme.headerBackgroundColor)};
1332
+ border-bottom: 1px solid ${({ $theme }) => $theme.borderColor};
1333
+ border: ${({ $dragOver, $theme }) => ($dragOver ? `2px dashed ${$theme.accentColor}` : '1px solid transparent')};
1334
+ transition: all 0.15s ease;
1335
+ flex-wrap: wrap;
1336
+
1337
+ ${({ $hasItems }) => !$hasItems &&
1338
+ css `
1339
+ justify-content: center;
1340
+ `}
1341
+ `;
1342
+ export const RowGroupsLabel = styled.span `
1343
+ display: flex;
1344
+ align-items: center;
1345
+ gap: 6px;
1346
+ font-size: 12px;
1347
+ color: ${({ $theme }) => $theme.headerTextColor};
1348
+ white-space: nowrap;
1349
+
1350
+ svg {
1351
+ width: 14px;
1352
+ height: 14px;
1353
+ opacity: 0.6;
1354
+ }
1355
+ `;
1356
+ export const RowGroupChip = styled.div `
1357
+ display: inline-flex;
1358
+ align-items: center;
1359
+ gap: 6px;
1360
+ padding: 4px 10px;
1361
+ font-size: 12px;
1362
+ font-weight: 500;
1363
+ background: ${({ $theme }) => $theme.accentColor}15;
1364
+ color: ${({ $theme }) => $theme.accentColor};
1365
+ border-radius: 16px;
1366
+ cursor: default;
1367
+
1368
+ button {
1369
+ display: flex;
1370
+ align-items: center;
1371
+ justify-content: center;
1372
+ width: 16px;
1373
+ height: 16px;
1374
+ padding: 0;
1375
+ border: none;
1376
+ background: transparent;
1377
+ cursor: pointer;
1378
+ opacity: 0.6;
1379
+ border-radius: 50%;
1380
+ transition: all 0.1s ease;
1381
+
1382
+ &:hover {
1383
+ opacity: 1;
1384
+ background: ${({ $theme }) => $theme.accentColor}30;
1385
+ }
1386
+
1387
+ svg {
1388
+ width: 10px;
1389
+ height: 10px;
1390
+ }
1391
+ }
1392
+ `;
1393
+ // ============================================================================
1394
+ // Values/Aggregation Panel
1395
+ // ============================================================================
1396
+ export const ValuesPanel = styled.div `
1397
+ min-height: 60px;
1398
+ `;
1399
+ export const ValueItem = styled.div `
1400
+ display: flex;
1401
+ align-items: center;
1402
+ justify-content: space-between;
1403
+ gap: 8px;
1404
+ padding: 6px 12px;
1405
+ font-size: 13px;
1406
+ color: ${({ $theme }) => $theme.textColor};
1407
+ cursor: pointer;
1408
+
1409
+ &:hover {
1410
+ background: ${({ $theme }) => $theme.hoverRowBackgroundColor};
1411
+ }
1412
+ `;
1413
+ export const ValueItemLabel = styled.span `
1414
+ display: flex;
1415
+ align-items: center;
1416
+ gap: 6px;
1417
+ flex: 1;
1418
+ overflow: hidden;
1419
+
1420
+ svg {
1421
+ width: 12px;
1422
+ height: 12px;
1423
+ opacity: 0.5;
1424
+ }
1425
+ `;
1426
+ export const ValueItemRemove = styled.button `
1427
+ display: flex;
1428
+ align-items: center;
1429
+ justify-content: center;
1430
+ width: 18px;
1431
+ height: 18px;
1432
+ padding: 0;
1433
+ border: none;
1434
+ background: transparent;
1435
+ cursor: pointer;
1436
+ opacity: 0.5;
1437
+ border-radius: 50%;
1438
+
1439
+ &:hover {
1440
+ opacity: 1;
1441
+ background: ${({ $theme }) => $theme.borderColor};
1442
+ }
1443
+
1444
+ svg {
1445
+ width: 12px;
1446
+ height: 12px;
1447
+ }
1448
+ `;
1449
+ // ============================================================================
1450
+ // Pivot Mode Toggle
1451
+ // ============================================================================
1452
+ export const PivotModeToggle = styled.div `
1453
+ display: flex;
1454
+ align-items: center;
1455
+ justify-content: space-between;
1456
+ padding: 10px 12px;
1457
+ border-bottom: 1px solid ${({ $theme }) => $theme.borderColor};
1458
+ `;
1459
+ export const PivotModeLabel = styled.span `
1460
+ font-size: 12px;
1461
+ font-weight: 500;
1462
+ color: ${({ $theme }) => $theme.textColor};
1463
+ `;
1464
+ export const ToggleSwitch = styled.label `
1465
+ position: relative;
1466
+ display: inline-block;
1467
+ width: 36px;
1468
+ height: 20px;
1469
+ cursor: pointer;
1470
+
1471
+ input {
1472
+ opacity: 0;
1473
+ width: 0;
1474
+ height: 0;
1475
+ }
1476
+
1477
+ span {
1478
+ position: absolute;
1479
+ inset: 0;
1480
+ background: ${({ $theme }) => $theme.borderColor};
1481
+ border-radius: 20px;
1482
+ transition: all 0.2s ease;
1483
+
1484
+ &::before {
1485
+ content: '';
1486
+ position: absolute;
1487
+ width: 14px;
1488
+ height: 14px;
1489
+ left: 3px;
1490
+ bottom: 3px;
1491
+ background: white;
1492
+ border-radius: 50%;
1493
+ transition: transform 0.2s ease;
1494
+ }
1495
+ }
1496
+
1497
+ input:checked + span {
1498
+ background: ${({ $theme }) => $theme.accentColor};
1499
+ }
1500
+
1501
+ input:checked + span::before {
1502
+ transform: translateX(16px);
1503
+ }
1504
+ `;
1505
+ // ============================================================================
1506
+ // Column Header Menu (Three Dot Menu)
1507
+ // ============================================================================
1508
+ export const HeaderMenuButton = styled.button `
1509
+ display: flex;
1510
+ align-items: center;
1511
+ justify-content: center;
1512
+ width: 20px;
1513
+ height: 20px;
1514
+ padding: 0;
1515
+ border: none;
1516
+ background: ${({ $active, $theme }) => ($active ? $theme.hoverRowBackgroundColor : 'transparent')};
1517
+ border-radius: 3px;
1518
+ cursor: pointer;
1519
+ opacity: ${({ $active }) => ($active ? 1 : 0)};
1520
+ transition: all 0.15s ease;
1521
+ flex-shrink: 0;
1522
+
1523
+ &:hover {
1524
+ opacity: 1;
1525
+ background: ${({ $theme }) => $theme.hoverRowBackgroundColor};
1526
+ }
1527
+
1528
+ svg {
1529
+ width: 14px;
1530
+ height: 14px;
1531
+ color: ${({ $theme }) => $theme.headerTextColor};
1532
+ }
1533
+ `;
1534
+ export const ColumnMenuPopup = styled.div `
1535
+ position: fixed;
1536
+ top: ${({ $y }) => $y}px;
1537
+ left: ${({ $x }) => $x}px;
1538
+ min-width: 200px;
1539
+ max-width: 280px;
1540
+ background: ${({ $theme }) => $theme.backgroundColor};
1541
+ border: 1px solid ${({ $theme }) => $theme.borderColor};
1542
+ border-radius: 6px;
1543
+ box-shadow: 0 4px 16px rgba(0, 0, 0, 0.15);
1544
+ z-index: 1000;
1545
+ overflow: hidden;
1546
+ animation: ${fadeIn} 0.15s ease;
1547
+ `;
1548
+ export const ColumnMenuSection = styled.div `
1549
+ padding: 4px 0;
1550
+ border-bottom: 1px solid ${({ $theme }) => $theme.borderColor};
1551
+
1552
+ &:last-child {
1553
+ border-bottom: none;
1554
+ }
1555
+ `;
1556
+ export const ColumnMenuItem = styled.div `
1557
+ display: flex;
1558
+ align-items: center;
1559
+ gap: 10px;
1560
+ padding: 8px 12px;
1561
+ font-size: 13px;
1562
+ color: ${({ $theme, $disabled }) => ($disabled ? $theme.headerTextColor : $theme.textColor)};
1563
+ cursor: ${({ $disabled }) => ($disabled ? 'not-allowed' : 'pointer')};
1564
+ opacity: ${({ $disabled }) => ($disabled ? 0.5 : 1)};
1565
+ transition: background-color 0.1s ease;
1566
+
1567
+ &:hover {
1568
+ background: ${({ $disabled, $theme }) => ($disabled ? 'transparent' : $theme.hoverRowBackgroundColor)};
1569
+ }
1570
+
1571
+ svg {
1572
+ width: 16px;
1573
+ height: 16px;
1574
+ opacity: 0.6;
1575
+ flex-shrink: 0;
1576
+ }
1577
+
1578
+ span {
1579
+ flex: 1;
1580
+ }
1581
+
1582
+ ${({ $hasSubmenu }) => $hasSubmenu &&
1583
+ css `
1584
+ &::after {
1585
+ content: '›';
1586
+ margin-left: auto;
1587
+ font-size: 16px;
1588
+ opacity: 0.5;
1589
+ }
1590
+ `}
1591
+ `;
1592
+ export const ColumnMenuSubmenu = styled.div `
1593
+ position: absolute;
1594
+ top: 0;
1595
+ left: 100%;
1596
+ min-width: 150px;
1597
+ background: ${({ $theme }) => $theme.backgroundColor};
1598
+ border: 1px solid ${({ $theme }) => $theme.borderColor};
1599
+ border-radius: 6px;
1600
+ box-shadow: 0 4px 16px rgba(0, 0, 0, 0.15);
1601
+ overflow: hidden;
1602
+ `;
1603
+ // ============================================================================
1604
+ // Set Filter (Filter by unique values)
1605
+ // ============================================================================
1606
+ export const SetFilterContainer = styled.div `
1607
+ min-width: 200px;
1608
+ max-width: 300px;
1609
+ max-height: 400px;
1610
+ background: ${({ $theme }) => $theme.backgroundColor};
1611
+ border: 1px solid ${({ $theme }) => $theme.borderColor};
1612
+ border-radius: 6px;
1613
+ box-shadow: 0 4px 16px rgba(0, 0, 0, 0.15);
1614
+ overflow: hidden;
1615
+ display: flex;
1616
+ flex-direction: column;
1617
+ `;
1618
+ export const SetFilterHeader = styled.div `
1619
+ padding: 8px 12px;
1620
+ border-bottom: 1px solid ${({ $theme }) => $theme.borderColor};
1621
+ font-size: 12px;
1622
+ font-weight: 600;
1623
+ color: ${({ $theme }) => $theme.headerTextColor};
1624
+ background: ${({ $theme }) => $theme.headerBackgroundColor};
1625
+ `;
1626
+ export const SetFilterSearch = styled.div `
1627
+ padding: 8px 10px;
1628
+ border-bottom: 1px solid ${({ $theme }) => $theme.borderColor};
1629
+
1630
+ input {
1631
+ width: 100%;
1632
+ padding: 6px 10px;
1633
+ font-size: 12px;
1634
+ border: 1px solid ${({ $theme }) => $theme.borderColor};
1635
+ border-radius: 4px;
1636
+ background: ${({ $theme }) => $theme.backgroundColor};
1637
+ color: ${({ $theme }) => $theme.textColor};
1638
+ outline: none;
1639
+
1640
+ &:focus {
1641
+ border-color: ${({ $theme }) => $theme.accentColor};
1642
+ }
1643
+
1644
+ &::placeholder {
1645
+ color: ${({ $theme }) => $theme.headerTextColor};
1646
+ opacity: 0.6;
1647
+ }
1648
+ }
1649
+ `;
1650
+ export const SetFilterList = styled.div `
1651
+ flex: 1;
1652
+ overflow-y: auto;
1653
+ max-height: 280px;
1654
+ `;
1655
+ export const SetFilterItem = styled.label `
1656
+ display: flex;
1657
+ align-items: center;
1658
+ gap: 8px;
1659
+ padding: 6px 12px;
1660
+ font-size: 13px;
1661
+ color: ${({ $theme }) => $theme.textColor};
1662
+ cursor: pointer;
1663
+ transition: background-color 0.1s ease;
1664
+ border-bottom: ${({ $selectAll, $theme }) => ($selectAll ? `1px solid ${$theme.borderColor}` : 'none')};
1665
+ font-weight: ${({ $selectAll }) => ($selectAll ? '500' : 'normal')};
1666
+
1667
+ &:hover {
1668
+ background: ${({ $theme }) => $theme.hoverRowBackgroundColor};
1669
+ }
1670
+
1671
+ input {
1672
+ margin: 0;
1673
+ accent-color: ${({ $theme }) => $theme.accentColor};
1674
+ }
1675
+ `;
1676
+ export const SetFilterActions = styled.div `
1677
+ display: flex;
1678
+ gap: 8px;
1679
+ padding: 8px 10px;
1680
+ border-top: 1px solid ${({ $theme }) => $theme.borderColor};
1681
+ background: ${({ $theme }) => $theme.headerBackgroundColor};
1682
+ `;
1683
+ export const SetFilterButton = styled.button `
1684
+ flex: 1;
1685
+ padding: 6px 12px;
1686
+ font-size: 12px;
1687
+ font-weight: 500;
1688
+ border: 1px solid ${({ $theme, $primary }) => ($primary ? $theme.accentColor : $theme.borderColor)};
1689
+ border-radius: 4px;
1690
+ background: ${({ $theme, $primary }) => ($primary ? $theme.accentColor : $theme.backgroundColor)};
1691
+ color: ${({ $primary, $theme }) => ($primary ? '#ffffff' : $theme.textColor)};
1692
+ cursor: pointer;
1693
+ transition: all 0.15s ease;
1694
+
1695
+ &:hover {
1696
+ filter: brightness(0.95);
1697
+ }
1698
+ `;
1699
+ // ============================================================================
1700
+ // Filter Panel in Side Bar
1701
+ // ============================================================================
1702
+ export const FilterPanelColumn = styled.div `
1703
+ border-bottom: 1px solid ${({ $theme }) => $theme.borderColor};
1704
+ `;
1705
+ export const FilterPanelHeader = styled.div `
1706
+ display: flex;
1707
+ align-items: center;
1708
+ gap: 8px;
1709
+ padding: 8px 12px;
1710
+ font-size: 13px;
1711
+ font-weight: 500;
1712
+ color: ${({ $theme, $hasFilter }) => ($hasFilter ? $theme.accentColor : $theme.textColor)};
1713
+ cursor: pointer;
1714
+ transition: background-color 0.1s ease;
1715
+
1716
+ &:hover {
1717
+ background: ${({ $theme }) => $theme.hoverRowBackgroundColor};
1718
+ }
1719
+
1720
+ svg {
1721
+ width: 12px;
1722
+ height: 12px;
1723
+ transition: transform 0.2s ease;
1724
+ transform: ${({ $expanded }) => ($expanded ? 'rotate(90deg)' : 'rotate(0deg)')};
1725
+ opacity: 0.5;
1726
+ }
1727
+ `;
1728
+ export const FilterPanelContent = styled.div `
1729
+ display: ${({ $expanded }) => ($expanded ? 'block' : 'none')};
1730
+ padding: 8px 12px;
1731
+ background: ${({ $theme }) => $theme.headerBackgroundColor}50;
1732
+ `;
1733
+ // ============================================================================
1734
+ // Grid Container with Side Panel Layout
1735
+ // ============================================================================
1736
+ export const GridLayout = styled.div `
1737
+ display: flex;
1738
+ width: 100%;
1739
+ height: 100%;
1740
+ overflow: hidden;
1741
+ `;
1742
+ export const GridMainArea = styled.div `
1743
+ flex: 1;
1744
+ display: flex;
1745
+ flex-direction: column;
1746
+ min-width: 0;
1747
+ overflow: hidden;
1748
+ `;
1749
+ // ============================================================================
1750
+ // Column Visibility Dropdown
1751
+ // ============================================================================
1752
+ export const ColumnVisibilityDropdown = styled.div `
1753
+ position: absolute;
1754
+ top: 100%;
1755
+ right: 0;
1756
+ min-width: 220px;
1757
+ max-height: 400px;
1758
+ background: ${({ $theme }) => $theme.backgroundColor};
1759
+ border: 1px solid ${({ $theme }) => $theme.borderColor};
1760
+ border-radius: 6px;
1761
+ box-shadow: 0 4px 16px rgba(0, 0, 0, 0.15);
1762
+ z-index: 100;
1763
+ overflow: hidden;
1764
+ display: flex;
1765
+ flex-direction: column;
1766
+ animation: ${fadeIn} 0.15s ease;
1767
+ `;
1768
+ export const ColumnVisibilityList = styled.div `
1769
+ flex: 1;
1770
+ overflow-y: auto;
1771
+ `;
1772
+ export const ColumnVisibilityItem = styled.label `
1773
+ display: flex;
1774
+ align-items: center;
1775
+ gap: 8px;
1776
+ padding: 8px 12px;
1777
+ font-size: 13px;
1778
+ color: ${({ $theme }) => $theme.textColor};
1779
+ cursor: pointer;
1780
+ transition: background-color 0.1s ease;
1781
+
1782
+ &:hover {
1783
+ background: ${({ $theme }) => $theme.hoverRowBackgroundColor};
1784
+ }
1785
+
1786
+ input {
1787
+ margin: 0;
1788
+ accent-color: ${({ $theme }) => $theme.accentColor};
1789
+ }
1790
+ `;
1791
+ // ============================================================================
1792
+ // Export all themes
1793
+ // ============================================================================
1794
+ export { themes };