@nxgt/material-core 0.11.1 → 0.13.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 +36 -0
- package/README.md +283 -24
- package/dist/backgrounds/activity.d.ts +11 -0
- package/dist/backgrounds/activity.d.ts.map +1 -0
- package/dist/backgrounds/build.d.ts +9 -0
- package/dist/backgrounds/build.d.ts.map +1 -0
- package/dist/backgrounds/id-prefix.d.ts +8 -0
- package/dist/backgrounds/id-prefix.d.ts.map +1 -0
- package/dist/backgrounds/index.d.ts +20 -0
- package/dist/backgrounds/index.d.ts.map +1 -0
- package/dist/backgrounds/index.js +467 -0
- package/dist/backgrounds/index.js.map +20 -0
- package/dist/backgrounds/noise.d.ts +7 -0
- package/dist/backgrounds/noise.d.ts.map +1 -0
- package/dist/backgrounds/presets/grain.d.ts +9 -0
- package/dist/backgrounds/presets/grain.d.ts.map +1 -0
- package/dist/backgrounds/presets.d.ts +16 -0
- package/dist/backgrounds/presets.d.ts.map +1 -0
- package/dist/backgrounds/primitives.d.ts +22 -0
- package/dist/backgrounds/primitives.d.ts.map +1 -0
- package/dist/backgrounds/rng.d.ts +12 -0
- package/dist/backgrounds/rng.d.ts.map +1 -0
- package/dist/backgrounds/scatter.d.ts +25 -0
- package/dist/backgrounds/scatter.d.ts.map +1 -0
- package/dist/backgrounds/scene.d.ts +21 -0
- package/dist/backgrounds/scene.d.ts.map +1 -0
- package/dist/backgrounds/tones.d.ts +4 -0
- package/dist/backgrounds/tones.d.ts.map +1 -0
- package/dist/backgrounds/types.d.ts +53 -0
- package/dist/backgrounds/types.d.ts.map +1 -0
- package/dist/chunks/index-mw5fa8qa.js +119 -0
- package/dist/chunks/index-mw5fa8qa.js.map +12 -0
- package/dist/csp/index.d.ts +10 -0
- package/dist/csp/index.d.ts.map +1 -0
- package/dist/csp/index.js +21 -0
- package/dist/csp/index.js.map +9 -0
- package/dist/csp/nonce.d.ts +35 -0
- package/dist/csp/nonce.d.ts.map +1 -0
- package/dist/csp/policy.d.ts +33 -0
- package/dist/csp/policy.d.ts.map +1 -0
- package/dist/csp/zod-jitless.d.ts +4 -0
- package/dist/csp/zod-jitless.d.ts.map +1 -0
- package/dist/lib/drawer-room.d.ts +8 -0
- package/dist/lib/drawer-room.d.ts.map +1 -0
- package/dist/lib/drawer-room.js +17 -0
- package/dist/lib/drawer-room.js.map +10 -0
- package/dist/lib/escape-forward.d.ts +14 -0
- package/dist/lib/escape-forward.d.ts.map +1 -1
- package/dist/lib/escape-forward.js +22 -2
- package/dist/lib/escape-forward.js.map +3 -3
- package/dist/lib/initials.d.ts +12 -0
- package/dist/lib/initials.d.ts.map +1 -0
- package/dist/lib/initials.js +15 -0
- package/dist/lib/initials.js.map +10 -0
- package/dist/pdf-viewer/index.d.ts +1 -0
- package/dist/pdf-viewer/index.d.ts.map +1 -1
- package/dist/pdf-viewer/index.js +68 -38
- package/dist/pdf-viewer/index.js.map +6 -5
- package/dist/pdf-viewer/pdf-reveal-hit.d.ts +7 -0
- package/dist/pdf-viewer/pdf-reveal-hit.d.ts.map +1 -0
- package/dist/pdf-viewer/pdf-scroll-spy.d.ts +24 -8
- package/dist/pdf-viewer/pdf-scroll-spy.d.ts.map +1 -1
- package/dist/states/copy.d.ts +46 -0
- package/dist/states/copy.d.ts.map +1 -0
- package/dist/states/describe-error.d.ts +18 -0
- package/dist/states/describe-error.d.ts.map +1 -0
- package/dist/states/illustrations.d.ts +24 -0
- package/dist/states/illustrations.d.ts.map +1 -0
- package/dist/states/index.d.ts +11 -0
- package/dist/states/index.d.ts.map +1 -0
- package/dist/states/index.js +253 -0
- package/dist/states/index.js.map +13 -0
- package/dist/states/kinds.d.ts +28 -0
- package/dist/states/kinds.d.ts.map +1 -0
- package/dist/vite/csp-dev-header.d.ts +11 -0
- package/dist/vite/csp-dev-header.d.ts.map +1 -0
- package/dist/vite/csp-hashes.d.ts +23 -0
- package/dist/vite/csp-hashes.d.ts.map +1 -0
- package/dist/vite/csp-header.d.ts +10 -0
- package/dist/vite/csp-header.d.ts.map +1 -0
- package/dist/vite/csp-plugin.d.ts +12 -0
- package/dist/vite/csp-plugin.d.ts.map +1 -0
- package/dist/vite/css-chain.d.ts +13 -0
- package/dist/vite/css-chain.d.ts.map +1 -0
- package/dist/vite/dependency-closure.d.ts +8 -0
- package/dist/vite/dependency-closure.d.ts.map +1 -0
- package/dist/vite/fonts-inter.d.ts +15 -0
- package/dist/vite/fonts-inter.d.ts.map +1 -0
- package/dist/vite/fonts-plugin.d.ts +12 -0
- package/dist/vite/fonts-plugin.d.ts.map +1 -0
- package/dist/vite/index.d.ts +17 -81
- package/dist/vite/index.d.ts.map +1 -1
- package/dist/vite/index.js +478 -2
- package/dist/vite/index.js.map +18 -4
- package/dist/vite/libraries.d.ts +13 -0
- package/dist/vite/libraries.d.ts.map +1 -0
- package/dist/vite/nxgt-material.d.ts +12 -0
- package/dist/vite/nxgt-material.d.ts.map +1 -0
- package/dist/vite/options.d.ts +56 -0
- package/dist/vite/options.d.ts.map +1 -0
- package/dist/vite/pdf-plugin.d.ts +19 -0
- package/dist/vite/pdf-plugin.d.ts.map +1 -0
- package/dist/vite/pdfkit-standard-fonts.d.ts +74 -0
- package/dist/vite/pdfkit-standard-fonts.d.ts.map +1 -0
- package/dist/vite/styles-plugin.d.ts +27 -0
- package/dist/vite/styles-plugin.d.ts.map +1 -0
- package/dist/vite/styles-scan.d.ts +14 -0
- package/dist/vite/styles-scan.d.ts.map +1 -0
- package/docs/README.md +4 -0
- package/docs/backgrounds.md +95 -0
- package/docs/roadmap.md +37 -23
- package/docs/states.md +85 -0
- package/docs/troubleshooting.md +174 -3
- package/package.json +40 -4
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"libraries.d.ts","sourceRoot":"","sources":["../../src/vite/libraries.ts"],"names":[],"mappings":"AAAA,mEAAmE;AACnE,MAAM,MAAM,mBAAmB,GAAG,gBAAgB,GAAG,oBAAoB,CAAC;AAE1E,MAAM,MAAM,iBAAiB,GAAG;IAC/B,IAAI,EAAE,mBAAmB,CAAC;IAC1B,qCAAqC;IACrC,UAAU,EAAE,MAAM,CAAC;IACnB,6EAA6E;IAC7E,WAAW,EAAE,OAAO,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,wBAAgB,eAAe,CAAC,IAAI,EAAE,mBAAmB,GAAG,iBAAiB,CAQ5E"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { Plugin } from 'vite';
|
|
2
|
+
import { type NxgtMaterialLibrary } from './libraries';
|
|
3
|
+
import { type NxgtMaterialOptions } from './options';
|
|
4
|
+
/**
|
|
5
|
+
* The one Vite plugin for `@nxgt/material` and `@nxgt/material-vue`: a strict
|
|
6
|
+
* Content Security Policy (hashes of the inline scripts, or a nonce
|
|
7
|
+
* placeholder), fonts that survive `font-src 'self'`, pdfkit's standard fonts, and a build that fails
|
|
8
|
+
* when the stylesheet is not wired. Everything is on; each part has an opt-out.
|
|
9
|
+
* Import it from the library: `import { nxgtMaterial } from '@nxgt/material/vite'`.
|
|
10
|
+
*/
|
|
11
|
+
export declare function nxgtMaterial(options?: NxgtMaterialOptions, library?: NxgtMaterialLibrary): Plugin[];
|
|
12
|
+
//# sourceMappingURL=nxgt-material.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"nxgt-material.d.ts","sourceRoot":"","sources":["../../src/vite/nxgt-material.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AAKnC,OAAO,EAAmB,KAAK,mBAAmB,EAAE,MAAM,aAAa,CAAC;AACxE,OAAO,EAAE,KAAK,mBAAmB,EAAkB,MAAM,WAAW,CAAC;AAIrE;;;;;;GAMG;AACH,wBAAgB,YAAY,CAC3B,OAAO,CAAC,EAAE,mBAAmB,EAC7B,OAAO,CAAC,EAAE,mBAAmB,GAC3B,MAAM,EAAE,CAmBV"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { type CspPolicyOptions } from '../csp';
|
|
2
|
+
export type NxgtMaterialCspOptions = {
|
|
3
|
+
/**
|
|
4
|
+
* `'hash'` (default): the sha256 of every inline script and style of
|
|
5
|
+
* `index.html` goes to `dist/.vite/nxgt-csp.json`; nothing public is ever
|
|
6
|
+
* written into the HTML, so a static host is safe. `'nonce'`: the HTML
|
|
7
|
+
* carries a placeholder your server replaces per request (`applyCspNonce`).
|
|
8
|
+
*/
|
|
9
|
+
mode?: 'hash' | 'nonce';
|
|
10
|
+
/** Nonce mode only: your own placeholder instead of `CSP_NONCE_PLACEHOLDER`. */
|
|
11
|
+
placeholder?: string;
|
|
12
|
+
/** An inline script that switches zod's `new Function` probe off. Default on. */
|
|
13
|
+
zodJitless?: boolean;
|
|
14
|
+
/** A `Content-Security-Policy-Report-Only` header on the dev server. Default on. */
|
|
15
|
+
dev?: boolean;
|
|
16
|
+
/** Refines the dev header and the generated one. */
|
|
17
|
+
policy?: CspPolicyOptions;
|
|
18
|
+
};
|
|
19
|
+
export type NxgtMaterialOptions = {
|
|
20
|
+
csp?: boolean | NxgtMaterialCspOptions;
|
|
21
|
+
fonts?: boolean | {
|
|
22
|
+
katex?: boolean;
|
|
23
|
+
sans?: 'inter' | false;
|
|
24
|
+
};
|
|
25
|
+
styles?: boolean | {
|
|
26
|
+
check?: boolean;
|
|
27
|
+
};
|
|
28
|
+
/**
|
|
29
|
+
* pdfkit's standard fonts (`pdfkitStandardFonts()`), on by default: it does
|
|
30
|
+
* nothing unless pdfkit goes through the bundle. `bundle: true` also puts
|
|
31
|
+
* the renderer into an SSR build (`ssr.noExternal`), for a server whose
|
|
32
|
+
* runtime image has no `node_modules`.
|
|
33
|
+
*/
|
|
34
|
+
pdf?: boolean | {
|
|
35
|
+
bundle?: boolean;
|
|
36
|
+
};
|
|
37
|
+
};
|
|
38
|
+
export type ResolvedCsp = Required<Omit<NxgtMaterialCspOptions, 'policy'>> & {
|
|
39
|
+
policy: CspPolicyOptions;
|
|
40
|
+
};
|
|
41
|
+
export type ResolvedOptions = {
|
|
42
|
+
csp: false | ResolvedCsp;
|
|
43
|
+
fonts: {
|
|
44
|
+
katex: boolean;
|
|
45
|
+
sans: 'inter' | false;
|
|
46
|
+
};
|
|
47
|
+
styles: {
|
|
48
|
+
check: boolean;
|
|
49
|
+
};
|
|
50
|
+
pdf: false | {
|
|
51
|
+
bundle: boolean;
|
|
52
|
+
};
|
|
53
|
+
};
|
|
54
|
+
/** Booleans and objects normalised; everything is on by default. */
|
|
55
|
+
export declare function resolveOptions(options?: NxgtMaterialOptions): ResolvedOptions;
|
|
56
|
+
//# sourceMappingURL=options.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"options.d.ts","sourceRoot":"","sources":["../../src/vite/options.ts"],"names":[],"mappings":"AAAA,OAAO,EAAyB,KAAK,gBAAgB,EAAE,MAAM,QAAQ,CAAC;AAEtE,MAAM,MAAM,sBAAsB,GAAG;IACpC;;;;;OAKG;IACH,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IACxB,gFAAgF;IAChF,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,iFAAiF;IACjF,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,oFAAoF;IACpF,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,oDAAoD;IACpD,MAAM,CAAC,EAAE,gBAAgB,CAAC;CAC1B,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG;IACjC,GAAG,CAAC,EAAE,OAAO,GAAG,sBAAsB,CAAC;IACvC,KAAK,CAAC,EAAE,OAAO,GAAG;QAAE,KAAK,CAAC,EAAE,OAAO,CAAC;QAAC,IAAI,CAAC,EAAE,OAAO,GAAG,KAAK,CAAA;KAAE,CAAC;IAC9D,MAAM,CAAC,EAAE,OAAO,GAAG;QAAE,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC;IACvC;;;;;OAKG;IACH,GAAG,CAAC,EAAE,OAAO,GAAG;QAAE,MAAM,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC;CACrC,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG,QAAQ,CAAC,IAAI,CAAC,sBAAsB,EAAE,QAAQ,CAAC,CAAC,GAAG;IAC5E,MAAM,EAAE,gBAAgB,CAAC;CACzB,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAC7B,GAAG,EAAE,KAAK,GAAG,WAAW,CAAC;IACzB,KAAK,EAAE;QAAE,KAAK,EAAE,OAAO,CAAC;QAAC,IAAI,EAAE,OAAO,GAAG,KAAK,CAAA;KAAE,CAAC;IACjD,MAAM,EAAE;QAAE,KAAK,EAAE,OAAO,CAAA;KAAE,CAAC;IAC3B,GAAG,EAAE,KAAK,GAAG;QAAE,MAAM,EAAE,OAAO,CAAA;KAAE,CAAC;CACjC,CAAC;AAEF,oEAAoE;AACpE,wBAAgB,cAAc,CAC7B,OAAO,GAAE,mBAAwB,GAC/B,eAAe,CA6BjB"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { Plugin } from 'vite';
|
|
2
|
+
import type { NxgtMaterialLibrary } from './libraries';
|
|
3
|
+
/**
|
|
4
|
+
* What an SSR build must bundle for pdfkit's standard fonts to be rewritten
|
|
5
|
+
* and for the result to run with no `node_modules`: pdfkit (its
|
|
6
|
+
* `#standard-fonts/*` calls are what the transform rewrites), the renderer and
|
|
7
|
+
* the dependencies it needs at runtime (fontkit, yoga, png-js…), read from the
|
|
8
|
+
* installed packages so the list follows its releases. The library and core
|
|
9
|
+
* are named only, not walked. `react` is a peer and stays the app's to bundle.
|
|
10
|
+
* Under Yarn PnP there is no node_modules to read: only the fixed names apply.
|
|
11
|
+
*/
|
|
12
|
+
export declare function pdfNoExternal(root: string, library?: NxgtMaterialLibrary): (string | RegExp)[];
|
|
13
|
+
/** Adds the packages above to `ssr.noExternal`; vite's merge keeps `true`. */
|
|
14
|
+
export declare function pdfBundlePlugin(library?: NxgtMaterialLibrary): Plugin;
|
|
15
|
+
/** The pdf part of `nxgtMaterial()`. */
|
|
16
|
+
export declare function pdfPlugins(pdf: {
|
|
17
|
+
bundle: boolean;
|
|
18
|
+
}, library?: NxgtMaterialLibrary): Plugin[];
|
|
19
|
+
//# sourceMappingURL=pdf-plugin.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pdf-plugin.d.ts","sourceRoot":"","sources":["../../src/vite/pdf-plugin.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AAEnC,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAUvD;;;;;;;;GAQG;AACH,wBAAgB,aAAa,CAC5B,IAAI,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE,mBAAmB,GAC3B,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,CAQrB;AAED,8EAA8E;AAC9E,wBAAgB,eAAe,CAAC,OAAO,CAAC,EAAE,mBAAmB,GAAG,MAAM,CAUrE;AAED,wCAAwC;AACxC,wBAAgB,UAAU,CACzB,GAAG,EAAE;IAAE,MAAM,EAAE,OAAO,CAAA;CAAE,EACxB,OAAO,CAAC,EAAE,mBAAmB,GAC3B,MAAM,EAAE,CAKV"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The pdfkit standard fonts plugin of the `/vite` entry (Node code that runs
|
|
3
|
+
* inside a consumer's `vite.config.ts` or a Nuxt app's Nitro build). It
|
|
4
|
+
* imports nothing at runtime: `Plugin` is a type, erased by the compiler.
|
|
5
|
+
*/
|
|
6
|
+
import type { Plugin } from 'vite';
|
|
7
|
+
/**
|
|
8
|
+
* Bundles pdfkit's fourteen standard fonts instead of leaving them to a
|
|
9
|
+
* `require` that cannot work in a bundle.
|
|
10
|
+
*
|
|
11
|
+
* **Only needed by an app that renders PDFs** (`@nxgt/material/print`, or
|
|
12
|
+
* `@nxgt/material-vue/pdf`). No other entry reaches `@react-pdf/renderer`, so
|
|
13
|
+
* an app that does not print never sees this at all.
|
|
14
|
+
* If you do print, read on, because the failure is spectacular and silent until
|
|
15
|
+
* production.
|
|
16
|
+
*
|
|
17
|
+
* Both are built on `@react-pdf/renderer`, which is built on
|
|
18
|
+
* `pdfkit`, whose node build ends with:
|
|
19
|
+
*
|
|
20
|
+
* ```js
|
|
21
|
+
* const require$1 = createRequire(import.meta.url);
|
|
22
|
+
* registerStdFontLoaders({ Helvetica: () => require$1('#standard-fonts/Helvetica'), … });
|
|
23
|
+
* ```
|
|
24
|
+
*
|
|
25
|
+
* `#standard-fonts/*` is a package-`imports` entry **private to pdfkit**, and
|
|
26
|
+
* that is a RUNTIME call, not an import — so no bundler resolves it. Bundle
|
|
27
|
+
* pdfkit into an SSR server (`ssr.noExternal`) and the literal survives into the
|
|
28
|
+
* output, where `createRequire` is rooted at the build directory and the importer
|
|
29
|
+
* is no longer inside pdfkit. The server then throws on **every request**,
|
|
30
|
+
* `/health` included:
|
|
31
|
+
*
|
|
32
|
+
* ```
|
|
33
|
+
* error: Cannot find module '#standard-fonts/Helvetica' from '…/build/app.js'
|
|
34
|
+
* ```
|
|
35
|
+
*
|
|
36
|
+
* A compose healthcheck that fetches a route never goes healthy either, so the
|
|
37
|
+
* container looks like it is failing to start rather than failing to serve.
|
|
38
|
+
*
|
|
39
|
+
* This plugin rewrites those calls into static imports of
|
|
40
|
+
* `./standard-fonts/<name>.mjs`, so the font data lands in the bundle and the
|
|
41
|
+
* server stays self-contained. Use it when the runtime image has **no
|
|
42
|
+
* `node_modules`** — a single-file `bun build` artifact copied alone into the
|
|
43
|
+
* image. When the image does keep `node_modules`, the lighter answer is to leave
|
|
44
|
+
* the library external instead (`--external` it in the bundle step, and keep it
|
|
45
|
+
* out of `ssr.noExternal`), which also keeps ~12 MB of
|
|
46
|
+
* pdfkit out of the artifact. `nxgtMaterial({ pdf: { bundle: true } })` adds this
|
|
47
|
+
* plugin and the `ssr.noExternal` list it needs; in Nuxt, `nxgtMaterial: { pdf: {
|
|
48
|
+
* bundle: true } }` adds this plugin to the Nitro build.
|
|
49
|
+
*
|
|
50
|
+
* ```ts
|
|
51
|
+
* // `@nxgt/material/vite` in a React app: the same function
|
|
52
|
+
* import { pdfkitStandardFonts } from '@nxgt/material-vue/vite';
|
|
53
|
+
* import { defineConfig } from 'vite';
|
|
54
|
+
*
|
|
55
|
+
* export default defineConfig({
|
|
56
|
+
* plugins: [pdfkitStandardFonts()],
|
|
57
|
+
* ssr: { noExternal: ['@nxgt/material-vue', '@nxgt/material-core'] },
|
|
58
|
+
* });
|
|
59
|
+
* ```
|
|
60
|
+
*
|
|
61
|
+
* Two things that look like fixes and are not:
|
|
62
|
+
*
|
|
63
|
+
* - **`resolve.alias`** mapping `#standard-fonts/` to `pdfkit/standard-fonts/`.
|
|
64
|
+
* An alias rewrites specifiers the resolver is *asked* about; this one is a
|
|
65
|
+
* string handed to `createRequire` at runtime, which the resolver never sees.
|
|
66
|
+
* - **`--external pdfkit`**. It is a transitive dependency, so the runtime cannot
|
|
67
|
+
* resolve it from the app's own directory: `Cannot find package 'pdfkit'`.
|
|
68
|
+
*
|
|
69
|
+
* The plugin throws if a `#standard-fonts/` reference survives the rewrite, so a
|
|
70
|
+
* future pdfkit that changes the shape of those calls fails the build instead of
|
|
71
|
+
* the first request.
|
|
72
|
+
*/
|
|
73
|
+
export declare function pdfkitStandardFonts(): Plugin;
|
|
74
|
+
//# sourceMappingURL=pdfkit-standard-fonts.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pdfkit-standard-fonts.d.ts","sourceRoot":"","sources":["../../src/vite/pdfkit-standard-fonts.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AAEnC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiEG;AACH,wBAAgB,mBAAmB,IAAI,MAAM,CA6C5C"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { Plugin } from 'vite';
|
|
2
|
+
import type { LibraryDescriptor } from './libraries';
|
|
3
|
+
/** What the build saw of the library's stylesheet; shared with the fonts part. */
|
|
4
|
+
export type StylesState = {
|
|
5
|
+
/** The stylesheets (ids) that import the library's `styles.css` (Tailwind's route). */
|
|
6
|
+
roots: Set<string>;
|
|
7
|
+
/**
|
|
8
|
+
* The stylesheets that `@import` the package itself: its root export's
|
|
9
|
+
* `style` condition, the compiled stylesheet of an app without Tailwind,
|
|
10
|
+
* which needs no `@source`.
|
|
11
|
+
*/
|
|
12
|
+
compiledRoots: Set<string>;
|
|
13
|
+
/** Modules that import it from JavaScript. */
|
|
14
|
+
jsImporters: Set<string>;
|
|
15
|
+
sourceOk: boolean;
|
|
16
|
+
};
|
|
17
|
+
export declare function createStylesState(): StylesState;
|
|
18
|
+
export declare function missingStylesheetMessage(lib: LibraryDescriptor): string;
|
|
19
|
+
export declare function missingSourceMessage(lib: LibraryDescriptor): string;
|
|
20
|
+
/**
|
|
21
|
+
* Fails a client `vite build` that never imports the library's stylesheet
|
|
22
|
+
* (`styles.css`, or the compiled one through `@import "<package>";`), or
|
|
23
|
+
* (React) imports `styles.css` without the `@source` line. `order: 'pre'` makes it see
|
|
24
|
+
* the raw stylesheet before `@tailwindcss/vite` rewrites it.
|
|
25
|
+
*/
|
|
26
|
+
export declare function stylesPlugin(lib: LibraryDescriptor, state: StylesState): Plugin;
|
|
27
|
+
//# sourceMappingURL=styles-plugin.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"styles-plugin.d.ts","sourceRoot":"","sources":["../../src/vite/styles-plugin.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AAEnC,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAMrD,kFAAkF;AAClF,MAAM,MAAM,WAAW,GAAG;IACzB,uFAAuF;IACvF,KAAK,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IACnB;;;;OAIG;IACH,aAAa,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAC3B,8CAA8C;IAC9C,WAAW,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IACzB,QAAQ,EAAE,OAAO,CAAC;CAClB,CAAC;AAEF,wBAAgB,iBAAiB,IAAI,WAAW,CAO/C;AAED,wBAAgB,wBAAwB,CAAC,GAAG,EAAE,iBAAiB,GAAG,MAAM,CAMvE;AAED,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,iBAAiB,GAAG,MAAM,CAMnE;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAC3B,GAAG,EAAE,iBAAiB,EACtB,KAAK,EAAE,WAAW,GAChB,MAAM,CA0CR"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/** Pure scans of a stylesheet's text. */
|
|
2
|
+
/** The specifiers of every `@import` (both quote styles, `url()`), comments skipped. */
|
|
3
|
+
export declare function cssImports(css: string): string[];
|
|
4
|
+
/** The paths of every plain `@source` (`not` and `inline()` forms add nothing to scan). */
|
|
5
|
+
export declare function cssSources(css: string): string[];
|
|
6
|
+
/** The `@import`s that point at a file next to the stylesheet. */
|
|
7
|
+
export declare function relativeImports(css: string): string[];
|
|
8
|
+
/** Whether a `@source` path points at the package (`…/node_modules/@nxgt/material/`). */
|
|
9
|
+
export declare function sourceCovers(path: string, name: string): boolean;
|
|
10
|
+
/** Whether a module's code imports `specifier` (static or dynamic, any quotes). */
|
|
11
|
+
export declare function jsImports(code: string, specifier: string): boolean;
|
|
12
|
+
/** Whether the stylesheet sets Tailwind's `--font-sans` itself. */
|
|
13
|
+
export declare function declaresFontSans(css: string): boolean;
|
|
14
|
+
//# sourceMappingURL=styles-scan.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"styles-scan.d.ts","sourceRoot":"","sources":["../../src/vite/styles-scan.ts"],"names":[],"mappings":"AAAA,yCAAyC;AASzC,wFAAwF;AACxF,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE,CAIhD;AAED,2FAA2F;AAC3F,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE,CAEhD;AAED,kEAAkE;AAClE,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE,CAErD;AAED,yFAAyF;AACzF,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAGhE;AAED,mFAAmF;AACnF,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAKlE;AAED,mEAAmE;AACnE,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAErD"}
|
package/docs/README.md
CHANGED
|
@@ -5,5 +5,9 @@ one example per subpath.
|
|
|
5
5
|
|
|
6
6
|
| Page | Read it when |
|
|
7
7
|
| --- | --- |
|
|
8
|
+
| [Backgrounds](backgrounds.md) | you build a background preset, or render a scene a preset produced |
|
|
8
9
|
| [Troubleshooting](troubleshooting.md) | an import, a render or a build fails with a message: the message is the heading |
|
|
9
10
|
| [Roadmap](roadmap.md) | you want to know what is coming, or whether something was already ruled out |
|
|
11
|
+
| [States](states.md) | you build on `/states`: the kinds, the copy keys, `describeError` or the illustrations' geometry |
|
|
12
|
+
|
|
13
|
+
The `/csp` subpath (the Content Security Policy for a server or a build) is documented in the [README](../README.md#the-csp-for-a-server-or-a-build-csp).
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
# Backgrounds (`@nxgt/material-core/backgrounds`)
|
|
2
|
+
|
|
3
|
+
The engine under the background presets of `@nxgt/material` and
|
|
4
|
+
`@nxgt/material-vue`. Use it to build a preset of your own, or to read what a
|
|
5
|
+
preset produces. Most apps use a library's `Background` component instead.
|
|
6
|
+
|
|
7
|
+
## The scene
|
|
8
|
+
|
|
9
|
+
A background's SVG is a plain tree, not a string:
|
|
10
|
+
|
|
11
|
+
```ts
|
|
12
|
+
interface SceneNode {
|
|
13
|
+
tag: SceneTag; // svg g path circle rect ellipse line polygon defs pattern
|
|
14
|
+
// linearGradient radialGradient stop filter feTurbulence feColorMatrix
|
|
15
|
+
// feGaussianBlur mask
|
|
16
|
+
attrs: Readonly<Record<string, string | number>>;
|
|
17
|
+
children?: readonly SceneNode[];
|
|
18
|
+
}
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
A library renders it with `createElement` (React) or `h` (Vue), so no
|
|
22
|
+
`dangerouslySetInnerHTML` or `v-html`. `el(tag, attrs, children)` builds a
|
|
23
|
+
node.
|
|
24
|
+
|
|
25
|
+
### What a scene may hold
|
|
26
|
+
|
|
27
|
+
Geometry and presentation attributes only (`SCENE_ATTRIBUTES`). `assertSafeScene(scene, idPrefix?)`
|
|
28
|
+
throws, naming the path (`svg>g>rect`), for:
|
|
29
|
+
|
|
30
|
+
- `style`, any `on*` handler, `href`, `xlink:href`, or any attribute not on the list;
|
|
31
|
+
- a URL (`javascript:`, `data:`, `http:`...) in a value, or a `url(...)` that is not `url(#id)` with
|
|
32
|
+
the id of an element **in the same scene**;
|
|
33
|
+
- an id or class with characters outside `A-Z a-z 0-9 _ -`, markup in a value, a number that is not finite;
|
|
34
|
+
- with `idPrefix`, an id that does not start with `<idPrefix>-`.
|
|
35
|
+
|
|
36
|
+
This is what keeps a background working under a strict Content Security Policy:
|
|
37
|
+
a `style` attribute in server-rendered HTML needs `style-src-attr 'unsafe-inline'`.
|
|
38
|
+
Colour an element with a class (`class: 'k1'` and a `color` rule in CSS, drawn with
|
|
39
|
+
`currentColor`), and spread durations or drift vectors over class buckets.
|
|
40
|
+
|
|
41
|
+
## Determinism
|
|
42
|
+
|
|
43
|
+
`mulberry32(seed)` returns a generator in [0, 1). `scatter`, `valueNoise2` and the
|
|
44
|
+
builders draw from it, so the same `seed` gives the same scene on the server and
|
|
45
|
+
the client and hydration finds no mismatch. The folder has no `Math.random` and
|
|
46
|
+
reads no clock (a repository spec checks). The geometry uses a fixed
|
|
47
|
+
`1600 x 1000` box that the SVG scales with `preserveAspectRatio="xMidYMid slice"`.
|
|
48
|
+
|
|
49
|
+
- `scatter(rand, sizes, { gap, pad, margin, attempts })`: variable-radius dart throwing, largest first; a size that finds
|
|
50
|
+
no room in `attempts` tries is dropped.
|
|
51
|
+
- `valueNoise2(rand, lx, ly, width, height)`: smooth noise in [0, 1] over a box.
|
|
52
|
+
- `motifShape(shape, halfSize, filled)` draws one of `MOTIF_SHAPES` (`circle`, `ring`,
|
|
53
|
+
`square`, `triangle`, `plus`, `line`, `arc`) in `currentColor`; `place({ x, y, rotation, className, opacity }, node)`
|
|
54
|
+
puts it somewhere.
|
|
55
|
+
- `MOTIF_DEFAULTS`: every shape, `density: 'default'`, `size: 'mixed'`, `rotate: true`,
|
|
56
|
+
`shapeFill: 'mixed'`, `opacitySpread: 'varied'`.
|
|
57
|
+
|
|
58
|
+
## Ids
|
|
59
|
+
|
|
60
|
+
An id inside `url(#...)` may not hold the characters React's `useId` produces (`:r1:`, `«r1»`).
|
|
61
|
+
`svgIdPrefix(useId())` returns `bg-r1`; name ids `${prefix}-grain` and so on, and every
|
|
62
|
+
scene on a page stays unique.
|
|
63
|
+
|
|
64
|
+
## Pausing an animation
|
|
65
|
+
|
|
66
|
+
`observeBackgroundActivity(element, onChange)` calls `onChange(paused)` once, then when
|
|
67
|
+
it changes: `paused` is true while the page is hidden, the element is off screen
|
|
68
|
+
(`IntersectionObserver`), or `prefers-reduced-motion: reduce` matches. It returns the
|
|
69
|
+
function that removes everything. It reads the DOM only when called, so call it from an effect
|
|
70
|
+
(`useEffect`, `onMounted`) and only for an animated background.
|
|
71
|
+
|
|
72
|
+
## The preset table
|
|
73
|
+
|
|
74
|
+
`BACKGROUND_PRESETS` lists the 20 ids in three families (`light`, `geometry`, `motif`) with
|
|
75
|
+
`kind` (`css`, `svg`, `css+svg`), `seeded` and the `motifControls` each reads. The ids are
|
|
76
|
+
final; the other columns follow how each preset ends up drawn.
|
|
77
|
+
`buildBackgroundScene(preset, { idPrefix, seed })` returns a preset's scene (checked with
|
|
78
|
+
`assertSafeScene`) or `null` when it is CSS-only or its builder is not there yet. Only
|
|
79
|
+
`grain` has one so far.
|
|
80
|
+
|
|
81
|
+
`SHIPPED_BACKGROUND_PRESETS` (`'gradient' | 'grain'`, type `ShippedBackgroundPreset`) is the
|
|
82
|
+
subset the libraries draw today; it widens as presets land. `resolveShippedPreset(id)` returns
|
|
83
|
+
`id` when it ships and `'gradient'` otherwise, with a one-time `console.warn` outside production.
|
|
84
|
+
|
|
85
|
+
## The grain
|
|
86
|
+
|
|
87
|
+
`buildGrain` (also `buildBackgroundScene('grain', ...)`) is a film-noise overlay: an `feTurbulence`
|
|
88
|
+
filter, turned grey, drawn on one rect. The filter id is `<idPrefix>-noise` and `seed` moves the noise.
|
|
89
|
+
|
|
90
|
+
```ts
|
|
91
|
+
import { buildBackgroundScene, svgIdPrefix } from '@nxgt/material-core/backgrounds';
|
|
92
|
+
|
|
93
|
+
const scene = buildBackgroundScene('grain', { idPrefix: svgIdPrefix(id), seed: 3 });
|
|
94
|
+
```
|
|
95
|
+
|
package/docs/roadmap.md
CHANGED
|
@@ -10,29 +10,10 @@ Nothing is in progress.
|
|
|
10
10
|
|
|
11
11
|
## Next
|
|
12
12
|
|
|
13
|
-
- **
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
helpers that exist today (`cspAssetsInlineLimit` and the others) stay
|
|
18
|
-
exported.
|
|
19
|
-
- `csp`: a nonce placeholder through `html.cspNonce` and
|
|
20
|
-
`applyCspNonce(html, nonce)`; zod's jitless mode as an inline nonced
|
|
21
|
-
script in `index.html` (`ZOD_JITLESS_SCRIPT` for server rendering); the
|
|
22
|
-
recommended policy sent by the dev server as Report-Only.
|
|
23
|
-
- `fonts`: the KaTeX fonts emitted as files, and `sans: 'inter'` for a
|
|
24
|
-
self-hosted Inter.
|
|
25
|
-
- `styles`: a build that fails with the exact fix when the stylesheet import
|
|
26
|
-
or the `@source` line is missing.
|
|
27
|
-
- `pdf`: pdfkit's standard fonts handled automatically when
|
|
28
|
-
`@react-pdf/renderer` is installed, and `bundle: true` (the Nuxt module's
|
|
29
|
-
`pdf.bundleStandardFonts` today) for a server that has no
|
|
30
|
-
`node_modules`.
|
|
31
|
-
- Nuxt: the Nuxt module takes the same options.
|
|
32
|
-
- Server helpers: `createCspNonce()` (Web Crypto) and `cspPolicy({ ... })`,
|
|
33
|
-
which returns `{ directives, header }` as `@nxgt/material`'s
|
|
34
|
-
Content Security Policy guide describes; `NonceProvider`'s `nonce`
|
|
35
|
-
becomes optional on the client. Ships as minors.
|
|
13
|
+
- **More background presets** — the rest of the planned presets (see
|
|
14
|
+
`BACKGROUND_PRESETS`: meshes, aurora, topography, shapes, constellation, ...)
|
|
15
|
+
as scene builders registered in `buildBackgroundScene`. Until one ships,
|
|
16
|
+
`resolveShippedPreset` falls back to the gradient.
|
|
36
17
|
- **The shared media player** — the player state machine (playback, queue and
|
|
37
18
|
shuffle, chapters, transcript sync, resume position, quality levels, Wake
|
|
38
19
|
Lock), its keyboard shortcuts and the shortcut-help list, so
|
|
@@ -76,6 +57,39 @@ Nothing is in progress.
|
|
|
76
57
|
|
|
77
58
|
## Shipped
|
|
78
59
|
|
|
60
|
+
- **The background presets' engine** (`/backgrounds`) — a seeded generator,
|
|
61
|
+
value noise, scattering, motif shapes, a plain SVG scene format with
|
|
62
|
+
`assertSafeScene` (safe under a strict CSP), ids for `url(#…)`, the observer
|
|
63
|
+
that pauses an animation, and the first builder, `buildGrain`. Behind both
|
|
64
|
+
libraries' `Background` on `/backgrounds`.
|
|
65
|
+
|
|
66
|
+
- **One Vite plugin for the whole setup** — `nxgtMaterial()` from
|
|
67
|
+
`@nxgt/material/vite` and `@nxgt/material-vue/vite` (one implementation in
|
|
68
|
+
`@nxgt/material-core/vite`) wires the library into a Vite app, each part on
|
|
69
|
+
by default and each switchable off; the helpers that existed before stay
|
|
70
|
+
exported ([Vite plugin guide](https://cdn.jsdelivr.net/npm/@nxgt/material@2/docs/guides/vite-plugin.md)). You get:
|
|
71
|
+
- `csp`: `mode: 'hash'` (default) writes the sha256 of every inline script
|
|
72
|
+
and style to `dist/.vite/nxgt-csp.json` with the header, or `mode: 'nonce'`
|
|
73
|
+
leaves a placeholder for `applyCspNonce`; zod's jitless script; a
|
|
74
|
+
Report-Only header on the dev server. `createCspNonce()`, `cspPolicy()`
|
|
75
|
+
and `cspHash()` ship in `@nxgt/material-core/csp`.
|
|
76
|
+
- `fonts`: `katex` (fonts stay files) and `sans: 'inter'` (self-hosted Inter).
|
|
77
|
+
- `styles`: a build that fails with the exact fix when the stylesheet import
|
|
78
|
+
or React's `@source` line is missing.
|
|
79
|
+
- `pdf`: pdfkit's standard fonts handled by the same plugin, with
|
|
80
|
+
`bundle: true` for an SSR server with no `node_modules`. The Nuxt module
|
|
81
|
+
calls `nxgtMaterial()` with the same `fonts`, `styles` and `pdf` options
|
|
82
|
+
(`pdf.bundleStandardFonts` is deprecated for `pdf.bundle`) and adds zod's
|
|
83
|
+
jitless script to the head on request; its CSP stays `nuxt-security`'s.
|
|
84
|
+
- `NonceProvider`'s `nonce` is optional on the client (a client-only app gets the
|
|
85
|
+
page's nonce from its first render; a hydrated app passes it on both sides).
|
|
86
|
+
Shipped in 0.13.0.
|
|
87
|
+
- **The room above a Drawer's footer** (`/drawer-room`) — the height an open
|
|
88
|
+
floating list may take inside a Drawer without covering its footer, behind
|
|
89
|
+
both libraries' `Autocomplete`.
|
|
90
|
+
- **An avatar's initials** (`/initials`) — the first letter of a name's
|
|
91
|
+
first and last word, upper-cased and never cut inside a character, behind
|
|
92
|
+
both libraries' `AccountMenu`.
|
|
79
93
|
- **A repeatable row group's focus rules** (`/repeatable-group`) — where the
|
|
80
94
|
focus goes after a row is added, removed or moved, the add and remove
|
|
81
95
|
limits, and what the live region announces, behind both libraries'
|
package/docs/states.md
ADDED
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
# States: `/states`
|
|
2
|
+
|
|
3
|
+
The framework-free half of `EmptyState` and `ErrorState`: which kinds exist,
|
|
4
|
+
where their text lives, what of an error may be shown, and the geometry of
|
|
5
|
+
their illustrations. Nothing runs at import, so it is safe on a server. The
|
|
6
|
+
README has the one-line example; this page has the detail.
|
|
7
|
+
|
|
8
|
+
## Kinds
|
|
9
|
+
|
|
10
|
+
| Family | Kinds | Meaning |
|
|
11
|
+
| --- | --- | --- |
|
|
12
|
+
| Empty | `empty`, `search`, `not-found`, `unauthorized` | an absence: nothing yet, nothing found, no such page, no access |
|
|
13
|
+
| Error | `generic`, `offline`, `maintenance` | something failed |
|
|
14
|
+
|
|
15
|
+
`resolveEmptyStateKind({ kind, variant })` returns `kind`, else the legacy
|
|
16
|
+
`variant` (all seven values), else `'generic'`, the default `EmptyState` has
|
|
17
|
+
always had. `isErrorKind(kind)` tells the families apart.
|
|
18
|
+
|
|
19
|
+
```ts
|
|
20
|
+
import { isErrorKind, resolveEmptyStateKind } from '@nxgt/material-core/states';
|
|
21
|
+
|
|
22
|
+
resolveEmptyStateKind({}); // 'generic'
|
|
23
|
+
resolveEmptyStateKind({ variant: 'offline' }); // 'offline'
|
|
24
|
+
resolveEmptyStateKind({ kind: 'search', variant: 'offline' }); // 'search'
|
|
25
|
+
isErrorKind('offline'); // true
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Copy
|
|
29
|
+
|
|
30
|
+
`stateCopy(kind, family)` returns `{ titleKey, descriptionKey, title,
|
|
31
|
+
description }`: the i18n keys and their English fallbacks.
|
|
32
|
+
|
|
33
|
+
- `'empty-state'` reads `material.empty-state.<kind>.*`, for all seven kinds
|
|
34
|
+
(so an app that overrides `material.empty-state.generic.title` keeps its
|
|
35
|
+
text on an `EmptyState` given a legacy error `variant`).
|
|
36
|
+
- `'error-state'` reads `material.error-state.<kind>.*` for the three error
|
|
37
|
+
kinds; any other kind falls back to `material.empty-state.*`.
|
|
38
|
+
|
|
39
|
+
`STATE_ACTION_KEYS` holds the keys of `ErrorState`'s Retry button and details
|
|
40
|
+
(`retry`, `details`, `detailsName`, `detailsMessage`, `detailsCause`), each
|
|
41
|
+
with its English fallback. An app that overrode `material.empty-state.generic|
|
|
42
|
+
offline|maintenance.*` must override the `material.error-state.*` keys too.
|
|
43
|
+
|
|
44
|
+
```ts
|
|
45
|
+
import { stateCopy } from '@nxgt/material-core/states';
|
|
46
|
+
|
|
47
|
+
const { titleKey, title } = stateCopy('offline', 'error-state');
|
|
48
|
+
t(titleKey, title); // 'material.error-state.offline.title', 'You are offline'
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## Error details
|
|
52
|
+
|
|
53
|
+
`describeError(error, { maxDepth })` returns `{ name, message }` for the
|
|
54
|
+
error, then for each `cause`, at most `maxDepth` entries (3 by default). It
|
|
55
|
+
takes an `Error`, a `{ message }` object, a string or any primitive; stops at
|
|
56
|
+
a cycle; returns `[]` for `null` and `undefined`; and does not throw on a
|
|
57
|
+
hostile getter. It **never reads `.stack`**: a stack names files and paths.
|
|
58
|
+
|
|
59
|
+
```ts
|
|
60
|
+
import { describeError } from '@nxgt/material-core/states';
|
|
61
|
+
|
|
62
|
+
describeError(new Error('Could not save', { cause: new TypeError('Failed to fetch') }));
|
|
63
|
+
// [{ name: 'Error', message: 'Could not save' },
|
|
64
|
+
// { name: 'TypeError', message: 'Failed to fetch' }]
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## Illustrations
|
|
68
|
+
|
|
69
|
+
`STATE_ILLUSTRATIONS[kind]` is `{ viewBox, shapes }`. A shape is `{ el, tone,
|
|
70
|
+
attrs }`: `el` is `path`, `circle`, `rect`, `ellipse` or `line`; `attrs` are
|
|
71
|
+
single-word SVG attributes (`d`, `cx`, `rx`, `transform`…); `tone` is
|
|
72
|
+
`surface`, `outline`, `accent`, `accent-soft` or `muted`. There is no colour
|
|
73
|
+
and no style in the data: a library maps the tone, and the kind's
|
|
74
|
+
`STATE_ACCENT` (`primary`, `error`, `warning`, `info`, `neutral`), to classes
|
|
75
|
+
on its theme tokens, so the SVG is CSP-safe. `STATE_ICON[kind]` is the kind's
|
|
76
|
+
lucide icon, in kebab-case.
|
|
77
|
+
|
|
78
|
+
```tsx
|
|
79
|
+
import { STATE_ILLUSTRATIONS } from '@nxgt/material-core/states';
|
|
80
|
+
|
|
81
|
+
const { viewBox, shapes } = STATE_ILLUSTRATIONS['not-found'];
|
|
82
|
+
<svg viewBox={viewBox} aria-hidden="true">
|
|
83
|
+
{shapes.map((s, i) => createElement(s.el, { key: i, className: toneClass(s.tone), ...s.attrs }))}
|
|
84
|
+
</svg>;
|
|
85
|
+
```
|