@nxgt/material-vue 0.42.0 → 0.43.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.
- package/CHANGELOG.md +111 -0
- package/README.md +18 -5
- package/dist/{Button-CWmzvv9p.js → Button-C3K6dhqd.js} +4 -4
- package/dist/{HoverCardTrigger-C5AbAyHE.js → HoverCardTrigger-Bga4YjEr.js} +69 -62
- package/dist/backgrounds/backgrounds.css +8 -0
- package/dist/backgrounds/css/base.css +169 -0
- package/dist/backgrounds/css/gradient.css +53 -0
- package/dist/backgrounds/css/grain.css +19 -0
- package/dist/backgrounds/css/motion.css +30 -0
- package/dist/backgrounds.js +111 -0
- package/dist/{camera-C-9slBUV.js → camera-BbF9_-ys.js} +4 -4
- package/dist/components/base.css +5 -2
- package/dist/components/components.css +5 -0
- package/dist/components/theme-tokens.css +21 -0
- package/dist/{components-DX4EycMi.js → components-yCdbry6Q.js} +14077 -13577
- package/dist/components.js +8 -8
- package/dist/composables.js +3 -3
- package/dist/dnd.js +1 -1
- package/dist/{form-scope-CN68PTXc.js → form-scope-CkWJrBCu.js} +1 -1
- package/dist/{i18n-provider-DmZSTBnp.js → i18n-provider-tL27-a8y.js} +1 -1
- package/dist/i18n.js +4 -4
- package/dist/{icon-button-DErh1aJS.js → icon-button-MyFFJpXA.js} +4 -4
- package/dist/lib/backgrounds/background/background.vue.d.ts +22 -0
- package/dist/lib/backgrounds/background/index.d.ts +2 -0
- package/dist/lib/backgrounds/background/partials/background-layers.vue.d.ts +9 -0
- package/dist/lib/backgrounds/background/partials/scene-svg.d.ts +10 -0
- package/dist/lib/backgrounds/background/types.d.ts +24 -0
- package/dist/lib/backgrounds/index.d.ts +13 -0
- package/dist/lib/components/ui/actions/button/button-tones.d.ts +3 -3
- package/dist/lib/components/ui/actions/responsive-button/responsive-button.vue.d.ts +3 -3
- package/dist/lib/components/ui/collections/data-table/data-table-context.d.ts +4 -0
- package/dist/lib/components/ui/collections/data-table/data-table.vue.d.ts +8 -0
- package/dist/lib/components/ui/collections/data-table/partials/data-table-body.vue.d.ts +8 -0
- package/dist/lib/components/ui/collections/data-table/partials/data-table-empty.vue.d.ts +5 -1
- package/dist/lib/components/ui/collections/data-table/partials/data-table-toolbar.d.ts +16 -3
- package/dist/lib/components/ui/collections/data-table/select-checkbox.d.ts +36 -0
- package/dist/lib/components/ui/collections/data-table/types.d.ts +15 -0
- package/dist/lib/components/ui/collections/data-table/use-data-table.d.ts +2 -0
- package/dist/lib/components/ui/feedback/circular-progress/circular-progress.vue.d.ts +1 -1
- package/dist/lib/components/ui/feedback/empty-state/empty-state.vue.d.ts +21 -8
- package/dist/lib/components/ui/feedback/empty-state/index.d.ts +1 -1
- package/dist/lib/components/ui/feedback/error-state/error-state.vue.d.ts +54 -0
- package/dist/lib/components/ui/feedback/error-state/index.d.ts +3 -0
- package/dist/lib/components/ui/feedback/error-state/partials/error-state-details.vue.d.ts +7 -0
- package/dist/lib/components/ui/feedback/index.d.ts +1 -0
- package/dist/lib/components/ui/feedback/state-frame/state-frame.vue.d.ts +36 -0
- package/dist/lib/components/ui/feedback/state-frame/state-icon.vue.d.ts +7 -0
- package/dist/lib/components/ui/feedback/state-frame/state-illustration.vue.d.ts +8 -0
- package/dist/lib/components/ui/feedback/state-frame/state-tones.d.ts +11 -0
- package/dist/lib/components/ui/fields/contacts/consts.d.ts +1 -1
- package/dist/lib/components/ui/layout/app-shell/use-truncated-title.d.ts +10 -0
- package/dist/lib/components/ui/layout/background/background.vue.d.ts +18 -3
- package/dist/lib/components/ui/layout/doc/partials/doc-empty.vue.d.ts +7 -4
- package/dist/lib/components/ui/media/stx-player/stx-player-viewport.vue.d.ts +2 -2
- package/dist/lib/components/ui/overlays/command/CommandSeparator.vue.d.ts +3 -1
- package/dist/lib/components/ui/overlays/dialog/in-dialog.d.ts +1 -1
- package/dist/lib/components/ui/overlays/dialog/use-escape-forward.d.ts +13 -0
- package/dist/lib/components/ui/overlays/dialog/use-modal-content.d.ts +2 -0
- package/dist/lib/components/ui/primitives/nonce-provider/nonce-provider.vue.d.ts +4 -1
- package/dist/lib/components/ui/selection/autocomplete/autocomplete-keyboard.d.ts +22 -4
- package/dist/lib/components/ui/selection/autocomplete/partials/autocomplete-box.vue.d.ts +6 -2
- package/dist/lib/components/ui/selection/autocomplete/partials/autocomplete-list.vue.d.ts +7 -0
- package/dist/lib/components/ui/selection/autocomplete/use-autocomplete-active.d.ts +17 -0
- package/dist/lib/components/ui/selection/autocomplete/use-autocomplete-keydown.d.ts +21 -0
- package/dist/lib/components/ui/selection/autocomplete/use-autocomplete-open.d.ts +3 -3
- package/dist/lib/components/ui/selection/autocomplete/use-autocomplete.d.ts +2 -1
- package/dist/lib/components/ui/selection/autocomplete/use-drawer-room.d.ts +11 -0
- package/dist/lib/components/ui/selection/autocomplete/use-query-change.d.ts +8 -0
- package/dist/lib/components/ui/widgets/charts/chart-container.vue.d.ts +2 -2
- package/dist/lib/components/ui/widgets/kanban/partials/kanban-empty.vue.d.ts +1 -0
- package/dist/lib/composables/use-background-activity.d.ts +8 -0
- package/dist/lib/i18n/resources/en/en.d.ts +24 -0
- package/dist/lib/i18n/resources/en/material.json.d.ts +25 -1
- package/dist/lib/i18n/resources/fr/fr.d.ts +24 -0
- package/dist/lib/i18n/resources/fr/material.json.d.ts +25 -1
- package/dist/lib/i18n/resources/resources.d.ts +48 -0
- package/dist/lib/i18n/translator.d.ts +1 -1
- package/dist/lib/lib/index.d.ts +1 -0
- package/dist/lib/nuxt/component-names.d.ts +1 -1
- package/dist/lib/nuxt/module.d.ts +2 -11
- package/dist/lib/nuxt/pdf-fonts.d.ts +1 -1
- package/dist/lib/nuxt/plugin-options.d.ts +58 -0
- package/dist/lib/vite/index.d.ts +4 -8
- package/dist/lib.js +52 -51
- package/dist/main.js +17 -17
- package/dist/map.js +4 -4
- package/dist/material-vue.css +1 -1
- package/dist/{pdf-outline-sidebar-BU4o_hBI.js → pdf-outline-sidebar-Kqsfd_cO.js} +2 -2
- package/dist/{pdf-page-anNe78Lc.js → pdf-page-Dx3jwxu6.js} +1 -1
- package/dist/{pdf-page-list-CSY76HH6.js → pdf-page-list-BsQmEHaY.js} +2 -2
- package/dist/{pdf-reader-BhZNrW7R.js → pdf-reader-CJo8SQVl.js} +15 -15
- package/dist/{pdf-sidebar-DcIpG7eh.js → pdf-sidebar-CcCUATl-.js} +3 -3
- package/dist/{pdf-thumbnail-sidebar-CUC0V4if.js → pdf-thumbnail-sidebar-BRxNRGfG.js} +4 -4
- package/dist/{pdf-toolbar-C373S-ul.js → pdf-toolbar-B0ckYBJ2.js} +4 -4
- package/dist/pdf.js +2 -2
- package/dist/{print-format.utils-C81c0weJ.js → print-format.utils-51joHpFb.js} +2 -2
- package/dist/{sortable-provider-CL2UGGn8.js → sortable-provider-BEx1B0Ky.js} +2 -2
- package/dist/{stored-language-Wtcj2HsU.js → stored-language-DVP9KzRu.js} +50 -2
- package/dist/{stx-player-CMmM3F5Z.js → stx-player-KPp9c7vS.js} +12 -12
- package/dist/styles.css +4 -0
- package/dist/{translator-D5Dp-dob.js → translator-Bm7i7dv-.js} +1 -1
- package/dist/use-background-activity-DdTBbNpX.js +17 -0
- package/dist/{use-heading-spy-BIBHtUXN.js → use-heading-spy-jn8f2ioE.js} +13 -13
- package/dist/{use-material-translation-COoBTGpB.js → use-material-translation-CfFZPSe0.js} +3 -3
- package/dist/vite.js +7 -2
- package/docs/README.md +3 -0
- package/docs/components/buttons-and-actions.md +2 -0
- package/docs/components/data-table-filter-and-lists.md +59 -8
- package/docs/components/feedback-and-status.md +79 -8
- package/docs/components/media-and-files.md +2 -0
- package/docs/components/navigation-and-layout.md +13 -5
- package/docs/components/overlays-and-menus.md +20 -3
- package/docs/components/primitives.md +5 -3
- package/docs/components/rich-widgets.md +1 -1
- package/docs/components/selection-and-choice.md +14 -4
- package/docs/getting-started.md +22 -3
- package/docs/guides/app-shell.md +1 -1
- package/docs/guides/backgrounds.md +143 -0
- package/docs/guides/csp.md +48 -6
- package/docs/guides/helpers.md +1 -0
- package/docs/guides/i18n.md +51 -1
- package/docs/guides/migrate-to-vite-plugin.md +259 -0
- package/docs/guides/pdf.md +11 -4
- package/docs/guides/ssr.md +1 -1
- package/docs/guides/theming.md +52 -4
- package/docs/guides/vite-plugin.md +194 -0
- package/docs/previews/backgrounds-matrix.webp +0 -0
- package/docs/previews/feedback-status-emptystate.webp +0 -0
- package/docs/previews/feedback-status-errorstate.webp +0 -0
- package/docs/roadmap.md +60 -32
- package/docs/troubleshooting.md +251 -7
- package/lib/backgrounds/backgrounds.css +8 -0
- package/lib/backgrounds/css/base.css +169 -0
- package/lib/backgrounds/css/gradient.css +53 -0
- package/lib/backgrounds/css/grain.css +19 -0
- package/lib/backgrounds/css/motion.css +30 -0
- package/lib/components/base.css +5 -2
- package/lib/components/components.css +5 -0
- package/lib/components/theme-tokens.css +21 -0
- package/lib/nuxt/component-names.ts +1 -0
- package/lib/nuxt/module.ts +29 -15
- package/lib/nuxt/pdf-fonts.ts +1 -1
- package/lib/nuxt/plugin-options.ts +92 -0
- package/lib/nuxt/runtime/inter.css +6 -0
- package/lib/styles.css +4 -0
- package/lib/vite/index.ts +19 -2
- package/package.json +24 -2
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
# The Vite plugin: `nxgtMaterial()`
|
|
2
|
+
|
|
3
|
+
One plugin for the build-time work `@nxgt/material-vue` asks of a Vite app: a strict
|
|
4
|
+
Content Security Policy that needs no hand-written nonce, fonts that survive
|
|
5
|
+
`font-src 'self'`, and a build that fails, with the exact fix, when the
|
|
6
|
+
stylesheet is not wired.
|
|
7
|
+
|
|
8
|
+
```ts
|
|
9
|
+
// vite.config.ts
|
|
10
|
+
import { nxgtMaterial } from '@nxgt/material-vue/vite';
|
|
11
|
+
import vue from '@vitejs/plugin-vue';
|
|
12
|
+
import tailwindcss from '@tailwindcss/vite';
|
|
13
|
+
import { defineConfig } from 'vite';
|
|
14
|
+
|
|
15
|
+
export default defineConfig({
|
|
16
|
+
plugins: [vue(), tailwindcss(), ...nxgtMaterial()],
|
|
17
|
+
});
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
`nxgtMaterial()` returns an array of plugins, hence the spread. Put it last in `plugins` and add no HTML minifier or rewriting plugin after it: a hash covers exact text, and anything that changes the inline scripts later invalidates it.
|
|
21
|
+
|
|
22
|
+
Every part is on by default and has an opt-out. It needs `vite` 5.2 or later (6, 7, 8; on Vite 5, as under Nuxt 3, every check runs as for the client).
|
|
23
|
+
|
|
24
|
+
| Option | Default | What it does |
|
|
25
|
+
| --- | --- | --- |
|
|
26
|
+
| `csp` | on, `mode: 'hash'` | Puts zod's jitless script in `index.html`, then writes the hash of every inline script and style of the built HTML to `nxgt-csp.json`; the header uses the script hashes. `csp: false` turns it all off |
|
|
27
|
+
| `csp.mode` | `'hash'` | `'hash'`: no placeholder ever lands in the HTML. `'nonce'`: the HTML carries a placeholder your server replaces on every request |
|
|
28
|
+
| `csp.placeholder` | `CSP_NONCE_PLACEHOLDER` | Nonce mode only: your own placeholder (or set Vite's `html.cspNonce`, which the plugin then reuses) |
|
|
29
|
+
| `csp.zodJitless` | `true` | The inline script that switches zod's `new Function` probe off |
|
|
30
|
+
| `csp.dev` | `true` | A `Content-Security-Policy-Report-Only` header on the dev server |
|
|
31
|
+
| `csp.policy` | `{}` | `cspPolicy` options (`directives`, `hashes`) added to the dev and generated headers |
|
|
32
|
+
| `fonts.katex` | `true` | Never inline a font as a `data:` URI (`cspAssetsInlineLimit`), composed with your own `build.assetsInlineLimit` |
|
|
33
|
+
| `fonts.sans` | `'inter'` | Loads self-hosted Inter when `@fontsource-variable/inter` is installed (otherwise warns and keeps the system stack), in your root stylesheet, and sets `--font-sans`; `false` to keep the system stack and silence the warning. `fonts: false` turns both off |
|
|
34
|
+
| `styles.check` | `true` | Fails `vite build` when the library's stylesheet is never imported (`@nxgt/material-vue/styles.css`, or the compiled one through `@import "@nxgt/material-vue";`) |
|
|
35
|
+
| `pdf` | on | pdfkit's standard fonts (`pdfkitStandardFonts()`): a no-op unless pdfkit goes through the bundle. `pdf: false` turns it off |
|
|
36
|
+
| `pdf.bundle` | `false` | Also adds the renderer to `ssr.noExternal`, for a server whose runtime image has no `node_modules` (see [Rendering PDFs on a bundled server](#rendering-pdfs-on-a-bundled-server)) |
|
|
37
|
+
|
|
38
|
+
## The two CSP modes
|
|
39
|
+
|
|
40
|
+
### Hash mode (default): safe on a static host
|
|
41
|
+
|
|
42
|
+
The build computes the sha256 of every inline `<script>` and `<style>` of the
|
|
43
|
+
built `index.html` (zod's jitless script, and anything of yours) and writes:
|
|
44
|
+
|
|
45
|
+
- `dist/.vite/nxgt-csp.json`: `{ mode, scriptHashes, styleHashes, header }`;
|
|
46
|
+
- a line in the build log with the ready-to-paste header.
|
|
47
|
+
|
|
48
|
+
```
|
|
49
|
+
Content-Security-Policy: default-src 'self'; script-src 'self' 'sha256-…'; style-src-elem 'self' 'unsafe-inline'; …
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
Scripts are allowed by hash only. `<style>` elements are allowed by
|
|
53
|
+
`'unsafe-inline'`: the components create some at runtime (`ScrollArea` and
|
|
54
|
+
`Select`, the modals' scroll lock, the rich text editor), which no build can
|
|
55
|
+
hash, and a browser ignores `'unsafe-inline'` as soon as a hash or a nonce is
|
|
56
|
+
in the same directive. So the header carries no style hash; `styleHashes` in
|
|
57
|
+
the JSON is there for a stricter policy you write yourself (it would block
|
|
58
|
+
those runtime `<style>` elements). An inline style runs no code; for a
|
|
59
|
+
`style-src-elem` without `'unsafe-inline'`, use nonce mode.
|
|
60
|
+
|
|
61
|
+
Send that header from your host (a `_headers` file, a CDN rule, the web
|
|
62
|
+
server). The HTML holds no placeholder and no nonce, so nothing public can be
|
|
63
|
+
mistaken for a secret. Rebuild, and the hashes follow the HTML. A hash covers
|
|
64
|
+
exact text: an inline script a CDN or a tag manager rewrites no longer matches.
|
|
65
|
+
|
|
66
|
+
### Nonce mode: for an app with a server
|
|
67
|
+
|
|
68
|
+
```ts
|
|
69
|
+
nxgtMaterial({ csp: { mode: 'nonce' } })
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
Vite's `html.cspNonce` is set to `NXGT_CSP_NONCE`, so every script, link and
|
|
73
|
+
`meta` of `index.html` carries `nonce="NXGT_CSP_NONCE"`. **That value is
|
|
74
|
+
public: never serve it as it is.** On every request, replace it:
|
|
75
|
+
|
|
76
|
+
```ts
|
|
77
|
+
import { applyCspNonce, cspPolicy, createCspNonce } from '@nxgt/material-vue/lib';
|
|
78
|
+
|
|
79
|
+
const nonce = createCspNonce();
|
|
80
|
+
const html = applyCspNonce(builtHtml, nonce);
|
|
81
|
+
res.setHeader('Content-Security-Policy', cspPolicy({ nonce }).header);
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
`applyCspNonce` and `cspPolicy({ nonce })` throw when given the placeholder as
|
|
85
|
+
the nonce. `nxgt-csp.json` still lists the header, with the placeholder in
|
|
86
|
+
it, as a template to read, not to serve.
|
|
87
|
+
|
|
88
|
+
Pick nonce mode when a server renders or serves your HTML and can run
|
|
89
|
+
`applyCspNonce`; pick hash mode for a static host. Nonce mode is also the
|
|
90
|
+
strict option for styles: `style-src-elem 'self' 'nonce-…'`, no
|
|
91
|
+
`'unsafe-inline'`.
|
|
92
|
+
|
|
93
|
+
## The dev server
|
|
94
|
+
|
|
95
|
+
`csp.dev` sends `Content-Security-Policy-Report-Only` (hash mode: no nonce,
|
|
96
|
+
and the hash of zod's jitless script when `csp.zodJitless` is on; nonce mode:
|
|
97
|
+
the placeholder, as the dev HTML carries it) with `ws:` for HMR.
|
|
98
|
+
Report-Only never blocks, so Vite's own inline scripts are reported and
|
|
99
|
+
that is expected. Vite's dev `<style>` elements (your CSS, injected in dev
|
|
100
|
+
only: `vite build` emits stylesheet files) are allowed by `'unsafe-inline'` in
|
|
101
|
+
hash mode and carry the placeholder in nonce mode.
|
|
102
|
+
|
|
103
|
+
## Fonts
|
|
104
|
+
|
|
105
|
+
- **`fonts.katex`**: Vite inlines an asset under 4096 bytes as a `data:` URI,
|
|
106
|
+
and `font-src 'self'` blocks it (KaTeX's `KaTeX_Size3-Regular.woff2` is
|
|
107
|
+
3.6 KB). The plugin sets `build.assetsInlineLimit` so a font is always a
|
|
108
|
+
file. Your own function or number still applies to every other asset.
|
|
109
|
+
- **`fonts.sans: 'inter'`**: in the stylesheet that imports
|
|
110
|
+
`@nxgt/material-vue/styles.css`, the plugin imports `@fontsource-variable/inter` first
|
|
111
|
+
and appends an unlayered `:root { --font-sans: "Inter Variable", … }` that
|
|
112
|
+
beats Tailwind's layered theme variable. Nothing is added when that
|
|
113
|
+
stylesheet (or a file it imports) already imports Inter or sets
|
|
114
|
+
`--font-sans` itself. A JavaScript `import '@fontsource-variable/inter'` is
|
|
115
|
+
not detected: pair it with `fonts: { sans: false }`. The package is an optional peer
|
|
116
|
+
and Inter loads only when your app has it installed:
|
|
117
|
+
`bun add @fontsource-variable/inter`. Without it the plugin warns once, in
|
|
118
|
+
dev and in `vite build`, keeps the system font stack and never fails the
|
|
119
|
+
build; `fonts: { sans: false }` turns Inter off and silences the warning.
|
|
120
|
+
|
|
121
|
+
## The styles check
|
|
122
|
+
|
|
123
|
+
`vite build` (client only; not under Vitest, not for `build.ssr`) fails when
|
|
124
|
+
the library's stylesheet is imported by no stylesheet and no module. Either
|
|
125
|
+
route passes: `@nxgt/material-vue/styles.css` (with Tailwind; it already
|
|
126
|
+
scans the package, so Vue needs no `@source`), or the compiled stylesheet of
|
|
127
|
+
an app without Tailwind, `@import "@nxgt/material-vue";` (the package's
|
|
128
|
+
`style` condition, see [theming](theming.md#without-tailwind)). The error message names the
|
|
129
|
+
exact `@import` line to add.
|
|
130
|
+
|
|
131
|
+
Opt out with `styles: false` (a Storybook build, for instance, may not import
|
|
132
|
+
it).
|
|
133
|
+
|
|
134
|
+
## Rendering PDFs on a bundled server
|
|
135
|
+
|
|
136
|
+
`pdf` is on by default and costs nothing for an app that never renders a PDF:
|
|
137
|
+
the transform only touches modules whose id contains `pdfkit`. Add
|
|
138
|
+
`pdf: { bundle: true }` to a Vite SSR server whose runtime image ships the
|
|
139
|
+
bundle alone:
|
|
140
|
+
|
|
141
|
+
```ts
|
|
142
|
+
// vite.config.ts (an SSR server)
|
|
143
|
+
export default defineConfig({
|
|
144
|
+
plugins: [...nxgtMaterial({ pdf: { bundle: true } })],
|
|
145
|
+
});
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
`bundle: true` puts `@nxgt/material-vue`, `@nxgt/material-core`, `pdfkit`, `@react-pdf/*`
|
|
149
|
+
and every dependency the renderer, pdfkit and core need at runtime (fontkit, yoga, png-js… read
|
|
150
|
+
from your installed packages, so the list follows the renderer's releases) into
|
|
151
|
+
`ssr.noExternal`, merged with your own array; `ssr.noExternal: true` is left as
|
|
152
|
+
it is. What it does not touch is yours to bundle the way you bundle the rest of
|
|
153
|
+
your server: `react` (the renderer's peer) and your app's other dependencies,
|
|
154
|
+
for example `ssr: { noExternal: ['react'] }`. The library's own
|
|
155
|
+
dependencies (a router, charts) are not walked, so a second copy never splits
|
|
156
|
+
their contexts. Under Yarn PnP there is no `node_modules` to read: only the
|
|
157
|
+
fixed names apply, and you list the renderer's dependencies yourself. Without `bundle`, the renderer
|
|
158
|
+
stays external and loads pdfkit's fonts from `node_modules`, as designed. See
|
|
159
|
+
[PDF documents](pdf.md#fonts-on-a-fully-inlined-server).
|
|
160
|
+
|
|
161
|
+
## Nuxt
|
|
162
|
+
|
|
163
|
+
The Nuxt module (`@nxgt/material-vue/nuxt`) calls `nxgtMaterial()` for you and
|
|
164
|
+
maps its own options onto it. Under Nuxt:
|
|
165
|
+
|
|
166
|
+
| Part | What the module does |
|
|
167
|
+
| --- | --- |
|
|
168
|
+
| `csp` | **Off.** Nuxt has no `index.html` for the plugin to hash or stamp, and a header on Vite's dev server never reaches the pages Nitro renders. The module sets no policy and sends no header: use `nuxt-security` for the CSP (its `nonce: true`, or its script hashes for prerendered pages) |
|
|
169
|
+
| `csp.zodJitless` | Opt-in (`nxgtMaterial: { csp: { zodJitless: true } }`): the script goes into `app.head.script` with `tagPriority: 'critical'`. It is inline: `nuxt-security` with `nonce: true` stamps it, otherwise a strict `script-src` blocks it |
|
|
170
|
+
| `fonts.katex` | On: a font is never inlined as a `data:` URI |
|
|
171
|
+
| `fonts.sans: 'inter'` | Opt-in: `@fontsource-variable/inter` and the `--font-sans` override are put first in `nuxt.options.css`. A missing package warns once and keeps the system font; the build never fails |
|
|
172
|
+
| `styles` | **Off** by default: Nuxt resolves `css` entries before Vite sees them. `styles: true` opts in |
|
|
173
|
+
| `pdf` | Nitro owns it, not Vite: `pdf.bundle` adds `pdfkitStandardFonts()` to the Nitro Rollup config (`pdf.bundleStandardFonts` is its deprecated name), and the module always traces pdfkit's font files into `.output/server/node_modules` |
|
|
174
|
+
|
|
175
|
+
Why hash mode is not used under Nuxt: a Nuxt app is server-rendered, so its
|
|
176
|
+
HTML is built per request, not once at build time. A policy that lists hashes
|
|
177
|
+
of a build-time `index.html` would describe a file that does not exist.
|
|
178
|
+
|
|
179
|
+
## Other frameworks without an `index.html`
|
|
180
|
+
|
|
181
|
+
Other SSR frameworks have no `index.html` to transform either: the CSP part
|
|
182
|
+
finds nothing to hash, the build warns once (`no index.html in this build: the
|
|
183
|
+
CSP part did nothing`) and the dev header only fits Vite's own server. On a
|
|
184
|
+
server, send `cspPolicy({ nonce }).header` and `zodJitlessTag(nonce)` per
|
|
185
|
+
request, or pass `csp: false`. The fonts part still works there, since it
|
|
186
|
+
rewrites the stylesheet rather than the HTML.
|
|
187
|
+
|
|
188
|
+
## Without the plugin
|
|
189
|
+
|
|
190
|
+
Everything above has a manual route: [CSP guide](csp.md) (KaTeX, Inter, zod,
|
|
191
|
+
SSR).
|
|
192
|
+
|
|
193
|
+
Migrating an app that wrote its own CSP header, nonce, zod setting or PDF bundling:
|
|
194
|
+
[Migrating to the Vite plugin](migrate-to-vite-plugin.md).
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/docs/roadmap.md
CHANGED
|
@@ -6,41 +6,15 @@ version they shipped in, and planned entries may name the major they target.
|
|
|
6
6
|
|
|
7
7
|
## Now
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
`ErrorState` in three sizes (`default`, `compact`, `inline`), with in-house
|
|
11
|
-
inline SVG illustrations or a slot for your own. `ErrorState` is a
|
|
12
|
-
`role="alert"` with a Retry action and collapsible technical details. Every
|
|
13
|
-
built-in empty or error state uses them — the `DataTable` default (your
|
|
14
|
-
`#empty` slot and `empty` prop still replace it), `PdfReader`, `CommandEmpty`,
|
|
15
|
-
the gallery, the kanban board, chat and the partials. Ships in
|
|
16
|
-
`@nxgt/material-vue` 1.0, with the rest of the redesign.
|
|
9
|
+
Nothing is in progress right now.
|
|
17
10
|
|
|
18
11
|
## Next
|
|
19
12
|
|
|
20
|
-
- **
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
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.
|
|
13
|
+
- **1.0: `EmptyState` is only about absence** — `variant` is removed, the
|
|
14
|
+
`generic`, `offline` and `maintenance` kinds leave `EmptyState` for
|
|
15
|
+
`ErrorState`, and `kind` defaults to `empty` (it is `generic` until then).
|
|
16
|
+
The upgrade is in
|
|
17
|
+
[Migrating from `variant`](components/feedback-and-status.md#migrating-from-variant).
|
|
44
18
|
- **One media player, video and audio** — `MediaPlayer`, `MediaPlayerMini`,
|
|
45
19
|
`useMediaPlayer` and `AudioPlayer`, built on the native `<video>` / `<audio>`.
|
|
46
20
|
`StxPlayer` and `VideoPlayer` are removed in `@nxgt/material-vue` 1.0, with a
|
|
@@ -94,6 +68,15 @@ version they shipped in, and planned entries may name the major they target.
|
|
|
94
68
|
|
|
95
69
|
## Later
|
|
96
70
|
|
|
71
|
+
- **`PdfReader` can retry a failed load** — its empty and error blocks become
|
|
72
|
+
`EmptyState` and `ErrorState` (compact) with a Retry button and the error's
|
|
73
|
+
details, as in the React reader. Only on the owner's request:
|
|
74
|
+
softistx/nxgt-material#702.
|
|
75
|
+
- **Vue /backgrounds: more presets and motifs** — the presets and motifs added
|
|
76
|
+
to React after the base (more gradients, geometric patterns, motif scenes)
|
|
77
|
+
reach `@nxgt/material-vue/backgrounds` on the owner's explicit ask. Until
|
|
78
|
+
then a preset id the Vue build lacks draws the gradient (and warns in
|
|
79
|
+
development). Tracked in softistx/nxgt-material#706.
|
|
97
80
|
- **A CSP without `style-src-attr 'unsafe-inline'`** — the four form controls'
|
|
98
81
|
hidden inputs no longer need it; the checked `Checkbox` indicator,
|
|
99
82
|
`SelectValue`, the `RadioGroup` root, `Slider` and popper positioning still
|
|
@@ -167,6 +150,51 @@ version they shipped in, and planned entries may name the major they target.
|
|
|
167
150
|
|
|
168
151
|
## Shipped
|
|
169
152
|
|
|
153
|
+
- **Empty and error states that look designed** — `EmptyState` with its
|
|
154
|
+
`kind` (`empty`, `search`, `not-found`, `unauthorized`) and a new
|
|
155
|
+
`ErrorState` (`generic`, `offline`, `maintenance`), each in two sizes
|
|
156
|
+
(`default`, `compact`), with in-house inline SVG illustrations or your own in
|
|
157
|
+
the `#illustration` slot. `ErrorState` is a `role="alert"` with a Retry
|
|
158
|
+
action and collapsible technical details. The `DataTable` default (your
|
|
159
|
+
`#empty` slot still replaces it, and `#empty-filtered` covers a filter that
|
|
160
|
+
hides every row), `CommandEmpty` and the built-in empty states that were
|
|
161
|
+
hand-rolled (notifications, gallery, quiz, sortable and transfer lists,
|
|
162
|
+
kanban, chat, charts, contacts, postal address, attributes, opening hours,
|
|
163
|
+
the player and the event calendar) use them. `variant` still works and is
|
|
164
|
+
deprecated. 0.43.0.
|
|
165
|
+
([EmptyState](components/feedback-and-status.md#emptystate),
|
|
166
|
+
[ErrorState](components/feedback-and-status.md#errorstate))
|
|
167
|
+
- **Background presets, the base** — `Background` from `@nxgt/material-vue/backgrounds`,
|
|
168
|
+
a superset of the one in `/components`: `preset` (`gradient` or `grain`),
|
|
169
|
+
`tone`, `intensity`, `animated` (drifts, and pauses while the page is hidden,
|
|
170
|
+
the background is off screen or the user prefers reduced motion), `grain`,
|
|
171
|
+
`seed` and `fill`. The SVG is built from plain data, so the server and the
|
|
172
|
+
client render the same markup and a strict CSP accepts it. The stylesheets
|
|
173
|
+
(`backgrounds.css`, `backgrounds/<preset>.css`) are opt-in. The grain's look
|
|
174
|
+
may still change.
|
|
175
|
+
|
|
176
|
+
- **One Vite plugin for the whole setup** — `nxgtMaterial()` from
|
|
177
|
+
`@nxgt/material/vite` and `@nxgt/material-vue/vite` (one implementation in
|
|
178
|
+
`@nxgt/material-core/vite`) wires the library into a Vite app, each part on
|
|
179
|
+
by default and each switchable off; the helpers that existed before stay
|
|
180
|
+
exported ([Vite plugin guide](guides/vite-plugin.md), and the migration guide moves a hand-written setup over). You get:
|
|
181
|
+
- `csp`: `mode: 'hash'` (default) writes the sha256 of every inline script
|
|
182
|
+
and style to `dist/.vite/nxgt-csp.json` with the header, or `mode: 'nonce'`
|
|
183
|
+
leaves a placeholder for `applyCspNonce`; zod's jitless script; a
|
|
184
|
+
Report-Only header on the dev server. `createCspNonce()`, `cspPolicy()`
|
|
185
|
+
and `cspHash()` ship in `@nxgt/material-core/csp`.
|
|
186
|
+
- `fonts`: `katex` (fonts stay files) and `sans: 'inter'` (self-hosted Inter).
|
|
187
|
+
- `styles`: a build that fails with the exact fix when the stylesheet import
|
|
188
|
+
or React's `@source` line is missing.
|
|
189
|
+
- `pdf`: pdfkit's standard fonts handled by the same plugin, with
|
|
190
|
+
`bundle: true` for an SSR server with no `node_modules`. The Nuxt module
|
|
191
|
+
calls `nxgtMaterial()` with the same `fonts`, `styles` and `pdf` options
|
|
192
|
+
(`pdf.bundleStandardFonts` is deprecated for `pdf.bundle`) and adds zod's
|
|
193
|
+
jitless script to the head on request; its CSP stays `nuxt-security`'s.
|
|
194
|
+
- `NonceProvider`'s `nonce` is optional on the client (it reads the page's
|
|
195
|
+
nonce from its first render).
|
|
196
|
+
Shipped in 0.43.0.
|
|
197
|
+
|
|
170
198
|
- **The app's brand, a header title and an account menu** — the app shell
|
|
171
199
|
takes the app's `logo` and `name`: the logo alone in the collapsed rail,
|
|
172
200
|
named by the app's name and shown as its tooltip, the logo and the name side
|