@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.
Files changed (114) hide show
  1. package/CHANGELOG.md +36 -0
  2. package/README.md +283 -24
  3. package/dist/backgrounds/activity.d.ts +11 -0
  4. package/dist/backgrounds/activity.d.ts.map +1 -0
  5. package/dist/backgrounds/build.d.ts +9 -0
  6. package/dist/backgrounds/build.d.ts.map +1 -0
  7. package/dist/backgrounds/id-prefix.d.ts +8 -0
  8. package/dist/backgrounds/id-prefix.d.ts.map +1 -0
  9. package/dist/backgrounds/index.d.ts +20 -0
  10. package/dist/backgrounds/index.d.ts.map +1 -0
  11. package/dist/backgrounds/index.js +467 -0
  12. package/dist/backgrounds/index.js.map +20 -0
  13. package/dist/backgrounds/noise.d.ts +7 -0
  14. package/dist/backgrounds/noise.d.ts.map +1 -0
  15. package/dist/backgrounds/presets/grain.d.ts +9 -0
  16. package/dist/backgrounds/presets/grain.d.ts.map +1 -0
  17. package/dist/backgrounds/presets.d.ts +16 -0
  18. package/dist/backgrounds/presets.d.ts.map +1 -0
  19. package/dist/backgrounds/primitives.d.ts +22 -0
  20. package/dist/backgrounds/primitives.d.ts.map +1 -0
  21. package/dist/backgrounds/rng.d.ts +12 -0
  22. package/dist/backgrounds/rng.d.ts.map +1 -0
  23. package/dist/backgrounds/scatter.d.ts +25 -0
  24. package/dist/backgrounds/scatter.d.ts.map +1 -0
  25. package/dist/backgrounds/scene.d.ts +21 -0
  26. package/dist/backgrounds/scene.d.ts.map +1 -0
  27. package/dist/backgrounds/tones.d.ts +4 -0
  28. package/dist/backgrounds/tones.d.ts.map +1 -0
  29. package/dist/backgrounds/types.d.ts +53 -0
  30. package/dist/backgrounds/types.d.ts.map +1 -0
  31. package/dist/chunks/index-mw5fa8qa.js +119 -0
  32. package/dist/chunks/index-mw5fa8qa.js.map +12 -0
  33. package/dist/csp/index.d.ts +10 -0
  34. package/dist/csp/index.d.ts.map +1 -0
  35. package/dist/csp/index.js +21 -0
  36. package/dist/csp/index.js.map +9 -0
  37. package/dist/csp/nonce.d.ts +35 -0
  38. package/dist/csp/nonce.d.ts.map +1 -0
  39. package/dist/csp/policy.d.ts +33 -0
  40. package/dist/csp/policy.d.ts.map +1 -0
  41. package/dist/csp/zod-jitless.d.ts +4 -0
  42. package/dist/csp/zod-jitless.d.ts.map +1 -0
  43. package/dist/lib/drawer-room.d.ts +8 -0
  44. package/dist/lib/drawer-room.d.ts.map +1 -0
  45. package/dist/lib/drawer-room.js +17 -0
  46. package/dist/lib/drawer-room.js.map +10 -0
  47. package/dist/lib/escape-forward.d.ts +14 -0
  48. package/dist/lib/escape-forward.d.ts.map +1 -1
  49. package/dist/lib/escape-forward.js +22 -2
  50. package/dist/lib/escape-forward.js.map +3 -3
  51. package/dist/lib/initials.d.ts +12 -0
  52. package/dist/lib/initials.d.ts.map +1 -0
  53. package/dist/lib/initials.js +15 -0
  54. package/dist/lib/initials.js.map +10 -0
  55. package/dist/pdf-viewer/index.d.ts +1 -0
  56. package/dist/pdf-viewer/index.d.ts.map +1 -1
  57. package/dist/pdf-viewer/index.js +68 -38
  58. package/dist/pdf-viewer/index.js.map +6 -5
  59. package/dist/pdf-viewer/pdf-reveal-hit.d.ts +7 -0
  60. package/dist/pdf-viewer/pdf-reveal-hit.d.ts.map +1 -0
  61. package/dist/pdf-viewer/pdf-scroll-spy.d.ts +24 -8
  62. package/dist/pdf-viewer/pdf-scroll-spy.d.ts.map +1 -1
  63. package/dist/states/copy.d.ts +46 -0
  64. package/dist/states/copy.d.ts.map +1 -0
  65. package/dist/states/describe-error.d.ts +18 -0
  66. package/dist/states/describe-error.d.ts.map +1 -0
  67. package/dist/states/illustrations.d.ts +24 -0
  68. package/dist/states/illustrations.d.ts.map +1 -0
  69. package/dist/states/index.d.ts +11 -0
  70. package/dist/states/index.d.ts.map +1 -0
  71. package/dist/states/index.js +253 -0
  72. package/dist/states/index.js.map +13 -0
  73. package/dist/states/kinds.d.ts +28 -0
  74. package/dist/states/kinds.d.ts.map +1 -0
  75. package/dist/vite/csp-dev-header.d.ts +11 -0
  76. package/dist/vite/csp-dev-header.d.ts.map +1 -0
  77. package/dist/vite/csp-hashes.d.ts +23 -0
  78. package/dist/vite/csp-hashes.d.ts.map +1 -0
  79. package/dist/vite/csp-header.d.ts +10 -0
  80. package/dist/vite/csp-header.d.ts.map +1 -0
  81. package/dist/vite/csp-plugin.d.ts +12 -0
  82. package/dist/vite/csp-plugin.d.ts.map +1 -0
  83. package/dist/vite/css-chain.d.ts +13 -0
  84. package/dist/vite/css-chain.d.ts.map +1 -0
  85. package/dist/vite/dependency-closure.d.ts +8 -0
  86. package/dist/vite/dependency-closure.d.ts.map +1 -0
  87. package/dist/vite/fonts-inter.d.ts +15 -0
  88. package/dist/vite/fonts-inter.d.ts.map +1 -0
  89. package/dist/vite/fonts-plugin.d.ts +12 -0
  90. package/dist/vite/fonts-plugin.d.ts.map +1 -0
  91. package/dist/vite/index.d.ts +17 -81
  92. package/dist/vite/index.d.ts.map +1 -1
  93. package/dist/vite/index.js +478 -2
  94. package/dist/vite/index.js.map +18 -4
  95. package/dist/vite/libraries.d.ts +13 -0
  96. package/dist/vite/libraries.d.ts.map +1 -0
  97. package/dist/vite/nxgt-material.d.ts +12 -0
  98. package/dist/vite/nxgt-material.d.ts.map +1 -0
  99. package/dist/vite/options.d.ts +56 -0
  100. package/dist/vite/options.d.ts.map +1 -0
  101. package/dist/vite/pdf-plugin.d.ts +19 -0
  102. package/dist/vite/pdf-plugin.d.ts.map +1 -0
  103. package/dist/vite/pdfkit-standard-fonts.d.ts +74 -0
  104. package/dist/vite/pdfkit-standard-fonts.d.ts.map +1 -0
  105. package/dist/vite/styles-plugin.d.ts +27 -0
  106. package/dist/vite/styles-plugin.d.ts.map +1 -0
  107. package/dist/vite/styles-scan.d.ts +14 -0
  108. package/dist/vite/styles-scan.d.ts.map +1 -0
  109. package/docs/README.md +4 -0
  110. package/docs/backgrounds.md +95 -0
  111. package/docs/roadmap.md +37 -23
  112. package/docs/states.md +85 -0
  113. package/docs/troubleshooting.md +174 -3
  114. 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
- - **One Vite plugin for the whole setup** — `nxgtMaterial()` is implemented
14
- once in `/vite` and re-exported by `@nxgt/material/vite` and
15
- `@nxgt/material-vue/vite`, so both libraries get the same one-call setup.
16
- Every option is on by default and each can be turned off or refined; the
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
+ ```