@nxgt/material-vue 0.26.1 → 0.28.0

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 (168) hide show
  1. package/CHANGELOG.md +202 -0
  2. package/README.md +10 -7
  3. package/dist/Button-D1uzdbOJ.js +728 -0
  4. package/dist/{DropdownMenuTrigger-BHAhXGUO.js → DropdownMenuTrigger-BsuyNVzV.js} +48 -41
  5. package/dist/HoverCardTrigger-DaM5d4hE.js +510 -0
  6. package/dist/{camera-DvKuqT4L.js → camera-CxXijySa.js} +4 -4
  7. package/dist/components/base-content.css +139 -0
  8. package/dist/components/base.css +150 -0
  9. package/dist/components/components.css +2 -0
  10. package/dist/components/reduced-motion.css +56 -0
  11. package/dist/components/theme-tokens.css +116 -0
  12. package/dist/components/ui/actions/button-group/button-group.css +1 -1
  13. package/dist/components/ui/feedback/toast/toast.css +21 -0
  14. package/dist/components/ui/primitives/label/label.css +33 -0
  15. package/dist/{components-CCWod7cJ.js → components-Db9OdMfQ.js} +19053 -18364
  16. package/dist/components.js +7 -7
  17. package/dist/composables.js +3 -3
  18. package/dist/dnd.js +1 -1
  19. package/dist/field-name-attribute-Bl7LSVK0.js +4 -0
  20. package/dist/{form-scope-x-7TYn2s.js → form-scope-BILi3ke-.js} +1 -1
  21. package/dist/{i18n-provider-CaaZCmaR.js → i18n-provider-BPK68eqM.js} +1 -1
  22. package/dist/i18n.js +4 -4
  23. package/dist/icon-button-D60G5B_Z.js +262 -0
  24. package/dist/lib/components/ui/actions/button/Button.vue.d.ts +22 -4
  25. package/dist/lib/components/ui/actions/button/button-tones.d.ts +36 -0
  26. package/dist/lib/components/ui/actions/button/button.variants.d.ts +1 -1
  27. package/dist/lib/components/ui/actions/button/button.wrap.d.ts +8 -0
  28. package/dist/lib/components/ui/actions/button/label-text.d.ts +9 -0
  29. package/dist/lib/components/ui/actions/button/prepend-to-child.d.ts +18 -0
  30. package/dist/lib/components/ui/actions/button/use-click-lock.d.ts +14 -0
  31. package/dist/lib/components/ui/actions/copy-button/copy-button.vue.d.ts +6 -2
  32. package/dist/lib/components/ui/actions/icon-button/icon-button.compound-variants.d.ts +28 -0
  33. package/dist/lib/components/ui/actions/icon-button/icon-button.vue.d.ts +1 -1
  34. package/dist/lib/components/ui/actions/responsive-button/responsive-button.vue.d.ts +1 -3
  35. package/dist/lib/components/ui/collections/data-table/partials/data-table-empty.vue.d.ts +5 -1
  36. package/dist/lib/components/ui/collections/data-table/partials/data-table-scroll-region.vue.d.ts +28 -0
  37. package/dist/lib/components/ui/collections/data-table/partials/data-table-toolbar.d.ts +60 -0
  38. package/dist/lib/components/ui/collections/data-table/types.d.ts +9 -0
  39. package/dist/lib/components/ui/collections/data-table/use-scroll-edges.d.ts +22 -0
  40. package/dist/lib/components/ui/collections/pagination/PaginationFirst.vue.d.ts +1 -1
  41. package/dist/lib/components/ui/collections/pagination/PaginationItem.vue.d.ts +1 -1
  42. package/dist/lib/components/ui/collections/pagination/PaginationLast.vue.d.ts +1 -1
  43. package/dist/lib/components/ui/collections/pagination/PaginationNext.vue.d.ts +1 -1
  44. package/dist/lib/components/ui/collections/pagination/PaginationPrevious.vue.d.ts +1 -1
  45. package/dist/lib/components/ui/dates/calendar/Calendar.vue.d.ts +4 -4
  46. package/dist/lib/components/ui/dates/calendar/calendar-day-label.d.ts +17 -0
  47. package/dist/lib/components/ui/dates/calendar/calendar-years.d.ts +11 -0
  48. package/dist/lib/components/ui/dates/calendar/partials/calendar-month-select.vue.d.ts +18 -0
  49. package/dist/lib/components/ui/dates/calendar/partials/calendar-year-select.vue.d.ts +19 -0
  50. package/dist/lib/components/ui/dates/calendar/use-calendar-locale.d.ts +7 -0
  51. package/dist/lib/components/ui/dates/calendar/use-calendar-selected-hint.d.ts +17 -0
  52. package/dist/lib/components/ui/dates/date-range-field/partials/date-range-day.vue.d.ts +8 -0
  53. package/dist/lib/components/ui/display/cards/cards.gallery.d.ts +3 -3
  54. package/dist/lib/components/ui/display/list-tile/list-tile.vue.d.ts +10 -6
  55. package/dist/lib/components/ui/feedback/alert-dialog/AlertDialogContent.vue.d.ts +2 -2
  56. package/dist/lib/components/ui/feedback/sonner/index.d.ts +1 -0
  57. package/dist/lib/components/ui/feedback/toast/toast.d.ts +7 -0
  58. package/dist/lib/components/ui/feedback/toast/toast.vue.d.ts +18 -2
  59. package/dist/lib/components/ui/fields/contacts/consts.d.ts +1 -1
  60. package/dist/lib/components/ui/forms/use-field-blur.d.ts +3 -0
  61. package/dist/lib/components/ui/layout/app-shell/activity-content.vue.d.ts +9 -3
  62. package/dist/lib/components/ui/layout/app-shell/activity-layout.vue.d.ts +21 -4
  63. package/dist/lib/components/ui/layout/app-shell/app-header.vue.d.ts +7 -5
  64. package/dist/lib/components/ui/layout/app-shell/app-sidebar.vue.d.ts +4 -1
  65. package/dist/lib/components/ui/layout/app-shell/index.d.ts +2 -2
  66. package/dist/lib/components/ui/layout/app-shell/router-menu-link.d.ts +7 -0
  67. package/dist/lib/components/ui/layout/app-shell/types.d.ts +8 -0
  68. package/dist/lib/components/ui/layout/app-shell/use-content-scroll.d.ts +13 -0
  69. package/dist/lib/components/ui/layout/app-shell/use-navigation-sheet.d.ts +17 -0
  70. package/dist/lib/components/ui/layout/sidebar/sidebar-context.d.ts +15 -0
  71. package/dist/lib/components/ui/layout/sidebar/sidebar-menu-item.vue.d.ts +13 -4
  72. package/dist/lib/components/ui/media/carousel/carousel-next.vue.d.ts +1 -1
  73. package/dist/lib/components/ui/media/carousel/carousel-previous.vue.d.ts +1 -1
  74. package/dist/lib/components/ui/menu-item-variant.d.ts +4 -4
  75. package/dist/lib/components/ui/overlays/context-menu/ContextMenuContent.vue.d.ts +2 -2
  76. package/dist/lib/components/ui/overlays/dialog/DialogContent.vue.d.ts +2 -2
  77. package/dist/lib/components/ui/overlays/dialog/DialogScrollContent.vue.d.ts +2 -2
  78. package/dist/lib/components/ui/overlays/dialog/use-escape-forward.d.ts +17 -0
  79. package/dist/lib/components/ui/overlays/dialog/use-inert-others.d.ts +17 -0
  80. package/dist/lib/components/ui/overlays/dialog/use-modal-content.d.ts +32 -0
  81. package/dist/lib/components/ui/overlays/drawer/DrawerContent.vue.d.ts +2 -2
  82. package/dist/lib/components/ui/overlays/dropdown-menu/DropdownMenu.vue.d.ts +3 -1
  83. package/dist/lib/components/ui/overlays/dropdown-menu/DropdownMenuContent.vue.d.ts +2 -2
  84. package/dist/lib/components/ui/overlays/popover/PopoverContent.vue.d.ts +2 -2
  85. package/dist/lib/components/ui/overlays/sheet/SheetContent.vue.d.ts +2 -2
  86. package/dist/lib/components/ui/primitives/card/CardTitle.vue.d.ts +11 -4
  87. package/dist/lib/components/ui/primitives/card/index.d.ts +1 -0
  88. package/dist/lib/components/ui/primitives/tabs/Tabs.vue.d.ts +6 -2
  89. package/dist/lib/components/ui/primitives/tabs/TabsList.vue.d.ts +2 -2
  90. package/dist/lib/components/ui/primitives/tabs/TabsTrigger.vue.d.ts +6 -4
  91. package/dist/lib/components/ui/primitives/tabs/tabs-classes.d.ts +27 -0
  92. package/dist/lib/components/ui/primitives/tabs/tabs-indicator.vue.d.ts +25 -0
  93. package/dist/lib/components/ui/primitives/tabs/tabs-variant.d.ts +5 -8
  94. package/dist/lib/components/ui/primitives/toggle/Toggle.vue.d.ts +1 -1
  95. package/dist/lib/components/ui/primitives/toggle/index.d.ts +1 -1
  96. package/dist/lib/components/ui/selection/autocomplete/partials/autocomplete-box.vue.d.ts +2 -0
  97. package/dist/lib/components/ui/selection/select/SelectContent.vue.d.ts +2 -2
  98. package/dist/lib/components/ui/selection/select-chip-field/select-chip-field.vue.d.ts +1 -0
  99. package/dist/lib/components/ui/widgets/emoji/types.d.ts +1 -6
  100. package/dist/lib/i18n/resources/en/en.d.ts +23 -0
  101. package/dist/lib/i18n/resources/en/material.json.d.ts +28 -5
  102. package/dist/lib/i18n/resources/fr/fr.d.ts +23 -0
  103. package/dist/lib/i18n/resources/fr/material.json.d.ts +28 -5
  104. package/dist/lib/i18n/resources/resources.d.ts +46 -0
  105. package/dist/lib/i18n/translator.d.ts +1 -1
  106. package/dist/lib/lib/field-name-attribute.d.ts +7 -0
  107. package/dist/lib/lib/focus-field.d.ts +17 -0
  108. package/dist/lib/lib/index.d.ts +1 -0
  109. package/dist/lib.js +76 -74
  110. package/dist/main.js +13 -13
  111. package/dist/map.js +4 -4
  112. package/dist/material-vue.css +1 -1
  113. package/dist/{pdf-outline-sidebar-D3vq2qfS.js → pdf-outline-sidebar-BXGTDISI.js} +2 -2
  114. package/dist/{pdf-page-BrJbyjQj.js → pdf-page-BR4G03kN.js} +1 -1
  115. package/dist/{pdf-page-list-BCgYEszV.js → pdf-page-list-bjQm6_kf.js} +2 -2
  116. package/dist/{pdf-reader-BAzevSJU.js → pdf-reader-DGVEFNc0.js} +9 -9
  117. package/dist/{pdf-sidebar-DSh2Mend.js → pdf-sidebar-CiM6dwAm.js} +3 -3
  118. package/dist/{pdf-thumbnail-sidebar-D_EMcbKF.js → pdf-thumbnail-sidebar-fM3DGJzD.js} +3 -3
  119. package/dist/{pdf-toolbar-BcL7HlfS.js → pdf-toolbar-mWlGTWU1.js} +5 -5
  120. package/dist/pdf.js +2 -2
  121. package/dist/{sortable-provider-DMpmM7Ke.js → sortable-provider-Dml11nQY.js} +2 -2
  122. package/dist/{stored-language-Bxhsx4iB.js → stored-language-UnInBB6T.js} +56 -10
  123. package/dist/{stx-player-MldK_ZAZ.js → stx-player-BS7-CXFx.js} +2 -2
  124. package/dist/styles.css +10 -368
  125. package/dist/{translator-CLI_7Crg.js → translator-J3_vaV_A.js} +1 -1
  126. package/dist/{use-heading-spy-VPuFj2Gt.js → use-heading-spy-_dk8kGwL.js} +19 -19
  127. package/dist/use-inert-others-CtGqZKR8.js +22 -0
  128. package/dist/{use-material-translation-CONqD9wJ.js → use-material-translation-Do6ztdtV.js} +3 -3
  129. package/docs/components/buttons-and-actions.md +71 -16
  130. package/docs/components/data-display.md +13 -2
  131. package/docs/components/data-table-filter-and-lists.md +85 -5
  132. package/docs/components/date-and-time.md +25 -1
  133. package/docs/components/feedback-and-status.md +86 -11
  134. package/docs/components/form-fields.md +13 -4
  135. package/docs/components/media-and-files.md +7 -0
  136. package/docs/components/navigation-and-layout.md +19 -1
  137. package/docs/components/overlays-and-menus.md +20 -4
  138. package/docs/components/primitives.md +97 -20
  139. package/docs/components/rich-widgets.md +10 -0
  140. package/docs/components/selection-and-choice.md +12 -1
  141. package/docs/getting-started.md +2 -2
  142. package/docs/guides/app-shell.md +102 -6
  143. package/docs/guides/forms.md +58 -5
  144. package/docs/guides/helpers.md +2 -1
  145. package/docs/guides/i18n.md +24 -4
  146. package/docs/guides/ssr.md +1 -1
  147. package/docs/guides/theming.md +148 -6
  148. package/docs/previews/data-display-codegroup.webp +0 -0
  149. package/docs/previews/data-display-description.webp +0 -0
  150. package/docs/previews/feedback-status-toast.webp +0 -0
  151. package/docs/previews/primitives-tabs.webp +0 -0
  152. package/docs/previews/rich-widgets-emojipicker.webp +0 -0
  153. package/docs/roadmap.md +30 -1
  154. package/docs/troubleshooting.md +889 -12
  155. package/lib/components/base-content.css +139 -0
  156. package/lib/components/base.css +150 -0
  157. package/lib/components/components.css +2 -0
  158. package/lib/components/reduced-motion.css +56 -0
  159. package/lib/components/theme-tokens.css +116 -0
  160. package/lib/components/ui/actions/button-group/button-group.css +1 -1
  161. package/lib/components/ui/feedback/toast/toast.css +21 -0
  162. package/lib/components/ui/primitives/label/label.css +33 -0
  163. package/lib/styles.css +10 -368
  164. package/package.json +2 -2
  165. package/dist/Button-16J7vTpE.js +0 -665
  166. package/dist/HoverCardTrigger-C41002JS.js +0 -455
  167. package/dist/icon-button-CDdNsZuZ.js +0 -227
  168. package/dist/lib/components/ui/widgets/emoji/emoji.groups.d.ts +0 -6
