@nxgt/material-vue 0.34.0 → 0.35.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 (42) hide show
  1. package/CHANGELOG.md +26 -0
  2. package/dist/{Button-DEA5W6O3.js → Button-C6GBoxwB.js} +1 -1
  3. package/dist/{HoverCardTrigger-CjSteFgk.js → HoverCardTrigger-BRajrP9V.js} +2 -2
  4. package/dist/{camera-C52IuvMH.js → camera-BIK3JMQq.js} +4 -4
  5. package/dist/{components-DFEmacXJ.js → components-B3e9Djen.js} +9010 -8974
  6. package/dist/components.js +5 -5
  7. package/dist/composables.js +2 -2
  8. package/dist/dnd.js +1 -1
  9. package/dist/{form-scope-CaYs-o2w.js → form-scope-DH96Nu9y.js} +1 -1
  10. package/dist/{i18n-provider-CiVi05fs.js → i18n-provider-D0wc5ysD.js} +1 -1
  11. package/dist/i18n.js +4 -4
  12. package/dist/{icon-button-CWcOcNHr.js → icon-button-Cep-hCMB.js} +1 -1
  13. package/dist/lib/components/ui/display/chip/chip.utils.d.ts +9 -0
  14. package/dist/lib/components/ui/display/chip/chip.vue.d.ts +29 -16
  15. package/dist/lib/components/ui/display/chip/index.d.ts +1 -0
  16. package/dist/lib/components/ui/selection/select-field/select-field.vue.d.ts +2 -0
  17. package/dist/lib/i18n/resources/en/material.json.d.ts +1 -1
  18. package/dist/lib/i18n/resources/fr/material.json.d.ts +1 -1
  19. package/dist/lib.js +2 -2
  20. package/dist/main.js +10 -10
  21. package/dist/map.js +4 -4
  22. package/dist/material-vue.css +1 -1
  23. package/dist/{pdf-outline-sidebar-C_iJ8gqD.js → pdf-outline-sidebar-Bjz8jMaZ.js} +2 -2
  24. package/dist/{pdf-page-DOiJlWQn.js → pdf-page-BRtEfDpx.js} +1 -1
  25. package/dist/{pdf-page-list-BTmUd7Ga.js → pdf-page-list-DUSFOt6b.js} +2 -2
  26. package/dist/{pdf-reader-CEMMLJnB.js → pdf-reader-Dhuuu3ud.js} +8 -8
  27. package/dist/{pdf-sidebar-KLd76E5S.js → pdf-sidebar-BOsuIcvK.js} +3 -3
  28. package/dist/{pdf-thumbnail-sidebar-B4JkT_LV.js → pdf-thumbnail-sidebar-CEinOvk3.js} +3 -3
  29. package/dist/{pdf-toolbar-Da6UMt1O.js → pdf-toolbar-ZYITLhtl.js} +4 -4
  30. package/dist/pdf.js +2 -2
  31. package/dist/{sortable-provider-Cvpqk8tp.js → sortable-provider-BCawiL69.js} +2 -2
  32. package/dist/{stored-language-GDRdeYD8.js → stored-language-CGMzf-kR.js} +2 -2
  33. package/dist/{stx-player-B6-PSgzP.js → stx-player-DAhHmRHW.js} +2 -2
  34. package/dist/{translator-BDFEmlcL.js → translator-DhrnT0YX.js} +1 -1
  35. package/dist/{use-heading-spy-ClhUg50z.js → use-heading-spy-BF4hsZLZ.js} +1 -1
  36. package/dist/{use-material-translation-CaHS6oZz.js → use-material-translation-D30V5LyT.js} +3 -3
  37. package/docs/components/data-display.md +14 -2
  38. package/docs/components/data-table-filter-and-lists.md +2 -1
  39. package/docs/components/selection-and-choice.md +2 -1
  40. package/docs/roadmap.md +33 -15
  41. package/docs/troubleshooting.md +26 -0
  42. package/package.json +2 -2
@@ -1,7 +1,7 @@
1
1
  import { n as e } from "./rolldown-runtime-CWhphoD1.js";
2
2
  import { t } from "./utils-CykWQ0iJ.js";
