@mendylanda/ui 0.3.0-alpha.1 → 0.3.0-alpha.10

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 (55) hide show
  1. package/README.md +20 -3
  2. package/dist/class-names.js +1 -1
  3. package/dist/filters/filter-bar.d.ts +1 -1
  4. package/dist/filters/filter-bar.js +53 -12
  5. package/dist/filters/filter-menu-focus.d.ts +1 -1
  6. package/dist/filters/filter-menu-panel.d.ts +1 -1
  7. package/dist/filters/use-menu-placement.d.ts +1 -1
  8. package/dist/primitives/popover.d.ts +5 -0
  9. package/dist/primitives/popover.js +10 -0
  10. package/dist/styles.css +147 -17
  11. package/dist/styles.tailwind3.css +147 -17
  12. package/dist/table/clipboard.d.ts +1 -1
  13. package/dist/table/clipboard.js +35 -22
  14. package/dist/table/column-widths.d.ts +9 -0
  15. package/dist/table/column-widths.js +23 -0
  16. package/dist/table/columns.d.ts +6 -0
  17. package/dist/table/columns.js +4 -0
  18. package/dist/table/data-table.d.ts +3 -0
  19. package/dist/table/data-table.js +6 -3
  20. package/dist/table/index.d.ts +1 -0
  21. package/dist/table/index.js +1 -0
  22. package/dist/table/table-column-settings.d.ts +6 -0
  23. package/dist/table/table-column-settings.js +55 -0
  24. package/dist/table/table-controls.d.ts +1 -3
  25. package/dist/table/table-controls.js +4 -45
  26. package/dist/table/table-feedback.d.ts +5 -1
  27. package/dist/table/table-feedback.js +4 -3
  28. package/dist/table/table-filters.d.ts +8 -0
  29. package/dist/table/table-filters.js +9 -0
  30. package/dist/table/table-frame.d.ts +10 -0
  31. package/dist/table/table-frame.js +10 -0
  32. package/dist/table/table-layout.d.ts +1 -0
  33. package/dist/table/table-layout.js +27 -10
  34. package/dist/table/table-loading.d.ts +2 -1
  35. package/dist/table/table-loading.js +4 -3
  36. package/dist/table/table-parts.d.ts +20 -2
  37. package/dist/table/table-parts.js +91 -37
  38. package/dist/table/table-view.d.ts +19 -2
  39. package/dist/table/table-view.js +58 -19
  40. package/dist/table/use-column-window.d.ts +42 -0
  41. package/dist/table/use-column-window.js +65 -0
  42. package/dist/table/use-data-table.d.ts +2 -2
  43. package/dist/table/use-data-table.js +15 -2
  44. package/dist/table/use-fill-layout.d.ts +2 -0
  45. package/dist/table/use-fill-layout.js +67 -0
  46. package/dist/table/use-inline-row-selection.d.ts +10 -0
  47. package/dist/table/use-inline-row-selection.js +33 -0
  48. package/dist/table/use-stable-array.d.ts +3 -0
  49. package/dist/table/use-stable-array.js +16 -0
  50. package/dist/table/use-table-interaction.d.ts +1 -1
  51. package/dist/table/use-table-interaction.js +32 -3
  52. package/dist/table/use-table-results.d.ts +8 -0
  53. package/dist/table/use-table-results.js +63 -0
  54. package/dist/utils.js +13 -2
  55. package/package.json +8 -7
@@ -16,6 +16,7 @@
16
16
  --font-weight-semibold: 600;
17
17
  --tracking-widest: 0.1em;
18
18
  --drop-shadow-md: 0 3px 3px rgb(0 0 0 / 0.12);
19
+ --animate-spin: mendy-spin 1s linear infinite;
19
20
  --animate-pulse: mendy-pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
20
21
  --default-transition-duration: 150ms;
21
22
  --default-transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
@@ -101,6 +102,9 @@
101
102
  .mui-014aadadffad:where([data-mendy-ui], [data-mendy-ui] *) {
102
103
  isolation: isolate;
103
104
  }
105
+ .mui-d7efd1b0b0f9:where([data-mendy-ui], [data-mendy-ui] *) {
106
+ z-index: 1;
107
+ }
104
108
  .mui-418e44ad4f9e:where([data-mendy-ui], [data-mendy-ui] *) {
105
109
  z-index: 10;
106
110
  }
@@ -152,6 +156,12 @@
152
156
  .mui-8cc46fa87f41:where([data-mendy-ui], [data-mendy-ui] *) {
153
157
  margin-inline-end: calc(var(--spacing) * -1.5);
154
158
  }
159
+ .mui-477d8f4dfce9:where([data-mendy-ui], [data-mendy-ui] *) {
160
+ margin-inline-end: calc(var(--spacing) * 1);
161
+ }
162
+ .mui-68d781378b03:where([data-mendy-ui], [data-mendy-ui] *) {
163
+ margin-inline-end: calc(var(--spacing) * 2);
164
+ }
155
165
  .mui-f28fea81a5cd:where([data-mendy-ui], [data-mendy-ui] *) {
156
166
  margin-top: calc(var(--spacing) * 2);
157
167
  }
@@ -208,6 +218,10 @@
208
218
  width: calc(var(--spacing) * 4);
209
219
  height: calc(var(--spacing) * 4);
210
220
  }