package/dist/styles.css CHANGED
@@ -2,6 +2,13 @@
2
2
  @import "tw-animate-css";
3
3
  /* The stylesheets the components need: lib/components/components.css. */
4
4
  @import "./components/components.css";
5
+ /* Reduced motion: unlayered on purpose, see the file. */
6
+ @import "./components/reduced-motion.css";
7
+ /* The theme's colour tokens, light (:root) and dark: lib/components/theme-tokens.css. */
8
+ @import "./components/theme-tokens.css";
9
+ /* The base layer: elements (base.css), then editor content and the form grid. */
10
+ @import "./components/base.css";
11
+ @import "./components/base-content.css";
5
12
  /* Consumers' Tailwind skips node_modules: scan the compiled components. */
6
13
  @source "../dist";
7
14
 
@@ -9,91 +16,6 @@
9
16
  &:where(.dark, .dark *, [data-theme="dark"], [data-theme="dark"] *)
10
17
  );
11
18
 
12
- :root {
13
- --radius: 0.625rem;
14
- --background: oklch(1 0 0);
15
- --foreground: oklch(0.14 0.036 258.53);
16
- --card: oklch(1 0 0);
17
- --card-foreground: oklch(0.129 0.042 264.695);
18
- --strix: oklch(45.91% 0.1864 310.75);
19
- --popover: oklch(1 0 0);
20
- --popover-foreground: oklch(0.129 0.042 264.695);
21
- --primary: oklch(46% 0.1135 276.35);
22
- --primary-foreground: oklch(0.984 0.003 247.858);
23
- --secondary: oklch(56.67% 0.1135 245.65);
24
- --secondary-foreground: oklch(0.984 0.003 247.858);
25
- --muted: oklch(0.968 0.007 247.896);
26
- --muted-foreground: oklch(0.554 0.046 257.417);
27
- --tooltip: oklch(0.446 0.043 257.281);
28
- --tooltip-foreground: oklch(1 0 0);
29
- --accent: oklch(0.9182 0.0077 228.86);
30
- --accent-foreground: oklch(0.216 0.006 56.043);
31
- --error: oklch(0.577 0.245 27.325);
32
- --error-foreground: oklch(0.984 0.003 247.858);
33
- --success: oklch(0.6 0.118 184.704);
34
- --success-foreground: oklch(0.984 0.003 247.858);
35
- --info: oklch(0.707 0.165 254.624);
36
- --info-foreground: oklch(0.984 0.003 247.858);
37
- --warning: oklch(0.646 0.222 41.116);
38
- --warning-foreground: oklch(0.984 0.003 247.858);
39
- --destructive: oklch(0.577 0.245 27.325);
40
- --border: oklch(0.929 0.013 255.508);
41
- --input: oklch(0.929 0.013 255.508);
42
- --ring: oklch(0.704 0.04 256.788);
43
- --chart-1: oklch(0.646 0.222 41.116);
44
- --chart-2: oklch(0.6 0.118 184.704);
45
- --chart-3: oklch(0.398 0.07 227.392);
46
- --chart-4: oklch(0.828 0.189 84.429);
47
- --chart-5: oklch(0.769 0.188 70.08);
48
- --sidebar: oklch(0.984 0.003 247.858);
49
- --sidebar-foreground: oklch(0.129 0.042 264.695);
50
- --sidebar-primary: oklch(0.208 0.042 265.755);
51
- --sidebar-primary-foreground: oklch(0.984 0.003 247.858);
52
- --sidebar-accent: oklch(0.968 0.007 247.896);
53
- --sidebar-accent-foreground: oklch(0.208 0.042 265.755);
54
- --sidebar-border: oklch(0.929 0.013 255.508);
55
- --sidebar-ring: oklch(0.704 0.04 256.788);
56
- }
57
-
58
- .dark,
59
- [data-theme="dark"] {
60
- --background: oklch(0.14 0.036 258.53);
61
- --foreground: oklch(0.984 0.003 247.858);
62
- --card: oklch(0.208 0.042 265.755);
63
- --card-foreground: oklch(0.984 0.003 247.858);
64
- --popover: oklch(0.208 0.042 265.755);
65
- --popover-foreground: oklch(0.984 0.003 247.858);
66
- --primary: oklch(46% 0.1135 276.35);
67
- --primary-foreground: oklch(0.984 0.003 247.858);
68
- --secondary: oklch(56.67% 0.1135 245.65);
69
- --secondary-foreground: oklch(0.984 0.003 247.858);
70
- --muted: oklch(0.968 0.007 247.896);
71
- --muted-foreground: oklch(0.554 0.046 257.417);
72
- --tooltip: oklch(0.929 0.013 255.508);
73
- --tooltip-foreground: oklch(0.446 0.043 257.281);
74
- --accent: oklch(0.268 0.007 34.298);
75
- --accent-foreground: oklch(0.985 0.001 106.423);
76
- --error: oklch(0.577 0.245 27.325);
77
- --error-foreground: oklch(0.984 0.003 247.858);
78
- --destructive: oklch(0.704 0.191 22.216);
79
- --border: oklch(1 0 0 / 10%);
80
- --input: oklch(1 0 0 / 15%);
81
- --ring: oklch(0.551 0.027 264.364);
82
- --chart-1: oklch(0.488 0.243 264.376);
83
- --chart-2: oklch(0.696 0.17 162.48);
84
- --chart-3: oklch(0.769 0.188 70.08);
85
- --chart-4: oklch(0.627 0.265 303.9);
86
- --chart-5: oklch(0.645 0.246 16.439);
87
- --sidebar: oklch(0.208 0.042 265.755);
88
- --sidebar-foreground: oklch(0.984 0.003 247.858);
89
- --sidebar-primary: oklch(0.488 0.243 264.376);
90
- --sidebar-primary-foreground: oklch(0.984 0.003 247.858);
91
- --sidebar-accent: oklch(0.279 0.041 260.031);
92
- --sidebar-accent-foreground: oklch(0.984 0.003 247.858);
93
- --sidebar-border: oklch(1 0 0 / 10%);
94
- --sidebar-ring: oklch(0.551 0.027 264.364);
95
- }
96
-
97
19
  @theme {
98
20
  --radius-sm: calc(var(--radius) - 4px);
99
21
  --radius-md: calc(var(--radius) - 2px);
@@ -118,6 +40,8 @@
118
40
  --color-secondary-container: --alpha(var(--secondary-foreground) / 20%);
119
41
  --color-muted: var(--muted);
120
42
  --color-muted-foreground: var(--muted-foreground);
43
+ --color-track: var(--track);
44
+ --color-track-fill: var(--track-fill);
121
45
  --color-tooltip: var(--tooltip);
122
46
  --color-tooltip-foreground: var(--tooltip-foreground);
123
47
  --color-accent: var(--accent);
@@ -126,6 +50,7 @@
126
50
  --color-error: var(--error);
127
51
  --color-error-foreground: var(--error-foreground);
128
52
  --color-error-container: --alpha(var(--error-foreground) / 20%);
53
+ --color-error-text: var(--error-text);
129
54
  --color-success: var(--success);
130
55
  --color-success-foreground: var(--success-foreground);
131
56
  --color-info: var(--info);
@@ -187,286 +112,3 @@
187
112
  bottom: -0.1875rem;
188
113
  transform: rotate(-45deg) scale(0.75);
189
114
  }
