@ninebone/datagrid 0.0.0-stage → 0.0.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.
@@ -0,0 +1,1713 @@
1
+
2
+ cell-button {
3
+ --cell-button-border: 1px solid #d1d5db;
4
+ --cell-button-color: #1f2937;
5
+ --cell-button-background: #f3f4f6;
6
+
7
+ --cell-button-hover-border: 1px solid #d1d5db;
8
+ --cell-button-hover-color: #1f2937;
9
+ --cell-button-hover-background: #f3f4f6;
10
+ --cell-button-active-border: 1px solid #d1d5db;
11
+ --cell-button-active-color: #1f2937;
12
+ --cell-button-active-background: #f3f4f6;
13
+
14
+ display: block;
15
+ position: absolute;
16
+ inset: 0; /* top: 0, right: 0, bottom: 0, left: 0 */
17
+ padding: 3px 4px;
18
+
19
+ button {
20
+ width: 100%;
21
+ display: inline-flex;
22
+ align-items: center;
23
+ justify-content: center;
24
+ border-radius: 4px;
25
+ border: var(--cell-button-border);
26
+ color: var(--cell-button-color);
27
+ background: var(--cell-button-background);
28
+ text-overflow: ellipsis;
29
+ white-space: nowrap;
30
+ overflow: hidden;
31
+ }
32
+ button:hover {
33
+ border: var(--cell-button-hover-border);
34
+ color: var(--cell-button-hover-color);
35
+ background: var(--cell-button-hover-background);
36
+ }
37
+ button:active {
38
+ border: var(--cell-button-active-border);
39
+ color: var(--cell-button-active-color);
40
+ background: var(--cell-button-active-background);
41
+ }
42
+ }
43
+
44
+ cell-checkbox {
45
+ display: flex;
46
+ align-items: center;
47
+ width: 100%;
48
+ height: 100%;
49
+
50
+ label {
51
+ display: inline-flex;
52
+ align-items: center;
53
+ user-select: none;
54
+ }
55
+ input[type="checkbox"] {
56
+ margin-left: 4px;
57
+ margin-right: 4px;
58
+ }
59
+ }
60
+
61
+
62
+ .CELL-CHECKBOX {
63
+ cell-checkbox {
64
+ justify-content: center;
65
+ }
66
+ label {
67
+ display: flex;
68
+ }
69
+ input {
70
+ background-color: #ffffff;
71
+ }
72
+ }
73
+ .CELL-CHECKBOX[text-align='left'] {
74
+ cell-checkbox {
75
+ justify-content: flex-start;
76
+ }
77
+ }
78
+ .CELL-CHECKBOX[text-align='center'] {
79
+ cell-checkbox {
80
+ justify-content: center;
81
+ }
82
+ }
83
+ .CELL-CHECKBOX[text-align='right'] {
84
+ cell-checkbox {
85
+ justify-content: flex-end;
86
+ }
87
+ label {
88
+ flex-direction: row-reverse;
89
+ }
90
+ }
91
+
92
+
93
+ cell-combo {
94
+ --cell-combo-button-border-color: #eee;
95
+ --cell-combo-button-bg-color: #f9f9f9;
96
+
97
+ button.btn1 {
98
+ width: calc(100% - 24px);
99
+ border: 1px solid var(--cell-combo-button-border-color);
100
+ border-right: none;
101
+ border-top-left-radius: 3px;
102
+ border-bottom-left-radius: 3px;
103
+ text-align: left;
104
+ background-color: white;
105
+ overflow: hidden;
106
+ text-overflow: ellipsis;
107
+ white-space: nowrap;
108
+ padding: 0 4px;
109
+ color: #000;
110
+ }
111
+ button.btn2 {
112
+ padding: 3px;
113
+ width: 24px;
114
+ border: 1px solid var(--cell-combo-button-border-color);
115
+ border-top-right-radius: 3px;
116
+ border-bottom-right-radius: 3px;
117
+ background-color: var(--cell-combo-button-bg-color);
118
+ display: flex;
119
+ align-items: center;
120
+ justify-content: center;
121
+ color: #333;
122
+ }
123
+ button.btn2:after {
124
+ content: "";
125
+ border-top: 0.3em solid;
126
+ border-right: 0.3em solid transparent;
127
+ border-bottom: 0;
128
+ border-left: 0.3em solid transparent;
129
+ }
130
+ }
131
+
132
+
133
+
134
+ cell-combo-panel {
135
+ z-index: 2;
136
+ position: absolute;
137
+ width: 250px;
138
+ height: 250px;
139
+ border: 1px solid #999;
140
+ background-color: white;
141
+ overflow: hidden;
142
+ box-shadow: 0 4px 12px rgba(0,0,0,0.15);
143
+ display: none;
144
+ flex-direction: column;
145
+ padding: 0;
146
+ margin: 0;
147
+ resize: both;
148
+
149
+ .head {
150
+ display: none;
151
+ padding: 6px;
152
+ background: #f8f9fa;
153
+ border-bottom: 1px solid #e5e7eb;
154
+
155
+ input[type="text"] {
156
+ width: 100%;
157
+ height: 26px;
158
+ padding: 0 6px;
159
+ border: 1px solid #d1d5db;
160
+ border-radius: 3px;
161
+ }
162
+ }
163
+
164
+ .footer {
165
+ display: none;
166
+ height: 32px;
167
+ background: #f3f4f6;
168
+ border-top: 1px solid #e5e7eb;
169
+ align-items: center;
170
+ padding: 0 8px;
171
+
172
+ label {
173
+ user-select: none;
174
+ }
175
+
176
+ button {
177
+ height: 22px;
178
+ padding: 0 12px;
179
+ background: #2563eb;
180
+ color: white;
181
+ border: none;
182
+ border-radius: 3px;
183
+ }
184
+
185
+ button:hover {
186
+ background: #1d4ed8;
187
+ }
188
+ }
189
+
190
+ nine-table-simple {
191
+ width: 100%;
192
+ flex: 1;
193
+ border: none;
194
+ }
195
+ }
196
+
197
+
198
+
199
+ cell-combo-panel.active {
200
+ display: flex;
201
+ }
202
+
203
+ cell-combo-panel.expand {
204
+ .head {
205
+ display: flex;
206
+ }
207
+ }
208
+
209
+ cell-combo-panel.multi {
210
+ .footer {
211
+ display: flex;
212
+ justify-content: space-between;
213
+ }
214
+ }
215
+
216
+
217
+
218
+ cell-combo-panel.loading {
219
+ nine-table-simple {
220
+ visibility: hidden;
221
+ }
222
+ }
223
+ cell-combo-panel.loading::after {
224
+ content: "";
225
+ position: absolute;
226
+ inset: 0;
227
+ background: rgba(255, 255, 255, 0.3);
228
+ z-index: 10;
229
+ display: flex;
230
+ align-items: center;
231
+ justify-content: center;
232
+ }
233
+ cell-combo-panel.loading::before {
234
+ content: "";
235
+ position: absolute;
236
+ top: 50%;
237
+ left: 50%;
238
+ width: 24px;
239
+ height: 24px;
240
+ margin: -12px 0 0 -12px;
241
+ border: 3px solid #e5e7eb;
242
+ border-top-color: #2563eb;
243
+ border-radius: 50%;
244
+ animation: combo-loading-spin 0.6s linear infinite;
245
+ z-index: 999999911;
246
+ }
247
+ @keyframes combo-loading-spin {
248
+ to {
249
+ transform: rotate(360deg);
250
+ }
251
+ }
252
+
253
+ :host {
254
+ --cell-input-border-color: #eee;
255
+ --cell-input-bg: #fff;
256
+ --cell-input-color: #333;
257
+ --cell-input-readonly-bg: #fdfdfd;
258
+ --cell-input-btn-bg: #f9f9f9;
259
+ }
260
+
261
+ cell-input {
262
+ input {
263
+ position: relative;
264
+ user-select: auto;
265
+ width: 100%;
266
+ border: 1px solid var(--cell-input-border-color);
267
+ padding-left: 4px;
268
+ background: var(--cell-input-bg);
269
+ color: var(--cell-input-color);
270
+ }
271
+
272
+ input:read-only {
273
+ border-color: var(--cell-input-readonly-bg);
274
+ filter: brightness(97%);
275
+ }
276
+ }
277
+
278
+ cell-input-color {
279
+
280
+ input[type=color] {
281
+ width: 100%;
282
+ padding: 0px;
283
+ margin-left: unset;
284
+ border: 1px solid var(--cell-input-border-color);
285
+ border-right: none;
286
+ -webkit-appearance: none;
287
+ -moz-appearance: none;
288
+ appearance: none;
289
+ background-color: transparent;
290
+ }
291
+
292
+ input[type=color]::-webkit-color-swatch {
293
+ border: 0;
294
+ }
295
+
296
+ input[type=color]::-webkit-color-swatch-wrapper {
297
+ padding: 1px;
298
+ }
299
+
300
+ button {
301
+ display: inline-flex;
302
+ width: 24px;
303
+ margin-right: unset;
304
+ border: 1px solid var(--cell-input-border-color);
305
+ background-color: var(--cell-input-btn-bg);
306
+ justify-content: center;
307
+ align-items: center;
308
+ }
309
+
310
+ button:after {
311
+ content: "";
312
+ border-top: 0.3em solid var(--cell-input-color);
313
+ border-right: 0.3em solid transparent;
314
+ border-bottom: 0;
315
+ border-left: 0.3em solid transparent;
316
+ }
317
+
318
+ input[type=color]:hover, button:hover {
319
+ filter: brightness(95%);
320
+ }
321
+ }
322
+
323
+ cell-input-date {
324
+
325
+ input {
326
+ position: relative;
327
+ margin: 0;
328
+ width: 100%;
329
+ padding: 0 4px;
330
+ border: 1px solid var(--cell-input-border-color);
331
+ background: var(--cell-input-bg);
332
+ -webkit-appearance: none;
333
+ -moz-appearance: none;
334
+ appearance: none;
335
+ background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="black" viewBox="0 0 24 24"><path d="M7 10l5 5 5-5z"/></svg>');
336
+ background-repeat: no-repeat;
337
+ background-position: right 4px center;
338
+ background-size: 14px 16px;
339
+ color: var(--cell-input-color);
340
+ }
341
+
342
+ input:hover {
343
+ filter: brightness(95%);
344
+ }
345
+
346
+ input::before {
347
+ content: attr(data-placeholder);
348
+ position: absolute;
349
+ display: flex;
350
+ align-items: center;
351
+ width: calc(100% - 22px);
352
+ height: 100%;
353
+ left: 1px;
354
+ top: 1px;
355
+ pointer-events: none;
356
+ }
357
+
358
+ input.has-value::before, input:focus::before {
359
+ display: none;
360
+ }
361
+
362
+ input:focus {
363
+
364
+ }
365
+ }
366
+
367
+ cell-input-number {
368
+ input.border-left-none {
369
+ border-left: 0;
370
+ border-top-left-radius: 0;
371
+ border-bottom-left-radius: 0;
372
+ }
373
+ input.border-right-none {
374
+ border-right: 0;
375
+ border-top-right-radius: 0;
376
+ border-bottom-right-radius: 0;
377
+ }
378
+
379
+ input {
380
+ position: relative;
381
+ user-select: auto;
382
+ width: 100%;
383
+ border: 1px solid var(--cell-input-border-color);
384
+ background: var(--cell-input-bg);
385
+ color: var(--cell-input-color);
386
+ text-align: right;
387
+ }
388
+
389
+ input:read-only {
390
+ border-color: var(--cell-input-readonly-bg);
391
+ filter: brightness(97%);
392
+ }
393
+ }
394
+ cell-radio {
395
+ height: 100%;
396
+ width: calc(100% - 8px);
397
+ display: flex;
398
+ align-items: center;
399
+ margin-left: 4px;
400
+ margin-right: 4px;
401
+
402
+ div {
403
+ display: flex;
404
+ flex-direction: row;
405
+ }
406
+
407
+ label {
408
+ display: flex;
409
+ align-items: center;
410
+ margin-right: 8px;
411
+ user-select: none;
412
+ }
413
+
414
+ label.disabled {
415
+ pointer-events: none;
416
+ opacity: 0.5;
417
+ }
418
+
419
+ span {
420
+ margin-left: 4px;
421
+ }
422
+ }
423
+
424
+ .CELL-RADIO[text-align='left'] {
425
+ cell-radio {
426
+ justify-content: flex-start;
427
+ }
428
+ }
429
+ .CELL-RADIO[text-align='center'] {
430
+ cell-radio {
431
+ justify-content: center;
432
+ }
433
+ }
434
+ .CELL-RADIO[text-align='right'] {
435
+ cell-radio {
436
+ justify-content: flex-end;
437
+ }
438
+ }
439
+
440
+
441
+
442
+
443
+
444
+ cell-renderer { /* Custom element host layout */
445
+ display: block;
446
+ span.wrapper {
447
+ display: block;
448
+ width: 100%;
449
+ overflow: hidden;
450
+ text-overflow: ellipsis;
451
+ white-space: nowrap; /* 줄바꿈 방지 */
452
+ }
453
+ }
454
+
455
+ .CELL-RENDERER { /* Parent cell hook */
456
+ text-align: left;
457
+ }
458
+ .CELL-RENDERER[text-align="center"] {
459
+ text-align: center;
460
+ }
461
+ .CELL-RENDERER[text-align="right"] {
462
+ text-align: right;
463
+ }
464
+ cell-row-indicator {
465
+ --row-indicator-prefix-size: 0.40rem;
466
+ --row-indicator-suffix-size: 0.55rem;
467
+ --row-indicator-sub-size: 0.40rem;
468
+ --row-indicator-sub-opacity: 0.2;
469
+ --row-indicator-status-size: 0.55rem;
470
+
471
+ display: block;
472
+ position: absolute; /* 💡 셀 전체를 강제로 꽉 채움 */
473
+ top: 0;
474
+ left: 0;
475
+ right: 0;
476
+ bottom: 0;
477
+ user-select: none;
478
+
479
+ .ng-row-main {
480
+ display: flex;
481
+ align-items: center;
482
+ justify-content: center;
483
+ width: 100%;
484
+ height: 100%;
485
+ text-align: center;
486
+ overflow: hidden;
487
+ font-size: 10px;
488
+ }
489
+
490
+ .ng-row-prefix {
491
+ font-weight: normal;
492
+ font-size: var(--row-indicator-prefix-size);
493
+ }
494
+
495
+ .ng-row-suffix {
496
+ font-size: var(--row-indicator-suffix-size);
497
+ }
498
+
499
+ .ng-row-sub {
500
+ position: absolute;
501
+ right: 2px;
502
+ bottom: 1px;
503
+ font-size: var(--row-indicator-sub-size);
504
+ line-height: 1;
505
+ opacity: var(--row-indicator-sub-opacity);
506
+ pointer-events: none;
507
+ }
508
+
509
+ .ng-row-status {
510
+ position: absolute;
511
+ right: 2px;
512
+ top: 1px;
513
+ font-size: var(--row-indicator-status-size);
514
+ line-height: 1;
515
+ pointer-events: none;
516
+ }
517
+ }
518
+ :host {
519
+ --cell-selection-bg: rgba(37, 99, 235, 0.08);
520
+ --cell-selection-border-color: #2563eb;
521
+ }
522
+
523
+ tbody {
524
+ .selected {
525
+ background-color: var(--cell-selection-bg);
526
+ }
527
+
528
+ .selected-start {
529
+ background-color: transparent;
530
+ }
531
+
532
+ .selected-top { border-top: 2px solid var(--cell-selection-border-color); }
533
+ .selected-bottom { border-bottom: 2px solid var(--cell-selection-border-color); }
534
+ .selected-left { border-left: 2px solid var(--cell-selection-border-color); }
535
+ .selected-right { border-right: 2px solid var(--cell-selection-border-color); }
536
+ }
537
+ nine-table-col-expand {
538
+ position: absolute;
539
+ right: 2px;
540
+ top: 2px;
541
+ width: 12px;
542
+ height: 12px;
543
+ background-repeat: no-repeat;
544
+ background-position: center;
545
+ background-size: contain;
546
+ z-index: 2;
547
+ pointer-events: auto;
548
+ background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="%234b5563" viewBox="0 0 16 16"><path fill-rule="evenodd" d="M6 8a.5.5 0 0 0 .5.5h5.793l-2.147 2.146a.5.5 0 0 0 .708.708l3-3a.5.5 0 0 0 0-.708l-3-3a.5.5 0 0 0-.708.708L12.293 7.5H6.5A.5.5 0 0 0 6 8m-2.5 7a.5.5 0 0 1-.5-.5v-13a.5.5 0 0 1 1 0v13a.5.5 0 0 1-.5.5"/></svg>');
549
+ }
550
+
551
+ nine-table-col-expand.expand {
552
+ right: 2px;
553
+ background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="%234b5563" viewBox="0 0 16 16"><path fill-rule="evenodd" d="M12.5 15a.5.5 0 0 1-.5-.5v-13a.5.5 0 0 1 1 0v13a.5.5 0 0 1-.5.5M10 8a.5.5 0 0 1-.5.5H3.707l2.147 2.146a.5.5 0 0 1-.708.708l-3-3a.5.5 0 0 1 0-.708l3-3a.5.5 0 1 1 .708.708L3.707 7.5H9.5a.5.5 0 0 1 .5.5"/></svg>');
554
+ }
555
+
556
+ nine-table-col-expand.collapsed {
557
+ left: 50%;
558
+ right: auto;
559
+ transform: translate(-50%, 0);
560
+ }
561
+
562
+
563
+ tr.col-indicator-rowgroup {
564
+ th,td {
565
+ padding: 0;
566
+ }
567
+ }
568
+
569
+ .col-indicator-rowgroup.expand {
570
+ height: 20px;
571
+ }
572
+ .col-indicator-rowgroup.collapse {
573
+ height: 2px;
574
+ }
575
+ .col-indicator-rowgroup.expand th {
576
+ background-color: #eee;
577
+ border-right-color: #ccc;
578
+ border-top: 2px solid #666;
579
+ }
580
+ .col-indicator-rowgroup.collapse th {
581
+ background-color: #666;
582
+ border: none;
583
+ }
584
+ .col-indicator-rowgroup.collapse div {
585
+ display: unset;
586
+ }
587
+ .col-indicator-rowgroup.collapse div {
588
+ display: none;
589
+ }
590
+ .ng-col-mover-indi {
591
+ position: absolute;
592
+ width: 2px;
593
+ background-color: #2563eb;
594
+ display: none;
595
+ pointer-events: none;
596
+ z-index: 10020;
597
+ }
598
+
599
+ .ng-col-mover-indi::before {
600
+ content: '';
601
+ position: absolute;
602
+ top: -6px;
603
+ left: -4px;
604
+ width: 0;
605
+ height: 0;
606
+ border-top: 6px solid #2563eb;
607
+ border-left: 5px solid transparent;
608
+ border-right: 5px solid transparent;
609
+ }
610
+
611
+ .ng-col-mover-indi::after {
612
+ content: '';
613
+ position: absolute;
614
+ bottom: -6px;
615
+ left: -4px;
616
+ width: 0;
617
+ height: 0;
618
+ border-bottom: 6px solid #2563eb;
619
+ border-left: 5px solid transparent;
620
+ border-right: 5px solid transparent;
621
+ }
622
+
623
+ .ng-col-mover-grip {
624
+ position: absolute;
625
+ display: none;
626
+ pointer-events: none;
627
+ z-index: 10010;
628
+ background-color: rgba(37, 99, 235, 0.12);
629
+ border: none;
630
+ box-shadow: 0 4px 12px rgba(37, 99, 235, 0.15);
631
+ overflow: hidden;
632
+ backdrop-filter: blur(1px);
633
+ transition: background-color 0.15s ease, border-color 0.15s ease;
634
+
635
+ .grip-header-content {
636
+ position: absolute;
637
+ top: 0;
638
+ left: 0;
639
+ width: 100%;
640
+ z-index: 2;
641
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
642
+ }
643
+
644
+ th, td {
645
+ user-select: none;
646
+ pointer-events: none;
647
+ }
648
+ }
649
+
650
+
651
+ .ng-col-mover-grip.invalid {
652
+ background-color: rgba(239, 68, 68, 0.12);
653
+ box-shadow: 0 4px 12px rgba(239, 68, 68, 0.15);
654
+
655
+ .grip-header-content {
656
+ border-bottom: 2px solid #ef4444;
657
+ }
658
+ }
659
+
660
+
661
+ thead {
662
+ .resizable-edge {
663
+ cursor: col-resize;
664
+ }
665
+ }
666
+
667
+ nine-table-col-resizer-panel {
668
+ --col-resizer-color: #2563eb;
669
+ --col-resizer-bg: rgba(37, 99, 235, 0.12);
670
+ --col-resizer-badge-bg: #1e40af;
671
+ --col-resizer-badge-color: #ffffff;
672
+
673
+ --col-resizer-tooltip-left: 0px;
674
+ --col-resizer-tooltip-width: 0px;
675
+
676
+ display: none;
677
+ position: absolute;
678
+ top: 0;
679
+ left: 0;
680
+ width: 100%;
681
+ height: 100%;
682
+ pointer-events: none;
683
+ z-index: 9999;
684
+
685
+ .resizer-overlay {
686
+ position: absolute;
687
+ top: 0;
688
+ left: var(--col-resizer-tooltip-left, 0px);
689
+ width: var(--col-resizer-tooltip-width, 0px);
690
+ height: 100%;
691
+ background-color: var(--col-resizer-bg);
692
+ border-left: 1px dashed var(--col-resizer-color);
693
+ border-right: 2px solid var(--col-resizer-color);
694
+ display: flex;
695
+ align-items: flex-start;
696
+ justify-content: center;
697
+ padding-top: 8px;
698
+ pointer-events: none;
699
+ opacity: 1;
700
+ transition: opacity 0.15s ease-out;
701
+
702
+ .size-badge {
703
+ padding: 2px 8px;
704
+ font-size: 11px;
705
+ font-weight: 700;
706
+ color: var(--col-resizer-badge-color);
707
+ background-color: var(--col-resizer-badge-bg);
708
+ border-radius: 4px;
709
+ line-height: 14px;
710
+ white-space: nowrap;
711
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
712
+ }
713
+ }
714
+
715
+ .resizer-overlay.fade-out {
716
+ opacity: 0;
717
+ }
718
+ }
719
+
720
+ nine-table-col-resizer-panel.active {
721
+ display: block;
722
+ }
723
+
724
+
725
+ nine-table-filter-button {
726
+ position: absolute;
727
+ bottom: 2px;
728
+ right: 2px;
729
+ width: 12px;
730
+ height: 12px;
731
+ z-index: 2;
732
+ cursor: pointer;
733
+ background-repeat: no-repeat;
734
+ background-position: center;
735
+ background-size: contain;
736
+ display: inline-block;
737
+ background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 16 16"><path fill="%239ca3af" d="M1.5 1.5A.5.5 0 0 1 2 1h12a.5.5 0 0 1 .5.5v2a.5.5 0 0 1-.128.334L10 8.692V13.5a.5.5 0 0 1-.342.474l-3 1A.5.5 0 0 1 6 14.5V8.692L1.628 3.834A.5.5 0 0 1 1.5 3.5zm1 .5v1.308l4.372 4.858A.5.5 0 0 1 7 8.5v5.306l2-.666V8.5a.5.5 0 0 1 .128-.334L13.5 3.308V2z"/></svg>');
738
+ }
739
+
740
+ nine-table-filter-button.filtered {
741
+ background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 16 16"><path fill="%232563eb" d="M1.5 1.5A.5.5 0 0 1 2 1h12a.5.5 0 0 1 .5.5v2a.5.5 0 0 1-.128.334L10 8.692V13.5a.5.5 0 0 1-.342.474l-3 1A.5.5 0 0 1 6 14.5V8.692L1.628 3.834A.5.5 0 0 1 1.5 3.5z"/></svg>');
742
+ }
743
+
744
+
745
+ nine-table-filter-panel {
746
+ z-index: 2;
747
+ position: absolute;
748
+ width: 250px;
749
+ height: 250px;
750
+ border: 1px solid #999;
751
+ background-color: white;
752
+ overflow: hidden;
753
+ box-shadow: 0 4px 12px rgba(0,0,0,0.15);
754
+ display: none;
755
+ flex-direction: column;
756
+ padding: 0;
757
+ margin: 0;
758
+ font-size: 12px;
759
+ resize: both;
760
+
761
+ nine-table-simple {
762
+ width: 100%;
763
+ flex: 1;
764
+ border: none;
765
+ }
766
+
767
+ .search-box {
768
+ width: 100%;
769
+ height: 28px;
770
+ box-sizing: border-box;
771
+ padding: 0px 8px;
772
+ border: none;
773
+ border-bottom: 1px solid #e5e7eb;
774
+ border-radius: 0px;
775
+ outline: none;
776
+ font-size: 12px;
777
+ background: #fafafa;
778
+ color: #333;
779
+ }
780
+ .search-box:focus {
781
+ background: #ffffff;
782
+ }
783
+ .footer-section {
784
+ display: flex;
785
+ flex-direction: column;
786
+ padding: 4px 6px;
787
+ gap: 8px;
788
+ border-top: 1px solid #e5e7eb;
789
+ background: #f9fafb;
790
+ flex-shrink: 0;
791
+ }
792
+ .footer-btns {
793
+ display: flex;
794
+ align-items: center;
795
+ justify-content: space-between;
796
+ gap: 6px;
797
+ }
798
+ .footer-btns label {
799
+ display: flex;
800
+ align-items: center;
801
+ gap: 4px;
802
+ cursor: pointer;
803
+ user-select: none;
804
+ }
805
+ .btn-group {
806
+ display: flex;
807
+ gap: 4px;
808
+ }
809
+ button {
810
+ padding: 4px 14px;
811
+ border-radius: 4px;
812
+ border: 1px solid #d1d5db;
813
+ background: #ffffff;
814
+ cursor: pointer;
815
+ font-size: 11px;
816
+ }
817
+ button:hover {
818
+ background: #f3f4f6;
819
+ }
820
+ button#btnOk {
821
+ background: #2563eb;
822
+ color: white;
823
+ border: none;
824
+ }
825
+ }
826
+ nine-table-filter-panel.active {
827
+ display: flex;
828
+ }
829
+
830
+ nine-table-filter-panel.loading {
831
+ nine-table-simple {
832
+ visibility: hidden;
833
+ }
834
+ }
835
+ nine-table-filter-panel.loading::after {
836
+ content: "";
837
+ position: absolute;
838
+ inset: 0;
839
+ background: rgba(255, 255, 255, 0.3);
840
+ z-index: 10;
841
+ display: flex;
842
+ align-items: center;
843
+ justify-content: center;
844
+ }
845
+ nine-table-filter-panel.loading::before {
846
+ content: "";
847
+ position: absolute;
848
+ top: 50%;
849
+ left: 50%;
850
+ width: 24px;
851
+ height: 24px;
852
+ margin: -12px 0 0 -12px;
853
+ border: 3px solid #e5e7eb;
854
+ border-top-color: #2563eb;
855
+ border-radius: 50%;
856
+ animation: filter-loading-spin 0.6s linear infinite;
857
+ z-index: 999999911;
858
+ }
859
+
860
+ @keyframes filter-loading-spin {
861
+ to {
862
+ transform: rotate(360deg);
863
+ }
864
+ }
865
+ :host {
866
+ width: 100%;
867
+ height: 100%;
868
+ }
869
+
870
+
871
+ :host {
872
+ display: flex;
873
+ flex-direction: column;
874
+ position: relative;
875
+ overflow: hidden;
876
+
877
+ background: #fff;
878
+ }
879
+
880
+ :host([theme="simple"]) {
881
+ /* 1. 불필요한 패널 및 컴포넌트 숨기기 */
882
+ .ng-part-header, .ng-part-footer,
883
+ nine-table-toolbar,
884
+ nine-table-sheets-footer,
885
+ nine-table-vscrollbar,
886
+ nine-table-hscrollbar,
887
+ nine-table-sheet .ng-scroll-edge {
888
+ display: none;
889
+ }
890
+
891
+ .col-indicator-rowgroup {
892
+ display: none;
893
+ }
894
+
895
+ tr {
896
+ height: 32px;
897
+ }
898
+
899
+ /* 2. 💡 [핵심] 스크롤바용 우측 16px 빈 공간을 제거하고 1열(1fr)로 꽉 채우기 */
900
+ nine-table-sheet {
901
+ border: none;
902
+ overflow: hidden;
903
+ grid-template-columns: 1fr;
904
+ grid-template-rows: 1fr;
905
+ }
906
+
907
+ nine-table-sheet tr th,
908
+ nine-table-sheet tr td {
909
+ border: none;
910
+ padding: 0 8px;
911
+ }
912
+
913
+ /**
914
+ nine-table-sheet tr td {
915
+ text-align: left;
916
+ } */
917
+
918
+ /* 4. 브라우저 기본 네이티브 스크롤바를 콘텐츠 위에 자연스럽게 오버레이(Overlay) */
919
+ nine-table-sheet .ng-sheet-body {
920
+ overflow-y: auto;
921
+ overflow-x: hidden;
922
+ scrollbar-width: thin;
923
+ scrollbar-color: rgba(0, 0, 0, 0.2) transparent;
924
+ }
925
+
926
+ nine-table-sheet .ng-sheet-body::-webkit-scrollbar {
927
+ display: block;
928
+ width: 6px;
929
+ height: 6px;
930
+ }
931
+
932
+ nine-table-sheet .ng-sheet-body::-webkit-scrollbar-track {
933
+ background: transparent;
934
+ }
935
+
936
+ nine-table-sheet .ng-sheet-body::-webkit-scrollbar-thumb {
937
+ background: rgba(0, 0, 0, 0.15);
938
+ border-radius: 3px;
939
+ }
940
+
941
+ nine-table-sheet .ng-sheet-body::-webkit-scrollbar-thumb:hover {
942
+ background: rgba(0, 0, 0, 0.3);
943
+ }
944
+ }
945
+
946
+ /* 🎯 Toolbar 숨김 제어 */
947
+ :host([theme="simple"]) nine-table-toolbar,
948
+ :host([show-header="false"]) nine-table-toolbar {
949
+ display: none;
950
+ }
951
+
952
+ /* 🎯 Footer(StatusBar) 숨김 제어 (show-statusbar="false") */
953
+ :host([theme="simple"]) nine-table-sheets-footer,
954
+ :host([show-statusbar="false"]) nine-table-sheets-footer {
955
+ display: none;
956
+ }
957
+
958
+ :host([theme="simple"]) {
959
+ col[data-col="0"], th[data-col="0"], td[data-col="0"] {
960
+ display: none;
961
+ }
962
+ .ng-container-right {
963
+ display: none;
964
+ }
965
+ tr {
966
+ height: 26px;
967
+ }
968
+ }
969
+
970
+ :host(.loading) {
971
+ .ng-loading-bar {
972
+ display: block;
973
+ }
974
+ }
975
+
976
+
977
+ .ng-loading-bar {
978
+ position: absolute;
979
+ top: 0;
980
+ left: 0;
981
+ right: 0;
982
+ height: 2px;
983
+ background: rgba(255, 255, 255, 0.08); /* 은은한 화이트 트랙 배경 */
984
+ z-index: 10000;
985
+ display: none;
986
+ overflow: hidden;
987
+ }
988
+
989
+ /* 🎯 아주 좁고 쨍한 빛 조각 형태로 압축 */
990
+ .ng-loading-bar::after {
991
+ content: '';
992
+ position: absolute;
993
+ top: 0;
994
+ left: 0;
995
+ bottom: 0;
996
+ width: 12%; /* 바의 전체 길이를 12%로 대폭 축소 */
997
+ background: linear-gradient(
998
+ 90deg,
999
+ transparent 0%,
1000
+ rgba(255, 255, 255, 0.4) 20%,
1001
+ #ffffff 50%,
1002
+ rgba(255, 255, 255, 0.4) 80%,
1003
+ transparent 100%
1004
+ );
1005
+ box-shadow: 0 0 10px rgba(255, 255, 255, 0.9);
1006
+ animation: ng-loading-slide 0.9s ease-in-out infinite;
1007
+ }
1008
+
1009
+ @keyframes ng-loading-slide {
1010
+ 0% {
1011
+ transform: translateX(-150%);
1012
+ }
1013
+ 100% {
1014
+ transform: translateX(850%); /* 폭이 좁아진 만큼 이동 거리 확장 */
1015
+ }
1016
+ }
1017
+
1018
+ input[type="checkbox"] {
1019
+ appearance: none;
1020
+ -webkit-appearance: none;
1021
+ width: 14px;
1022
+ height: 14px;
1023
+ background-color: #ffffff; /* 미체크 시 배경 */
1024
+ border: 1px solid #9ca3af;
1025
+ border-radius: 3px;
1026
+ margin: 0;
1027
+ display: inline-flex;
1028
+ align-items: center;
1029
+ justify-content: center;
1030
+ transition: background-color 0.15s ease, border-color 0.15s ease;
1031
+ }
1032
+ input[type="checkbox"]:checked {
1033
+ background-color: #2563eb; /* 체크 시 파란색 배경 */
1034
+ border-color: #2563eb;
1035
+ background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="10" height="10" viewBox="0 0 24 24" fill="none" stroke="white" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"><polyline points="20 6 9 17 4 12"></polyline></svg>');
1036
+ background-repeat: no-repeat;
1037
+ background-position: center;
1038
+ }
1039
+
1040
+ input[type="radio"] {
1041
+ appearance: none;
1042
+ -webkit-appearance: none;
1043
+ width: 14px;
1044
+ height: 14px;
1045
+ background-color: #ffffff;
1046
+ border: 1px solid #9ca3af;
1047
+ border-radius: 50%;
1048
+ margin: 0;
1049
+ display: inline-flex;
1050
+ align-items: center;
1051
+ justify-content: center;
1052
+ }
1053
+
1054
+ input[type="radio"]:checked {
1055
+ background-image: url('data:image/svg+xml;utf8,<svg height="14" width="14" xmlns="http://www.w3.org/2000/svg"><circle r="3.5" cx="50%" cy="50%" fill="%232563eb" /></svg>');
1056
+ background-repeat: no-repeat;
1057
+ background-position: center;
1058
+ }
1059
+ * {
1060
+ outline: none;
1061
+ box-sizing: border-box;
1062
+ cursor: default;
1063
+ font-size: 12px;
1064
+ }
1065
+
1066
+ nine-table-body { display: flex; flex-direction: row; flex: 1; overflow: hidden; position: relative; }
1067
+ nine-table-summary { display: none; width: 250px; flex-shrink: 0; border-right: 1px solid #e5e7eb; }
1068
+ nine-table-analysis { display: none; }
1069
+ nine-table-footer { display: none; }
1070
+
1071
+ nine-table-sheets {
1072
+ flex: 1;
1073
+ display: flex;
1074
+ flex-direction: column;
1075
+ overflow: hidden;
1076
+ position: relative;
1077
+ background: #fff;
1078
+
1079
+ nine-table-sheets-body {
1080
+ flex: 1;
1081
+ overflow: hidden;
1082
+ position: relative;
1083
+ display: flex;
1084
+ flex-direction: row;
1085
+ }
1086
+ }
1087
+
1088
+ cell-input, cell-input-number, cell-button, cell-input-color, cell-input-date, cell-combo {
1089
+ position: absolute;
1090
+ inset: 0;
1091
+ padding: 2px 4px;
1092
+ display: flex;
1093
+
1094
+ input, button {
1095
+ height: 100%;
1096
+ }
1097
+ }
1098
+
1099
+
1100
+ .empty-value {
1101
+ color: #999;
1102
+ }
1103
+
1104
+
1105
+ nine-table-menu-panel {
1106
+ .menu-wrapper {
1107
+ background: #ffffff;
1108
+ border: 1px solid #d1d5db;
1109
+ box-shadow: 0 4px 12px rgba(0,0,0,0.15);
1110
+ border-radius: 4px;
1111
+ padding: 4px 0;
1112
+ min-width: 150px;
1113
+ }
1114
+
1115
+ ul {
1116
+ list-style: none;
1117
+ margin: 0;
1118
+ padding: 0;
1119
+ }
1120
+
1121
+ li {
1122
+ position: relative;
1123
+ padding: 6px 16px;
1124
+ color: #374151;
1125
+ display: flex;
1126
+ align-items: center;
1127
+ justify-content: space-between;
1128
+ }
1129
+
1130
+ li:hover {
1131
+ background-color: #f3f4f6;
1132
+ color: #111827;
1133
+ }
1134
+
1135
+ li.on::before {
1136
+ content: '✓';
1137
+ position: absolute;
1138
+ left: 4px;
1139
+ font-weight: bold;
1140
+ }
1141
+
1142
+ li.disabled {
1143
+ opacity: 0.5;
1144
+ cursor: not-allowed;
1145
+ background: transparent !important;
1146
+ }
1147
+
1148
+ li.ng-menu-separator {
1149
+ height: 1px;
1150
+ background: #e5e7eb;
1151
+ margin: 4px 0;
1152
+ padding: 0;
1153
+ }
1154
+
1155
+ li.submenu::after {
1156
+ content: '▶';
1157
+ font-size: 9px;
1158
+ margin-left: 8px;
1159
+ color: #9ca3af;
1160
+ }
1161
+
1162
+ .ng-menu-sublist {
1163
+ display: none;
1164
+ position: absolute;
1165
+ top: -4px;
1166
+ left: 100%;
1167
+ background: #ffffff;
1168
+ border: 1px solid #d1d5db;
1169
+ box-shadow: 0 4px 12px rgba(0,0,0,0.15);
1170
+ border-radius: 4px;
1171
+ padding: 4px 0;
1172
+ min-width: 140px;
1173
+ }
1174
+
1175
+ li.submenu:hover > .ng-menu-sublist {
1176
+ display: block;
1177
+ }
1178
+ }
1179
+ :host {
1180
+ --hscrollbar-height: 16px;
1181
+ --vscrollbar-width: 16px;
1182
+ }
1183
+
1184
+ .scroll-edge {
1185
+ display: none; /* 평소에는 기본 숨김 */
1186
+ grid-row: 2;
1187
+ grid-column: 2;
1188
+ width: var(--vscrollbar-width);
1189
+ height: var(--hscrollbar-height);
1190
+ background: #f3f4f6;
1191
+ border-top: 1px solid #e5e7eb;
1192
+ z-index: 10;
1193
+ }
1194
+
1195
+ nine-table-hscrollbar {
1196
+
1197
+ --hscrollbar-background: #f9fafb;
1198
+ --hscrollbar-border-top: 1px solid #e5e7eb;
1199
+ --hscrollbar-button-background: #f3f4f6;
1200
+ --hscrollbar-track-background: #f3f4f6;
1201
+ --hscrollbar-thumb-background: #9ca3af;
1202
+ --hscrollbar-thumb-hover-background: #6b7280;
1203
+
1204
+ display: none;
1205
+ grid-row: 2;
1206
+ grid-column: 1;
1207
+ flex-direction: row;
1208
+ height: var(--hscrollbar-height);
1209
+ min-height: var(--hscrollbar-height);
1210
+ background: var(--hscrollbar-background);
1211
+ border-top: var(--hscrollbar-border-top);
1212
+ z-index: 10;
1213
+ overflow: hidden;
1214
+ width: 100%;
1215
+ user-select: none;
1216
+ position: relative;
1217
+
1218
+ button {
1219
+ width: var(--hscrollbar-height);
1220
+ height: 100%;
1221
+ background: var(--hscrollbar-button-background);
1222
+ border: none;
1223
+ display: flex;
1224
+ align-items: center;
1225
+ justify-content: center;
1226
+ padding: 0;
1227
+ flex-shrink: 0;
1228
+ z-index: 2;
1229
+ }
1230
+ button:disabled {
1231
+ opacity: 0.4;
1232
+ }
1233
+
1234
+ .scroll-icon {
1235
+ width: 100%;
1236
+ height: 100%;
1237
+ background-repeat: no-repeat;
1238
+ background-position: center;
1239
+ }
1240
+
1241
+ .scroll-left .scroll-icon {
1242
+ background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="10" height="10" viewBox="0 0 16 16"><path fill="none" stroke="%236b7280" stroke-linecap="round" stroke-linejoin="round" stroke-width="2.5" d="M10 12L6 8l4-4"/></svg>');
1243
+ }
1244
+
1245
+ .scroll-right .scroll-icon {
1246
+ background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="10" height="10" viewBox="0 0 16 16"><path fill="none" stroke="%236b7280" stroke-linecap="round" stroke-linejoin="round" stroke-width="2.5" d="M6 4l4 4-4 4"/></svg>');
1247
+ }
1248
+
1249
+ .scroll-track {
1250
+ flex: 1;
1251
+ height: 100%;
1252
+ position: relative;
1253
+ background: var(--hscrollbar-track-background);
1254
+ overflow: hidden;
1255
+ }
1256
+ .scroll-thumb {
1257
+ position: absolute;
1258
+ top: 2px;
1259
+ bottom: 2px;
1260
+ left: 0px;
1261
+ background: var(--hscrollbar-thumb-background);
1262
+ border-radius: 4px;
1263
+ z-index: 1;
1264
+ }
1265
+ .scroll-thumb:hover {
1266
+ background: var(--hscrollbar-thumb-hover-background);
1267
+ }
1268
+ }
1269
+
1270
+ nine-table-vscrollbar {
1271
+
1272
+ --vscrollbar-background: #f9fafb;
1273
+ --vscrollbar-border-top: 2px solid #333;
1274
+ --vscrollbar-button-background: #f3f4f6;
1275
+ --vscrollbar-track-background: #f3f4f6;
1276
+ --vscrollbar-thumb-background: #9ca3af;
1277
+ --vscrollbar-thumb-hover-background: #6b7280;
1278
+
1279
+ display: none;
1280
+ border-top: var(--vscrollbar-border-top);
1281
+ grid-row: 1;
1282
+ grid-column: 2;
1283
+ width: var(--vscrollbar-width);
1284
+ height: 100%;
1285
+ z-index: 50;
1286
+ flex-direction: column;
1287
+ background: var(--vscrollbar-background);
1288
+ user-select: none;
1289
+ position: relative;
1290
+
1291
+ button {
1292
+ height: var(--vscrollbar-width);
1293
+ width: 100%;
1294
+ background: var(--vscrollbar-button-background);
1295
+ border: none;
1296
+ display: flex;
1297
+ align-items: center;
1298
+ justify-content: center;
1299
+ padding: 0;
1300
+ flex-shrink: 0;
1301
+ z-index: 2;
1302
+ }
1303
+ button:disabled {
1304
+ opacity: 0.4;
1305
+ }
1306
+
1307
+ .scroll-icon {
1308
+ width: 100%;
1309
+ height: 100%;
1310
+ background-repeat: no-repeat;
1311
+ background-position: center;
1312
+ }
1313
+
1314
+ .scroll-top .scroll-icon {
1315
+ background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="10" height="10" viewBox="0 0 16 16"><path fill="none" stroke="%236b7280" stroke-linecap="round" stroke-linejoin="round" stroke-width="2.5" d="M4 10l4-4 4 4"/></svg>');
1316
+ }
1317
+
1318
+ .scroll-bottom .scroll-icon {
1319
+ background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="10" height="10" viewBox="0 0 16 16"><path fill="none" stroke="%236b7280" stroke-linecap="round" stroke-linejoin="round" stroke-width="2.5" d="M4 6l4 4 4-4"/></svg>');
1320
+ }
1321
+
1322
+ .scroll-track {
1323
+ flex: 1;
1324
+ width: 100%;
1325
+ position: relative;
1326
+ background: var(--vscrollbar-track-background);
1327
+ overflow: hidden;
1328
+ }
1329
+ .scroll-thumb {
1330
+ position: absolute;
1331
+ left: 2px;
1332
+ right: 2px;
1333
+ top: 0px;
1334
+ height: 30px;
1335
+ background: var(--vscrollbar-thumb-background);
1336
+ border-radius: 4px;
1337
+ z-index: 1;
1338
+ }
1339
+ .scroll-thumb:hover {
1340
+ background: var(--vscrollbar-thumb-hover-background);
1341
+ }
1342
+ }
1343
+
1344
+
1345
+ /* --- 세로 스크롤바가 활성화되었을 때만 CSS로 2열 너비 확장 및 요소 표시 --- */
1346
+ nine-table-sheet.vscroll-visible {
1347
+ grid-template-columns: 1fr var(--vscrollbar-width);
1348
+
1349
+ nine-table-vscrollbar {
1350
+ display: flex;
1351
+ }
1352
+ }
1353
+
1354
+ /* --- 가로 스크롤바가 활성화되었을 때만 CSS로 행 높이 확장 및 요소 표시 --- */
1355
+ nine-table-sheet.hscroll-visible {
1356
+ grid-template-rows: 1fr var(--hscrollbar-height);
1357
+
1358
+ nine-table-hscrollbar, .scroll-edge {
1359
+ display: flex;
1360
+ }
1361
+ }
1362
+
1363
+
1364
+ nine-table-sheet {
1365
+ --sheet-bg: #ffffff;
1366
+ --sheet-nodata-color: #9ca3af;
1367
+ --sheet-fixed-brightness: 99%;
1368
+
1369
+ display: none;
1370
+ grid-template-columns: 1fr 0;
1371
+ grid-template-rows: 1fr 0;
1372
+ width: 100%;
1373
+ height: 100%;
1374
+ position: relative;
1375
+ background: var(--sheet-bg);
1376
+ overflow: hidden;
1377
+
1378
+ .ng-sheet-body {
1379
+ display: block;
1380
+ flex: 1 1 auto;
1381
+ width: 100%;
1382
+ height: 100%;
1383
+ overflow-y: auto;
1384
+ overflow-x: hidden;
1385
+ position: relative;
1386
+ scrollbar-width: none;
1387
+ &::-webkit-scrollbar { display: none; height: 0px; width: 0px; }
1388
+ }
1389
+
1390
+ .ng-sheet-body-content {
1391
+ display: flex;
1392
+ flex-direction: row;
1393
+ width: 100%;
1394
+ height: 100%;
1395
+ left: 0;
1396
+ top: 0;
1397
+ position: sticky;
1398
+ }
1399
+
1400
+ .ng-container-left, .ng-container-body, .ng-container-right {
1401
+ flex-direction: column;
1402
+ position: relative;
1403
+ background: var(--sheet-bg);
1404
+ }
1405
+ .ng-container-body {
1406
+ display: flex;
1407
+ }
1408
+ .ng-container-left, .ng-container-right {
1409
+ border: none;
1410
+ flex-shrink: 0;
1411
+ overflow: hidden;
1412
+ filter: brightness(var(--sheet-fixed-brightness));
1413
+ }
1414
+ .ng-container-body {
1415
+ flex: 1;
1416
+ overflow-x: auto;
1417
+ overflow-y: hidden;
1418
+ scrollbar-width: none;
1419
+ &::-webkit-scrollbar { display: none; height: 0px; width: 0px; }
1420
+ }
1421
+
1422
+ .nodata-overlay {
1423
+ display: none;
1424
+ position: absolute;
1425
+ top: 0;
1426
+ left: 0;
1427
+ right: 0;
1428
+ bottom: 0;
1429
+ background: var(--sheet-bg);
1430
+ z-index: 20;
1431
+ align-items: center;
1432
+ justify-content: center;
1433
+ color: var(--sheet-nodata-color);
1434
+ }
1435
+ }
1436
+
1437
+ nine-table-sheet.active {
1438
+ display: grid;
1439
+ }
1440
+
1441
+
1442
+
1443
+
1444
+ nine-table-sheets-footer {
1445
+ display: flex;
1446
+ height: 26px;
1447
+ --background: #f3f4f6;
1448
+ border-top: 1px solid #e5e7eb;
1449
+ align-items: center;
1450
+ justify-content: space-between;
1451
+ padding: 0 8px;
1452
+ flex-shrink: 0;
1453
+
1454
+ .sheets-counter {
1455
+ color: #6b7280;
1456
+ padding-left: 12px;
1457
+ flex-shrink: 0;
1458
+
1459
+ span#row-count {
1460
+ font-weight: 700;
1461
+ }
1462
+ }
1463
+
1464
+
1465
+
1466
+ .nine-tab-bar {
1467
+ display: flex;
1468
+ align-items: flex-start;
1469
+ gap: 2px;
1470
+ overflow-x: auto;
1471
+ flex: 1;
1472
+ height: 100%;
1473
+
1474
+
1475
+
1476
+ nt-sheets-tab-item {
1477
+ padding: 4px 12px;
1478
+ color: #4b5563;
1479
+ background: #f9fafb;
1480
+ border: 1px solid #e5e7eb;
1481
+ border-top: none;
1482
+ border-radius: 0 0 3px 3px;
1483
+ user-select: none;
1484
+ height: 100%;
1485
+ display: flex;
1486
+ align-items: center;
1487
+ }
1488
+
1489
+ nt-sheets-tab-item.active {
1490
+ background: white;
1491
+ color: #111827;
1492
+ font-weight: 600;
1493
+ border-bottom: 2px solid green;
1494
+ }
1495
+ }
1496
+ }
1497
+
1498
+
1499
+ .asc::after,
1500
+ .desc::after {
1501
+ --sort-icon-size: 10px;
1502
+
1503
+ content: "";
1504
+ display: inline-block;
1505
+ width: var(--sort-icon-size);
1506
+ height: var(--sort-icon-size);
1507
+ flex-shrink: 0;
1508
+ margin-left: 4px;
1509
+ vertical-align: middle;
1510
+ background-repeat: no-repeat;
1511
+ background-position: center;
1512
+ background-size: contain;
1513
+ }
1514
+
1515
+ .asc::after {
1516
+ --sort-icon-color: #2563eb;
1517
+ background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="10" height="10" viewBox="0 0 16 16"><path fill="%232563eb" d="M8 3L3 11h10L8 3z"/></svg>');
1518
+ }
1519
+
1520
+ .desc::after {
1521
+ --sort-icon-color: #dc2626;
1522
+ background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="10" height="10" viewBox="0 0 16 16"><path fill="%23dc2626" d="M8 13L3 5h10l-5 8z"/></svg>');
1523
+ }
1524
+ table {
1525
+ --table-th-bg: #f9fafb;
1526
+ --table-th-color: #111827;
1527
+ --table-td-bg: #fff;
1528
+ --table-td-color: #111827;
1529
+ --table-disabled-bg: #f0f0f0;
1530
+ --th-border-left: none;
1531
+ --th-border-top: none;
1532
+ --th-border-right: 1px solid #e5e7eb;
1533
+ --th-border-bottom: 1px solid #e5e7eb;
1534
+ --td-border-left: none;
1535
+ --tD-border-top: none;
1536
+ --td-border-right: 1px solid #e5e7eb;
1537
+ --td-border-bottom: 1px solid #e5e7eb;
1538
+
1539
+
1540
+ border-collapse: separate;
1541
+ border-spacing: 0;
1542
+ width: auto;
1543
+ min-width: 100%;
1544
+ table-layout: fixed;
1545
+ }
1546
+
1547
+ nine-table-sheet[auto-fit-col="true"] table {
1548
+ width: 100%;
1549
+ min-width: 100%;
1550
+ }
1551
+
1552
+ col {
1553
+ width: attr(width px);
1554
+ }
1555
+
1556
+ thead {
1557
+ display: table-header-group;
1558
+ position: sticky;
1559
+ top: 0;
1560
+ z-index: 10;
1561
+ }
1562
+
1563
+ tfoot {
1564
+ display: table-footer-group;
1565
+ position: sticky;
1566
+ bottom: 0;
1567
+ z-index: 10;
1568
+ }
1569
+
1570
+ tbody {
1571
+ position: relative;
1572
+ }
1573
+
1574
+ tbody.foot {
1575
+ height: 100vh;
1576
+ }
1577
+
1578
+ thead tr {
1579
+ height: 48px;
1580
+ }
1581
+ tbody tr {
1582
+ height: 32px;
1583
+ }
1584
+ tfoot tr {
1585
+ height: 32px;
1586
+ }
1587
+
1588
+ tr.hover th, tr.hover td {
1589
+ background-color: rgba(37, 99, 235, 0.06);
1590
+ }
1591
+
1592
+ th, td {
1593
+ overflow: hidden;
1594
+ white-space: nowrap;
1595
+ text-overflow: ellipsis;
1596
+ padding: 0px 4px;
1597
+ border-top: 1px solid transparent;
1598
+ border-left: 1px solid transparent;
1599
+ color: var(--table-td-color);
1600
+ position: relative;
1601
+ }
1602
+
1603
+ th {
1604
+ border-left: var(--th-border-left);
1605
+ border-top: var(--th-border-top);
1606
+ border-right: var(--th-border-right);
1607
+ border-bottom: var(--th-border-bottom);
1608
+ background: var(--table-th-bg);
1609
+ color: var(--table-th-color);
1610
+ font-weight: 600;
1611
+ user-select: none;
1612
+ }
1613
+
1614
+ td {
1615
+ border-left: var(--td-border-left);
1616
+ border-top: var(--td-border-top);
1617
+ border-right: var(--td-border-right);
1618
+ border-bottom: var(--td-border-bottom);
1619
+ background: var(--table-td-bg);
1620
+ color: var(--table-td-color);
1621
+ }
1622
+
1623
+ td.invalid::after {
1624
+ content: "";
1625
+ position: absolute;
1626
+ top: 0;
1627
+ right: 0;
1628
+ width: 0;
1629
+ height: 0;
1630
+ border-top: 2px solid red;
1631
+ border-right: 2px solid red;
1632
+ border-bottom: 2px solid transparent;
1633
+ border-left: 2px solid transparent;
1634
+ z-index: 1;
1635
+ pointer-events: none;
1636
+ }
1637
+
1638
+ td[disabled="true"] {
1639
+ input, button {
1640
+ background: var(--table-disabled-bg);
1641
+ opacity: 0.5;
1642
+ pointer-events: none;
1643
+ }
1644
+ }
1645
+
1646
+ td[text-align="left"] {
1647
+ input {
1648
+ text-align: left;
1649
+ }
1650
+ }
1651
+ td[text-align="right"] {
1652
+ input {
1653
+ text-align: right;
1654
+ }
1655
+ }
1656
+ td[text-align="center"] {
1657
+ input {
1658
+ text-align: center;
1659
+ }
1660
+ }
1661
+
1662
+ nine-table-toolbar {
1663
+ --display: flex;
1664
+ display: none;
1665
+ align-items: center;
1666
+ justify-content: space-between;
1667
+ height: 40px;
1668
+ padding: 0 12px;
1669
+ --border-bottom: 1px solid #e5e7eb;
1670
+ background: #ffffff;
1671
+ user-select: none;
1672
+ flex-shrink: 0;
1673
+
1674
+
1675
+ .ng-toolbar-left {
1676
+ display: flex;
1677
+ align-items: center;
1678
+ gap: 8px;
1679
+ }
1680
+ .ng-toolbar-title {
1681
+ font-size: 13px;
1682
+ font-weight: 600;
1683
+ color: #111827;
1684
+ }
1685
+ .ng-toolbar-menu-btn {
1686
+ display: inline-flex;
1687
+ align-items: center;
1688
+ justify-content: center;
1689
+ background: none;
1690
+ border: none;
1691
+ padding: 4px;
1692
+ border-radius: 4px;
1693
+ }
1694
+ .ng-toolbar-menu-btn:hover {
1695
+ background-color: #f3f4f6;
1696
+ }
1697
+ .ng-toolbar-custom {
1698
+ display: flex;
1699
+ align-items: center;
1700
+ gap: 6px;
1701
+ }
1702
+ }
1703
+
1704
+ :host([theme="simple"]) nine-table-toolbar,
1705
+ :host([show-header="false"]) nine-table-toolbar {
1706
+ display: none;
1707
+
1708
+ .ng-toolbar-menu-btn {
1709
+ display: none;
1710
+ }
1711
+ }
1712
+
1713
+