221
+ .mui-2bd43fb57913:where([data-mendy-ui], [data-mendy-ui] *) {
222
+ width: calc(var(--spacing) * 5);
223
+ height: calc(var(--spacing) * 5);
224
+ }
211
225
  .mui-0712570dcc9f:where([data-mendy-ui], [data-mendy-ui] *) {
212
226
  width: calc(var(--spacing) * 6);
213
227
  height: calc(var(--spacing) * 6);
@@ -247,6 +261,9 @@
247
261
  .mui-ce1945804664:where([data-mendy-ui], [data-mendy-ui] *) {
248
262
  height: calc(var(--spacing) * 6);
249
263
  }
264
+ .mui-c8e50836f8a1:where([data-mendy-ui], [data-mendy-ui] *) {
265
+ height: calc(var(--spacing) * 7);
266
+ }
250
267
  .mui-1fb07b38c63b:where([data-mendy-ui], [data-mendy-ui] *) {
251
268
  height: calc(var(--spacing) * 8);
252
269
  }
@@ -271,8 +288,11 @@
271
288
  .mui-1f061e70178e:where([data-mendy-ui], [data-mendy-ui] *) {
272
289
  max-height: var(--radix-dropdown-menu-content-available-height);
273
290
  }
274
- .mui-b057efba3283:where([data-mendy-ui], [data-mendy-ui] *) {
275
- max-height: calc(var(--spacing) * 96);
291
+ .mui-4d3f1304ebb2:where([data-mendy-ui], [data-mendy-ui] *) {
292
+ max-height: var(--radix-popover-content-available-height);
293
+ }
294
+ .mui-da0beef015c9:where([data-mendy-ui], [data-mendy-ui] *) {
295
+ max-height: 400px;
276
296
  }
277
297
  .mui-80baa5d03af7:where([data-mendy-ui], [data-mendy-ui] *) {
278
298
  max-height: calc(var(--filter-menu-height) - 2px);
@@ -286,6 +306,9 @@
286
306
  .mui-dcd942c18ddc:where([data-mendy-ui], [data-mendy-ui] *) {
287
307
  max-height: var(--radix-dropdown-menu-content-available-height);
288
308
  }
309
+ .mui-7bd696ca6be3:where([data-mendy-ui], [data-mendy-ui] *) {
310
+ max-height: 100%;
311
+ }
289
312
  .mui-410da8dfa8ac:where([data-mendy-ui], [data-mendy-ui] *) {
290
313
  min-height: calc(var(--spacing) * 0);
291
314
  }
@@ -313,12 +336,12 @@
313
336
  .mui-4ac4ec8dfbce:where([data-mendy-ui], [data-mendy-ui] *) {
314
337
  width: calc(var(--spacing) * 40);
315
338
  }
316
- .mui-72b37c1a040d:where([data-mendy-ui], [data-mendy-ui] *) {
317
- width: calc(var(--spacing) * 64);
318
- }
319
339
  .mui-37535002f0f7:where([data-mendy-ui], [data-mendy-ui] *) {
320
340
  width: calc(var(--spacing) * 72);
321
341
  }
342
+ .mui-a4cce7869436:where([data-mendy-ui], [data-mendy-ui] *) {
343
+ width: 300px;
344
+ }
322
345
  .mui-fc6a57ff7553:where([data-mendy-ui], [data-mendy-ui] *) {
323
346
  width: var(--mendy-filter-editor-width,19rem);
324
347
  }
@@ -364,6 +387,9 @@
364
387
  .mui-27ead27a81df:where([data-mendy-ui], [data-mendy-ui] *) {
365
388
  flex-shrink: 0;
366
389
  }
390
+ .mui-adca5146416e:where([data-mendy-ui], [data-mendy-ui] *) {
391
+ flex-grow: 1;
392
+ }
367
393
  .mui-215061302c50:where([data-mendy-ui], [data-mendy-ui] *) {
368
394
  border-collapse: collapse;
369
395
  }
@@ -374,6 +400,12 @@
374
400
  --mendy-tw-translate-y: calc(calc(1 / 2 * 100%) * -1);
375
401
  translate: var(--mendy-tw-translate-x) var(--mendy-tw-translate-y);
376
402
  }
403
+ .mui-4e3f08588318:where([data-mendy-ui], [data-mendy-ui] *) {
404
+ rotate: calc(45deg * -1);
405
+ }
406
+ .mui-c80411b7591f:where([data-mendy-ui], [data-mendy-ui] *) {
407
+ rotate: 45deg;
408
+ }
377
409
  .mui-aa214ea38326:where([data-mendy-ui], [data-mendy-ui] *) {
378
410
  transform: var(--mendy-tw-rotate-x,) var(--mendy-tw-rotate-y,) var(--mendy-tw-rotate-z,) var(--mendy-tw-skew-x,) var(--mendy-tw-skew-y,);
379
411
  }
@@ -383,12 +415,21 @@
383
415
  .mui-7b3cd77eb999:where([data-mendy-ui], [data-mendy-ui] *) {
384
416
  animation: var(--animate-pulse);
385
417
  }
418
+ .mui-2c14b55d77e6:where([data-mendy-ui], [data-mendy-ui] *) {
419
+ animation: var(--animate-spin);
420
+ }
386
421
  .mui-2194d094b585:where([data-mendy-ui], [data-mendy-ui] *) {
387
422
  cursor: col-resize;
388
423
  }
389
424
  .mui-d343f41ba73e:where([data-mendy-ui], [data-mendy-ui] *) {
390
425
  cursor: default;
391
426
  }
427
+ .mui-f2e47d9c52ad:where([data-mendy-ui], [data-mendy-ui] *) {
428
+ cursor: grab;
429
+ }
430
+ .mui-d2fa8848968d:where([data-mendy-ui], [data-mendy-ui] *) {
431
+ cursor: pointer;
432
+ }
392
433
  .mui-739a9a000791:where([data-mendy-ui], [data-mendy-ui] *) {
393
434
  touch-action: none;
394
435
  }
@@ -550,6 +591,9 @@
550
591
  border-color: color-mix(in oklab, var(--muted-foreground, #737373) 50%, transparent);
551
592
  }
552
593
  }
594
+ .mui-515f9fdc6db7:where([data-mendy-ui], [data-mendy-ui] *) {
595
+ border-color: var(--primary, #171717);
596
+ }
553
597
  .mui-292affc1f780:where([data-mendy-ui], [data-mendy-ui] *) {
554
598
  background-color: var(--accent, #f5f5f5);
555
599
  }
@@ -568,6 +612,9 @@
568
612
  .mui-047624ec0c39:where([data-mendy-ui], [data-mendy-ui] *) {
569
613
  background-color: var(--color-green-100);
570
614
  }
615
+ .mui-6ba846e1630e:where([data-mendy-ui], [data-mendy-ui] *) {
616
+ background-color: inherit;
617
+ }
571
618
  .mui-87ecb59f2d2d:where([data-mendy-ui], [data-mendy-ui] *) {
572
619
  background-color: var(--muted, #f5f5f5);
573
620
  }
@@ -637,6 +684,12 @@
637
684
  .mui-b5edc3ea7c91:where([data-mendy-ui], [data-mendy-ui] *) {
638
685
  padding-block: calc(var(--spacing) * 2);
639
686
  }
687
+ .mui-d3cea061f2f3:where([data-mendy-ui], [data-mendy-ui] *) {
688
+ padding-block: calc(var(--spacing) * 3);
689
+ }
690
+ .mui-96b92a971c95:where([data-mendy-ui], [data-mendy-ui] *) {
691
+ padding-block: calc(var(--spacing) * 5);
692
+ }
640
693
  .mui-078d945937da:where([data-mendy-ui], [data-mendy-ui] *) {
641
694
  padding-inline-start: calc(var(--spacing) * 8);
642
695
  }
@@ -777,6 +830,13 @@
777
830
  --mendy-tw-shadow: 0 1px 2px 0 var(--mendy-tw-shadow-color, rgb(0 0 0 / 0.05));
778
831
  box-shadow: var(--mendy-tw-inset-shadow), var(--mendy-tw-inset-ring-shadow), var(--mendy-tw-ring-offset-shadow), var(--mendy-tw-ring-shadow), var(--mendy-tw-shadow);
779
832
  }
833
+ .mui-853be6c11609:where([data-mendy-ui], [data-mendy-ui] *) {
834
+ --mendy-tw-ring-shadow: var(--mendy-tw-ring-inset,) 0 0 0 calc(2px + var(--mendy-tw-ring-offset-width)) var(--mendy-tw-ring-color, currentcolor);
835
+ box-shadow: var(--mendy-tw-inset-shadow), var(--mendy-tw-inset-ring-shadow), var(--mendy-tw-ring-offset-shadow), var(--mendy-tw-ring-shadow), var(--mendy-tw-shadow);
836
+ }
837
+ .mui-fd9d0b696aac:where([data-mendy-ui], [data-mendy-ui] *) {
838
+ --mendy-tw-ring-color: var(--primary, #171717);
839
+ }
780
840
  .mui-59edd3d33673:where([data-mendy-ui], [data-mendy-ui] *) {
781
841
  --mendy-tw-outline-style: none;
782
842
  outline-style: none;
@@ -789,6 +849,10 @@
789
849
  outline-style: var(--mendy-tw-outline-style);
790
850
  outline-width: 1px;
791
851
  }
852
+ .mui-e42932b7a79c:where([data-mendy-ui], [data-mendy-ui] *) {
853
+ --mendy-tw-blur: blur(8px);
854
+ filter: var(--mendy-tw-blur,) var(--mendy-tw-brightness,) var(--mendy-tw-contrast,) var(--mendy-tw-grayscale,) var(--mendy-tw-hue-rotate,) var(--mendy-tw-invert,) var(--mendy-tw-saturate,) var(--mendy-tw-sepia,) var(--mendy-tw-drop-shadow,);
855
+ }
792
856
  .mui-e0122edc668b:where([data-mendy-ui], [data-mendy-ui] *) {
793
857
  --mendy-tw-drop-shadow-size: drop-shadow(0 3px 3px var(--mendy-tw-drop-shadow-color, rgb(0 0 0 / 0.12)));
794
858
  --mendy-tw-drop-shadow: drop-shadow(var(--drop-shadow-md));
@@ -853,6 +917,13 @@
853
917
  }
854
918
  }
855
919
  }
920
+ .mui-34a57d4b4103:where([data-mendy-ui], [data-mendy-ui] *) {
921
+ &:is(:where(.mui-ad936fcbed63):hover *) {
922
+ @media (hover: hover) {
923
+ opacity: 50%;
924
+ }
925
+ }
926
+ }
856
927
  .mui-9af9a4182597:where([data-mendy-ui], [data-mendy-ui] *) {
857
928
  &:is(:where(.mui-ad936fcbed63)[data-disabled="true"] *) {
858
929
  pointer-events: none;
@@ -938,12 +1009,6 @@
938
1009
  border-inline-start-width: 0px;
939
1010
  }
940
1011
  }
941
- .mui-beeef6663906:where([data-mendy-ui], [data-mendy-ui] *) {
942
- &:last-child {
943
- border-inline-end-style: var(--mendy-tw-border-style);
944
- border-inline-end-width: 0px;
945
- }
946
- }
947
1012
  .mui-37ad15a95595:where([data-mendy-ui], [data-mendy-ui] *) {
948
1013
  &:hover {
949
1014
  @media (hover: hover) {
@@ -951,22 +1016,22 @@
951
1016
  }
952
1017
  }
953
1018
  }
954
- .mui-63b29dace366:where([data-mendy-ui], [data-mendy-ui] *) {
1019
+ .mui-bb6a4b3e902d:where([data-mendy-ui], [data-mendy-ui] *) {
955
1020
  &:hover {
956
1021
  @media (hover: hover) {
957
- background-color: var(--accent, #f5f5f5);
1022
+ background-color: var(--destructive, #dc2626);
958
1023
  @supports (color: color-mix(in lab, red, red)) {
959
- background-color: color-mix(in oklab, var(--accent, #f5f5f5) 50%, transparent);
1024
+ background-color: color-mix(in oklab, var(--destructive, #dc2626) 90%, transparent);
960
1025
  }
961
1026
  }
962
1027
  }
963
1028
  }
964
- .mui-bb6a4b3e902d:where([data-mendy-ui], [data-mendy-ui] *) {
1029
+ .mui-5cbdd1b32f1a:where([data-mendy-ui], [data-mendy-ui] *) {
965
1030
  &:hover {
966
1031
  @media (hover: hover) {
967
- background-color: var(--destructive, #dc2626);
1032
+ background-color: var(--muted, #f5f5f5);
968
1033
  @supports (color: color-mix(in lab, red, red)) {
969
- background-color: color-mix(in oklab, var(--destructive, #dc2626) 90%, transparent);
1034
+ background-color: color-mix(in oklab, var(--muted, #f5f5f5) 50%, transparent);
970
1035
  }
971
1036
  }
972
1037
  }
@@ -1059,6 +1124,11 @@
1059
1124
  }
1060
1125
  }
1061
1126
  }
1127
+ .mui-b8b1747fa763:where([data-mendy-ui], [data-mendy-ui] *) {
1128
+ &:focus-visible {
1129
+ opacity: 100%;
1130
+ }
1131
+ }
1062
1132
  .mui-39be5a15b766:where([data-mendy-ui], [data-mendy-ui] *) {
1063
1133
  &:focus-visible {
1064
1134
  --mendy-tw-ring-shadow: var(--mendy-tw-ring-inset,) 0 0 0 calc(1px + var(--mendy-tw-ring-offset-width)) var(--mendy-tw-ring-color, currentcolor);
@@ -1128,6 +1198,11 @@
1128
1198
  --mendy-tw-ring-inset: inset;
1129
1199
  }
1130
1200
  }
1201
+ .mui-71998ea7a2d0:where([data-mendy-ui], [data-mendy-ui] *) {
1202
+ &:active {
1203
+ cursor: grabbing;
1204
+ }
1205
+ }
1131
1206
  .mui-8d3c1014b967:where([data-mendy-ui], [data-mendy-ui] *) {
1132
1207
  &:disabled {
1133
1208
  pointer-events: none;
@@ -1138,11 +1213,25 @@
1138
1213
  cursor: not-allowed;
1139
1214
  }
1140
1215
  }
1216
+ .mui-d2e4a66bb430:where([data-mendy-ui], [data-mendy-ui] *) {
1217
+ &:disabled {
1218
+ opacity: 0% !important;
1219
+ }
1220
+ }
1141
1221
  .mui-4600b77303d6:where([data-mendy-ui], [data-mendy-ui] *) {
1142
1222
  &:disabled {
1143
1223
  opacity: 50%;
1144
1224
  }
1145
1225
  }
1226
+ .mui-978f422895e5:where([data-mendy-ui], [data-mendy-ui] *) {
1227
+ &:is(:where(.mui-ad936fcbed63):hover *) {
1228
+ @media (hover: hover) {
1229
+ &:disabled {
1230
+ opacity: 50% !important;
1231
+ }
1232
+ }
1233
+ }
1234
+ }
1146
1235
  .mui-7eb7501a2ef0:where([data-mendy-ui], [data-mendy-ui] *) {
1147
1236
  &:has(*:focus) {
1148
1237
  border-color: var(--ring, #737373);
@@ -1355,6 +1444,18 @@
1355
1444
  color: var(--primary-foreground, #fafafa);
1356
1445
  }
1357
1446
  }
1447
+ .mui-d0c2ae8419e1:where([data-mendy-ui], [data-mendy-ui] *) {
1448
+ &[data-state="checked"] {
1449
+ opacity: 100%;
1450
+ }
1451
+ }
1452
+ .mui-9c02852bfc55:where([data-mendy-ui], [data-mendy-ui] *) {
1453
+ &[data-state="checked"] {
1454
+ &:disabled {
1455
+ opacity: 100% !important;
1456
+ }
1457
+ }
1458
+ }
1358
1459
  .mui-37d8a3f448ff:where([data-mendy-ui], [data-mendy-ui] *) {
1359
1460
  &[data-state="closed"] {
1360
1461
  animation: none !important;
@@ -1377,6 +1478,18 @@
1377
1478
  --mendy-tw-exit-scale: .95;
1378
1479
  }
1379
1480
  }
1481
+ .mui-e2ed522ed9b7:where([data-mendy-ui], [data-mendy-ui] *) {
1482
+ &[data-state="indeterminate"] {
1483
+ opacity: 100%;
1484
+ }
1485
+ }
1486
+ .mui-cbd3aed703f7:where([data-mendy-ui], [data-mendy-ui] *) {
1487
+ &[data-state="indeterminate"] {
1488
+ &:disabled {
1489
+ opacity: 100% !important;
1490
+ }
1491
+ }
1492
+ }
1380
1493
  .mui-bae1e782f277:where([data-mendy-ui], [data-mendy-ui] *) {
1381
1494
  &[data-state="open"] {
1382
1495
  animation: mendy-enter var(--mendy-tw-animation-duration,var(--mendy-tw-duration,.15s))var(--mendy-tw-ease,ease)var(--mendy-tw-animation-delay,0s)var(--mendy-tw-animation-iteration-count,1)var(--mendy-tw-animation-direction,normal)var(--mendy-tw-animation-fill-mode,none);
@@ -1703,6 +1816,18 @@
1703
1816
  color: var(--muted-foreground, #737373);
1704
1817
  }
1705
1818
  }
1819
+ .mui-fa8e1efead3c:where([data-mendy-ui], [data-mendy-ui] *) {
1820
+ @media (hover:none) {
1821
+ opacity: 100%;
1822
+ }
1823
+ }
1824
+ .mui-eaedb91f8774:where([data-mendy-ui], [data-mendy-ui] *) {
1825
+ @media (hover:none) {
1826
+ &:disabled {
1827
+ opacity: 100% !important;
1828
+ }
1829
+ }
1830
+ }
1706
1831
  .mui-b8293c91796c:where([data-mendy-ui], [data-mendy-ui] *) {
1707
1832
  [data-slot=card-content] & {
1708
1833
  background-color: transparent;
@@ -2029,6 +2154,11 @@
2029
2154
  syntax: "*";
2030
2155
  inherits: false;
2031
2156
  }
2157
+ @keyframes mendy-spin {
2158
+ to {
2159
+ transform: rotate(360deg);
2160
+ }
2161
+ }
2032
2162
  @keyframes mendy-pulse {
2033
2163
  50% {
2034
2164
  opacity: 0.5;
@@ -1,5 +1,5 @@
1
1
  import type { DataTableInstance } from "./use-data-table.js";
2
- export declare const interactiveSelector = "button, a, input, textarea, select, [contenteditable]:not([contenteditable=\"false\"]), [role=\"checkbox\"], [role=\"button\"], [role=\"textbox\"]";
2
+ export declare const interactiveSelector = "button, a, summary, input, textarea, select, [contenteditable]:not([contenteditable=\"false\"]), [role=\"checkbox\"], [role=\"button\"], [role=\"textbox\"]";
3
3
  export declare function selectedCellsText<T extends object>(table: DataTableInstance<T>): string;
4
4
  export declare function tableCsv<T extends object>(table: DataTableInstance<T>, options?: {
5
5
  selectedOnly?: boolean;
@@ -1,27 +1,40 @@
1
+ import { constructCell } from "@tanstack/react-table";
1
2
  import { csvValue, tsvValue } from "./state.js";
2
- export const interactiveSelector = 'button, a, input, textarea, select, [contenteditable]:not([contenteditable="false"]), [role="checkbox"], [role="button"], [role="textbox"]';
3
+ export const interactiveSelector = 'button, a, summary, input, textarea, select, [contenteditable]:not([contenteditable="false"]), [role="checkbox"], [role="button"], [role="textbox"]';
3
4
  export function selectedCellsText(table) {
4
- const selected = new Set(table.getSelectedCellIds());
5
- const rows = table
6
- .getRowsInDisplayOrder()
7
- .filter((row) => row.getVisibleCells().some((cell) => selected.has(cell.id)));
8
- const columns = new Set(rows.flatMap((row) => row
9
- .getVisibleCells()
10
- .filter((cell) => selected.has(cell.id))
11
- .map((cell) => cell.column.id)));
12
- return rows
13
- .map((row) => row
14
- .getVisibleCells()
15
- .filter((cell) => columns.has(cell.column.id))
16
- .map((cell) => {
17
- if (!selected.has(cell.id))
18
- return "";
19
- const definition = cell.column.columnDef;
20
- return tsvValue(definition.copyValue?.(row.original) ??
21
- definition.getCellValue?.(row.original) ??
22
- String(cell.getValue() ?? ""));
23
- })
24
- .join("\t"))
5
+ const rows = table.getRowsInDisplayOrder();
6
+ const columns = [
7
+ ...table.getStartVisibleLeafColumns(),
8
+ ...table.getCenterVisibleLeafColumns(),
9
+ ...table.getEndVisibleLeafColumns(),
10
+ ];
11
+ // Bounds already resolve include/exclude operations in display order. Visiting
12
+ // only these cells avoids materializing every column of every selected row.
13
+ const values = new Map();
14
+ const includedColumns = new Set();
15
+ for (const bounds of table.getCellSelectionBounds()) {
16
+ for (let r = bounds.minRowIndex; r <= bounds.maxRowIndex; r++) {
17
+ const row = rows[r];
18
+ for (let c = bounds.minColumnIndex; c <= bounds.maxColumnIndex; c++) {
19
+ const column = columns[c];
20
+ const cell = constructCell(column, row, row.table);
21
+ if (!cell.getCanSelect())
22
+ continue;
23
+ const definition = column.columnDef;
24
+ let rowValues = values.get(r);
25
+ if (!rowValues)
26
+ values.set(r, (rowValues = new Map()));
27
+ rowValues.set(c, tsvValue(definition.copyValue?.(row.original) ??
28
+ definition.getCellValue?.(row.original) ??
29
+ String(cell.getValue() ?? "")));
30
+ includedColumns.add(c);
31
+ }
32
+ }
33
+ }
34
+ const columnIndexes = [...includedColumns].sort((a, b) => a - b);
35
+ return [...values]
36
+ .sort(([a], [b]) => a - b)
37
+ .map(([, row]) => columnIndexes.map((c) => row.get(c) ?? "").join("\t"))
25
38
  .join("\n");
26
39
  }
27
40
  export function tableCsv(table, options = {}) {
@@ -0,0 +1,9 @@
1
+ interface WidthColumn {
2
+ id: string;
3
+ size: number;
4
+ maxSize: number;
5
+ grow: number | false;
6
+ }
7
+ /** Allocate spare space without changing stored or user-resized column widths. */
8
+ export declare function distributeColumnWidths(columns: WidthColumn[], viewport: number | null): Map<string, number>;
9
+ export {};
@@ -0,0 +1,23 @@
1
+ /** Allocate spare space without changing stored or user-resized column widths. */
2
+ export function distributeColumnWidths(columns, viewport) {
3
+ const widths = new Map(columns.map((column) => [column.id, column.size]));
4
+ let spare = (viewport ?? 0) - columns.reduce((sum, column) => sum + column.size, 0);
5
+ let flexible = columns.filter((column) => typeof column.grow === "number" &&
6
+ Number.isFinite(column.grow) &&
7
+ column.grow > 0 &&
8
+ column.maxSize > column.size);
9
+ while (spare > 0.01 && flexible.length) {
10
+ const unit = flexible.reduce((max, column) => Math.max(max, Number(column.grow)), 0);
11
+ const weight = flexible.reduce((sum, column) => sum + Number(column.grow) / unit, 0);
12
+ let used = 0;
13
+ for (const column of flexible) {
14
+ const size = widths.get(column.id);
15
+ const extra = Math.min(column.maxSize - size, spare * (Number(column.grow) / unit / weight));
16
+ widths.set(column.id, size + extra);
17
+ used += extra;
18
+ }
19
+ spare -= used;
20
+ flexible = flexible.filter((column) => column.maxSize - widths.get(column.id) > 0.01);
21
+ }
22
+ return widths;
23
+ }
@@ -4,6 +4,8 @@ import type { DataTableFeatures } from "./features.js";
4
4
  export type TableColumn<T extends object> = ColumnDef<DataTableFeatures, T> & {
5
5
  label?: string;
6
6
  align?: "start" | "center" | "end";
7
+ /** Share of spare viewport width. Defaults to 1 for data columns, false for display columns. */
8
+ grow?: number | false;
7
9
  defaultHidden?: boolean;
8
10
  pin?: "start" | "end";
9
11
  copyValue?: (row: T) => string;
@@ -28,6 +30,7 @@ export interface ValueFormat<V> {
28
30
  interface ValueOptions<T extends object, V> {
29
31
  label: string;
30
32
  size?: number;
33
+ grow?: number | false;
31
34
  minSize?: number;
32
35
  maxSize?: number;
33
36
  hidden?: boolean;
@@ -48,6 +51,9 @@ interface ColumnBuilder<T extends object> {
48
51
  label: string;
49
52
  render: (row: T) => ReactNode;
50
53
  size?: number;
54
+ minSize?: number;
55
+ maxSize?: number;
56
+ grow?: number | false;
51
57
  pin?: "start" | "end";
52
58
  }): TableColumn<T>;
53
59
  }
@@ -9,6 +9,7 @@ function valueColumn(id, value, options) {
9
9
  header: options.label,
10
10
  label: options.label,
11
11
  size: options.size,
12
+ grow: options.grow,
12
13
  minSize: options.minSize,
13
14
  maxSize: options.maxSize,
14
15
  defaultHidden: options.hidden,
@@ -45,6 +46,9 @@ export function defineColumns(define) {
45
46
  label: options.label,
46
47
  header: options.label,
47
48
  size: options.size,
49
+ minSize: options.minSize,
50
+ maxSize: options.maxSize,
51
+ grow: options.grow ?? false,
48
52
  pin: options.pin,
49
53
  enableSorting: false,
50
54
  enableCellSelection: false,
@@ -1,11 +1,14 @@
1
1
  import type { ReactNode } from "react";
2
2
  import type { UseDataTableOptions, DataTableInstance } from "./use-data-table.js";
3
3
  import type { TableViewProps } from "./table-view.js";
4
+ import { type TableFiltersProps } from "./table-filters.js";
4
5
  type Appearance<T extends object> = Omit<TableViewProps<T>, "table"> & {
5
6
  toolbar?: ReactNode;
6
7
  footer?: ReactNode;
7
8
  showColumnSettings?: boolean;
8
9
  showPagination?: boolean;
10
+ /** Customize the built-in filter bar, or render it yourself with false. */
11
+ filterBar?: Omit<TableFiltersProps, "filters"> | false;
9
12
  };
10
13
  export type DataTableProps<T extends object> = Appearance<T> & (UseDataTableOptions<T> | {
11
14
  table: DataTableInstance<T>;
@@ -1,10 +1,13 @@
1
1
  "use client";
2
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
3
3
  import { useDataTable } from "./use-data-table.js";
4
4
  import { TableView } from "./table-view.js";
5
5
  import { TableColumnSettings, TablePagination } from "./table-controls.js";
6
- function ControlledTable({ table, toolbar, footer, showColumnSettings = true, showPagination = false, ...view }) {
7
- return (_jsxs("div", { "data-mendy-ui": "", className: "mui-184ddc11e5f9 mui-267171770524", children: [(toolbar || showColumnSettings) && (_jsxs("div", { className: "mui-222f930b8752 mui-faa8a23c68f6 mui-b9677bd1cb66 mui-32c92bb1fde4 mui-074569488cca", children: [_jsx("div", { className: "mui-184ddc11e5f9 mui-7bd5bab6d7f4", children: toolbar }), showColumnSettings && _jsx(TableColumnSettings, { table: table })] })), _jsx(TableView, { table: table, ...view }), showPagination && (_jsx(TablePagination, { table: table, loading: view.status === "loading" || view.refreshing })), footer] }));
6
+ import { TableFilters } from "./table-filters.js";
7
+ import { TableFrame } from "./table-frame.js";
8
+ function ControlledTable({ table, toolbar, footer, showColumnSettings = true, showPagination = false, filters, filterBar, layout = "content", ...view }) {
9
+ const fill = layout === "fill";
10
+ return (_jsx(TableFrame, { layout: layout, slot: "data-table", header: (toolbar || showColumnSettings || (filters && filterBar !== false)) && (_jsxs("div", { className: "mui-222f930b8752 mui-27ead27a81df mui-faa8a23c68f6 mui-b9677bd1cb66 mui-32c92bb1fde4 mui-074569488cca", children: [_jsxs("div", { className: "mui-184ddc11e5f9 mui-7bd5bab6d7f4 mui-267171770524", children: [filters && filterBar !== false && _jsx(TableFilters, { ...filterBar, filters: filters }), !filters && toolbar] }), filters && toolbar, showColumnSettings && _jsx(TableColumnSettings, { table: table })] })), footer: showPagination || footer ? (_jsxs(_Fragment, { children: [showPagination && (_jsx("div", { className: "mui-27ead27a81df", children: _jsx(TablePagination, { table: table, loading: view.status === "loading" || view.refreshing }) })), footer] })) : undefined, children: _jsx(TableView, { table: table, filters: filters, ...view, height: fill ? "100%" : view.height }) }));
8
11
  }
9
12
  function ConfiguredTable(props) {
10
13
  const table = useDataTable(props);
@@ -6,4 +6,5 @@ export * from "./use-result-selection.js";
6
6
  export * from "./table-view.js";
7
7
  export * from "./table-controls.js";
8
8
  export * from "./data-table.js";
9
+ export * from "./table-filters.js";
9
10
  export * from "./clipboard.js";
@@ -6,4 +6,5 @@ export * from "./use-result-selection.js";
6
6
  export * from "./table-view.js";
7
7
  export * from "./table-controls.js";
8
8
  export * from "./data-table.js";
9
+ export * from "./table-filters.js";
9
10
  export * from "./clipboard.js";
@@ -0,0 +1,6 @@
1
+ import type { ReactNode } from "react";
2
+ import type { DataTableInstance } from "./use-data-table.js";
3
+ export declare function TableColumnSettings<T extends object>({ table, children, }: {
4
+ table: DataTableInstance<T>;
5
+ children?: ReactNode;
6
+ }): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,55 @@
1
+ "use client";
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { useId } from "react";
4
+ import { DragDropContext, Draggable, Droppable } from "@hello-pangea/dnd";
5
+ import { GripVertical, Pin, RotateCcw, SlidersHorizontal } from "lucide-react";
6
+ import { useMendyUI } from "../customization.js";
7
+ import { Button } from "../primitives/button.js";
8
+ import { Checkbox } from "../primitives/checkbox.js";
9
+ import { Popover, PopoverContent, PopoverTrigger } from "../primitives/popover.js";
10
+ import { cn } from "../utils.js";
11
+ import { applyTablePreferences } from "./use-data-table.js";
12
+ export function TableColumnSettings({ table, children, }) {
13
+ const id = useId();
14
+ const { portalContainer } = useMendyUI();
15
+ const columns = table.getAllLeafColumns();
16
+ const byId = new Map(columns.map((column) => [column.id, column]));
17
+ const order = [
18
+ ...new Set([...table.state.columnOrder, ...columns.map((column) => column.id)]),
19
+ ].filter((key) => byId.has(key));
20
+ const ordered = order.map((key) => byId.get(key));
21
+ const hidden = columns.filter((column) => !column.getIsVisible()).length;
22
+ const start = columns.filter((column) => column.getIsPinned() === "start").length;
23
+ const end = columns.filter((column) => column.getIsPinned() === "end").length;
24
+ const summary = [
25
+ hidden && `${hidden} hidden`,
26
+ start && `${start} pinned left`,
27
+ end && `${end} pinned right`,
28
+ ]
29
+ .filter(Boolean)
30
+ .join(", ");
31
+ function reorder(result) {
32
+ if (!result.destination || result.destination.index === result.source.index)
33
+ return;
34
+ const next = [...order];
35
+ const [moved] = next.splice(result.source.index, 1);
36
+ next.splice(result.destination.index, 0, moved);
37
+ table.setColumnOrder(next);
38
+ }
39
+ return (_jsxs(Popover, { children: [_jsx(PopoverTrigger, { asChild: true, children: _jsx(Button, { variant: "outline", size: "icon-sm", "aria-label": "Column settings", title: "Column settings", children: _jsx(SlidersHorizontal, { className: "mui-100c22d5776b" }) }) }), _jsxs(PopoverContent, { align: "end", "aria-label": "Column settings", className: "mui-222f930b8752 mui-a4cce7869436 mui-302c0d124a94 mui-04760bcd507f", onCloseAutoFocus: (event) => {
40
+ if (document.activeElement?.closest('[role="grid"]'))
41
+ event.preventDefault();
42
+ }, children: [_jsxs("div", { className: "mui-27ead27a81df mui-bbe39cfb5cc6 mui-9513b3968002 mui-d3cea061f2f3", children: [_jsx("h4", { className: "mui-c74ab393b96d mui-daaac3fbf55e", children: "Column settings" }), _jsx("p", { className: "mui-3992de70b033 mui-35f35c41d134", children: "Drag to reorder, toggle visibility, and pin columns." })] }), children, _jsx(DragDropContext, { onDragEnd: reorder, children: _jsx(Droppable, { droppableId: id, getContainerForClone: () => portalContainer ?? document.body, renderClone: (provided, snapshot, rubric) => (_jsx(ColumnSettingsRow, { column: ordered[rubric.source.index], provided: provided, dragging: snapshot.isDragging })), children: (provided) => (_jsxs("div", { ref: provided.innerRef, ...provided.droppableProps, className: "mui-410da8dfa8ac mui-da0beef015c9 mui-2368e909f3a5 mui-b97db4a9f432", children: [ordered.map((column, index) => (_jsx(Draggable, { draggableId: `${id}-${column.id}`, disableInteractiveElementBlocking: true, index: index, children: (provided, snapshot) => (_jsx(ColumnSettingsRow, { column: column, provided: provided, dragging: snapshot.isDragging })) }, column.id))), provided.placeholder] })) }) }), _jsxs("div", { className: "mui-222f930b8752 mui-27ead27a81df mui-71556df3b421 mui-32c92bb1fde4 mui-074569488cca mui-894c3815a57f mui-9513b3968002 mui-b5edc3ea7c91", children: [_jsx("p", { className: "mui-3992de70b033 mui-35f35c41d134", "aria-live": "polite", children: summary || "No changes" }), _jsxs(Button, { variant: "ghost", size: "sm", className: "mui-c8e50836f8a1 mui-e7e01cc7f4df mui-3992de70b033", "aria-label": "Reset columns", onClick: () => applyTablePreferences(table, { version: 1, ...table.initialState }), children: [_jsx(RotateCcw, { className: "mui-5e34f5313859" }), "Reset"] })] })] })] }));
43
+ }
44
+ function ColumnSettingsRow({ column, provided, dragging, }) {
45
+ const definition = column.columnDef;
46
+ const label = definition.label ?? (typeof definition.header === "string" ? definition.header : column.id);
47
+ const pin = column.getIsPinned();
48
+ const next = pin === "start" ? "end" : pin === "end" ? false : "start";
49
+ const pinLabel = next === "start"
50
+ ? `Pin ${label} to left`
51
+ : next === "end"
52
+ ? `Pin ${label} to right`
53
+ : `Unpin ${label}`;
54
+ return (_jsxs("div", { ref: provided.innerRef, ...provided.draggableProps, "data-mendy-ui": "", "data-column-setting": column.id, "data-dragging": dragging, style: provided.draggableProps.style, className: cn("mui-222f930b8752 mui-71556df3b421 mui-074569488cca mui-3fa8c572949b mui-5b272f3c5076 mui-e7e01cc7f4df mui-a8c1dfb1d4ef mui-c74ab393b96d mui-957a109f887f", dragging ? "mui-3eef1ce97dba mui-0d4ca75de41c mui-853be6c11609 mui-fd9d0b696aac" : "mui-5cbdd1b32f1a"), children: [_jsx("button", { type: "button", ...provided.dragHandleProps, "aria-label": `Reorder ${label}`, title: "Drag to reorder. Press Space to move with arrow keys.", className: "mui-222f930b8752 mui-2bd43fb57913 mui-27ead27a81df mui-f2e47d9c52ad mui-71556df3b421 mui-a503dd374cca mui-02e603944040 mui-35f35c41d134 mui-b30fc56058b6 mui-355efe22aedb mui-db549d38ff19 mui-71998ea7a2d0", children: _jsx(GripVertical, { className: "mui-61c000c8a98a" }) }), _jsxs("label", { className: "mui-222f930b8752 mui-184ddc11e5f9 mui-7bd5bab6d7f4 mui-d2fa8848968d mui-71556df3b421 mui-074569488cca", children: [_jsx(Checkbox, { checked: column.getIsVisible(), disabled: !column.getCanHide(), onCheckedChange: (value) => column.toggleVisibility(value === true), "aria-label": `Show ${label}` }), _jsx("span", { className: "mui-5a3a4ee420c2", title: label, children: label })] }), _jsx(Button, { variant: "ghost", size: "icon-sm", disabled: !column.getCanPin(), "aria-label": pinLabel, title: pinLabel, className: cn("mui-0712570dcc9f mui-27ead27a81df", pin && "mui-87ecb59f2d2d"), onClick: () => column.pin(next), children: _jsx(Pin, { className: cn("mui-61c000c8a98a", pin === "start" && "mui-4e3f08588318", pin === "end" && "mui-c80411b7591f", !pin && "mui-35f35c41d134") }) })] }));
55
+ }
@@ -2,9 +2,7 @@ import type { ReactNode } from "react";
2
2
  import type { DataTableInstance } from "./use-data-table.js";
3
3
  import type { TableColumn } from "./columns.js";
4
4
  import type { SavedTableView } from "./state.js";
5
- export declare function TableColumnSettings<T extends object>({ table }: {
6
- table: DataTableInstance<T>;
7
- }): import("react/jsx-runtime").JSX.Element;
5
+ export { TableColumnSettings } from "./table-column-settings.js";
8
6
  export declare function TablePagination<T extends object>({ table, loading, }: {
9
7
  table: DataTableInstance<T>;
10
8
  loading?: boolean;