190
-
191
- @layer base {
192
- * {
193
- @apply border-border outline-ring/50 selection:bg-primary selection:text-primary-foreground;
194
- &::-webkit-scrollbar {
195
- @apply w-1 gap-4 h-1 md:w-1.5 md:h-1.5 cursor-pointer;
196
- }
197
- &::-webkit-scrollbar-track {
198
- @apply rounded bg-primary/20;
199
- }
200
- &::-webkit-scrollbar-thumb {
201
- @apply rounded bg-muted-foreground;
202
- }
203
-
204
- input::-webkit-outer-spin-button,
205
- ::-webkit-inner-spin-button {
206
- -webkit-appearance: none;
207
- margin: 0;
208
- }
209
- }
210
- body {
211
- @apply bg-background text-foreground;
212
-
213
- input[type="number"] {
214
- -moz-appearance: textfield;
215
- }
216
-
217
- [data-slot="icon"] {
218
- @apply dark:fill-foreground;
219
- }
220
-
221
- h1 {
222
- font-size: var(--text-2xl);
223
- font-weight: var(--font-weight-medium);
224
- }
225
- h2 {
226
- font-size: var(--text-xl);
227
- font-weight: var(--font-weight-medium);
228
- }
229
- h3 {
230
- font-size: var(--text-lg);
231
- font-weight: var(--font-weight-medium);
232
- }
233
- h4 {
234
- font-size: var(--text-base);
235
- font-weight: var(--font-weight-medium);
236
- }
237
- h5 {
238
- font-size: var(--text-sm);
239
- font-weight: var(--font-weight-medium);
240
- }
241
- h6 {
242
- font-size: var(--text-xs);
243
- font-weight: var(--font-weight-medium);
244
- }
245
- a:not(:has(> button)) {
246
- @apply focus:underline underline-offset-4 hover:underline cursor-pointer;
247
- @apply text-info [&_svg]:data-[slot=icon]:text-info hover:bg-info/10 active:bg-info/5 focus:bg-info/15;
248
- }
249
-
250
- code {
251
- @apply rounded bg-muted px-[0.3rem] py-[0.2rem] font-mono mx-0.5;
252
- }
253
-
254
- blockquote {
255
- @apply border-l-2 border-primary/40 pl-4 italic text-muted-foreground my-1;
256
- }
257
- pre {
258
- @apply bg-muted rounded p-4 overflow-x-auto my-1;
259
- code {
260
- @apply text-sm;
261
- }
262
- }
263
-
264
- ul li p,
265
- ol li p {
266
- display: inline;
267
- }
268
-
269
- ul[data-type="taskList"] {
270
- list-style-type: disc;
271
- }
272
- ol[data-type="taskList"] {
273
- list-style-type: decimal;
274
- }
275
-
276
- ul[data-type="taskList"] li {
277
- @apply flex gap-2 items-center;
278
- }
279
-
280
- ul,
281
- ol {
282
- @apply list-inside marker:text-muted-foreground;
283
- }
284
-
285
- [data-type="emoji"] {
286
- img {
287
- @apply size-4;
288
- }
289
- }
290
-
291
- input[type="checkbox"] {
292
- display: grid;
293
- place-content: center;
294
- -webkit-appearance: none;
295
- appearance: none;
296
- font: inherit;
297
- color: ---value(--color-primary);
298
- width: 1.05em;
299
- height: 1.05em;
300
- border: 0.13em solid var(--muted-foreground);
301
- border-radius: 0.15em;
302
- }
303
- input[type="checkbox"]::before {
304
- content: "";
305
- width: 0.55em;
306
- height: 0.55em;
307
- transform: scale(0);
308
- transition: 120ms transform ease-in-out;
309
- box-shadow: inset 1em 1em var(--color-primary);
310
- }
311
- input[type="checkbox"]:checked::before {
312
- transform: scale(1);
313
- }
314
- input[type="checkbox"]:indeterminate::before {
315
- height: 0.15em;
316
- }
317
-
318
- table {
319
- overflow: hidden;
320
- table-layout: fixed;
321
- @apply border-collapse w-full overflow-hidden rounded;
322
-
323
- tr {
324
- @apply even:bg-primary/5;
325
- }
326
-
327
- td,
328
- th {
329
- @apply border-0 p-1 py-2;
330
- }
331
-
332
- th {
333
- @apply bg-primary/15 text-left text-muted-foreground dark:text-primary-foreground;
334
- }
335
- }
336
-
337
- .tiptap {
338
- ul li p,
339
- ol li p {
340
- display: inline;
341
- }
342
-
343
- ul:not([data-type="taskList"]) {
344
- list-style-type: disc;
345
- }
346
- ol {
347
- list-style-type: decimal;
348
- }
349
-
350
- ul:not([data-type="taskList"]),
351
- ol {
352
- @apply list-inside marker:text-muted-foreground;
353
- }
354
-
355
- ul[data-type="taskList"] li {
356
- @apply flex gap-2 items-center;
357
- }
358
-
359
- :first-child {
360
- margin-top: 0;
361
- }
362
-
363
- table {
364
- /* Override the global `body table { width: w-full }` base rule
365
- (see @layer base above) — it fights TipTap's resizable colgroup
366
- widths, which only get applied as an inline table width once
367
- every column has an explicit pixel width. Letting the table size
368
- itself (still table-layout: fixed) makes resizing and
369
- center/right alignment actually visible. */
370
- width: auto;
371
-
372
- .selectedCell {
373
- @apply bg-primary/20;
374
- }
375
-
376
- .column-resize-handle {
377
- background-color: var(--color-primary);
378
- bottom: -2px;
379
- pointer-events: none;
380
- position: absolute;
381
- right: -2px;
382
- top: 0;
383
- width: 4px;
384
- }
385
-
386
- &[data-table-caption]::before {
387
- content: attr(data-table-caption);
388
- display: block;
389
- margin-bottom: 0.5rem;
390
- @apply text-sm text-muted-foreground text-center;
391
- }
392
- }
393
-
394
- .tableWrapper {
395
- margin: 1.5rem 0;
396
- overflow-x: auto;
397
-
398
- &:has(table[data-table-align="center"]) {
399
- width: fit-content;
400
- margin-inline: auto;
401
- }
402
-
403
- &:has(table[data-table-align="right"]) {
404
- width: fit-content;
405
- margin-left: auto;
406
- margin-right: 0;
407
- }
408
- }
409
-
410
- &.resize-cursor {
411
- cursor: col-resize;
412
- }
413
-
414
- .is-empty::before {
415
- content: attr(data-placeholder);
416
- float: left;
417
- height: 0;
418
- pointer-events: none;
419
- @apply text-muted-foreground;
420
- }
421
-
422
- .has-focus {
423
- @apply bg-accent/40 rounded;
424
- }
425
- }
426
- }
427
-
428
- .form-grid-layout {
429
- @apply relative flex flex-col gap-2 @container;
430
- [data-slot="form-fields"] {
431
- @apply grid @2xl:grid-cols-2 @4xl:grid-cols-3 @6xl:grid-cols-4 gap-2 bg-background/80 p-4 place-items-start overflow-auto;
432
-
433
- [data-slot="separator"] {
434
- @apply col-start-full;
435
- }
436
-
437
- [data-slot*="text-field"],
438
- [data-slot*="autocomplete-field"][data-mode="single"],
439
- [data-slot*="currency-form-field"],
440
- [data-slot*="time-field"],
441
- [data-slot*="image-field"],
442
- [data-slot*="select-field"] {
443
- @apply w-full;
444
- }
445
-
446
- [data-slot="switch-field"],
447
- [data-slot="textarea-field"],
448
- [data-slot="autocomplete-field"][data-mode="multiple"],
449
- [data-slot="select-chip-field"],
450
- [data-slot="file-picker-field"] {
451
- @apply col-start-full @6xl:col-span-2;
452
- }
453
-
454
- [data-slot="files-form-field"],
455
- [data-slot="rich-text-editor"] {
456
- @apply col-start-full;
457
- }
458
- }
459
- [data-slot="form-actions"] {
460
- @apply flex w-full justify-end gap-2 bottom-2 p-4 max-sm:*:flex-1;
461
- }
462
- }
463
-
464
- .form-grid-layout,
465
- [data-slot="data-table"] {
466
- @apply max-h-[calc(100lvh-184px)] md:max-h-[calc(100lvh-242px)] lg:max-h-[calc(100lvh-280px)];
467
- }
468
-
469
- [data-slot="table-wrapper"] {
470
- @apply max-h-[calc(100vh-432px)] md:max-h-[calc(100vh-490px)] lg:max-h-[calc(100vh-528px)];
471
- }
472
- }
@@ -1,4 +1,4 @@
1
- import { a as e, i as t, r as n, t as r } from "./stored-language-Bxhsx4iB.js";
1
+ import { a as e, i as t, r as n, t as r } from "./stored-language-UnInBB6T.js";
2
2
  import { t as i } from "./get-CTzJAwfc.js";
