@nxgt/material 3.6.0 → 3.7.1
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 +26 -0
- package/README.md +46 -1
- package/dist/{button-1Fornjtn.js → button--cF4gY14.js} +1 -1
- package/dist/charts.js +1 -1
- package/dist/{code-editor-DeZYlIO2.js → code-editor-0CdGwKDg.js} +3 -3
- package/dist/code-editor.js +3 -3
- package/dist/{code-language-items-Bb7afEj-.js → code-language-items-CGARRbVm.js} +1 -1
- package/dist/components/animations/scroll.css +1 -1
- package/dist/components/base-content.css +1 -1
- package/dist/components/base.css +1 -1
- package/dist/components/components.css +2 -0
- package/dist/components/editor-field-expressive.css +5 -0
- package/dist/components/editor-prose.css +1 -1
- package/dist/components/theme-tokens.css +17 -4
- package/dist/components/ui/display/period-cards/period-cards.css +2 -2
- package/dist/components/ui/media/pdf-viewer/pdf-viewer.css +1 -1
- package/dist/components/ui/widgets/drawing/drawing-animate.css +123 -0
- package/dist/components/ui/widgets/drawing/drawing.css +459 -0
- package/dist/{components-BCYZgeoV.js → components-bYGPzyKd.js} +761 -761
- package/dist/components.js +18 -18
- package/dist/{dialog-JQT6iETD.js → dialog-DdJ1C4BR.js} +168 -168
- package/dist/dnd.js +1 -1
- package/dist/draw-animate.js +106 -0
- package/dist/draw-png.js +2 -0
- package/dist/draw-sketch.js +38 -0
- package/dist/draw.js +65 -0
- package/dist/drawing-B8VuG7nx.js +390 -0
- package/dist/drawing-context-CeKeZE6b.js +10 -0
- package/dist/{dropdown-menu-DiZvX4tG.js → dropdown-menu-DWtgUVW7.js} +1 -1
- package/dist/editor-viewer.js +1 -1
- package/dist/editor.js +120 -120
- package/dist/{empty-state-Cpvsmk0R.js → empty-state-CRWLQ1sM.js} +2 -2
- package/dist/{icon-badge-C30yKsAM.js → icon-badge-Bb5-73XP.js} +18 -18
- package/dist/{icon-button-BXlI3DJ_.js → icon-button-5A6Mrj6w.js} +60 -90
- package/dist/lib/components/ui/display/shape/use-shape-morph.d.ts +1 -0
- package/dist/lib/components/ui/widgets/drawing/drawing-a11y.d.ts +20 -0
- package/dist/lib/components/ui/widgets/drawing/drawing-context.d.ts +23 -0
- package/dist/lib/components/ui/widgets/drawing/drawing-types.d.ts +63 -0
- package/dist/lib/components/ui/widgets/drawing/drawing.d.ts +17 -0
- package/dist/lib/components/ui/widgets/drawing/index.d.ts +5 -0
- package/dist/lib/components/ui/widgets/drawing/partials/drawing-root.d.ts +17 -0
- package/dist/lib/components/ui/widgets/drawing/partials/interactive-node.d.ts +22 -0
- package/dist/lib/components/ui/widgets/drawing/partials/primitives/content.d.ts +20 -0
- package/dist/lib/components/ui/widgets/drawing/partials/primitives/path.d.ts +29 -0
- package/dist/lib/components/ui/widgets/drawing/partials/primitives/primitive.d.ts +19 -0
- package/dist/lib/components/ui/widgets/drawing/partials/primitives/shapes.d.ts +18 -0
- package/dist/lib/components/ui/widgets/drawing/partials/react-attrs.d.ts +5 -0
- package/dist/lib/components/ui/widgets/drawing/partials/ring.d.ts +9 -0
- package/dist/lib/components/ui/widgets/drawing/partials/svg-tree.d.ts +29 -0
- package/dist/lib/components/ui/widgets/drawing/use-exact-text.d.ts +16 -0
- package/dist/lib/draw/index.d.ts +32 -0
- package/dist/lib/draw-animate/index.d.ts +19 -0
- package/dist/lib/draw-animate/morph-drawing.d.ts +32 -0
- package/dist/lib/draw-animate/reduced-motion.d.ts +2 -0
- package/dist/lib/draw-animate/use-drawing-controls.d.ts +27 -0
- package/dist/lib/draw-animate/use-scene-morph.d.ts +15 -0
- package/dist/lib/draw-png/index.d.ts +11 -0
- package/dist/lib/draw-sketch/index.d.ts +17 -0
- package/dist/lib/draw-sketch/sketch.d.ts +19 -0
- package/dist/lib/print/components/print-drawing.d.ts +16 -0
- package/dist/lib/print/index.d.ts +2 -1
- package/dist/main.js +23 -23
- package/dist/map.js +63 -63
- package/dist/material.css +1 -1
- package/dist/pdf-reader.js +1 -1
- package/dist/print.js +123 -115
- package/dist/{public-Cde8_SN8.js → public-SsiazLEv.js} +743 -743
- package/dist/{render-json-BwJX1jZ2.js → render-json-DyFYFIkZ.js} +1 -1
- package/dist/{rich-code-block-yxMXBuGd.js → rich-code-block-CwNwQs5z.js} +3 -3
- package/dist/{rich-text-viewer-Bq-2vTVm.js → rich-text-viewer-LO1IZCWs.js} +1 -1
- package/dist/{sortable-provider-DYlpq8lP.js → sortable-provider-BvD98s8Y.js} +19 -19
- package/dist/{spinner-D-FE_mTW.js → spinner-CtGCPza-.js} +4 -4
- package/dist/styles.css +1 -0
- package/dist/{toolbar-items-DnkS3bDY.js → toolbar-items-DsDDD5AY.js} +1 -1
- package/dist/{use-chat-composer-BwpSgP_D.js → use-chat-composer-DZ01a16D.js} +923 -922
- package/dist/use-shape-morph-BKA_R5P5.js +35 -0
- package/docs/README.md +1 -0
- package/docs/components/rich-widgets.md +196 -0
- package/docs/guides/drawing.md +499 -0
- package/docs/guides/printing.md +47 -0
- package/docs/guides/theming.md +3 -2
- package/docs/previews/rich-widgets-drawing.webp +0 -0
- package/docs/roadmap.md +17 -0
- package/docs/troubleshooting.md +145 -1
- package/lib/components/animations/scroll.css +1 -1
- package/lib/components/base-content.css +1 -1
- package/lib/components/base.css +1 -1
- package/lib/components/components.css +2 -0
- package/lib/components/editor-field-expressive.css +5 -0
- package/lib/components/editor-prose.css +1 -1
- package/lib/components/theme-tokens.css +17 -4
- package/lib/components/ui/display/period-cards/period-cards.css +2 -2
- package/lib/components/ui/media/pdf-viewer/pdf-viewer.css +1 -1
- package/lib/components/ui/widgets/drawing/drawing-animate.css +123 -0
- package/lib/components/ui/widgets/drawing/drawing.css +459 -0
- package/lib/styles.css +1 -0
- package/package.json +22 -2
package/docs/troubleshooting.md
CHANGED
|
@@ -389,6 +389,19 @@ words in your error.
|
|
|
389
389
|
- [My gradient colour override stopped working](#my-gradient-colour-override-stopped-working)
|
|
390
390
|
- [A preset's items use class names my own CSS also uses (`fl`, `d1`, `k1`, `mo`)](#a-presets-items-use-class-names-my-own-css-also-uses-fl-d1-k1-mo)
|
|
391
391
|
|
|
392
|
+
**Drawing**
|
|
393
|
+
|
|
394
|
+
- [`A decorative drawing has an interactive node: give the Drawing a title instead`](#a-decorative-drawing-has-an-interactive-node-give-the-drawing-a-title-instead)
|
|
395
|
+
- [`Unsafe drawing at <tag>: <reason>` from a scene or a JSX drawing](#unsafe-drawing-at-tag-reason-from-a-scene-or-a-jsx-drawing)
|
|
396
|
+
- [`Tones "a" and "b" meet on one element: use two nodes in a group`](#tones-a-and-b-meet-on-one-element-use-two-nodes-in-a-group)
|
|
397
|
+
- [`No colour for "brand": pass palette: { "brand": "#rrggbb" }`](#no-colour-for-brand-pass-palette--brand-rrggbb-)
|
|
398
|
+
- [`shapeOutline: unknown shape "x"; expected one of SHAPE_NAMES (…)`](#shapeoutline-unknown-shape-x-expected-one-of-shape_names-)
|
|
399
|
+
- [`drawingToPng: cannot read the image "<url>" (<reason>)…`](#drawingtopng-cannot-read-the-image-url-reason)
|
|
400
|
+
- [`drawingToPng: the canvas gave no PNG.` and its siblings](#drawingtopng-the-canvas-gave-no-png-and-its-siblings)
|
|
401
|
+
- [A drawing is black, or its role colours do nothing](#a-drawing-is-black-or-its-role-colours-do-nothing)
|
|
402
|
+
- [A Server Component that renders `Drawing` fails](#a-server-component-that-renders-drawing-fails)
|
|
403
|
+
- [`Duplicate identifier 'text'` when importing from `/draw` and `/print`](#duplicate-identifier-text-when-importing-from-draw-and-print)
|
|
404
|
+
|
|
392
405
|
**Content Security Policy**
|
|
393
406
|
|
|
394
407
|
- [`[nxgt-material] html.cspNonce is set, but the CSP is in hash mode (the default): set nxgtMaterial({ csp: { mode: 'nonce' } }) or drop html.cspNonce.`](#nxgt-material-htmlcspnonce-is-set-but-the-csp-is-in-hash-mode-the-default-set-nxgtmaterial-csp--mode-nonce---or-drop-htmlcspnonce)
|
|
@@ -906,7 +919,7 @@ catalogue's own field messages pass.
|
|
|
906
919
|
**Why:** it is drawn with `text-error`, the fill colour. The dark `--error` is
|
|
907
920
|
kept dark enough for near-white text on a filled error surface, which makes it
|
|
908
921
|
too dark to read as text on the dark surfaces. Error text has its own token,
|
|
909
|
-
`--error-text`, lightened in the dark theme (5.
|
|
922
|
+
`--error-text`, lightened in the dark theme (5.9:1 on `--background`, 5.3:1 on
|
|
910
923
|
`--card`).
|
|
911
924
|
**Fix:** draw text with `text-error-text`; keep `text-error` for fills,
|
|
912
925
|
borders and icons that stand alone. On a `Button` or `IconButton` drop the
|
|
@@ -947,6 +960,15 @@ An app that overrides `--primary` under `:root` and `.dark, [data-theme="dark"]`
|
|
|
947
960
|
gets `--primary-text` for free; set `--primary-text` after it to choose another
|
|
948
961
|
colour. On an element below the root, set `--color-primary-text`.
|
|
949
962
|
|
|
963
|
+
The same goes for a primary mark that is not text: a bar, a dot, a selected or
|
|
964
|
+
focused border, a ring or a spinner arc. In dark, `--primary` is only 2.1 to
|
|
965
|
+
2.5:1 on the surfaces, under the 3:1 of WCAG 1.4.11. Draw it with
|
|
966
|
+
`bg-primary-indicator`, `border-primary-indicator`, `ring-primary-indicator` or
|
|
967
|
+
`stroke-primary-indicator`: `--primary-indicator` is `--primary` in light and
|
|
968
|
+
`--primary` mixed 25 % with white in dark (3.7:1 or more on `--background`,
|
|
969
|
+
`--card` and `--muted`). It follows an app's own `--primary`; set
|
|
970
|
+
`--primary-indicator` after it to choose another dark colour.
|
|
971
|
+
|
|
950
972
|
### `expectTapTargets` reports a checkbox, switch or chip remove button under 44px
|
|
951
973
|
|
|
952
974
|
**When:** a phone project's `expectTapTargets` (`@nxgt/playwright`) lists a
|
|
@@ -6788,6 +6810,128 @@ import '@nxgt/material/backgrounds.css'; // every preset
|
|
|
6788
6810
|
|
|
6789
6811
|
---
|
|
6790
6812
|
|
|
6813
|
+
## Drawing
|
|
6814
|
+
|
|
6815
|
+
How to use it is in the [Drawing guide](guides/drawing.md); the engine's own
|
|
6816
|
+
errors (`Invalid colour`, `Invalid path data`, `Unsupported scene version`,
|
|
6817
|
+
`[pdf] A drawing mask is not supported in a PDF: dropped.`) are in the
|
|
6818
|
+
[core troubleshooting](https://cdn.jsdelivr.net/npm/@nxgt/material-core@0/docs/troubleshooting.md#drawing).
|
|
6819
|
+
|
|
6820
|
+
### `A decorative drawing has an interactive node: give the Drawing a title instead`
|
|
6821
|
+
|
|
6822
|
+
**When:** a `Drawing` with `decorative` renders, or contains, a node with `onClick` (or any event), `interactive`, or an entry in `handlers`. It throws on the render.
|
|
6823
|
+
**Why:** `decorative` is `aria-hidden`, and a focusable node inside it would be reachable by keyboard and invisible to assistive technology.
|
|
6824
|
+
**Fix:** give the drawing a `title` (and each interactive node a `label`), or drop the events:
|
|
6825
|
+
|
|
6826
|
+
```tsx
|
|
6827
|
+
<Drawing scene={board} title="Board columns" onNodeClick={open} />
|
|
6828
|
+
```
|
|
6829
|
+
|
|
6830
|
+
### `Unsafe drawing at <tag>: <reason>` from a scene or a JSX drawing
|
|
6831
|
+
|
|
6832
|
+
**When:** `Drawing`, `toSVG`, `compileScene` or `assertSafeDrawing` throws `Unsafe drawing at <image>: href must be http(s), relative or data:image (png, jpeg, gif, webp)` or another reason (`tag not allowed`, `style not allowed`, `<attribute> not finite`, `id used twice`...).
|
|
6833
|
+
**Why:** a strict CSP could not accept what the scene would write. From a scene loaded as JSON the cause is usually an `image` `href` (`javascript:`, `file:` or `data:image/svg+xml`), a `className` or node `id` with unusual characters, or a coordinate that is `NaN`.
|
|
6834
|
+
**Fix:** correct the value the message names. Check untrusted JSON before drawing it:
|
|
6835
|
+
|
|
6836
|
+
```ts
|
|
6837
|
+
import { assertSafeDrawing } from '@nxgt/material/draw';
|
|
6838
|
+
|
|
6839
|
+
assertSafeDrawing(scene); // throws with the element and the reason
|
|
6840
|
+
```
|
|
6841
|
+
|
|
6842
|
+
The reasons are listed in the [core troubleshooting](https://cdn.jsdelivr.net/npm/@nxgt/material-core@0/docs/troubleshooting.md#unsafe-drawing-at-tag-reason).
|
|
6843
|
+
|
|
6844
|
+
### `Tones "a" and "b" meet on one element: use two nodes in a group`
|
|
6845
|
+
|
|
6846
|
+
**When:** a node has `fill: tone('brand')` and `stroke: tone('accent')` where both are app tones.
|
|
6847
|
+
**Why:** an app tone is carried by one `data-tone` attribute on the element, so an element can have only one.
|
|
6848
|
+
**Fix:** one node per tone, in a group, or name a theme tone for one of them:
|
|
6849
|
+
|
|
6850
|
+
```tsx
|
|
6851
|
+
group({}, [
|
|
6852
|
+
circle({ cx: 20, cy: 20, r: 14, fill: tone('brand', 'container') }),
|
|
6853
|
+
circle({ cx: 20, cy: 20, r: 14, fill: 'transparent', stroke: tone('accent') }),
|
|
6854
|
+
]);
|
|
6855
|
+
```
|
|
6856
|
+
|
|
6857
|
+
### `No colour for "brand": pass palette: { "brand": "#rrggbb" }`
|
|
6858
|
+
|
|
6859
|
+
**When:** `toSVG` (the default `colors: 'literal'`) or a PDF meets an app tone or token that has no literal colour.
|
|
6860
|
+
**Why:** a standalone SVG has no theme to read, so every token needs a hex; only the theme's own roles have one.
|
|
6861
|
+
**Fix:** pass it, or use `colors: 'vars'` for an inline SVG:
|
|
6862
|
+
|
|
6863
|
+
```ts
|
|
6864
|
+
toSVG(art, { palette: { brand: '#0a7c59' } });
|
|
6865
|
+
```
|
|
6866
|
+
|
|
6867
|
+
### `shapeOutline: unknown shape "x"; expected one of SHAPE_NAMES (…)`
|
|
6868
|
+
|
|
6869
|
+
**When:** `shape('cookie-99', …)` or `morph` is given a name the registry does not have.
|
|
6870
|
+
**Why:** a typo, or a name from another library. The message lists the valid ones.
|
|
6871
|
+
**Fix:** use a name of `SHAPE_NAMES`, with or without the `m3-` prefix:
|
|
6872
|
+
|
|
6873
|
+
```ts
|
|
6874
|
+
import { SHAPE_NAMES, shape } from '@nxgt/material/draw';
|
|
6875
|
+
|
|
6876
|
+
shape('cookie-9', { x: 0, y: 0, w: 80, h: 80 }); // or 'm3-cookie-9'
|
|
6877
|
+
console.log(SHAPE_NAMES);
|
|
6878
|
+
```
|
|
6879
|
+
|
|
6880
|
+
### `drawingToPng: cannot read the image "<url>" (<reason>)…`
|
|
6881
|
+
|
|
6882
|
+
**When:** `drawingToPng` or `downloadDrawingPng` rejects, and the drawing holds an `image` with a URL.
|
|
6883
|
+
**Why:** an SVG drawn as an image loads nothing external, so the function fetches each image and inlines its bytes; the browser refused the fetch, almost always CORS. Nothing is left to taint the canvas: the failure is reported before it can happen.
|
|
6884
|
+
**Fix:** serve the image with `Access-Control-Allow-Origin`, or put a `data:image/png|jpeg|gif|webp` URL in the scene:
|
|
6885
|
+
|
|
6886
|
+
```ts
|
|
6887
|
+
image({ href: 'data:image/png;base64,…', x: 0, y: 0, w: 64, h: 64 });
|
|
6888
|
+
```
|
|
6889
|
+
|
|
6890
|
+
### `drawingToPng: the canvas gave no PNG.` and its siblings
|
|
6891
|
+
|
|
6892
|
+
**When:** a PNG fails with one of `drawingToPng: the canvas gave no PNG.`, `drawingToPng: no 2D canvas in this browser.`, `drawingToPng: scale must be above 0.`, `drawingToPng: the drawing has no size.` or `drawingToPng: the browser could not draw the SVG.`.
|
|
6893
|
+
**Why:** respectively a canvas the browser refused to encode (usually far too large: `scale` times the drawing's size), no canvas support, a zero or negative `scale`, a live `<svg>` with no `width`, `height` or `viewBox`, and an SVG that does not load as an image.
|
|
6894
|
+
**Fix:** lower the `scale`, pass a positive one, give the `<svg>` a `viewBox`, or draw from the scene instead of the live element:
|
|
6895
|
+
|
|
6896
|
+
```ts
|
|
6897
|
+
await drawingToPng(scene, { scale: 1 });
|
|
6898
|
+
```
|
|
6899
|
+
|
|
6900
|
+
### A drawing is black, or its role colours do nothing
|
|
6901
|
+
|
|
6902
|
+
**When:** a `Drawing` renders in black (or the browser's default colours), whatever its `fill="primary"`.
|
|
6903
|
+
**Why:** role colours are classes of `styles.css` (`nxgt-draw-f-primary`...); without the stylesheet nothing maps them. A standalone `toSVG` file does not use classes: it writes hex.
|
|
6904
|
+
**Fix:** import the stylesheet once in the app:
|
|
6905
|
+
|
|
6906
|
+
```ts
|
|
6907
|
+
import '@nxgt/material/styles.css';
|
|
6908
|
+
```
|
|
6909
|
+
|
|
6910
|
+
### A Server Component that renders `Drawing` fails
|
|
6911
|
+
|
|
6912
|
+
**When:** a Next.js or RSC page imports `Drawing`, a primitive, `Sketch` or the animate hooks and the build reports that a hook or a context only works in a Client Component.
|
|
6913
|
+
**Why:** `@nxgt/material/draw` is its own entry whose built files carry no `'use client'` directive (the components use hooks).
|
|
6914
|
+
**Fix:** render it from a file of yours that starts with `'use client'`; the builders and `toSVG` can stay in the Server Component and pass the scene as a prop:
|
|
6915
|
+
|
|
6916
|
+
```tsx
|
|
6917
|
+
// drawing-client.tsx
|
|
6918
|
+
'use client';
|
|
6919
|
+
export { Drawing } from '@nxgt/material/draw';
|
|
6920
|
+
```
|
|
6921
|
+
|
|
6922
|
+
### `Duplicate identifier 'text'` when importing from `/draw` and `/print`
|
|
6923
|
+
|
|
6924
|
+
**When:** TypeScript reports `Duplicate identifier 'text'` (or `Import declaration conflicts with local declaration of 'text'`, or the same for `image`) in a file that imports from both entries.
|
|
6925
|
+
**Why:** `@nxgt/material/draw` and `@nxgt/material/print` each export a `text` and an `image`: the first builds a drawing node, the second a PDF block.
|
|
6926
|
+
**Fix:** rename one of them:
|
|
6927
|
+
|
|
6928
|
+
```ts
|
|
6929
|
+
import { text as drawText } from '@nxgt/material/draw';
|
|
6930
|
+
import { text } from '@nxgt/material/print';
|
|
6931
|
+
```
|
|
6932
|
+
|
|
6933
|
+
---
|
|
6934
|
+
|
|
6791
6935
|
## Content Security Policy
|
|
6792
6936
|
|
|
6793
6937
|
How to set up the policy is in the [Content Security Policy guide](guides/csp.md).
|
package/lib/components/base.css
CHANGED
|
@@ -124,7 +124,7 @@
|
|
|
124
124
|
height: 0.55em;
|
|
125
125
|
transform: scale(0);
|
|
126
126
|
transition: 120ms transform ease-in-out;
|
|
127
|
-
box-shadow: inset 1em 1em var(--color-primary);
|
|
127
|
+
box-shadow: inset 1em 1em var(--color-primary-indicator);
|
|
128
128
|
}
|
|
129
129
|
input[type="checkbox"]:checked::before {
|
|
130
130
|
transform: scale(1);
|
|
@@ -196,3 +196,5 @@
|
|
|
196
196
|
@import "../backgrounds/css/base.css";
|
|
197
197
|
@import "../backgrounds/css/gradient.css";
|
|
198
198
|
@import "../backgrounds/css/motion.css";
|
|
199
|
+
@import "./ui/widgets/drawing/drawing.css"; /* @nxgt/material/draw: role colours, focus ring */
|
|
200
|
+
@import "./ui/widgets/drawing/drawing-animate.css";
|
|
@@ -37,6 +37,11 @@
|
|
|
37
37
|
border-color: color-mix(in oklab, var(--primary) 60%, transparent);
|
|
38
38
|
box-shadow: 0 0 0 3px color-mix(in oklab, var(--primary) 50%, transparent);
|
|
39
39
|
}
|
|
40
|
+
/* Dark: the 60 % border is under 3:1 on the card (WCAG 1.4.11). */
|
|
41
|
+
:is(.dark, [data-theme="dark"])
|
|
42
|
+
[data-slot="compact-editor"][data-look="expressive"]:focus-within {
|
|
43
|
+
border-color: var(--primary-indicator);
|
|
44
|
+
}
|
|
40
45
|
[data-slot="editor-field"][data-invalid]
|
|
41
46
|
:is(
|
|
42
47
|
[data-slot="compact-editor"],
|
|
@@ -115,7 +115,7 @@
|
|
|
115
115
|
}
|
|
116
116
|
|
|
117
117
|
blockquote {
|
|
118
|
-
border-inline-start: 3px solid var(--primary);
|
|
118
|
+
border-inline-start: 3px solid var(--primary-indicator);
|
|
119
119
|
padding-inline-start: 1.1em;
|
|
120
120
|
color: var(--muted-foreground);
|
|
121
121
|
font-family: var(--nxgt-prose-heading-font);
|
|
@@ -17,6 +17,11 @@
|
|
|
17
17
|
the violet page (7.9:1 on a Card; the colour itself gives 6.8:1 on the
|
|
18
18
|
page); the dark theme lifts it. */
|
|
19
19
|
--primary-text: color-mix(in oklab, var(--primary) 96%, black);
|
|
20
|
+
/* Primary drawn as a non-text mark (WCAG 1.4.11, 3:1): an indicator bar or dot,
|
|
21
|
+
a selected or focused border, a ring, a spinner arc, a progress fill
|
|
22
|
+
(`bg-primary-indicator`, `border-primary-indicator`...). Light is --primary;
|
|
23
|
+
the dark theme lifts it. */
|
|
24
|
+
--primary-indicator: var(--primary);
|
|
20
25
|
/* --secondary, --success and --info are 0.02 darker than before: on the
|
|
21
26
|
violet page tint (--background, 97.3 %) their own 15 % tonal tint gave the
|
|
22
27
|
text 4.3 to 4.5:1; now 4.7:1 or more on the page and on a Card. */
|
|
@@ -53,7 +58,9 @@
|
|
|
53
58
|
--destructive: var(--error);
|
|
54
59
|
--border: oklch(0.912 0.016 293.7);
|
|
55
60
|
--input: oklch(0.912 0.016 293.7);
|
|
56
|
-
|
|
61
|
+
/* The focus indicator (WCAG 1.4.11, 3:1): 3.40:1 on --background, 3.69:1 on
|
|
62
|
+
--card, 3.23:1 on --muted. */
|
|
63
|
+
--ring: oklch(0.62 0.04 291);
|
|
57
64
|
--chart-1: oklch(0.646 0.222 41.116);
|
|
58
65
|
--chart-2: oklch(0.6 0.118 184.704);
|
|
59
66
|
--chart-3: oklch(0.398 0.07 227.392);
|
|
@@ -86,7 +93,7 @@
|
|
|
86
93
|
--sidebar-accent: oklch(0.955 0.012 292);
|
|
87
94
|
--sidebar-accent-foreground: oklch(0.227 0.017 290);
|
|
88
95
|
--sidebar-border: oklch(0.912 0.016 293.7);
|
|
89
|
-
--sidebar-ring: oklch(0.
|
|
96
|
+
--sidebar-ring: oklch(0.62 0.04 291);
|
|
90
97
|
}
|
|
91
98
|
|
|
92
99
|
.dark,
|
|
@@ -102,6 +109,9 @@
|
|
|
102
109
|
/* Mixed 60 % toward white (the tonal Button labels' recipe): readable as text
|
|
103
110
|
on --background and --card. */
|
|
104
111
|
--primary-text: color-mix(in oklab, var(--primary) 40%, white);
|
|
112
|
+
/* --primary itself is 2.5:1 on --background, 2.3:1 on --card and 2.1:1 on
|
|
113
|
+
--muted. Mixed 25 % toward white: 4.5:1, 4.1:1 and 3.7:1. */
|
|
114
|
+
--primary-indicator: color-mix(in oklab, var(--primary) 75%, white);
|
|
105
115
|
/* Brighter than the light one: it is read as text on the dark surfaces (6.3:1
|
|
106
116
|
on --background, 5.8:1 on --card; 4.6:1 on its own 15 % tonal tint over a
|
|
107
117
|
Card). A filled secondary surface mixes it toward --background (the opaque
|
|
@@ -120,8 +130,10 @@
|
|
|
120
130
|
--error: oklch(0.577 0.245 27.325);
|
|
121
131
|
--error-foreground: oklch(0.995 0.002 291.3);
|
|
122
132
|
/* --error stays the fill under near-white text; as text it would give only
|
|
123
|
-
3.9:1 on --background and 3.5:1 on --card. Lightened
|
|
124
|
-
|
|
133
|
+
3.9:1 on --background and 3.5:1 on --card. Lightened (76 % --error), 5.85
|
|
134
|
+
and 5.35:1, and 4.78:1 on a focused error menu item (bg-error/20 over the
|
|
135
|
+
popover; 4.45:1 at the former 80 %, which missed 4.5:1 once rendered). */
|
|
136
|
+
--error-text: color-mix(in oklab, var(--error) 76%, white);
|
|
125
137
|
/* The light brights: on the dark surfaces they read as text and as the
|
|
126
138
|
badge's 60% tint, which keeps its contrast under near-white text (success
|
|
127
139
|
7.1:1, info 5.6:1, error 9.1:1). */
|
|
@@ -137,6 +149,7 @@
|
|
|
137
149
|
--destructive: oklch(0.704 0.191 22.216);
|
|
138
150
|
--border: oklch(0.301 0.025 291.4);
|
|
139
151
|
--input: oklch(0.34 0.027 291.4);
|
|
152
|
+
/* 3.78:1 on --background, 3.45:1 on --card, 3.09:1 on --muted. */
|
|
140
153
|
--ring: oklch(0.551 0.03 290);
|
|
141
154
|
--chart-1: oklch(0.488 0.243 264.376);
|
|
142
155
|
--chart-2: oklch(0.696 0.17 162.48);
|
|
@@ -49,8 +49,8 @@
|
|
|
49
49
|
pointer-events: none;
|
|
50
50
|
}
|
|
51
51
|
[data-slot="period-card"][data-state="current"] {
|
|
52
|
-
--card-bar: var(--primary);
|
|
53
|
-
border-color: var(--primary);
|
|
52
|
+
--card-bar: var(--primary-indicator);
|
|
53
|
+
border-color: var(--primary-indicator);
|
|
54
54
|
background: color-mix(in oklab, var(--primary) 7%, var(--card));
|
|
55
55
|
}
|
|
56
56
|
[data-slot="period-card"][data-state="past"] {
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
/* Entry animations (`drawOn` and `appear` of @nxgt/material/draw/animate).
|
|
2
|
+
* A node carries `nxgt-draw-on` or `nxgt-draw-appear`, a delay step
|
|
3
|
+
* `nxgt-draw-d-<0..19>` and a duration `nxgt-draw-t-<s|m|l>`: never an inline
|
|
4
|
+
* style. The delay is the step times `--nxgt-draw-stagger` (60ms), set on the
|
|
5
|
+
* drawing or an ancestor to speed it up or slow it down. The animations fill
|
|
6
|
+
* both ways, so a replay (`useDrawingControls`) can find them and the last
|
|
7
|
+
* frame is the drawing itself: a stroke is traced with a dash as long as its
|
|
8
|
+
* path (`pathLength` 1), a fill fades in, a node fades and grows in. */
|
|
9
|
+
.nxgt-draw-t-s {
|
|
10
|
+
--nxgt-draw-dur: 300ms;
|
|
11
|
+
}
|
|
12
|
+
.nxgt-draw-t-m {
|
|
13
|
+
--nxgt-draw-dur: 600ms;
|
|
14
|
+
}
|
|
15
|
+
.nxgt-draw-t-l {
|
|
16
|
+
--nxgt-draw-dur: 1000ms;
|
|
17
|
+
}
|
|
18
|
+
.nxgt-draw-d-0 {
|
|
19
|
+
--nxgt-draw-i: 0;
|
|
20
|
+
}
|
|
21
|
+
.nxgt-draw-d-1 {
|
|
22
|
+
--nxgt-draw-i: 1;
|
|
23
|
+
}
|
|
24
|
+
.nxgt-draw-d-2 {
|
|
25
|
+
--nxgt-draw-i: 2;
|
|
26
|
+
}
|
|
27
|
+
.nxgt-draw-d-3 {
|
|
28
|
+
--nxgt-draw-i: 3;
|
|
29
|
+
}
|
|
30
|
+
.nxgt-draw-d-4 {
|
|
31
|
+
--nxgt-draw-i: 4;
|
|
32
|
+
}
|
|
33
|
+
.nxgt-draw-d-5 {
|
|
34
|
+
--nxgt-draw-i: 5;
|
|
35
|
+
}
|
|
36
|
+
.nxgt-draw-d-6 {
|
|
37
|
+
--nxgt-draw-i: 6;
|
|
38
|
+
}
|
|
39
|
+
.nxgt-draw-d-7 {
|
|
40
|
+
--nxgt-draw-i: 7;
|
|
41
|
+
}
|
|
42
|
+
.nxgt-draw-d-8 {
|
|
43
|
+
--nxgt-draw-i: 8;
|
|
44
|
+
}
|
|
45
|
+
.nxgt-draw-d-9 {
|
|
46
|
+
--nxgt-draw-i: 9;
|
|
47
|
+
}
|
|
48
|
+
.nxgt-draw-d-10 {
|
|
49
|
+
--nxgt-draw-i: 10;
|
|
50
|
+
}
|
|
51
|
+
.nxgt-draw-d-11 {
|
|
52
|
+
--nxgt-draw-i: 11;
|
|
53
|
+
}
|
|
54
|
+
.nxgt-draw-d-12 {
|
|
55
|
+
--nxgt-draw-i: 12;
|
|
56
|
+
}
|
|
57
|
+
.nxgt-draw-d-13 {
|
|
58
|
+
--nxgt-draw-i: 13;
|
|
59
|
+
}
|
|
60
|
+
.nxgt-draw-d-14 {
|
|
61
|
+
--nxgt-draw-i: 14;
|
|
62
|
+
}
|
|
63
|
+
.nxgt-draw-d-15 {
|
|
64
|
+
--nxgt-draw-i: 15;
|
|
65
|
+
}
|
|
66
|
+
.nxgt-draw-d-16 {
|
|
67
|
+
--nxgt-draw-i: 16;
|
|
68
|
+
}
|
|
69
|
+
.nxgt-draw-d-17 {
|
|
70
|
+
--nxgt-draw-i: 17;
|
|
71
|
+
}
|
|
72
|
+
.nxgt-draw-d-18 {
|
|
73
|
+
--nxgt-draw-i: 18;
|
|
74
|
+
}
|
|
75
|
+
.nxgt-draw-d-19 {
|
|
76
|
+
--nxgt-draw-i: 19;
|
|
77
|
+
}
|
|
78
|
+
.nxgt-draw-on,
|
|
79
|
+
.nxgt-draw-appear {
|
|
80
|
+
animation-duration: var(--nxgt-draw-dur, 600ms);
|
|
81
|
+
animation-delay: calc(var(--nxgt-draw-i, 0) * var(--nxgt-draw-stagger, 60ms));
|
|
82
|
+
animation-timing-function: cubic-bezier(0.2, 0, 0, 1);
|
|
83
|
+
animation-fill-mode: both;
|
|
84
|
+
}
|
|
85
|
+
.nxgt-draw-on {
|
|
86
|
+
animation-name: nxgt-draw-trace, nxgt-draw-fill;
|
|
87
|
+
}
|
|
88
|
+
.nxgt-draw-appear {
|
|
89
|
+
animation-name: nxgt-draw-fade, nxgt-draw-grow;
|
|
90
|
+
transform-box: fill-box;
|
|
91
|
+
transform-origin: center;
|
|
92
|
+
}
|
|
93
|
+
@keyframes nxgt-draw-trace {
|
|
94
|
+
from {
|
|
95
|
+
stroke-dasharray: 1;
|
|
96
|
+
stroke-dashoffset: 1;
|
|
97
|
+
}
|
|
98
|
+
to {
|
|
99
|
+
stroke-dasharray: 1;
|
|
100
|
+
stroke-dashoffset: 0;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
@keyframes nxgt-draw-fill {
|
|
104
|
+
from {
|
|
105
|
+
fill-opacity: 0;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
@keyframes nxgt-draw-fade {
|
|
109
|
+
from {
|
|
110
|
+
opacity: 0;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
@keyframes nxgt-draw-grow {
|
|
114
|
+
from {
|
|
115
|
+
scale: 0.92;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
@media (prefers-reduced-motion: reduce) {
|
|
119
|
+
.nxgt-draw-on,
|
|
120
|
+
.nxgt-draw-appear {
|
|
121
|
+
animation: none;
|
|
122
|
+
}
|
|
123
|
+
}
|