@keenmate/pure-admin-core 2.3.1 → 2.3.3

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 (70) hide show
  1. package/README.md +30 -9
  2. package/dist/css/main.css +205 -190
  3. package/package.json +1 -1
  4. package/snippets/buttons.html +375 -365
  5. package/snippets/command-palette.html +15 -13
  6. package/src/scss/_base-css-variables.scss +10 -0
  7. package/src/scss/_core.scss +121 -121
  8. package/src/scss/core-components/_alerts.scss +227 -227
  9. package/src/scss/core-components/_badges.scss +16 -16
  10. package/src/scss/core-components/_base.scss +125 -125
  11. package/src/scss/core-components/_buttons.scss +31 -16
  12. package/src/scss/core-components/_callouts.scss +152 -152
  13. package/src/scss/core-components/_cards.scss +488 -488
  14. package/src/scss/core-components/_checkbox-lists.scss +289 -289
  15. package/src/scss/core-components/_code.scss +141 -141
  16. package/src/scss/core-components/_command-palette.scss +518 -509
  17. package/src/scss/core-components/_comparison.scss +172 -172
  18. package/src/scss/core-components/_data-display.scss +9 -9
  19. package/src/scss/core-components/_data-viz.scss +9 -9
  20. package/src/scss/core-components/_detail-panel.scss +1 -1
  21. package/src/scss/core-components/_file-selector.scss +780 -780
  22. package/src/scss/core-components/_filter-card.scss +58 -58
  23. package/src/scss/core-components/_forms.scss +16 -16
  24. package/src/scss/core-components/_grid.scss +293 -293
  25. package/src/scss/core-components/_layout.scss +15 -15
  26. package/src/scss/core-components/_lists.scss +211 -211
  27. package/src/scss/core-components/_loaders.scss +277 -277
  28. package/src/scss/core-components/_logic-tree.scss +280 -280
  29. package/src/scss/core-components/_modals.scss +203 -203
  30. package/src/scss/core-components/_notifications.scss +320 -320
  31. package/src/scss/core-components/_pagers.scss +141 -141
  32. package/src/scss/core-components/_popconfirm.scss +170 -170
  33. package/src/scss/core-components/_profile.scss +405 -405
  34. package/src/scss/core-components/_scrollbars.scss +40 -40
  35. package/src/scss/core-components/_settings-panel.scss +141 -141
  36. package/src/scss/core-components/_statistics.scss +200 -201
  37. package/src/scss/core-components/_tables.scss +900 -900
  38. package/src/scss/core-components/_tabs.scss +504 -504
  39. package/src/scss/core-components/_timeline.scss +589 -589
  40. package/src/scss/core-components/_toasts.scss +425 -425
  41. package/src/scss/core-components/_tooltips.scss +605 -605
  42. package/src/scss/core-components/_utilities.scss +1 -1
  43. package/src/scss/core-components/_web-components-theme.scss +21 -21
  44. package/src/scss/core-components/badges/_badge-base.scss +121 -121
  45. package/src/scss/core-components/badges/_badge-group.scss +25 -25
  46. package/src/scss/core-components/badges/_composite-badge-variants.scss +396 -396
  47. package/src/scss/core-components/badges/_composite-badge.scss +70 -70
  48. package/src/scss/core-components/badges/_index.scss +10 -10
  49. package/src/scss/core-components/badges/_labels.scss +155 -155
  50. package/src/scss/core-components/forms/_checkboxes-radios.scss +205 -205
  51. package/src/scss/core-components/forms/_form-inputs.scss +3 -3
  52. package/src/scss/core-components/forms/_form-layout.scss +66 -66
  53. package/src/scss/core-components/forms/_form-states.scss +115 -115
  54. package/src/scss/core-components/forms/_index.scss +12 -12
  55. package/src/scss/core-components/forms/_input-groups.scss +154 -154
  56. package/src/scss/core-components/forms/_input-wrapper.scss +89 -89
  57. package/src/scss/core-components/forms/_query-editor.scss +313 -313
  58. package/src/scss/core-components/layout/_index.scss +11 -11
  59. package/src/scss/core-components/layout/_layout-container.scss +168 -168
  60. package/src/scss/core-components/layout/_layout-responsive.scss +99 -99
  61. package/src/scss/core-components/layout/_navbar-elements.scss +250 -250
  62. package/src/scss/core-components/layout/_navbar.scss +83 -83
  63. package/src/scss/core-components/layout/_sidebar-states.scss +237 -237
  64. package/src/scss/core-components/layout/_sidebar.scss +234 -234
  65. package/src/scss/main.scss +7 -7
  66. package/src/scss/utilities.scss +740 -740
  67. package/src/scss/variables/_base.scss +228 -228
  68. package/src/scss/variables/_components.scss +748 -748
  69. package/src/scss/variables/_layout.scss +65 -65
  70. 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
+