@keenmate/pure-admin-core 2.3.0 → 2.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (69) hide show
  1. package/README.md +7 -5
  2. package/dist/css/main.css +207 -181
  3. package/package.json +1 -1
  4. package/snippets/buttons.html +375 -365
  5. package/src/scss/_base-css-variables.scss +8 -0
  6. package/src/scss/_core.scss +121 -121
  7. package/src/scss/core-components/_alerts.scss +227 -227
  8. package/src/scss/core-components/_badges.scss +16 -16
  9. package/src/scss/core-components/_base.scss +125 -125
  10. package/src/scss/core-components/_buttons.scss +580 -548
  11. package/src/scss/core-components/_callouts.scss +152 -152
  12. package/src/scss/core-components/_cards.scss +488 -488
  13. package/src/scss/core-components/_checkbox-lists.scss +289 -289
  14. package/src/scss/core-components/_code.scss +141 -141
  15. package/src/scss/core-components/_command-palette.scss +509 -509
  16. package/src/scss/core-components/_comparison.scss +172 -172
  17. package/src/scss/core-components/_data-display.scss +9 -9
  18. package/src/scss/core-components/_data-viz.scss +9 -9
  19. package/src/scss/core-components/_detail-panel.scss +1 -1
  20. package/src/scss/core-components/_file-selector.scss +780 -780
  21. package/src/scss/core-components/_filter-card.scss +58 -58
  22. package/src/scss/core-components/_forms.scss +16 -16
  23. package/src/scss/core-components/_grid.scss +293 -293
  24. package/src/scss/core-components/_layout.scss +15 -15
  25. package/src/scss/core-components/_lists.scss +211 -211
  26. package/src/scss/core-components/_loaders.scss +277 -277
  27. package/src/scss/core-components/_logic-tree.scss +280 -280
  28. package/src/scss/core-components/_modals.scss +203 -203
  29. package/src/scss/core-components/_notifications.scss +320 -320
  30. package/src/scss/core-components/_pagers.scss +141 -141
  31. package/src/scss/core-components/_popconfirm.scss +170 -170
  32. package/src/scss/core-components/_profile.scss +405 -405
  33. package/src/scss/core-components/_scrollbars.scss +40 -40
  34. package/src/scss/core-components/_settings-panel.scss +141 -141
  35. package/src/scss/core-components/_statistics.scss +200 -201
  36. package/src/scss/core-components/_tables.scss +900 -900
  37. package/src/scss/core-components/_tabs.scss +504 -504
  38. package/src/scss/core-components/_timeline.scss +589 -589
  39. package/src/scss/core-components/_toasts.scss +425 -425
  40. package/src/scss/core-components/_tooltips.scss +605 -605
  41. package/src/scss/core-components/_utilities.scss +1 -1
  42. package/src/scss/core-components/_web-components-theme.scss +21 -21
  43. package/src/scss/core-components/badges/_badge-base.scss +121 -121
  44. package/src/scss/core-components/badges/_badge-group.scss +25 -25
  45. package/src/scss/core-components/badges/_composite-badge-variants.scss +396 -396
  46. package/src/scss/core-components/badges/_composite-badge.scss +70 -70
  47. package/src/scss/core-components/badges/_index.scss +10 -10
  48. package/src/scss/core-components/badges/_labels.scss +155 -155
  49. package/src/scss/core-components/forms/_checkboxes-radios.scss +205 -205
  50. package/src/scss/core-components/forms/_form-inputs.scss +136 -135
  51. package/src/scss/core-components/forms/_form-layout.scss +66 -66
  52. package/src/scss/core-components/forms/_form-states.scss +115 -115
  53. package/src/scss/core-components/forms/_index.scss +12 -12
  54. package/src/scss/core-components/forms/_input-groups.scss +154 -154
  55. package/src/scss/core-components/forms/_input-wrapper.scss +89 -89
  56. package/src/scss/core-components/forms/_query-editor.scss +313 -313
  57. package/src/scss/core-components/layout/_index.scss +11 -11
  58. package/src/scss/core-components/layout/_layout-container.scss +168 -168
  59. package/src/scss/core-components/layout/_layout-responsive.scss +99 -99
  60. package/src/scss/core-components/layout/_navbar-elements.scss +250 -250
  61. package/src/scss/core-components/layout/_navbar.scss +83 -83
  62. package/src/scss/core-components/layout/_sidebar-states.scss +237 -237
  63. package/src/scss/core-components/layout/_sidebar.scss +234 -234
  64. package/src/scss/main.scss +7 -7
  65. package/src/scss/utilities.scss +740 -740
  66. package/src/scss/variables/_base.scss +228 -228
  67. package/src/scss/variables/_components.scss +748 -748
  68. package/src/scss/variables/_layout.scss +65 -65
  69. package/src/scss/variables/_typography.scss +37 -37