3
3
  //#region ../../node_modules/@formatjs/fast-memoize/index.js
4
4
  function a(e, t) {
@@ -1,34 +1,28 @@
1
- import { a as e } from "./i18n-provider-CaaZCmaR.js";
1
+ import { a as e } from "./i18n-provider-BPK68eqM.js";
2
2
  import { c as t, d as n, f as r, l as i, n as a, u as o } from "./number.utils-Cy1z6qI7.js";
3
3
  import { computed as s, getCurrentInstance as c, onMounted as l, ref as u, toValue as d } from "vue";
4
4
  import { useIntersectionObserver as f, useMediaQuery as p, useSSRWidth as m, useStorage as h } from "@vueuse/core";
5
- //#region lib/composables/use-ssr-media-query.ts
6
- var g = 1024;
7
- function _(e) {
8
- return c() ? p(e, { ssrWidth: m() ?? g }) : p(e);
9
- }
10
- //#endregion
11
- //#region lib/composables/use-mobile.ts
12
- var v = 768;
13
- function y() {
14
- return _(`(max-width: ${v - 1}px)`);
15
- }
16
- //#endregion
17
5
  //#region lib/composables/resolve-theme.ts
18
- function b(e, t) {
6
+ function g(e, t) {
19
7
  let n = e === "light" || e === "dark" ? e : "system";
20
8
  return {
21
9
  theme: n === "system" ? t ? "dark" : "light" : n,
22
10
  preference: n
23
11
  };
24
12
  }
25
- function x(e) {
13
+ function _(e) {
26
14
  typeof document > "u" || (document.documentElement.classList.toggle("dark", e === "dark"), document.documentElement.style.colorScheme = e);
27
15
  }
28
16
  //#endregion
17
+ //#region lib/composables/use-ssr-media-query.ts
18
+ var v = 1024;
19
+ function y(e) {
20
+ return c() ? p(e, { ssrWidth: m() ?? v }) : p(e);
21
+ }
22
+ //#endregion
29
23
  //#region lib/composables/use-theme.ts
30
- function S() {
31
- let e = _("(prefers-color-scheme: dark)"), t = h("theme", null, void 0, { initOnMounted: !0 }), n = s(() => b(t.value, !!e.value));
24
+ function b() {
25
+ let e = y("(prefers-color-scheme: dark)"), t = h("theme", null, void 0, { initOnMounted: !0 }), n = s(() => g(t.value, !!e.value));
32
26
  return {
33
27
  get theme() {
34
28
  return n.value.theme;
@@ -37,11 +31,17 @@ function S() {
37
31
  return n.value.preference;
38
32
  },
39
33
  updateTheme: (n) => {
40
- n === "system" ? t.value = null : t.value = n, x(b(n === "system" ? void 0 : n, !!e.value).theme);
34
+ n === "system" ? t.value = null : t.value = n, _(g(n === "system" ? void 0 : n, !!e.value).theme);
41
35
  }
42
36
  };
43
37
  }
44
38
  //#endregion
39
+ //#region lib/composables/use-mobile.ts
40
+ var x = 768;
41
+ function S() {
42
+ return y(`(max-width: ${x - 1}px)`);
43
+ }
44
+ //#endregion
45
45
  //#region ../../node_modules/date-fns/locale/fr/_lib/formatDistance.js
46
46
  var C = {
47
47
  lessThanXSeconds: {
@@ -477,4 +477,4 @@ function z(e, t, n) {
477
477
  });
478
478
  }
479
479
  //#endregion
480
- export { b as a, x as i, I as n, y as o, S as r, _ as s, z as t };
480
+ export { y as a, b as i, I as n, _ as o, S as r, g as s, z as t };
@@ -0,0 +1,22 @@
1
+ import { nextTick as e, useTemplateRef as t, watch as n } from "vue";
2
+ import { unrefElement as r } from "@vueuse/core";
3
+ import { inertOthers as i } from "@nxgt/material-core/inert-others";
4
+ //#region lib/components/ui/overlays/dialog/use-inert-others.ts
5
+ function a(a, o) {
6
+ let s = typeof a == "string" ? t(a) : a;
7
+ n(o, (t, n, a) => {
8
+ if (!t || typeof document > "u") return;
9
+ let o, c = !1;
10
+ e(() => {
11
+ let e = r(s);
12
+ !c && e instanceof Element && (o = i(e));
13
+ }), a(() => {
14
+ c = !0, o?.();
15
+ });
16
+ }, {
17
+ immediate: !0,
18
+ flush: "post"
19
+ });
20
+ }
21
+ //#endregion
22
+ export { a as t };
@@ -1,6 +1,6 @@
1
- import "./stored-language-Bxhsx4iB.js";
2
- import { a as e } from "./i18n-provider-CaaZCmaR.js";
3
- import { i as t, r as n } from "./translator-CLI_7Crg.js";
1
+ import "./stored-language-UnInBB6T.js";
2
+ import { a as e } from "./i18n-provider-BPK68eqM.js";
3
+ import { i as t, r as n } from "./translator-J3_vaV_A.js";
4
4
  //#region lib/i18n/translate-material.ts
5
5
  function r(e, r, i, a) {
6
6
  if (e) for (let t of /* @__PURE__ */ new Set([e, e.split("-")[0]])) {
@@ -54,17 +54,71 @@ function save() {
54
54
  | `variant` | `'filled' \| 'tonal' \| 'outlined' \| 'ghost' \| 'link'` | `'filled'` | the style |
55
55
  | `color` | `'primary' \| 'secondary' \| 'success' \| 'info' \| 'warning' \| 'error' \| 'default'` | `'primary'` | the colour; `default` is the foreground colour |
56
56
  | `size` | `'default' \| 'xs' \| 'sm' \| 'lg' \| 'icon' \| 'icon-xs' \| 'icon-sm' \| 'icon-lg'` | — (36 px) | height; the `icon*` sizes are square |
57
- | `loading` | `boolean` | — | shows a spinner, sets `aria-busy` and disables the button |
57
+ | `loading` | `boolean` | — | busy: a spinner, `aria-busy="true"` and `aria-disabled="true"`, and every click cancelled before your `@click` — a submit button submits neither on a click nor on Enter in a field. It stays focusable (no native `disabled`), so focus is not lost |
58
+ | `lock-on-click` | `boolean` | — | a click makes the button busy at once, until `loading` has turned true and back (or for one second when it never does): for a `loading` that turns true only after an `await` |
58
59
  | `spinner-variant` | `SpinnerProps['variant']` | `'2'` | which spinner `loading` shows |
60
+ | `wrap` | `boolean` | — | the label breaks onto as many lines as it needs, centred, instead of being cut with “…”: the button grows taller, never shorter than its `size`. Ignored by the `icon*` sizes |
59
61
  | `tooltip` | `string` | — | wraps the button in a `Tooltip` |
60
- | `as-child` / `as` | `boolean` / tag or component | `false` / `'button'` | styles its only child, or renders another element |
62
+ | `as-child` / `as` | `boolean` / tag or component | `false` / `'button'` | styles its only child, or renders another element. With `as-child` the child keeps its own attributes (`class`, `style` and listeners merge) and its slot content; while `loading`, the spinner goes inside the child, `aria-busy` and `aria-disabled` land on it, and the child stays the same element, keeping its focus, ref and directives. A component child with no slot content shows only the spinner while busy |
61
63
  | `type` | `'button' \| 'submit' \| 'reset'` | `'button'` | not `submit` by default — pass it inside a form |
62
64
 
63
- Unlike React, `loading` disables the button (it is not focusable while
64
- loading). The classes are exported as `buttonVariants` for styling your own
65
- element.
65
+ The classes are exported as `buttonVariants` for styling your own element.
66
66
 
67
- **Storybook:** `Buttons & actions/Button` · **React:** `Button`
67
+ **On a phone.** A button is never wider than its container, and keeps its
68
+ content's width in a column: a label too
69
+ long for it (a card on a phone) is cut with “…” on one line, and its
70
+ accessible name — and a `title` you give it — keep the whole text. Give a
71
+ label that must be read in full `wrap`, or a width of your own (`w-full`).
72
+ The text is put in a `<span data-slot="button-label">` (one per run of
73
+ text) that shrinks and ends in the ellipsis; it needs the text to be the button's own slot content; with
74
+ `as-child`, put the label in a `<span>` inside the child element.
75
+
76
+ ```vue
77
+ <template>
78
+ <Button title="Continue to the payment details">Continue to the payment details</Button>
79
+ <Button wrap>Continue to the payment details and confirm the order</Button>
80
+ </template>
81
+ ```
82
+
83
+ **Submitting once.** Give a submit button `:loading="isSubmitting"` from
84
+ `useForm`: vee-validate sets it as `handleSubmit` starts, so the button is
85
+ busy from the first click and a double click, or Enter pressed twice,
86
+ submits once. When `loading` comes from something that turns true later — a
87
+ mutation's pending flag after an `await` — the second click comes first: add
88
+ `lock-on-click`.
89
+
90
+ ```vue
91
+ <script setup lang="ts">
92
+ import { useForm } from 'vee-validate';
93
+ import { Button, EmailFormField } from '@nxgt/material-vue/components';
94
+
95
+ const { handleSubmit, isSubmitting } = useForm();
96
+ const onSubmit = handleSubmit(async (values) => {
97
+ // …
98
+ });
99
+ </script>
100
+
101
+ <template>
102
+ <form @submit="onSubmit">
103
+ <EmailFormField name="email" label="Email" />
104
+ <Button type="submit" :loading="isSubmitting">Sign in</Button>
105
+ </form>
106
+ </template>
107
+ ```
108
+
109
+ **What the guard covers.** Clicks on this button, Space and Enter on it,
110
+ and Enter in a field when it is the form's first submit button (the default
111
+ one, which the browser clicks). `form.requestSubmit()` and `form.submit()`
112
+ fire no click, so a submit your code starts — an OTP step that submits on its
113
+ last digit, a keyboard shortcut — must check `isSubmitting` itself.
114
+ With `lock-on-click`, a `loading` that never turns true releases the lock after
115
+ one second.
116
+
117
+ A test finds a busy button by its state, not by `disabled`:
118
+ `expect(button).toHaveAttribute('aria-busy', 'true')` (`toBeDisabled()` is
119
+ false: it is still focusable).
120
+
121
+ **Storybook:** `Buttons & actions/Button` (`Submits Once`, `Lock On Click`), `Buttons & actions/Button/Phone` · **React:** `Button`
68
122
 
69
123
  ---
70
124
 
@@ -204,7 +258,7 @@ function save(options?: { draft: boolean }) {
204
258
  | --- | --- | --- | --- |
205
259
  | `#menu` slot | — | — | the `DropdownMenu*` items shown by the chevron |
206
260
  | `menu-label` | `string` | `"More actions"` (translated) | the chevron's `aria-label` |
207
- | `variant`, `color`, `loading`, `disabled` | as `Button` | as `Button` | applied to both halves; `loading` also disables the chevron |
261
+ | `variant`, `color`, `loading`, `disabled` | as `Button` | as `Button` | `variant`, `color` and `disabled` apply to both halves; `loading` makes the main half busy (spinner, clicks ignored, still focusable) and disables the chevron (native `disabled`) |
208
262
 
209
263
  Other `Button` props and `@click` go to the main half.
210
264
 
@@ -216,7 +270,7 @@ Other `Button` props and `@click` go to the main half.
216
270
 
217
271
  ![ResponsiveButton](../previews/buttons-actions-responsivebutton.webp)
218
272
 
219
- Shows its label on desktop and collapses to icon-only on mobile.
273
+ Shows its label from 768 px up and collapses to icon-only below. The collapse is a CSS media query, not a JS effect, so the server HTML is the same everywhere and nothing flashes.
220
274
 
221
275
  ```vue
222
276
  <script setup lang="ts">
@@ -235,10 +289,10 @@ import { Plus } from '@lucide/vue';
235
289
  | Prop | Type | Default | Effect |
236
290
  | --- | --- | --- | --- |
237
291
  | `#icon` slot | — | — | always shown |
238
- | `expanded` | `boolean` | not mobile (`useIsMobile`) | forces the label on or off |
292
+ | `expanded` | `boolean` | by width (`max-md` CSS) | forces the label on or off at every width |
239
293
 
240
- Every `Button` prop applies. Collapsed, the label stays in the button as
241
- screen-reader text, so it keeps its accessible name; an `aria-label` would
294
+ Every `Button` prop applies. The label is always in the DOM, so the accessible
295
+ name is the same at every width; collapsed, it is screen-reader text; an `aria-label` would
242
296
  replace that name, so pass one only when it should differ from the label.
243
297
  `expanded` is layout, not disclosure: the button has no `aria-expanded` of its
244
298
  own, so it is not announced as "collapsed". Used as a popover, drawer or menu
@@ -297,7 +351,7 @@ Needs `vue-router` installed on the app (`app.use(router)`).
297
351
 
298
352
  ![CopyButton](../previews/buttons-actions-copybutton.webp)
299
353
 
300
- Copies a value to the clipboard and briefly shows a check mark.
354
+ Copies a value to the clipboard and briefly shows a check mark (or a cross when the clipboard refuses).
301
355
 
302
356
  ```vue
303
357
  <script setup lang="ts">
@@ -315,11 +369,12 @@ import { CopyButton } from '@nxgt/material-vue/components';
315
369
  | Prop | Type | Default | Effect |
316
370
  | --- | --- | --- | --- |
317
371
  | `value` | `string \| (() => string)` | — (required) | what is copied; a function is read at click time |
318
- | `label` / `copied-label` | `string` | `"Copy"` / `"Copied"` (translated) | tooltip and `aria-label`, before and after |
372
+ | `label` | `string` | `"Copy"` (translated) | the button's accessible name; it never changes after a click |
373
+ | `copied-label` / `failed-label` | `string` | `"Copied"` / `"Copy failed"` (translated) | announced in the status region (and shown in the tooltip) once the write succeeded or failed |
319
374
  | `#icon` slot | — | a copy icon | replaces the idle icon |
320
375
  | `variant`, `color` | as `IconButton` | `'ghost'`, `'default'` | the button style |
321
376
 
322
- The check mark stays for 1.5 s. `copyToClipboard(text)` is the same copy
377
+ The write is awaited: "Copied" appears only once the clipboard accepted the text, and a refusal (no permission, an insecure page, no Clipboard API) shows "Copy failed" instead. The outcome is announced through a visually hidden `role="status"` (polite) region rendered next to the button, not by renaming the button: `getByRole('button', { name: 'Copy' })` keeps matching, and a test reads the outcome with `within(button.parentElement!).getByRole('status')` (a bare `getByRole('status')` is ambiguous: every `CopyButton` renders a `status` region, and so do `Banner`, `DataTable` and the skeletons). Its one root is a `span` with `display: contents` (no box) around the button and the status region, so `v-show`, `Transition` and `$el` work, and a class still goes to the button. The result stays for 1.5 s. `copyToClipboard(text)` is the same copy
323
378
  without a button.
324
379
 
325
380
  `CopyValue` shows the value in a monospace chip with the button beside it:
@@ -399,7 +454,7 @@ const emit = defineEmits<{ next: [] }>();
399
454
  | `label` | `string` | `"Load more"` (translated) | tooltip, `aria-label` and expanded label |
400
455
  | `#icon` slot | — | a rotate icon | replaces it |
401
456
  | `variant` | as `Button` | `'tonal'` | the style |
402
- | `loading` | `boolean` | — | spinner, button disabled |
457
+ | `loading` | `boolean` | — | spinner, clicks ignored |
403
458
 
404
459
  Icon-only by default because it sits in a pagination bar next to other icon
405
460
  buttons.
@@ -522,7 +577,7 @@ on load.
522
577
 
523
578
  ![LanguageSwitcher](../previews/buttons-actions-languageswitcher.webp)
524
579
 
525
- Globe button with a menu of the `I18nProvider` languages.
580
+ Globe button with a menu of the `I18nProvider` languages. Its menu is non-modal (see [DropdownMenu](overlays-and-menus.md#dropdownmenu)).
526
581
 
527
582
  ```vue
528
583
  <script setup lang="ts">