3
- import { kf as n } from "./components-DFEmacXJ.js";
4
- import { t as r } from "./use-material-translation-CaHS6oZz.js";
3
+ import { kf as n } from "./components-B3e9Djen.js";
4
+ import { t as r } from "./use-material-translation-D30V5LyT.js";
5
5
  import { Fragment as i, computed as a, createBlock as o, createCommentVNode as s, createElementBlock as c, createElementVNode as l, defineComponent as u, normalizeClass as d, normalizeStyle as f, openBlock as p, ref as m, renderList as h, toDisplayString as g, unref as _, withCtx as v } from "vue";
6
6
  //#region lib/components/ui/media/pdf-viewer/partials/pdf-outline-row.vue?vue&type=script&setup=true&lang.ts
7
7
  var y = {
@@ -1,5 +1,5 @@
1
1
  import { t as e } from "./utils-CykWQ0iJ.js";
2
- import { Mp as t } from "./components-DFEmacXJ.js";
2
+ import { Mp as t } from "./components-B3e9Djen.js";
3
3
  import { computed as n, createBlock as r, createCommentVNode as i, createElementBlock as a, createElementVNode as o, defineComponent as s, nextTick as c, normalizeClass as l, normalizeStyle as u, onBeforeUnmount as d, openBlock as f, ref as p, shallowRef as m, unref as h, watch as g } from "vue";
4
4
  import { DEFAULT_PAGE_SIZE as _, escapeHtml as v, findTextMatches as y, highlightItemHtml as b, placeholderSize as x, rotatedSize as S } from "@nxgt/material-core/pdf-viewer";
5
5
  //#region lib/components/ui/media/pdf-viewer/pdf-note-icons.ts
@@ -1,6 +1,6 @@
1
1
  import { n as e } from "./rolldown-runtime-CWhphoD1.js";
2
- import { kf as t } from "./components-DFEmacXJ.js";
3
- import { t as n } from "./pdf-page-DOiJlWQn.js";
2
+ import { kf as t } from "./components-B3e9Djen.js";
3
+ import { t as n } from "./pdf-page-BRtEfDpx.js";
4
4
  import { Fragment as r, createBlock as i, createElementBlock as a, createElementVNode as o, defineComponent as s, openBlock as c, renderList as l, withCtx as u } from "vue";
5
5
  //#region lib/components/ui/media/pdf-viewer/partials/pdf-page-list.vue?vue&type=script&setup=true&lang.ts
6
6
  var d = { class: "flex flex-col items-center gap-4 px-4 py-4" }, f = /*@__PURE__*/ s({
@@ -1,12 +1,12 @@
1
1
  import { t as e } from "./utils-CykWQ0iJ.js";
2
- import { kn as t } from "./components-DFEmacXJ.js";
3
- import { t as n } from "./use-material-translation-CaHS6oZz.js";
4
- import { t as r } from "./Button-DEA5W6O3.js";
5
- import { o as i } from "./HoverCardTrigger-CjSteFgk.js";
6
- import { n as a } from "./pdf-page-DOiJlWQn.js";
7
- import { t as o } from "./pdf-page-list-BTmUd7Ga.js";
8
- import { t as s } from "./pdf-sidebar-KLd76E5S.js";
9
- import { t as c } from "./pdf-toolbar-Da6UMt1O.js";
2
+ import { kn as t } from "./components-B3e9Djen.js";
3
+ import { t as n } from "./use-material-translation-D30V5LyT.js";
4
+ import { t as r } from "./Button-C6GBoxwB.js";
5
+ import { o as i } from "./HoverCardTrigger-BRajrP9V.js";
6
+ import { n as a } from "./pdf-page-BRtEfDpx.js";
7
+ import { t as o } from "./pdf-page-list-DUSFOt6b.js";
8
+ import { t as s } from "./pdf-sidebar-BOsuIcvK.js";
9
+ import { t as c } from "./pdf-toolbar-ZYITLhtl.js";
10
10
  import { computed as l, createBlock as u, createCommentVNode as d, createElementBlock as f, createElementVNode as p, createTextVNode as m, createVNode as h, defineComponent as g, nextTick as _, normalizeClass as v, onBeforeUnmount as y, onMounted as b, openBlock as x, reactive as S, ref as C, shallowRef as w, toDisplayString as T, toRef as E, unref as D, useId as O, watch as k, withCtx as A } from "vue";
11
11
  import { AlertCircle as j, FileX2 as M, KeyRound as N, Loader2 as P } from "@lucide/vue";
12
12
  import { pdfSourceKey as F, toPdfjsParams as I } from "@nxgt/material-core/pdf-source";
@@ -1,8 +1,8 @@
1
1
  import { n as e } from "./rolldown-runtime-CWhphoD1.js";
2
2
  import { t } from "./utils-CykWQ0iJ.js";
3
- import { t as n } from "./use-material-translation-CaHS6oZz.js";
4
- import { t as r } from "./pdf-outline-sidebar-C_iJ8gqD.js";
5
- import { t as i } from "./pdf-thumbnail-sidebar-B4JkT_LV.js";
3
+ import { t as n } from "./use-material-translation-D30V5LyT.js";
4
+ import { t as r } from "./pdf-outline-sidebar-Bjz8jMaZ.js";
5
+ import { t as i } from "./pdf-thumbnail-sidebar-CEinOvk3.js";
6
6
  import { createElementBlock as a, createElementVNode as o, createVNode as s, defineComponent as c, normalizeClass as l, openBlock as u, toDisplayString as d, unref as f, useId as p, useTemplateRef as m } from "vue";
7
7
  //#region lib/components/ui/media/pdf-viewer/partials/pdf-sidebar.vue?vue&type=script&setup=true&lang.ts
8
8
  var h = ["aria-label"], g = ["aria-label"], _ = [
@@ -1,8 +1,8 @@
1
1
  import { n as e } from "./rolldown-runtime-CWhphoD1.js";
2
2
  import { t } from "./utils-CykWQ0iJ.js";
3
- import { kf as n } from "./components-DFEmacXJ.js";
4
- import { t as r } from "./use-material-translation-CaHS6oZz.js";
5
- import { t as i } from "./pdf-page-DOiJlWQn.js";
3
+ import { kf as n } from "./components-B3e9Djen.js";
4
+ import { t as r } from "./use-material-translation-D30V5LyT.js";
5
+ import { t as i } from "./pdf-page-BRtEfDpx.js";
6
6
  import { Fragment as a, createCommentVNode as o, createElementBlock as s, createElementVNode as c, createVNode as l, defineComponent as u, normalizeClass as d, openBlock as f, renderList as p, toDisplayString as m, unref as h, withCtx as g } from "vue";
7
7
  //#region lib/components/ui/media/pdf-viewer/partials/pdf-thumbnail-sidebar.vue?vue&type=script&setup=true&lang.ts
8
8
  var _ = ["aria-label"], v = {
@@ -1,10 +1,10 @@
1
1
  import { n as e } from "./rolldown-runtime-CWhphoD1.js";
2
2
  import { t } from "./utils-CykWQ0iJ.js";
3
- import { t as n } from "./use-material-translation-CaHS6oZz.js";
4
- import { d as r } from "./Button-DEA5W6O3.js";
5
- import { t as i } from "./icon-button-CWcOcNHr.js";
3
+ import { t as n } from "./use-material-translation-D30V5LyT.js";
4
+ import { d as r } from "./Button-C6GBoxwB.js";
5
+ import { t as i } from "./icon-button-Cep-hCMB.js";
6
6
  import { a, i as o, n as s, o as c, r as l, t as u } from "./DropdownMenuTrigger-BsuyNVzV.js";
7
- import { o as d } from "./HoverCardTrigger-CjSteFgk.js";
7
+ import { o as d } from "./HoverCardTrigger-BRajrP9V.js";
8
8
  import { Fragment as f, computed as p, createBlock as m, createCommentVNode as h, createElementBlock as g, createElementVNode as _, createTextVNode as v, createVNode as y, defineComponent as b, nextTick as x, normalizeClass as S, openBlock as C, ref as w, renderList as T, toDisplayString as E, unref as D, useTemplateRef as O, watch as k, withCtx as A } from "vue";
9
9
  import { ChevronDown as j, ChevronLeft as M, ChevronRight as N, ChevronUp as P, Download as F, Maximize2 as I, Minimize2 as L, Moon as R, Printer as z, RotateCw as B, Search as V, Sidebar as H, ZoomIn as U, ZoomOut as W } from "@lucide/vue";
10
10
  //#region lib/components/ui/media/pdf-viewer/partials/pdf-toolbar-search.vue?vue&type=script&setup=true&lang.ts
package/dist/pdf.js CHANGED
@@ -1,5 +1,5 @@
1
- import { n as e, t } from "./use-material-translation-CaHS6oZz.js";
2
- import { t as n } from "./Button-DEA5W6O3.js";
1
+ import { n as e, t } from "./use-material-translation-D30V5LyT.js";
2
+ import { t as n } from "./Button-C6GBoxwB.js";
3
3
  import { computed as r, createBlock as i, createTextVNode as a, defineComponent as o, getCurrentInstance as s, nextTick as c, onMounted as l, onScopeDispose as u, openBlock as d, ref as f, renderSlot as p, shallowRef as m, toDisplayString as ee, toValue as h, unref as g, watch as te, withCtx as ne } from "vue";
4
4
  import { contentDisposition as re, pdfBytesResponse as ie, toWebStream as ae } from "@nxgt/material-core/pdf/http";
5
5
  import { badge as oe, dataTable as se, defaultPdfTheme as ce, definePdfDocument as _, divider as v, header as y, heading as b, image as x, keyValue as S, keyValueOf as C, link as w, metric as T, page as E, pageBreak as D, pageNumber as O, pdfDocument as k, resolvePdfColor as A, resolvePdfTheme as j, row as M, section as N, spacer as P, stack as F, table as I, text as L, totals as R } from "@nxgt/material-core/pdf/model";
@@ -1,6 +1,6 @@
1
1
  import { t as e } from "./utils-CykWQ0iJ.js";
2
- import { t } from "./use-material-translation-CaHS6oZz.js";
3
- import { t as n } from "./icon-button-CWcOcNHr.js";
2
+ import { t } from "./use-material-translation-D30V5LyT.js";
3
+ import { t as n } from "./icon-button-Cep-hCMB.js";
4
4
  import { Teleport as r, computed as i, createBlock as a, createCommentVNode as o, createElementBlock as s, createVNode as c, defineComponent as l, inject as u, mergeProps as d, normalizeStyle as f, onUnmounted as p, openBlock as m, provide as h, reactive as g, ref as _, renderSlot as v, toValue as y, unref as b, useAttrs as x, watch as S, watchEffect as C, withCtx as w, withModifiers as T } from "vue";
5
5
  import { GripVertical as E } from "@lucide/vue";
6
6
  import { Primitive as D } from "reka-ui";
@@ -355,7 +355,7 @@ var e = {
355
355
  "go-to-first-page": "Go to first page",
356
356
  "go-to-last-page": "Go to last page",
357
357
  "rows-per-page": "Rows per page",
358
- "rows-selected": "{count} of {total} {count, plural, =0 {row selected} one {row selected} other {rows selected} }",
358
+ "rows-selected": "{count, plural, =0 {No rows selected} one {# row selected} other {# rows selected}} of {total}",
359
359
  "page-of": "Page {page} of {total}",
360
360
  label: "Pagination",
361
361
  range: "{from}–{to} of {total}",
@@ -1558,7 +1558,7 @@ var e = {
1558
1558
  "go-to-first-page": "Aller à la première page",
1559
1559
  "go-to-last-page": "Aller à la dernière page",
1560
1560
  "rows-per-page": "Lignes par page",
1561
- "rows-selected": "{count} sur {total} {count, plural, =0 {ligne sélectionnée} one {ligne sélectionnée} other {lignes sélectionnées} }",
1561
+ "rows-selected": "{count, plural, =0 {Aucune ligne sélectionnée} one {# ligne sélectionnée} other {# lignes sélectionnées}} sur {total}",
1562
1562
  "page-of": "Page {page} sur {total}",
1563
1563
  label: "Pagination",
1564
1564
  range: "{from}–{to} sur {total}",
@@ -1,6 +1,6 @@
1
1
  import { t as e } from "./utils-CykWQ0iJ.js";
2
- import { $t as t, Fp as n, Jt as r, Qt as i, Xt as a, Yt as o, en as s, tn as c } from "./components-DFEmacXJ.js";
3
- import { t as l } from "./use-material-translation-CaHS6oZz.js";
2
+ import { $t as t, Fp as n, Jt as r, Qt as i, Xt as a, Yt as o, en as s, tn as c } from "./components-B3e9Djen.js";
3
+ import { t as l } from "./use-material-translation-D30V5LyT.js";
4
4
  import { createBlock as u, createCommentVNode as d, createElementBlock as f, createElementVNode as p, createTextVNode as m, createVNode as h, defineComponent as g, normalizeClass as _, openBlock as v, toDisplayString as y, unref as b, withCtx as x } from "vue";
5
5
  //#region lib/components/ui/media/stx-player/partials/stx-player-frame.vue?vue&type=script&setup=true&lang.ts
6
6
  var S = ["data-layout", "aria-label"], C = {
@@ -1,4 +1,4 @@
1
- import { a as e, i as t, r as n, t as r } from "./stored-language-GDRdeYD8.js";
1
+ import { a as e, i as t, r as n, t as r } from "./stored-language-CGMzf-kR.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,4 +1,4 @@
1
- import { a as e } from "./i18n-provider-CiVi05fs.js";
1
+ import { a as e } from "./i18n-provider-D0wc5ysD.js";
2
2
  import { c as t, d as n, f as r, l as i, r as a, u as o } from "./number.utils-Bpo9tUaJ.js";
3
3
  import { computed as s, getCurrentInstance as c, inject as l, onMounted as u, ref as d, toValue as f } from "vue";
4
4
  import { injectConfigProviderContext as p } from "reka-ui";
@@ -1,6 +1,6 @@
1
- import "./stored-language-GDRdeYD8.js";
2
- import { a as e } from "./i18n-provider-CiVi05fs.js";
3
- import { i as t, r as n } from "./translator-BDFEmlcL.js";
1
+ import "./stored-language-CGMzf-kR.js";
2
+ import { a as e } from "./i18n-provider-D0wc5ysD.js";
3
+ import { i as t, r as n } from "./translator-DhrnT0YX.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]])) {
@@ -171,8 +171,12 @@ Pill with leading, avatar and trailing slots, an active state and a dismiss butt
171
171
 
172
172
  ```vue
173
173
  <script setup lang="ts">
174
+ import { ref } from 'vue';
174
175
  import { Avatar, AvatarFallback, Chip } from '@nxgt/material-vue/components';
175
176
 
177
+ const chip = ref<InstanceType<typeof Chip>>();
178
+ // chip.value?.focus()
179
+
176
180
  function remove(id: string) {
177
181
  console.log('remove', id);
178
182
  }
@@ -185,6 +189,9 @@ function remove(id: string) {
185
189
  </template>
186
190
  </Chip>
187
191
  <Chip label="Shipped" color="success" active />
192
+ <Chip label="Frontend" :dismiss-label="(label) => `Clear ${label} filter`" @dismiss="remove('fe')" />
193
+ <Chip label="+ Field" variant="dashed" :active="added" @click="add" />
194
+ <Chip ref="chip" label="Compact" size="sm" />
188
195
  </template>
189
196
  ```
190
197
 
@@ -192,12 +199,17 @@ function remove(id: string) {
192
199
  | --- | --- | --- | --- |
193
200
  | `label` | `string` | — | the text; the default slot replaces it |
194
201
  | `active` | `boolean` | — | filled appearance |
195
- | `variant` | Button `variant` | `'outlined'` | appearance when not active |
202
+ | `variant` | Button `variant`, or `'dashed'` | `'outlined'` | appearance when not active; `dashed` is a muted dashed pill (a "+ Field" pill) that turns solid and normal once `active` |
203
+ | `size` | `'default' \| 'sm'` | `'default'` | `sm` is a compact chip; the ✕ and every target stay at least 24px |
196
204
  | `color` | Button `color` | — | tone |
197
205
  | `disabled` | `boolean` | — | disables the chip and its ✕ |
198
- | `@dismiss` | `() => void` | — | a listener adds the ✕ button, named "Remove {label}" (`material.chip.dismiss-label`), `{label}` being the text the chip shows: the default slot's when given, else `label`; "Remove" when it shows none |
206
+ | `@dismiss` | `() => void` | — | a listener adds the ✕ button, named "Remove {label}" (`material.chip.dismiss-label`), `{label}` being the text the chip shows: the default slot's when given, else `label`; "Remove" when it shows none; the ✕ is a 24px target |
207
+ | `dismissLabel` | `string \| ((label: string) => string)` | — | names the ✕ instead of "Remove {label}": a string as is, or a function of the text the chip shows |
199
208
  | `@click` | `(event: MouseEvent) => void` | — | a listener makes the chip (or its body, when dismissible) a button |
200
209
  | `#leading`, `#avatar`, `#trailing` | slots | — | `#avatar` is shrunk to fit and replaces `#leading` |
210
+ | exposed `el`, `focus(options?)` | `HTMLElement \| null`, `(options?: FocusOptions) => void` | — | the chip's body (the Button, the inner button, or the label span with `tabindex="-1"`) and a method focusing it: `chip.value?.focus()` |
211
+
212
+ The dashed look's muted text meets 4.5:1 on the `background` and `card` surfaces, but not on `accent`.
201
213
 
202
214
  **Storybook:** `Data display/Chip` · **React:** `Chip`
203
215
 
@@ -356,7 +356,8 @@ async function archive() {
356
356
  in the URL; `manual` turns client filtering off.
357
357
  - **Selection** is `v-model:row-selection`, keyed by `getRowId`, so it
358
358
  survives a page change: ids of other pages stay in it, and the footer
359
- counts them all ("3 rows selected", `material.table.pagination.selected`).
359
+ counts them all ("3 rows selected of 128", `material.table.pagination.rows-selected`; "Page n of m"
360
+ is hidden when the table has no rows).
360
361
  `#actions="{ table }"` reads it too (`table.store.state.rowSelection`). To
361
362
  keep it across a reload, put it in the URL or `sessionStorage`. Unbound,
362
363
  both models are held inside, as before. Bind both halves (`v-model`, or
@@ -144,6 +144,7 @@ const framework = ref('nuxt');
144
144
  | `placeholder` | `string` | `label` | the trigger's text while nothing is selected |
145
145
  | `required` | `boolean` | — | an asterisk after the label, and the select's `required`; the trigger is named by the label |
146
146
  | `label`, `helper-text`, `error`, `disabled` | | — | the field's text and state |
147
+ | `ariaLabelledby` (`aria-labelledby` in a template) | `string` | — | the id of an element that names the trigger when `label` is absent; `label` wins when both are given |
147
148
 
148
149
  `#option` renders each option's content in the list (React's
149
150
  `renderOption`); it receives `{ option, index, selected }`. The trigger shows
@@ -166,7 +167,7 @@ the picked option's text.
166
167
  **Accessibility:** the trigger is named by `label`, described by the help or
167
168
  error text (`aria-describedby`) and marked `aria-invalid` on error, so
168
169
  `getByRole('combobox', { name: 'Framework' })` finds it and
169
- `toHaveAccessibleDescription(…)` / `toBeInvalid()` match.
170
+ `toHaveAccessibleDescription(…)` / `toBeInvalid()` match. Without a `label`, `aria-labelledby` (`ariaLabelledby` in the script; the id of another element) names the trigger; when both are given, `label` wins.
170
171
  **Emits:** `update:modelValue` with `string`.
171
172
  **Form wrapper:** `SelectFormField` — `name` inside a vee-validate form, see
172
173
  [forms](../guides/forms.md#the-pair) and [what each field emits](../guides/forms.md#what-each-field-emits).
package/docs/roadmap.md CHANGED
@@ -6,21 +6,6 @@ version they shipped in, and planned entries may name the major they target.
6
6
 
7
7
  ## Now
8
8
 
9
- - **A strict Content Security Policy** — a page that sends `script-src` with
10
- a nonce and no `'unsafe-eval'`, and `style-src-elem` with a nonce and no
11
- `'unsafe-inline'`, runs every component with no violation report: a
12
- `NonceProvider` forwards the nonce to each component, the CSS the
13
- dependencies inject moves into the stylesheet, zod becomes external with
14
- schemas built lazily, and the KaTeX fonts ship as files. Done so far:
15
- KaTeX's fonts are files beside the compiled stylesheet instead of 1.4 MB of
16
- `data:` URIs inside it, so `font-src 'self'` needs no `data:`;
17
- `NonceProvider` takes the nonce to reka's `Select`, `Combobox`,
18
- `ScrollArea` and `Splitter`, `InputOTP` and `RichTextEditor`;
19
- `ImageCropper` is measured and injects no `<style>`, and `InputOTP`'s rules
20
- are in the stylesheet too; zod is no longer bundled and no schema is built
21
- at import, so the app's `z.config({ jitless: true })` keeps zod from
22
- probing `new Function`. Today the
23
- [Content Security Policy guide](guides/csp.md) lists what is left to relax.
24
9
  - **Empty and error states that look designed** — `EmptyState` and a new
25
10
  `ErrorState` in three sizes (`default`, `compact`, `inline`), with in-house
26
11
  inline SVG illustrations or a slot for your own. `ErrorState` is a
@@ -32,6 +17,30 @@ version they shipped in, and planned entries may name the major they target.
32
17
 
33
18
  ## Next
34
19
 
20
+ - **One Vite plugin for the whole setup** — `nxgtMaterial()` from
21
+ `@nxgt/material-vue/vite` is the one call that wires the library
22
+ into a Vite app; it is implemented once in `@nxgt/material-core/vite`, and
23
+ `@nxgt/material/vite` is the same plugin.
24
+ Every option is on by default and each can be turned off or refined; the
25
+ helpers that exist today stay exported.
26
+ - `csp`: a nonce placeholder through `html.cspNonce` and
27
+ `applyCspNonce(html, nonce)` to fill it; zod's jitless mode set by an
28
+ inline nonced script in `index.html` (`ZOD_JITLESS_SCRIPT` for a server
29
+ that renders the page itself); and the recommended policy sent by the dev
30
+ server as Report-Only.
31
+ - `fonts`: the KaTeX fonts emitted as files, and `sans: 'inter'` for a
32
+ self-hosted Inter.
33
+ - `styles`: a build that fails with the exact fix when the stylesheet import
34
+ or the `@source` line is missing.
35
+ - `pdf`: pdfkit's standard fonts handled automatically when
36
+ `@react-pdf/renderer` is installed, and `bundle: true` (the Nuxt module's
37
+ `pdf.bundleStandardFonts` today) for a server that has no
38
+ `node_modules`.
39
+ - Nuxt: the Nuxt module takes the same options.
40
+ - On the server, `@nxgt/material-core` gains `createCspNonce()` (Web Crypto)
41
+ and `cspPolicy({ ... })`, which returns `{ directives, header }` as the
42
+ [Content Security Policy guide](guides/csp.md) describes; `NonceProvider`'s
43
+ `nonce` becomes optional on the client. Ships as minors.
35
44
  - **One media player, video and audio** — `MediaPlayer`, `MediaPlayerMini`,
36
45
  `useMediaPlayer` and `AudioPlayer`, built on the native `<video>` / `<audio>`.
37
46
  `StxPlayer` and `VideoPlayer` are removed in `@nxgt/material-vue` 1.0, with a
@@ -113,6 +122,8 @@ version they shipped in, and planned entries may name the major they target.
113
122
 
114
123
  ## Not planned
115
124
 
125
+ - **A Next.js plugin** — the plugin targets Vite only. No supported consumer
126
+ builds with Next.js, and `withNxgtPrint` stays the config helper for it.
116
127
  - **The `Combobox` primitive family** — `ComboboxFormField` covers forms; the
117
128
  low-level `Combobox` parts stay in `@nxgt/material` only.
118
129
  - **The React library's state and form stacks** — widgets keep their state in
@@ -151,6 +162,13 @@ version they shipped in, and planned entries may name the major they target.
151
162
 
152
163
  ## Shipped
153
164
 
165
+ - **A strict Content Security Policy** — a page that sends `script-src` with a
166
+ nonce and no `'unsafe-eval'`, and `style-src-elem` with a nonce and no
167
+ `'unsafe-inline'`, runs every component with no violation report:
168
+ `NonceProvider` forwards the nonce to each component, the CSS the
169
+ dependencies inject is in the stylesheet, zod is external and its schemas are
170
+ built on first use, and the KaTeX fonts are files. The
171
+ [Content Security Policy guide](guides/csp.md) has the policy. 0.33.0.
154
172
  - **An `Autocomplete` that searches a server** — `on-search`, `debounce-ms`, `min-query-length`, `filter`, `loading`, `search-error`: a
155
173
  debounced search with an `AbortSignal` whose stale responses are dropped,
156
174
  a polite "Loading…" / "N results" announcement, and local matching that
@@ -154,6 +154,7 @@ words in your error.
154
154
  - [An `Icon` is named "Icon {name}" although you passed `aria-label`](#an-icon-is-named-icon-name-although-you-passed-aria-label)
155
155
  - [An end-to-end test no longer finds the `Close` or `Zoom in` button](#an-end-to-end-test-no-longer-finds-the-close-or-zoom-in-button)
156
156
  - [A test no longer finds a pagination, breadcrumb or other built-in label by its English name](#a-test-no-longer-finds-a-pagination-breadcrumb-or-other-built-in-label-by-its-english-name)
157
+ - [The selection count reads in the wrong order after overriding `material.table.pagination.rows-selected`](#the-selection-count-reads-in-the-wrong-order-after-overriding-materialtablepaginationrows-selected)
157
158
  - [A test no longer finds a chip's remove button by the exact name `Remove`, or a `LocationPreview` by its place name](#a-test-no-longer-finds-a-chips-remove-button-by-the-exact-name-remove-or-a-locationpreview-by-its-place-name)
158
159
  - [A test no longer finds an icon badge by role `button`, or an `Icon` named "Icon {name}" inside a button](#a-test-no-longer-finds-an-icon-badge-by-role-button-or-an-icon-named-icon-name-inside-a-button)
159
160
  - [A button named "Icon plus Add" is now named "Add"](#a-button-named-icon-plus-add-is-now-named-add)
@@ -2827,6 +2828,31 @@ await page.getByRole('button', { name: /^(Next|Suivant)$/ }).click();
2827
2828
  <PaginationNext aria-label="Next results" />
2828
2829
  ```
2829
2830
 
2831
+ ### The selection count reads in the wrong order after overriding `material.table.pagination.rows-selected`
2832
+
2833
+ **When:** after upgrading, the data table's footer reads "of 128 3 rows
2834
+ selected" (or the French "sur 128 3 lignes sélectionnées") because your
2835
+ `I18nProvider` overrides `material.table.pagination.rows-selected` with the old
2836
+ text.
2837
+ **Why:** the message now leads with the count and ends with the total, so
2838
+ "3 rows selected of 128" and "No rows selected of 128" read as a sentence, and
2839
+ the plural covers zero. The old form, `{count} of {total} {count, plural, …}`,
2840
+ put the count and the total first. An override keeps its own text, so it keeps
2841
+ the old order. The same release hides "Page n of m" when the table has no rows.
2842
+ **Fix:** adopt the new ICU form in your override, or delete the override:
2843
+
2844
+ ```json
2845
+ {
2846
+ "material": {
2847
+ "table": {
2848
+ "pagination": {
2849
+ "rows-selected": "{count, plural, =0 {No rows selected} one {# row selected} other {# rows selected}} of {total}"
2850
+ }
2851
+ }
2852
+ }
2853
+ }
2854
+ ```
2855
+
2830
2856
  ### A test no longer finds a chip's remove button by the exact name `Remove`, or a `LocationPreview` by its place name
2831
2857
 
2832
2858
  **When:** after an update (0.22.0 and later),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nxgt/material-vue",
3
- "version": "0.34.0",
3
+ "version": "0.35.0",
4
4
  "license": "MIT",
5
5
  "bugs": {
6
6
  "email": "stevegires@gmail.com"
@@ -124,7 +124,7 @@
124
124
  "docs:previews": "vitest run --project previews"
125
125
  },
126
126
  "dependencies": {
127
- "@nxgt/material-core": "^0.9.0",
127
+ "@nxgt/material-core": "^0.9.1",
128
128
  "@floating-ui/dom": "^1.8.0",
129
129
  "@fortawesome/fontawesome-common-types": "7.3.1",
130
130
  "@lucide/vue": "^1.45.0",