@@ -1,900 +1,900 @@
1
- /* ========================================
2
- Table Components
3
- Tables, virtual tables, with striped, hover, and spacing variants
4
- ======================================== */
5
- @use '../variables' as *;
6
-
7
- // Duplicate alert definition removed - consolidated above with theme-aware colors
8
-
9
-
10
- // Tables
11
- .pa-table-container {
12
- overflow-x: auto;
13
- border-radius: $border-radius;
14
- border: $border-width-base solid var(--pa-border-color);
15
- background-color: var(--pa-table-bg);
16
-
17
- // Panel modifier - card-like visual containment
18
- &--panel {
19
- box-shadow: $shadow-sm;
20
- border-radius: $card-border-radius;
21
- margin-bottom: $spacing-base;
22
- transition: box-shadow $transition-fast $easing-snappy;
23
-
24
- &:hover {
25
- box-shadow: $shadow-lg;
26
- }
27
- }
28
-
29
- // Header for panel tables
30
- &__header {
31
- display: flex;
32
- align-items: center;
33
- justify-content: space-between;
34
- padding: $card-header-padding-v $card-header-padding-h;
35
- min-height: $card-header-min-height;
36
- border-bottom: $border-width-base solid var(--pa-border-color);
37
- background: var(--pa-card-header-bg);
38
- border-top-left-radius: $card-border-radius;
39
- border-top-right-radius: $card-border-radius;
40
- }
41
-
42
- &__title {
43
- font-size: $font-size-base;
44
- font-weight: $font-weight-semibold;
45
- margin: 0;
46
- color: var(--pa-text-color-1);
47
- }
48
-
49
- &__actions {
50
- display: flex;
51
- align-items: center;
52
- gap: $spacing-sm;
53
-
54
- // Buttons in header - negative margin to prevent header height growth
55
- .pa-btn {
56
- margin-top: -0.25rem;
57
- margin-bottom: -0.25rem;
58
- }
59
- }
60
- }
61
-
62
- // ============================================================================
63
- // TABLE CARD
64
- // Card-like container specifically designed for tables
65
- // Similar to pa-card but with table as body content (no body padding)
66
- // ============================================================================
67
- .pa-table-card {
68
- background: var(--pa-card-bg);
69
- border: $card-border-width solid var(--pa-border-color);
70
- border-radius: $card-border-radius;
71
- margin-bottom: $spacing-base;
72
- box-shadow: $shadow-sm;
73
- transition: box-shadow $transition-fast $easing-snappy;
74
- display: flex;
75
- flex-direction: column;
76
- overflow: hidden; // Ensure table respects border-radius
77
-
78
- &:hover {
79
- box-shadow: $shadow-lg;
80
- }
81
-
82
- // When containing a detail view, allow body to establish positioning context
83
- &:has(.pa-detail-view) {
84
- .pa-table-card__body {
85
- position: relative;
86
- overflow: hidden; // Clip detail panel to card boundaries
87
- display: flex;
88
- flex-direction: column;
89
-
90
- // Detail view stretches to fill body
91
- .pa-detail-view {
92
- flex: 1;
93
- }
94
- }
95
- }
96
-
97
- &__header {
98
- padding: $card-header-padding-v $card-header-padding-h;
99
- min-height: $card-header-min-height;
100
- border-top-left-radius: $card-border-radius;
101
- border-top-right-radius: $card-border-radius;
102
- border-bottom: $border-width-base solid var(--pa-border-color);
103
- background: var(--pa-card-header-bg);
104
- display: flex;
105
- justify-content: space-between;
106
- align-items: center;
107
- min-width: 0;
108
-
109
- h1, h2, h3, h4, h5, h6, p {
110
- margin: 0;
111
- padding: 0;
112
- }
113
-
114
- h1, h2, h3, h4, h5, h6 {
115
- color: var(--pa-text-color-1);
116
- font-size: $font-size-base;
117
- font-weight: $font-weight-semibold;
118
- }
119
-
120
- .pa-btn {
121
- margin-top: -0.25rem;
122
- margin-bottom: -0.25rem;
123
- }
124
- }
125
-
126
- &__title {
127
- display: flex;
128
- align-items: center;
129
- gap: $spacing-sm;
130
- min-width: 0;
131
- flex: 1;
132
-
133
- &-text {
134
- overflow: hidden;
135
- text-overflow: ellipsis;
136
- white-space: nowrap;
137
- margin: 0;
138
- color: var(--pa-text-color-1);
139
- font-size: $font-size-base;
140
- font-weight: $font-weight-semibold;
141
- line-height: 1;
142
- }
143
- }
144
-
145
- &__actions {
146
- display: flex;
147
- gap: $spacing-sm;
148
- align-items: center;
149
- }
150
-
151
- &__body {
152
- flex: 1;
153
- min-width: 0; // Allow body to shrink below content size for proper overflow
154
-
155
- // Scrollable wrapper for tables (optional - use when table needs horizontal scroll)
156
- &--scrollable {
157
- overflow-x: auto;
158
- }
159
-
160
- // Table inside body
161
- .pa-table {
162
- border-radius: 0;
163
-
164
- // Align first/last column with card header/footer padding
165
- th:first-child,
166
- td:first-child {
167
- padding-inline-start: $card-header-padding-h; // RTL: flips to padding-right
168
- }
169
-
170
- th:last-child,
171
- td:last-child {
172
- padding-inline-end: $card-header-padding-h; // RTL: flips to padding-left
173
- }
174
-
175
- // Remove bottom border from last row (card border handles it)
176
- tbody tr:last-child td {
177
- border-bottom: none;
178
- }
179
- }
180
-
181
- // Detail view inside table card body
182
- // Supports both inline split-view and overlay modes
183
- .pa-detail-view {
184
- height: 100%;
185
-
186
- // Table inside detail view main area
187
- .pa-detail-view__main {
188
- .pa-table {
189
- border-radius: 0;
190
-
191
- th:first-child,
192
- td:first-child {
193
- padding-inline-start: $card-header-padding-h;
194
- }
195
-
196
- th:last-child,
197
- td:last-child {
198
- padding-inline-end: $card-header-padding-h;
199
- }
200
-
201
- tbody tr:last-child td {
202
- border-bottom: none;
203
- }
204
- }
205
-
206
- // web-grid inside detail view
207
- web-grid {
208
- --wg-cell-padding-left: #{$card-header-padding-h};
209
- --wg-cell-padding-right: #{$card-header-padding-h};
210
- }
211
- }
212
- }
213
- }
214
-
215
- &__footer {
216
- padding: $card-footer-padding-v $card-footer-padding-h;
217
- border-top: $border-width-base solid var(--pa-border-color);
218
- border-end-start-radius: $card-border-radius; // RTL: bottom-right in RTL
219
- border-end-end-radius: $card-border-radius; // RTL: bottom-left in RTL
220
- background: var(--pa-card-footer-bg);
221
- display: flex;
222
- justify-content: space-between;
223
- align-items: center;
224
- }
225
-
226
- // Color variants
227
- &--primary {
228
- border-color: var(--pa-accent);
229
-
230
- .pa-table-card__header {
231
- background-color: var(--pa-accent);
232
- color: var(--pa-btn-primary-text);
233
-
234
- h1, h2, h3, h4, h5, h6 {
235
- color: var(--pa-btn-primary-text);
236
- }
237
- }
238
- }
239
-
240
- &--success {
241
- border-color: var(--pa-success-bg);
242
-
243
- .pa-table-card__header {
244
- background-color: var(--pa-success-bg);
245
- color: var(--pa-btn-success-text);
246
-
247
- h1, h2, h3, h4, h5, h6 {
248
- color: var(--pa-btn-success-text);
249
- }
250
- }
251
- }
252
-
253
- &--warning {
254
- border-color: var(--pa-warning-bg);
255
-
256
- .pa-table-card__header {
257
- background-color: var(--pa-warning-bg);
258
- color: var(--pa-btn-warning-text);
259
-
260
- h1, h2, h3, h4, h5, h6 {
261
- color: var(--pa-btn-warning-text);
262
- }
263
- }
264
- }
265
-
266
- &--danger {
267
- border-color: var(--pa-danger-bg);
268
-
269
- .pa-table-card__header {
270
- background-color: var(--pa-danger-bg);
271
- color: var(--pa-btn-danger-text);
272
-
273
- h1, h2, h3, h4, h5, h6 {
274
- color: var(--pa-btn-danger-text);
275
- }
276
- }
277
- }
278
-
279
- // Theme color variants (color-1 through color-9)
280
- @for $i from 1 through 9 {
281
- &--color-#{$i} {
282
- border-color: var(--pa-color-#{$i});
283
-
284
- .pa-table-card__header {
285
- background-color: var(--pa-color-#{$i});
286
- color: var(--pa-color-#{$i}-text);
287
-
288
- h1, h2, h3, h4, h5, h6 {
289
- color: var(--pa-color-#{$i}-text);
290
- }
291
- }
292
- }
293
- }
294
-
295
- // Plain variant - no card visual styling, just layout structure
296
- &--plain {
297
- background: transparent;
298
- border: none;
299
- box-shadow: none;
300
- border-radius: 0;
301
-
302
- &:hover {
303
- box-shadow: none;
304
- }
305
-
306
- // Header in plain mode - simple text header without card styling
307
- .pa-table-card__header {
308
- background: transparent;
309
- border-bottom: none;
310
- border-radius: 0;
311
- padding-inline: 0;
312
- }
313
-
314
- // Body in plain mode with detail view - ensure proper containment
315
- .pa-table-card__body {
316
- // When containing overlay detail view, establish positioning context
317
- &:has(.pa-detail-view--overlay) {
318
- position: relative;
319
- overflow: hidden;
320
- }
321
- }
322
-
323
- // Footer in plain mode
324
- .pa-table-card__footer {
325
- background: transparent;
326
- border-top: none;
327
- border-radius: 0;
328
- padding-inline: 0;
329
- }
330
- }
331
- }
332
-
333
- .pa-table {
334
- width: 100%;
335
- border-collapse: collapse;
336
- font-size: $font-size-sm;
337
- background-color: var(--pa-table-bg);
338
-
339
- th,
340
- td {
341
- padding: $table-padding-base-v $table-padding-base-h;
342
- text-align: start; // RTL: flips to right
343
- border-bottom: $border-width-base solid var(--pa-border-color);
344
- vertical-align: middle;
345
- line-height: $line-height-tight;
346
- }
347
-
348
- th {
349
- background-color: var(--pa-table-header-bg);
350
- font-weight: $font-weight-semibold;
351
- color: var(--pa-text-color-1);
352
- border-bottom: $border-width-medium solid var(--pa-border-color);
353
- }
354
-
355
- td {
356
- color: var(--pa-text-color-1);
357
- background-color: var(--pa-table-bg);
358
- height: $table-cell-height;
359
-
360
- // Buttons in table cells - negative margin to prevent row height growth
361
- .pa-btn {
362
- margin-top: -0.25rem;
363
- margin-bottom: -0.25rem;
364
- }
365
- }
366
-
367
- &:not(&--responsive) {
368
- // Remove bottom border from last row
369
- tbody tr:last-child td {
370
- border-bottom: none;
371
- }
372
- }
373
-
374
- // Striped variant
375
- &--striped {
376
- tbody tr:nth-child(even) td {
377
- background-color: var(--pa-table-stripe);
378
- }
379
- }
380
-
381
- // Bordered variant - full cell borders
382
- &--bordered {
383
- border: $border-width-base solid var(--pa-border-color);
384
-
385
- th,
386
- td {
387
- border: $border-width-base solid var(--pa-border-color);
388
- }
389
-
390
- // Keep last row border in bordered mode
391
- &:not(&--responsive) {
392
- tbody tr:last-child td {
393
- border-bottom: $border-width-base solid var(--pa-border-color);
394
- }
395
- }
396
- }
397
-
398
- // Size variants - synchronized with button/input sizes
399
- &--xs {
400
- th, td {
401
- padding: $table-padding-xs-v $table-padding-xs-h;
402
- }
403
- td {
404
- height: $table-cell-height-xs;
405
- }
406
- }
407
-
408
- &--sm {
409
- th, td {
410
- padding: $table-padding-sm-v $table-padding-sm-h;
411
- }
412
- td {
413
- height: $table-cell-height-sm;
414
- }
415
- }
416
-
417
- &--lg {
418
- th, td {
419
- padding: $table-padding-lg-v $table-padding-lg-h;
420
- }
421
- td {
422
- height: $table-cell-height-lg;
423
- }
424
- }
425
-
426
- &--xl {
427
- th, td {
428
- padding: $table-padding-xl-v $table-padding-xl-h;
429
- }
430
- td {
431
- height: $table-cell-height-xl;
432
- }
433
- }
434
-
435
- // Hover effects
436
- @if $table-hover-accent-width > 0 {
437
- // Header alignment - add padding to match hover accent border
438
- th:first-child {
439
- padding-inline-start: $table-hover-accent-width + $table-padding-base-h; // RTL: flips to padding-right
440
- }
441
-
442
- tbody tr {
443
- border-inline-start: #{$table-hover-accent-width} solid transparent; // RTL: flips to border-right
444
- transition: border-color $transition-normal $easing-smooth;
445
- }
446
- }
447
-
448
- tbody tr:hover {
449
- background-color: var(--pa-table-hover-bg);
450
-
451
- // Apply hover accent if enabled
452
- @if $table-hover-accent-width > 0 {
453
- border-inline-start-color: var(--pa-table-hover-accent-color); // RTL: flips to border-right-color
454
- }
455
- }
456
-
457
- tbody tr:hover td {
458
- background-color: var(--pa-table-hover-bg);
459
- }
460
-
461
- // Remove margin from button groups inside table cells
462
- td .pa-btn-group {
463
- margin-bottom: 0;
464
- flex-wrap: nowrap; // Keep buttons in a row, don't stack vertically
465
- }
466
-
467
- // Column width helper - auto-width columns that shrink to content
468
- .col-auto {
469
- width: 1%;
470
- white-space: nowrap;
471
- }
472
- }
473
-
474
- // Pager
475
- .pa-pager {
476
- display: flex;
477
- margin: $pager-button-margin 0;
478
-
479
- // Remove margins when first/last child in card body
480
- .pa-card__body &:first-child {
481
- margin-top: 0;
482
- }
483
- .pa-card__body &:last-child {
484
- margin-bottom: 0;
485
- }
486
-
487
- // Default center alignment
488
- justify-content: center;
489
-
490
- // Positioning modifiers
491
- &--start {
492
- justify-content: flex-start;
493
- }
494
-
495
- &--center {
496
- justify-content: center;
497
- }
498
-
499
- &--end {
500
- justify-content: flex-end;
501
- }
502
-
503
- &__container {
504
- display: flex;
505
- align-items: center;
506
- gap: $spacing-sm;
507
- white-space: nowrap;
508
- }
509
-
510
- &__controls {
511
- display: flex;
512
- gap: $pager-controls-gap;
513
- }
514
-
515
- &__info {
516
- display: flex;
517
- align-items: center;
518
- gap: $spacing-sm;
519
- }
520
-
521
- &__input {
522
- width: $pager-input-width !important;
523
- text-align: center;
524
- }
525
-
526
- &__text {
527
- color: var(--pa-text-color-2);
528
- font-size: $font-size-sm;
529
- }
530
- }
531
-
532
- // Load More
533
- .pa-load-more {
534
- display: flex;
535
- margin: $spacing-base 0;
536
-
537
- // Remove margins when first/last child in card body
538
- .pa-card__body &:first-child {
539
- margin-top: 0;
540
- }
541
- .pa-card__body &:last-child {
542
- margin-bottom: 0;
543
- }
544
-
545
- // Default center alignment
546
- justify-content: center;
547
-
548
- // Positioning modifiers
549
- &--start {
550
- justify-content: flex-start;
551
- }
552
-
553
- &--center {
554
- justify-content: center;
555
- }
556
-
557
- &--end {
558
- justify-content: flex-end;
559
- }
560
-
561
- &__button {
562
- display: flex;
563
- align-items: center;
564
- gap: $spacing-sm;
565
- padding: $btn-padding-v $btn-padding-h;
566
- background-color: transparent;
567
- border: $border-width-base solid var(--pa-border-color);
568
- border-radius: $border-radius;
569
- color: var(--pa-text-color-1);
570
- font-size: $font-size-sm;
571
- cursor: pointer;
572
- transition: all $transition-fast $easing-snappy;
573
-
574
- &:hover {
575
- border-color: var(--pa-accent);
576
- color: var(--pa-accent);
577
- background-color: var(--pa-accent-light);
578
- }
579
-
580
- &--loading {
581
- pointer-events: none;
582
- opacity: 0.7;
583
-
584
- .pa-load-more__spinner {
585
- animation: pa-spin 1s linear infinite;
586
- }
587
- }
588
- }
589
-
590
- &__spinner {
591
- width: $spinner-size;
592
- height: $spinner-size;
593
- border: $spinner-border-width solid var(--pa-border-color);
594
- border-top: $spinner-border-width solid var(--pa-accent);
595
- border-radius: 50%;
596
- }
597
-
598
- &__text {
599
- color: inherit;
600
- }
601
-
602
- &__count {
603
- color: var(--pa-text-color-2);
604
- font-size: $font-size-xs;
605
- margin-inline-start: $spacing-xs; // RTL: flips to margin-right
606
- }
607
- }
608
-
609
- // Virtual Table Styles
610
- .pa-virtual-table {
611
- border: $border-width-base solid var(--pa-border-color);
612
- border-radius: $border-radius;
613
- height: $chart-height;
614
- overflow: auto;
615
- position: relative;
616
- background-color: var(--pa-table-bg);
617
- font-size: $font-size-sm; // Match pa-table font size
618
- }
619
-
620
- .pa-virtual-table__header {
621
- display: grid;
622
- grid-template-columns: $dashboard-grid-col-sm 1fr 1fr $dashboard-grid-col-lg $dashboard-grid-col-md $dashboard-grid-col-md;
623
- background: var(--pa-table-header-bg);
624
- border-bottom: $border-width-medium solid var(--pa-border-color);
625
- position: sticky;
626
- top: 0;
627
- z-index: 10;
628
- }
629
-
630
- .pa-virtual-table__header-cell {
631
- padding: $virtual-table-cell-padding-v $virtual-table-cell-padding-h;
632
- font-weight: $font-weight-semibold;
633
- border-inline-end: $border-width-base solid var(--pa-border-color); // RTL: flips to border-left
634
- background: var(--pa-table-header-bg);
635
- color: var(--pa-text-color-1);
636
- }
637
-
638
- .pa-virtual-table__header-cell:last-child {
639
- border-inline-end: none;
640
- }
641
-
642
- .pa-virtual-table__body {
643
- position: relative;
644
- }
645
-
646
- .pa-virtual-table__row {
647
- display: grid;
648
- grid-template-columns: $dashboard-grid-col-sm 1fr 1fr $dashboard-grid-col-lg $dashboard-grid-col-md $dashboard-grid-col-md;
649
- border-bottom: $border-width-base solid var(--pa-border-color);
650
- background: var(--pa-table-bg);
651
-
652
- // Setup for hover accent border (same as pa-table)
653
- @if $table-hover-accent-width > 0 {
654
- border-inline-start: #{$table-hover-accent-width} solid transparent; // RTL: flips to border-right
655
- transition: border-color $transition-normal $easing-smooth;
656
- }
657
- }
658
-
659
- .pa-virtual-table__row:nth-child(even) {
660
- background: var(--pa-table-stripe);
661
- }
662
-
663
- .pa-virtual-table__row:hover {
664
- background: var(--pa-table-hover-bg);
665
-
666
- // Apply hover accent if enabled (same as pa-table)
667
- @if $table-hover-accent-width > 0 {
668
- border-inline-start-color: var(--pa-table-hover-accent-color); // RTL: flips to border-right-color
669
- }
670
- }
671
-
672
- .pa-virtual-table__cell {
673
- padding: $virtual-table-cell-padding-v $virtual-table-cell-padding-h;
674
- border-inline-end: $border-width-base solid var(--pa-border-color); // RTL: flips to border-left
675
- overflow: hidden;
676
- text-overflow: ellipsis;
677
- white-space: nowrap;
678
- color: var(--pa-text-color-1);
679
- background-color: inherit;
680
- }
681
-
682
- .pa-virtual-table__cell:last-child {
683
- border-inline-end: none;
684
- }
685
-
686
- // Responsive Tables - Stackable Layout
687
- .pa-table--responsive {
688
- // Between tablet and mobile: Enable horizontal scrolling
689
- @media (max-width: $tablet-breakpoint) and (min-width: $table-responsive-breakpoint + 1) {
690
- // Table becomes scrollable but maintains desktop layout
691
- overflow-x: auto;
692
- -webkit-overflow-scrolling: touch; // Smooth scrolling on iOS
693
-
694
- // Show subtle scroll hint with border
695
- border-inline: $border-width-base solid var(--pa-border-color); // RTL: no change needed (symmetric)
696
- }
697
-
698
- // Mobile: Stack into cards
699
- @media (max-width: $table-responsive-breakpoint) {
700
- // Hide table headers
701
- thead {
702
- display: none;
703
- }
704
-
705
- // Make each row a card
706
- tbody tr {
707
- display: block;
708
- margin-bottom: $table-responsive-card-margin;
709
- border: $border-width-base solid var(--pa-border-color);
710
- border-radius: $border-radius;
711
- overflow: hidden;
712
-
713
- // Reset hover accent border for mobile
714
- @if $table-hover-accent-width > 0 {
715
- border-inline-start: $border-width-base solid var(--pa-border-color) !important; // RTL: flips
716
- }
717
-
718
- &:last-child {
719
- margin-bottom: 0;
720
- }
721
- }
722
-
723
- // Make each cell a row within the card
724
- tbody td {
725
- display: block;
726
- text-align: end; // RTL: flips to left (value on end side)
727
- padding: $table-responsive-card-padding;
728
- position: relative;
729
- border-bottom: $border-width-base solid var(--pa-border-color);
730
-
731
- // Last cell in row has no border
732
- &:last-child {
733
- border-bottom: none;
734
- }
735
-
736
- // Label before content
737
- &::before {
738
- content: attr(data-label);
739
- position: absolute;
740
- inset-inline-start: $table-responsive-card-padding; // RTL: flips to right
741
- top: $table-responsive-card-padding;
742
- font-weight: $table-responsive-label-font-weight;
743
- text-align: start; // RTL: flips to right
744
- width: $table-responsive-label-width;
745
- }
746
-
747
- // Value aligned to the end (leave space for label on start side)
748
- padding-inline-start: calc($table-responsive-label-width + $table-responsive-card-padding * 2); // RTL: flips
749
- }
750
-
751
- // Disable col-auto effect in responsive view
752
- .col-auto {
753
- width: auto;
754
- white-space: normal;
755
- }
756
-
757
- // Striped variant - apply background to entire row (card)
758
- &.pa-table--striped tbody tr:nth-child(even) {
759
- background-color: var(--pa-table-stripe);
760
- }
761
-
762
- // Ensure cells inside striped rows have transparent background
763
- &.pa-table--striped tbody tr:nth-child(even) td {
764
- background-color: transparent;
765
- }
766
-
767
- // Hover effect on the card
768
- tbody tr:hover {
769
- background-color: transparent;
770
- box-shadow: $shadow-sm;
771
- }
772
-
773
- tbody tr:hover td {
774
- background-color: transparent;
775
- }
776
- }
777
- }
778
-
779
- // Responsive Tables - CSS Grid Layout
780
- // Allows custom grid layouts on mobile instead of simple stacking
781
- .pa-table--responsive-grid {
782
- // Between tablet and mobile: Enable horizontal scrolling
783
- @media (max-width: $tablet-breakpoint) and (min-width: $table-responsive-breakpoint + 1) {
784
- display: block;
785
- overflow-x: auto;
786
- -webkit-overflow-scrolling: touch;
787
- border-inline: $border-width-base solid var(--pa-border-color); // RTL: no change needed (symmetric)
788
- }
789
-
790
- // Mobile: CSS Grid layout
791
- @media (max-width: $table-responsive-breakpoint) {
792
- thead {
793
- display: none;
794
- }
795
-
796
- tbody tr {
797
- display: block;
798
- margin-bottom: $table-responsive-card-margin;
799
- border: $border-width-base solid var(--pa-border-color);
800
- border-radius: $border-radius;
801
- overflow: hidden;
802
-
803
- &:last-child {
804
- margin-bottom: 0;
805
- }
806
- }
807
-
808
- tbody td {
809
- display: block;
810
- padding: $table-responsive-card-padding;
811
- border-bottom: $border-width-base solid var(--pa-border-color);
812
-
813
- &:last-child {
814
- border-bottom: none;
815
- }
816
-
817
- // Label above content (block layout by default)
818
- &::before {
819
- content: attr(data-label);
820
- display: block;
821
- font-weight: $table-responsive-label-font-weight;
822
- color: var(--pa-text-color-2);
823
- font-size: $font-size-xs;
824
- margin-bottom: $spacing-xs;
825
- text-transform: uppercase;
826
- letter-spacing: 0.5px;
827
- }
828
- }
829
-
830
- // Grid container modifier - apply to tbody tr
831
- // Usage: Add data-grid class to <tr> elements that need custom grid
832
- tbody tr[data-grid] {
833
- display: grid;
834
- padding: $table-responsive-card-padding;
835
- gap: $table-responsive-card-padding;
836
- }
837
-
838
- // Grid cell modifier - cells within grid container
839
- tbody tr[data-grid] td {
840
- padding: 0;
841
- border: none;
842
-
843
- &::before {
844
- margin-bottom: $spacing-xs;
845
- }
846
- }
847
-
848
- // Predefined grid layouts
849
- // 2-column grid: data-grid="2"
850
- tbody tr[data-grid="2"] {
851
- grid-template-columns: 1fr 1fr;
852
- }
853
-
854
- // 3-column grid: data-grid="3"
855
- tbody tr[data-grid="3"] {
856
- grid-template-columns: 1fr 1fr 1fr;
857
- }
858
-
859
- // Span helpers for custom layouts
860
- // Use data-span="2" on td to span 2 columns
861
- tbody tr[data-grid] td[data-span="2"] {
862
- grid-column: span 2;
863
- }
864
-
865
- tbody tr[data-grid] td[data-span="3"] {
866
- grid-column: span 3;
867
- }
868
-
869
- tbody tr[data-grid] td[data-span="full"] {
870
- grid-column: 1 / -1; // Span all columns
871
- }
872
-
873
- // Disable col-auto effect in responsive view
874
- .col-auto {
875
- width: auto;
876
- white-space: normal;
877
- }
878
-
879
- // Striped variant - apply background to entire row (card)
880
- &.pa-table--striped tbody tr:nth-child(even) {
881
- background-color: var(--pa-table-stripe);
882
- }
883
-
884
- // Ensure cells inside striped rows have transparent background
885
- &.pa-table--striped tbody tr:nth-child(even) td {
886
- background-color: transparent;
887
- }
888
-
889
- // Hover effect
890
- tbody tr:hover {
891
- background-color: transparent;
892
- box-shadow: $shadow-sm;
893
- }
894
-
895
- tbody tr:hover td {
896
- background-color: transparent;
897
- }
898
- }
899
- }
900
-
1
+ /* ========================================
2
+ Table Components
3
+ Tables, virtual tables, with striped, hover, and spacing variants
4
+ ======================================== */
5
+ @use '../variables' as *;
6
+
7
+ // Duplicate alert definition removed - consolidated above with theme-aware colors
8
+
9
+
10
+ // Tables
11
+ .pa-table-container {
12
+ overflow-x: auto;
13
+ border-radius: var(--pa-border-radius);
14
+ border: $border-width-base solid var(--pa-border-color);
15
+ background-color: var(--pa-table-bg);
16
+
17
+ // Panel modifier - card-like visual containment
18
+ &--panel {
19
+ box-shadow: $shadow-sm;
20
+ border-radius: var(--pa-border-radius-lg);
21
+ margin-bottom: $spacing-base;
22
+ transition: box-shadow $transition-fast $easing-snappy;
23
+
24
+ &:hover {
25
+ box-shadow: $shadow-lg;
26
+ }
27
+ }
28
+
29
+ // Header for panel tables
30
+ &__header {
31
+ display: flex;
32
+ align-items: center;
33
+ justify-content: space-between;
34
+ padding: $card-header-padding-v $card-header-padding-h;
35
+ min-height: $card-header-min-height;
36
+ border-bottom: $border-width-base solid var(--pa-border-color);
37
+ background: var(--pa-card-header-bg);
38
+ border-top-left-radius: $card-border-radius;
39
+ border-top-right-radius: $card-border-radius;
40
+ }
41
+
42
+ &__title {
43
+ font-size: $font-size-base;
44
+ font-weight: $font-weight-semibold;
45
+ margin: 0;
46
+ color: var(--pa-text-color-1);
47
+ }
48
+
49
+ &__actions {
50
+ display: flex;
51
+ align-items: center;
52
+ gap: $spacing-sm;
53
+
54
+ // Buttons in header - negative margin to prevent header height growth
55
+ .pa-btn {
56
+ margin-top: -0.25rem;
57
+ margin-bottom: -0.25rem;
58
+ }
59
+ }
60
+ }
61
+
62
+ // ============================================================================
63
+ // TABLE CARD
64
+ // Card-like container specifically designed for tables
65
+ // Similar to pa-card but with table as body content (no body padding)
66
+ // ============================================================================
67
+ .pa-table-card {
68
+ background: var(--pa-card-bg);
69
+ border: $card-border-width solid var(--pa-border-color);
70
+ border-radius: var(--pa-border-radius-lg);
71
+ margin-bottom: $spacing-base;
72
+ box-shadow: $shadow-sm;
73
+ transition: box-shadow $transition-fast $easing-snappy;
74
+ display: flex;
75
+ flex-direction: column;
76
+ overflow: hidden; // Ensure table respects border-radius
77
+
78
+ &:hover {
79
+ box-shadow: $shadow-lg;
80
+ }
81
+
82
+ // When containing a detail view, allow body to establish positioning context
83
+ &:has(.pa-detail-view) {
84
+ .pa-table-card__body {
85
+ position: relative;
86
+ overflow: hidden; // Clip detail panel to card boundaries
87
+ display: flex;
88
+ flex-direction: column;
89
+
90
+ // Detail view stretches to fill body
91
+ .pa-detail-view {
92
+ flex: 1;
93
+ }
94
+ }
95
+ }
96
+
97
+ &__header {
98
+ padding: $card-header-padding-v $card-header-padding-h;
99
+ min-height: $card-header-min-height;
100
+ border-top-left-radius: $card-border-radius;
101
+ border-top-right-radius: $card-border-radius;
102
+ border-bottom: $border-width-base solid var(--pa-border-color);
103
+ background: var(--pa-card-header-bg);
104
+ display: flex;
105
+ justify-content: space-between;
106
+ align-items: center;
107
+ min-width: 0;
108
+
109
+ h1, h2, h3, h4, h5, h6, p {
110
+ margin: 0;
111
+ padding: 0;
112
+ }
113
+
114
+ h1, h2, h3, h4, h5, h6 {
115
+ color: var(--pa-text-color-1);
116
+ font-size: $font-size-base;
117
+ font-weight: $font-weight-semibold;
118
+ }
119
+
120
+ .pa-btn {
121
+ margin-top: -0.25rem;
122
+ margin-bottom: -0.25rem;
123
+ }
124
+ }
125
+
126
+ &__title {
127
+ display: flex;
128
+ align-items: center;
129
+ gap: $spacing-sm;
130
+ min-width: 0;
131
+ flex: 1;
132
+
133
+ &-text {
134
+ overflow: hidden;
135
+ text-overflow: ellipsis;
136
+ white-space: nowrap;
137
+ margin: 0;
138
+ color: var(--pa-text-color-1);
139
+ font-size: $font-size-base;
140
+ font-weight: $font-weight-semibold;
141
+ line-height: 1;
142
+ }
143
+ }
144
+
145
+ &__actions {
146
+ display: flex;
147
+ gap: $spacing-sm;
148
+ align-items: center;
149
+ }
150
+
151
+ &__body {
152
+ flex: 1;
153
+ min-width: 0; // Allow body to shrink below content size for proper overflow
154
+
155
+ // Scrollable wrapper for tables (optional - use when table needs horizontal scroll)
156
+ &--scrollable {
157
+ overflow-x: auto;
158
+ }
159
+
160
+ // Table inside body
161
+ .pa-table {
162
+ border-radius: 0;
163
+
164
+ // Align first/last column with card header/footer padding
165
+ th:first-child,
166
+ td:first-child {
167
+ padding-inline-start: $card-header-padding-h; // RTL: flips to padding-right
168
+ }
169
+
170
+ th:last-child,
171
+ td:last-child {
172
+ padding-inline-end: $card-header-padding-h; // RTL: flips to padding-left
173
+ }
174
+
175
+ // Remove bottom border from last row (card border handles it)
176
+ tbody tr:last-child td {
177
+ border-bottom: none;
178
+ }
179
+ }
180
+
181
+ // Detail view inside table card body
182
+ // Supports both inline split-view and overlay modes
183
+ .pa-detail-view {
184
+ height: 100%;
185
+
186
+ // Table inside detail view main area
187
+ .pa-detail-view__main {
188
+ .pa-table {
189
+ border-radius: 0;
190
+
191
+ th:first-child,
192
+ td:first-child {
193
+ padding-inline-start: $card-header-padding-h;
194
+ }
195
+
196
+ th:last-child,
197
+ td:last-child {
198
+ padding-inline-end: $card-header-padding-h;
199
+ }
200
+
201
+ tbody tr:last-child td {
202
+ border-bottom: none;
203
+ }
204
+ }
205
+
206
+ // web-grid inside detail view
207
+ web-grid {
208
+ --wg-cell-padding-left: #{$card-header-padding-h};
209
+ --wg-cell-padding-right: #{$card-header-padding-h};
210
+ }
211
+ }
212
+ }
213
+ }
214
+
215
+ &__footer {
216
+ padding: $card-footer-padding-v $card-footer-padding-h;
217
+ border-top: $border-width-base solid var(--pa-border-color);
218
+ border-end-start-radius: $card-border-radius; // RTL: bottom-right in RTL
219
+ border-end-end-radius: $card-border-radius; // RTL: bottom-left in RTL
220
+ background: var(--pa-card-footer-bg);
221
+ display: flex;
222
+ justify-content: space-between;
223
+ align-items: center;
224
+ }
225
+
226
+ // Color variants
227
+ &--primary {
228
+ border-color: var(--pa-accent);
229
+
230
+ .pa-table-card__header {
231
+ background-color: var(--pa-accent);
232
+ color: var(--pa-btn-primary-text);
233
+
234
+ h1, h2, h3, h4, h5, h6 {
235
+ color: var(--pa-btn-primary-text);
236
+ }
237
+ }
238
+ }
239
+
240
+ &--success {
241
+ border-color: var(--pa-success-bg);
242
+
243
+ .pa-table-card__header {
244
+ background-color: var(--pa-success-bg);
245
+ color: var(--pa-btn-success-text);
246
+
247
+ h1, h2, h3, h4, h5, h6 {
248
+ color: var(--pa-btn-success-text);
249
+ }
250
+ }
251
+ }
252
+
253
+ &--warning {
254
+ border-color: var(--pa-warning-bg);
255
+
256
+ .pa-table-card__header {
257
+ background-color: var(--pa-warning-bg);
258
+ color: var(--pa-btn-warning-text);
259
+
260
+ h1, h2, h3, h4, h5, h6 {
261
+ color: var(--pa-btn-warning-text);
262
+ }
263
+ }
264
+ }
265
+
266
+ &--danger {
267
+ border-color: var(--pa-danger-bg);
268
+
269
+ .pa-table-card__header {
270
+ background-color: var(--pa-danger-bg);
271
+ color: var(--pa-btn-danger-text);
272
+
273
+ h1, h2, h3, h4, h5, h6 {
274
+ color: var(--pa-btn-danger-text);
275
+ }
276
+ }
277
+ }
278
+
279
+ // Theme color variants (color-1 through color-9)
280
+ @for $i from 1 through 9 {
281
+ &--color-#{$i} {
282
+ border-color: var(--pa-color-#{$i});
283
+
284
+ .pa-table-card__header {
285
+ background-color: var(--pa-color-#{$i});
286
+ color: var(--pa-color-#{$i}-text);
287
+
288
+ h1, h2, h3, h4, h5, h6 {
289
+ color: var(--pa-color-#{$i}-text);
290
+ }
291
+ }
292
+ }
293
+ }
294
+
295
+ // Plain variant - no card visual styling, just layout structure
296
+ &--plain {
297
+ background: transparent;
298
+ border: none;
299
+ box-shadow: none;
300
+ border-radius: 0;
301
+
302
+ &:hover {
303
+ box-shadow: none;
304
+ }
305
+
306
+ // Header in plain mode - simple text header without card styling
307
+ .pa-table-card__header {
308
+ background: transparent;
309
+ border-bottom: none;
310
+ border-radius: 0;
311
+ padding-inline: 0;
312
+ }
313
+
314
+ // Body in plain mode with detail view - ensure proper containment
315
+ .pa-table-card__body {
316
+ // When containing overlay detail view, establish positioning context
317
+ &:has(.pa-detail-view--overlay) {
318
+ position: relative;
319
+ overflow: hidden;
320
+ }
321
+ }
322
+
323
+ // Footer in plain mode
324
+ .pa-table-card__footer {
325
+ background: transparent;
326
+ border-top: none;
327
+ border-radius: 0;
328
+ padding-inline: 0;
329
+ }
330
+ }
331
+ }
332
+
333
+ .pa-table {
334
+ width: 100%;
335
+ border-collapse: collapse;
336
+ font-size: $font-size-sm;
337
+ background-color: var(--pa-table-bg);
338
+
339
+ th,
340
+ td {
341
+ padding: $table-padding-base-v $table-padding-base-h;
342
+ text-align: start; // RTL: flips to right
343
+ border-bottom: $border-width-base solid var(--pa-border-color);
344
+ vertical-align: middle;
345
+ line-height: $line-height-tight;
346
+ }
347
+
348
+ th {
349
+ background-color: var(--pa-table-header-bg);
350
+ font-weight: $font-weight-semibold;
351
+ color: var(--pa-text-color-1);
352
+ border-bottom: $border-width-medium solid var(--pa-border-color);
353
+ }
354
+
355
+ td {
356
+ color: var(--pa-text-color-1);
357
+ background-color: var(--pa-table-bg);
358
+ height: $table-cell-height;
359
+
360
+ // Buttons in table cells - negative margin to prevent row height growth
361
+ .pa-btn {
362
+ margin-top: -0.25rem;
363
+ margin-bottom: -0.25rem;
364
+ }
365
+ }
366
+
367
+ &:not(&--responsive) {
368
+ // Remove bottom border from last row
369
+ tbody tr:last-child td {
370
+ border-bottom: none;
371
+ }
372
+ }
373
+
374
+ // Striped variant
375
+ &--striped {
376
+ tbody tr:nth-child(even) td {
377
+ background-color: var(--pa-table-stripe);
378
+ }
379
+ }
380
+
381
+ // Bordered variant - full cell borders
382
+ &--bordered {
383
+ border: $border-width-base solid var(--pa-border-color);
384
+
385
+ th,
386
+ td {
387
+ border: $border-width-base solid var(--pa-border-color);
388
+ }
389
+
390
+ // Keep last row border in bordered mode
391
+ &:not(&--responsive) {
392
+ tbody tr:last-child td {
393
+ border-bottom: $border-width-base solid var(--pa-border-color);
394
+ }
395
+ }
396
+ }
397
+
398
+ // Size variants - synchronized with button/input sizes
399
+ &--xs {
400
+ th, td {
401
+ padding: $table-padding-xs-v $table-padding-xs-h;
402
+ }
403
+ td {
404
+ height: $table-cell-height-xs;
405
+ }
406
+ }
407
+
408
+ &--sm {
409
+ th, td {
410
+ padding: $table-padding-sm-v $table-padding-sm-h;
411
+ }
412
+ td {
413
+ height: $table-cell-height-sm;
414
+ }
415
+ }
416
+
417
+ &--lg {
418
+ th, td {
419
+ padding: $table-padding-lg-v $table-padding-lg-h;
420
+ }
421
+ td {
422
+ height: $table-cell-height-lg;
423
+ }
424
+ }
425
+
426
+ &--xl {
427
+ th, td {
428
+ padding: $table-padding-xl-v $table-padding-xl-h;
429
+ }
430
+ td {
431
+ height: $table-cell-height-xl;
432
+ }
433
+ }
434
+
435
+ // Hover effects
436
+ @if $table-hover-accent-width > 0 {
437
+ // Header alignment - add padding to match hover accent border
438
+ th:first-child {
439
+ padding-inline-start: $table-hover-accent-width + $table-padding-base-h; // RTL: flips to padding-right
440
+ }
441
+
442
+ tbody tr {
443
+ border-inline-start: #{$table-hover-accent-width} solid transparent; // RTL: flips to border-right
444
+ transition: border-color $transition-normal $easing-smooth;
445
+ }
446
+ }
447
+
448
+ tbody tr:hover {
449
+ background-color: var(--pa-table-hover-bg);
450
+
451
+ // Apply hover accent if enabled
452
+ @if $table-hover-accent-width > 0 {
453
+ border-inline-start-color: var(--pa-table-hover-accent-color); // RTL: flips to border-right-color
454
+ }
455
+ }
456
+
457
+ tbody tr:hover td {
458
+ background-color: var(--pa-table-hover-bg);
459
+ }
460
+
461
+ // Remove margin from button groups inside table cells
462
+ td .pa-btn-group {
463
+ margin-bottom: 0;
464
+ flex-wrap: nowrap; // Keep buttons in a row, don't stack vertically
465
+ }
466
+
467
+ // Column width helper - auto-width columns that shrink to content
468
+ .col-auto {
469
+ width: 1%;
470
+ white-space: nowrap;
471
+ }
472
+ }
473
+
474
+ // Pager
475
+ .pa-pager {
476
+ display: flex;
477
+ margin: $pager-button-margin 0;
478
+
479
+ // Remove margins when first/last child in card body
480
+ .pa-card__body &:first-child {
481
+ margin-top: 0;
482
+ }
483
+ .pa-card__body &:last-child {
484
+ margin-bottom: 0;
485
+ }
486
+
487
+ // Default center alignment
488
+ justify-content: center;
489
+
490
+ // Positioning modifiers
491
+ &--start {
492
+ justify-content: flex-start;
493
+ }
494
+
495
+ &--center {
496
+ justify-content: center;
497
+ }
498
+
499
+ &--end {
500
+ justify-content: flex-end;
501
+ }
502
+
503
+ &__container {
504
+ display: flex;
505
+ align-items: center;
506
+ gap: $spacing-sm;
507
+ white-space: nowrap;
508
+ }
509
+
510
+ &__controls {
511
+ display: flex;
512
+ gap: $pager-controls-gap;
513
+ }
514
+
515
+ &__info {
516
+ display: flex;
517
+ align-items: center;
518
+ gap: $spacing-sm;
519
+ }
520
+
521
+ &__input {
522
+ width: $pager-input-width !important;
523
+ text-align: center;
524
+ }
525
+
526
+ &__text {
527
+ color: var(--pa-text-color-2);
528
+ font-size: $font-size-sm;
529
+ }
530
+ }
531
+
532
+ // Load More
533
+ .pa-load-more {
534
+ display: flex;
535
+ margin: $spacing-base 0;
536
+
537
+ // Remove margins when first/last child in card body
538
+ .pa-card__body &:first-child {
539
+ margin-top: 0;
540
+ }
541
+ .pa-card__body &:last-child {
542
+ margin-bottom: 0;
543
+ }
544
+
545
+ // Default center alignment
546
+ justify-content: center;
547
+
548
+ // Positioning modifiers
549
+ &--start {
550
+ justify-content: flex-start;
551
+ }
552
+
553
+ &--center {
554
+ justify-content: center;
555
+ }
556
+
557
+ &--end {
558
+ justify-content: flex-end;
559
+ }
560
+
561
+ &__button {
562
+ display: flex;
563
+ align-items: center;
564
+ gap: $spacing-sm;
565
+ padding: $btn-padding-v $btn-padding-h;
566
+ background-color: transparent;
567
+ border: $border-width-base solid var(--pa-border-color);
568
+ border-radius: var(--pa-border-radius);
569
+ color: var(--pa-text-color-1);
570
+ font-size: $font-size-sm;
571
+ cursor: pointer;
572
+ transition: all $transition-fast $easing-snappy;
573
+
574
+ &:hover {
575
+ border-color: var(--pa-accent);
576
+ color: var(--pa-accent);
577
+ background-color: var(--pa-accent-light);
578
+ }
579
+
580
+ &--loading {
581
+ pointer-events: none;
582
+ opacity: 0.7;
583
+
584
+ .pa-load-more__spinner {
585
+ animation: pa-spin 1s linear infinite;
586
+ }
587
+ }
588
+ }
589
+
590
+ &__spinner {
591
+ width: $spinner-size;
592
+ height: $spinner-size;
593
+ border: $spinner-border-width solid var(--pa-border-color);
594
+ border-top: $spinner-border-width solid var(--pa-accent);
595
+ border-radius: 50%;
596
+ }
597
+
598
+ &__text {
599
+ color: inherit;
600
+ }
601
+
602
+ &__count {
603
+ color: var(--pa-text-color-2);
604
+ font-size: $font-size-xs;
605
+ margin-inline-start: $spacing-xs; // RTL: flips to margin-right
606
+ }
607
+ }
608
+
609
+ // Virtual Table Styles
610
+ .pa-virtual-table {
611
+ border: $border-width-base solid var(--pa-border-color);
612
+ border-radius: var(--pa-border-radius);
613
+ height: $chart-height;
614
+ overflow: auto;
615
+ position: relative;
616
+ background-color: var(--pa-table-bg);
617
+ font-size: $font-size-sm; // Match pa-table font size
618
+ }
619
+
620
+ .pa-virtual-table__header {
621
+ display: grid;
622
+ grid-template-columns: $dashboard-grid-col-sm 1fr 1fr $dashboard-grid-col-lg $dashboard-grid-col-md $dashboard-grid-col-md;
623
+ background: var(--pa-table-header-bg);
624
+ border-bottom: $border-width-medium solid var(--pa-border-color);
625
+ position: sticky;
626
+ top: 0;
627
+ z-index: 10;
628
+ }
629
+
630
+ .pa-virtual-table__header-cell {
631
+ padding: $virtual-table-cell-padding-v $virtual-table-cell-padding-h;
632
+ font-weight: $font-weight-semibold;
633
+ border-inline-end: $border-width-base solid var(--pa-border-color); // RTL: flips to border-left
634
+ background: var(--pa-table-header-bg);
635
+ color: var(--pa-text-color-1);
636
+ }
637
+
638
+ .pa-virtual-table__header-cell:last-child {
639
+ border-inline-end: none;
640
+ }
641
+
642
+ .pa-virtual-table__body {
643
+ position: relative;
644
+ }
645
+
646
+ .pa-virtual-table__row {
647
+ display: grid;
648
+ grid-template-columns: $dashboard-grid-col-sm 1fr 1fr $dashboard-grid-col-lg $dashboard-grid-col-md $dashboard-grid-col-md;
649
+ border-bottom: $border-width-base solid var(--pa-border-color);
650
+ background: var(--pa-table-bg);
651
+
652
+ // Setup for hover accent border (same as pa-table)
653
+ @if $table-hover-accent-width > 0 {
654
+ border-inline-start: #{$table-hover-accent-width} solid transparent; // RTL: flips to border-right
655
+ transition: border-color $transition-normal $easing-smooth;
656
+ }
657
+ }
658
+
659
+ .pa-virtual-table__row:nth-child(even) {
660
+ background: var(--pa-table-stripe);
661
+ }
662
+
663
+ .pa-virtual-table__row:hover {
664
+ background: var(--pa-table-hover-bg);
665
+
666
+ // Apply hover accent if enabled (same as pa-table)
667
+ @if $table-hover-accent-width > 0 {
668
+ border-inline-start-color: var(--pa-table-hover-accent-color); // RTL: flips to border-right-color
669
+ }
670
+ }
671
+
672
+ .pa-virtual-table__cell {
673
+ padding: $virtual-table-cell-padding-v $virtual-table-cell-padding-h;
674
+ border-inline-end: $border-width-base solid var(--pa-border-color); // RTL: flips to border-left
675
+ overflow: hidden;
676
+ text-overflow: ellipsis;
677
+ white-space: nowrap;
678
+ color: var(--pa-text-color-1);
679
+ background-color: inherit;
680
+ }
681
+
682
+ .pa-virtual-table__cell:last-child {
683
+ border-inline-end: none;
684
+ }
685
+
686
+ // Responsive Tables - Stackable Layout
687
+ .pa-table--responsive {
688
+ // Between tablet and mobile: Enable horizontal scrolling
689
+ @media (max-width: $tablet-breakpoint) and (min-width: $table-responsive-breakpoint + 1) {
690
+ // Table becomes scrollable but maintains desktop layout
691
+ overflow-x: auto;
692
+ -webkit-overflow-scrolling: touch; // Smooth scrolling on iOS
693
+
694
+ // Show subtle scroll hint with border
695
+ border-inline: $border-width-base solid var(--pa-border-color); // RTL: no change needed (symmetric)
696
+ }
697
+
698
+ // Mobile: Stack into cards
699
+ @media (max-width: $table-responsive-breakpoint) {
700
+ // Hide table headers
701
+ thead {
702
+ display: none;
703
+ }
704
+
705
+ // Make each row a card
706
+ tbody tr {
707
+ display: block;
708
+ margin-bottom: $table-responsive-card-margin;
709
+ border: $border-width-base solid var(--pa-border-color);
710
+ border-radius: var(--pa-border-radius);
711
+ overflow: hidden;
712
+
713
+ // Reset hover accent border for mobile
714
+ @if $table-hover-accent-width > 0 {
715
+ border-inline-start: $border-width-base solid var(--pa-border-color) !important; // RTL: flips
716
+ }
717
+
718
+ &:last-child {
719
+ margin-bottom: 0;
720
+ }
721
+ }
722
+
723
+ // Make each cell a row within the card
724
+ tbody td {
725
+ display: block;
726
+ text-align: end; // RTL: flips to left (value on end side)
727
+ padding: $table-responsive-card-padding;
728
+ position: relative;
729
+ border-bottom: $border-width-base solid var(--pa-border-color);
730
+
731
+ // Last cell in row has no border
732
+ &:last-child {
733
+ border-bottom: none;
734
+ }
735
+
736
+ // Label before content
737
+ &::before {
738
+ content: attr(data-label);
739
+ position: absolute;
740
+ inset-inline-start: $table-responsive-card-padding; // RTL: flips to right
741
+ top: $table-responsive-card-padding;
742
+ font-weight: $table-responsive-label-font-weight;
743
+ text-align: start; // RTL: flips to right
744
+ width: $table-responsive-label-width;
745
+ }
746
+
747
+ // Value aligned to the end (leave space for label on start side)
748
+ padding-inline-start: calc($table-responsive-label-width + $table-responsive-card-padding * 2); // RTL: flips
749
+ }
750
+
751
+ // Disable col-auto effect in responsive view
752
+ .col-auto {
753
+ width: auto;
754
+ white-space: normal;
755
+ }
756
+
757
+ // Striped variant - apply background to entire row (card)
758
+ &.pa-table--striped tbody tr:nth-child(even) {
759
+ background-color: var(--pa-table-stripe);
760
+ }
761
+
762
+ // Ensure cells inside striped rows have transparent background
763
+ &.pa-table--striped tbody tr:nth-child(even) td {
764
+ background-color: transparent;
765
+ }
766
+
767
+ // Hover effect on the card
768
+ tbody tr:hover {
769
+ background-color: transparent;
770
+ box-shadow: $shadow-sm;
771
+ }
772
+
773
+ tbody tr:hover td {
774
+ background-color: transparent;
775
+ }
776
+ }
777
+ }
778
+
779
+ // Responsive Tables - CSS Grid Layout
780
+ // Allows custom grid layouts on mobile instead of simple stacking
781
+ .pa-table--responsive-grid {
782
+ // Between tablet and mobile: Enable horizontal scrolling
783
+ @media (max-width: $tablet-breakpoint) and (min-width: $table-responsive-breakpoint + 1) {
784
+ display: block;
785
+ overflow-x: auto;
786
+ -webkit-overflow-scrolling: touch;
787
+ border-inline: $border-width-base solid var(--pa-border-color); // RTL: no change needed (symmetric)
788
+ }
789
+
790
+ // Mobile: CSS Grid layout
791
+ @media (max-width: $table-responsive-breakpoint) {
792
+ thead {
793
+ display: none;
794
+ }
795
+
796
+ tbody tr {
797
+ display: block;
798
+ margin-bottom: $table-responsive-card-margin;
799
+ border: $border-width-base solid var(--pa-border-color);
800
+ border-radius: var(--pa-border-radius);
801
+ overflow: hidden;
802
+
803
+ &:last-child {
804
+ margin-bottom: 0;
805
+ }
806
+ }
807
+
808
+ tbody td {
809
+ display: block;
810
+ padding: $table-responsive-card-padding;
811
+ border-bottom: $border-width-base solid var(--pa-border-color);
812
+
813
+ &:last-child {
814
+ border-bottom: none;
815
+ }
816
+
817
+ // Label above content (block layout by default)
818
+ &::before {
819
+ content: attr(data-label);
820
+ display: block;
821
+ font-weight: $table-responsive-label-font-weight;
822
+ color: var(--pa-text-color-2);
823
+ font-size: $font-size-xs;
824
+ margin-bottom: $spacing-xs;
825
+ text-transform: uppercase;
826
+ letter-spacing: 0.5px;
827
+ }
828
+ }
829
+
830
+ // Grid container modifier - apply to tbody tr
831
+ // Usage: Add data-grid class to <tr> elements that need custom grid
832
+ tbody tr[data-grid] {
833
+ display: grid;
834
+ padding: $table-responsive-card-padding;
835
+ gap: $table-responsive-card-padding;
836
+ }
837
+
838
+ // Grid cell modifier - cells within grid container
839
+ tbody tr[data-grid] td {
840
+ padding: 0;
841
+ border: none;
842
+
843
+ &::before {
844
+ margin-bottom: $spacing-xs;
845
+ }
846
+ }
847
+
848
+ // Predefined grid layouts
849
+ // 2-column grid: data-grid="2"
850
+ tbody tr[data-grid="2"] {
851
+ grid-template-columns: 1fr 1fr;
852
+ }
853
+
854
+ // 3-column grid: data-grid="3"
855
+ tbody tr[data-grid="3"] {
856
+ grid-template-columns: 1fr 1fr 1fr;
857
+ }
858
+
859
+ // Span helpers for custom layouts
860
+ // Use data-span="2" on td to span 2 columns
861
+ tbody tr[data-grid] td[data-span="2"] {
862
+ grid-column: span 2;
863
+ }
864
+
865
+ tbody tr[data-grid] td[data-span="3"] {
866
+ grid-column: span 3;
867
+ }
868
+
869
+ tbody tr[data-grid] td[data-span="full"] {
870
+ grid-column: 1 / -1; // Span all columns
871
+ }
872
+
873
+ // Disable col-auto effect in responsive view
874
+ .col-auto {
875
+ width: auto;
876
+ white-space: normal;
877
+ }
878
+
879
+ // Striped variant - apply background to entire row (card)
880
+ &.pa-table--striped tbody tr:nth-child(even) {
881
+ background-color: var(--pa-table-stripe);
882
+ }
883
+
884
+ // Ensure cells inside striped rows have transparent background
885
+ &.pa-table--striped tbody tr:nth-child(even) td {
886
+ background-color: transparent;
887
+ }
888
+
889
+ // Hover effect
890
+ tbody tr:hover {
891
+ background-color: transparent;
892
+ box-shadow: $shadow-sm;
893
+ }
894
+
895
+ tbody tr:hover td {
896
+ background-color: transparent;
897
+ }
898
+ }
899
+ }
900
+