@umriss-ui/charts 0.3.0-rc.0 → 0.3.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 CHANGED
@@ -21,10 +21,57 @@ specs; the document itself came into being only with
21
21
  `library-audit` 08. They are grouped by unit of delivery, not by commit, and were
22
22
  never published.
23
23
 
24
- **Release candidates.** `0.3.0-rc.0` is the first version for the registry, under
25
- the tag `next` rather than `latest`: `pnpm add @umriss-ui/charts@next`. A release
26
- candidate promises nothing a `0.x` does not already fail to promise; it says the
27
- interface is still expected to move before `0.3.0`.
24
+ **Release candidates.** `0.3.0-rc.0` and `0.3.0-rc.1` were the two versions on
25
+ the registry, under the tag `next`. With `0.3.0` that is over: the tag is gone
26
+ and `pnpm add @umriss-ui/charts` is the whole install line. A release candidate
27
+ promised nothing a `0.x` does not already fail to promise; it said the
28
+ interface was still expected to move before `0.3.0`.
29
+
30
+ ---
31
+
32
+ ## 0.3.0 – Arithmetic with a second consumer (Sep. 2026)
33
+
34
+ From `.scratch/schedule/spec.md` (ADR-0022): `@umriss-ui/schedule` takes its
35
+ time arithmetic from here, so what it uses is public now.
36
+
37
+ ### Added
38
+
39
+ - **`resolveColours(root, colours)`** — any CSS colours, tokens and
40
+ `light-dark()` included, resolved to values a canvas can draw in the scheme
41
+ that applies at `root`. **`subscribeTheme(notify)`** tells a canvas when to
42
+ resolve again.
43
+ - **`toOperatingTimeClamped`** — wall clock to operating time without `NaN`: a
44
+ time in removed time lands on its seam.
45
+
46
+ ### No longer a release candidate
47
+
48
+ The tag `next` is gone: `0.3.0` publishes to `latest`, and
49
+ `pnpm add @umriss-ui/charts` is the whole install line. Nothing in the package
50
+ changed for that — the candidates 0.3.0-rc.0 and 0.3.0-rc.1 are what this is,
51
+ with the arithmetic above added for `@umriss-ui/schedule`, which now stands on
52
+ it in a released version of its own.
53
+
54
+ ---
55
+
56
+ ## 0.3.0-rc.1 – Styles that load themselves, and touch nothing else (Sep. 2026)
57
+
58
+ Delivery report for `.scratch/styles-without-side-effects/spec.md`, the charts'
59
+ share (ADR-0021).
60
+
61
+ ### Changed
62
+
63
+ - **No stylesheet import any more.** `dist/charts.js` imports its own
64
+ stylesheet; `@umriss-ui/charts/styles.css` stays exported and is optional.
65
+ - **The classes are `uc-*`.** Every `kc-*` class of the DOM - `.kc-root`,
66
+ `.kc-plot`, `.kc-axis`, `.kc-tooltip` and the rest - is `uc-*`. A selector an
67
+ application wrote against them changes its prefix.
68
+ - **Cascade layer.** The rules lie in `umriss.components` and select only the
69
+ chart's own elements.
70
+ - **Light and dark follow `color-scheme`.** Canvas colours are resolved through
71
+ the browser, so a `light-dark()` token draws in the scheme that applies. The
72
+ resolved theme is read anew when an attribute of `<html>` changes (a
73
+ `style="color-scheme: …"`, a class) or the system preference does;
74
+ `invalidateTheme()` stays for a switch on another ancestor.
28
75
 
29
76
  ---
30
77
 
@@ -69,7 +116,7 @@ case table and that test therefore moved in a single commit; a divergence stays
69
116
  red test and not a report from the field.
70
117
 
71
118
  `--uc-color-alarm` is unchanged. What moved beside the model is
72
- `.kc-limit-label[data-severity="warnung"]`, which now reads `"warning"` — the
119
+ `.uc-limit-label[data-severity="warnung"]`, which now reads `"warning"` — the
73
120
  same word `tone` has carried all along.
74
121
 
75
122
  ## 0.3.0-rc.0 – Where the library contradicted itself (Sep. 2026)
@@ -104,10 +151,10 @@ on first mounting as before in JSX order, after that a returning series gets its
104
151
  colour back. A series without a `name` still takes the colour of its position and
105
152
  warns in DEV when that shifts. Drawing happens unchanged in registration order.
106
153
 
107
- **`role="img"` and `aria-label` stand at the plot area** (`.kc-plot`), no longer
154
+ **`role="img"` and `aria-label` stand at the plot area** (`.uc-plot`), no longer
108
155
  at the root. The root contains the legend, and the descendants of an image are
109
156
  presentation to a screen reader — the legend was unreachable. Whoever looked for
110
- the role at `.kc-root` finds it one level deeper.
157
+ the role at `.uc-root` finds it one level deeper.
111
158
 
112
159
  ### New
113
160
 
package/README.md CHANGED
@@ -13,26 +13,17 @@ lint rule over `packages/charts/src/**` holds that fast.
13
13
  ## Install
14
14
 
15
15
  ```bash
16
- pnpm add @umriss-ui/charts@next
16
+ pnpm add @umriss-ui/charts
17
17
  ```
18
18
 
19
- The package is a **release candidate**, published under the tag `next`. As long
20
- as no released version exists, npm points `latest` at the candidate too — a plain
21
- `pnpm add @umriss-ui/charts` installs it as well.
22
-
23
19
  React 18 or 19 as a peer, and nothing else. `@umriss-ui/core` is **not** a
24
20
  dependency and not a peer dependency — if an application uses both packages, it
25
21
  does so because it chose to, not because this one required it (ADR-0020).
26
22
 
27
- No fonts are shipped either. The charts use Geist when the application loads it
28
- (`@fontsource/geist-sans`, `@fontsource/geist-mono`) and the system fonts
29
- otherwise.
30
-
31
23
  ## The smallest chart that runs
32
24
 
33
25
  ```tsx
34
26
  import { Chart, Line, XAxis, YAxis, Tooltip } from "@umriss-ui/charts";
35
- import "@umriss-ui/charts/styles.css";
36
27
 
37
28
  interface Point {
38
29
  t: number;
@@ -61,15 +52,22 @@ export function Course() {
61
52
  A series is an element, not an entry in a configuration object: the order in the
62
53
  JSX decides what lies over what, and at the same time the palette colour.
63
54
 
64
- ## The stylesheet
65
-
66
- ```ts
67
- import "@umriss-ui/charts/styles.css";
68
- ```
69
-
70
- The axes, ticks, legend and tooltip are DOM and take their values from the
71
- stylesheet; only the series themselves are drawn on canvas. The JavaScript loads
72
- no CSS of its own, so the application imports the stylesheet itself.
55
+ ## Styles
56
+
57
+ Nothing to import. `dist/charts.js` loads its own stylesheet; the axes, ticks,
58
+ legend and tooltip are DOM and take their values from it, and only the series
59
+ are drawn on canvas. The stylesheet touches nothing but the chart's own `uc-`
60
+ elements and lies in the layer `umriss.components`, so an application's CSS
61
+ wins. `@umriss-ui/charts/styles.css` stays exported for setups that link
62
+ stylesheets by hand.
63
+
64
+ **Colours** come from `--uc-*` variables that fall back to the tokens of
65
+ `@umriss-ui/core` where they exist and to literals where they do not. **Light and
66
+ dark** follow the application's `color-scheme`: the canvas colours are resolved
67
+ anew when the root element's attributes or the system preference change;
68
+ `invalidateTheme()` covers a switch made on another ancestor. **Fonts** are not
69
+ loaded: Geist when the application has it, the system fonts otherwise.
70
+ **Browsers:** Chrome 123, Firefox 120, Safari 17.5 or newer.
73
71
 
74
72
  ## What it can do
75
73
 
package/dist/charts.css CHANGED
@@ -1 +1 @@
1
- .kc-root{--uc-color-axis: var(--u-edge-color-strong, rgba(23, 23, 23, .17));--uc-color-grid: var(--u-hairline, rgba(23, 23, 23, .06));--uc-color-text: var(--u-color-text-muted, #71717a);--uc-color-bg: var(--u-color-surface, #ffffff);--uc-font: var( --u-font-sans, "Geist Sans", "Geist", -apple-system, "Segoe UI", system-ui, sans-serif );--uc-font-mono: var( --u-font-mono, "Geist Mono", ui-monospace, "Cascadia Mono", "Consolas", monospace );--uc-color-warning: var(--u-color-warning, #8a5c00);--uc-color-alarm: var(--u-color-danger, #b13636);--uc-color-ok: var(--u-color-success, #217a4b);--uc-series-1: var(--u-chart-1, #2563eb);--uc-series-2: var(--u-chart-2, #db2777);--uc-series-3: var(--u-chart-3, #059669);--uc-series-4: var(--u-chart-4, #d97706);--uc-series-5: var(--u-chart-5, #7c3aed);--uc-series-6: var(--u-chart-6, #0891b2);--uc-size-tick: 11.5px;--uc-size-title: 12px;--uc-size-legend: 12.5px;--uc-radius: 6px;--uc-shadow: 0 1px 2px rgba(0, 0, 0, .06), 0 4px 12px rgba(0, 0, 0, .08);position:relative;display:flex;flex-direction:column;font-family:var(--uc-font);color:var(--uc-color-text);font-variant-numeric:tabular-nums;font-feature-settings:"tnum" 1}.kc-plot{position:relative;flex:1 1 auto;min-height:0;min-width:0}.kc-plot>canvas{position:absolute;top:0;right:0;bottom:0;left:0;display:block;pointer-events:none}.kc-axes{position:absolute;top:0;right:0;bottom:0;left:0;pointer-events:none}.kc-axis{position:absolute}.kc-axis-line{position:absolute;background:var(--uc-color-axis)}.kc-axis-y>.kc-axis-line{top:0;width:1px;height:100%}.kc-axis-left>.kc-axis-line{right:0}.kc-axis-right>.kc-axis-line{left:0}.kc-axis-x>.kc-axis-line{left:0;width:100%;height:1px}.kc-axis-bottom>.kc-axis-line{top:0}.kc-axis-top>.kc-axis-line{bottom:0}.kc-tick{position:absolute}.kc-axis-y>.kc-tick{left:0;right:0;height:1px}.kc-axis-x>.kc-tick{top:0;bottom:0;width:1px}.kc-tick-mark{position:absolute;background:var(--uc-color-axis)}.kc-axis-y>.kc-tick>.kc-tick-mark{top:0;width:5px;height:1px}.kc-axis-left>.kc-tick>.kc-tick-mark{right:0}.kc-axis-right>.kc-tick>.kc-tick-mark{left:0}.kc-axis-x>.kc-tick>.kc-tick-mark{left:0;width:1px;height:5px}.kc-axis-bottom>.kc-tick>.kc-tick-mark{top:0}.kc-axis-top>.kc-tick>.kc-tick-mark{bottom:0}.kc-tick-label{position:absolute;white-space:pre;font-size:var(--uc-size-tick);line-height:1.25;letter-spacing:.005em;color:var(--uc-color-text)}.kc-axis-y>.kc-tick>.kc-tick-label{top:50%;transform:translateY(-50%)}.kc-axis-left>.kc-tick>.kc-tick-label{text-align:right}.kc-axis-right>.kc-tick>.kc-tick-label{text-align:left}.kc-axis-title{position:absolute;white-space:pre;font-size:var(--uc-size-title);line-height:1.25;letter-spacing:.01em;color:var(--uc-color-text)}.kc-axis-x>.kc-axis-title{left:0;right:0;text-align:center}.kc-axis-bottom>.kc-axis-title{bottom:0}.kc-axis-top>.kc-axis-title{top:0}.kc-axis-y>.kc-axis-title{top:50%;writing-mode:vertical-rl}.kc-axis-left>.kc-axis-title{left:0;transform:translateY(-50%) rotate(180deg)}.kc-axis-right>.kc-axis-title{right:0;transform:translateY(-50%)}.kc-legend{display:flex;flex-wrap:wrap;gap:4px 14px;font-size:var(--uc-size-legend);line-height:1.35;color:var(--uc-color-text)}.kc-legend-top{order:-1;padding-bottom:8px}.kc-legend-bottom{order:1;padding-top:8px}.kc-legend-item{display:inline-flex;align-items:center;gap:6px;cursor:default}.kc-legend-chip{display:inline-block;width:10px;height:10px;border-radius:2px}.kc-tooltip{position:absolute;top:0;left:0;z-index:2;pointer-events:none;opacity:0;transition:opacity 80ms ease-out;min-width:96px;padding:7px 9px;border:1px solid var(--uc-color-axis);border-radius:var(--uc-radius);background:var(--uc-color-bg);box-shadow:var(--uc-shadow);font-size:12px;line-height:1.35;color:var(--uc-color-text)}.kc-tooltip-head{font-family:var(--uc-font-mono);font-size:11.5px;letter-spacing:.01em;padding-bottom:5px;margin-bottom:5px;border-bottom:1px solid var(--uc-color-grid)}.kc-tooltip-list{display:grid;grid-template-columns:auto 1fr auto;gap:3px 8px;align-items:center}.kc-tooltip-row{display:contents}.kc-tooltip-chip{width:8px;height:8px;border-radius:2px}.kc-tooltip-name{white-space:nowrap}.kc-tooltip-value{font-family:var(--uc-font-mono);text-align:right;white-space:nowrap}@media(prefers-reduced-motion:reduce){.kc-tooltip{transition:none}}.kc-measure{position:absolute;top:0;left:0;right:auto;bottom:auto;transform:none;visibility:hidden;pointer-events:none;white-space:pre;writing-mode:horizontal-tb}.kc-limit-label{position:absolute;font-size:var(--uc-size-tick);line-height:1.25;white-space:nowrap;font-variant-numeric:tabular-nums;background:var(--uc-color-bg);padding:0 2px}.kc-limit-label[data-severity=warning]{color:var(--uc-color-warning)}.kc-limit-label[data-severity=alarm]{color:var(--uc-color-alarm)}.kc-limit-label[data-role=control],.kc-limit-label[data-role=zone]{color:var(--uc-color-text)}.kc-axis-y .kc-limit-label{transform:translateY(-50%)}.kc-axis-left .kc-limit-label{right:9px}.kc-axis-right .kc-limit-label{left:9px}.kc-break{position:absolute;top:0;width:7px;height:9px;margin-left:-3.5px;color:var(--uc-color-text)}.kc-break:before,.kc-break:after{content:"";position:absolute;top:0;width:1px;height:9px;background:currentColor;opacity:.55;transform:skew(-20deg)}.kc-break:before{left:1px}.kc-break:after{left:4px}
1
+ @layer umriss.tokens,umriss.base,umriss.components;@layer umriss.components{.uc-root,.uc-root:before,.uc-root:after{box-sizing:border-box}.uc-plot,.uc-plot:before,.uc-plot:after{box-sizing:border-box}.uc-axes,.uc-axes:before,.uc-axes:after{box-sizing:border-box}.uc-axis,.uc-axis:before,.uc-axis:after{box-sizing:border-box}.uc-axis-line,.uc-axis-line:before,.uc-axis-line:after{box-sizing:border-box}.uc-axis-y,.uc-axis-y:before,.uc-axis-y:after{box-sizing:border-box}.uc-axis-left,.uc-axis-left:before,.uc-axis-left:after{box-sizing:border-box}.uc-axis-right,.uc-axis-right:before,.uc-axis-right:after{box-sizing:border-box}.uc-axis-x,.uc-axis-x:before,.uc-axis-x:after{box-sizing:border-box}.uc-axis-bottom,.uc-axis-bottom:before,.uc-axis-bottom:after{box-sizing:border-box}.uc-axis-top,.uc-axis-top:before,.uc-axis-top:after{box-sizing:border-box}.uc-tick,.uc-tick:before,.uc-tick:after{box-sizing:border-box}.uc-tick-mark,.uc-tick-mark:before,.uc-tick-mark:after{box-sizing:border-box}.uc-tick-label,.uc-tick-label:before,.uc-tick-label:after{box-sizing:border-box}.uc-axis-title,.uc-axis-title:before,.uc-axis-title:after{box-sizing:border-box}.uc-legend,.uc-legend:before,.uc-legend:after{box-sizing:border-box}.uc-legend-top,.uc-legend-top:before,.uc-legend-top:after{box-sizing:border-box}.uc-legend-bottom,.uc-legend-bottom:before,.uc-legend-bottom:after{box-sizing:border-box}.uc-legend-item,.uc-legend-item:before,.uc-legend-item:after{box-sizing:border-box}.uc-legend-chip,.uc-legend-chip:before,.uc-legend-chip:after{box-sizing:border-box}.uc-tooltip,.uc-tooltip:before,.uc-tooltip:after{box-sizing:border-box}.uc-tooltip-head,.uc-tooltip-head:before,.uc-tooltip-head:after{box-sizing:border-box}.uc-tooltip-list,.uc-tooltip-list:before,.uc-tooltip-list:after{box-sizing:border-box}.uc-tooltip-row,.uc-tooltip-row:before,.uc-tooltip-row:after{box-sizing:border-box}.uc-tooltip-chip,.uc-tooltip-chip:before,.uc-tooltip-chip:after{box-sizing:border-box}.uc-tooltip-name,.uc-tooltip-name:before,.uc-tooltip-name:after{box-sizing:border-box}.uc-tooltip-value,.uc-tooltip-value:before,.uc-tooltip-value:after{box-sizing:border-box}.uc-measure,.uc-measure:before,.uc-measure:after{box-sizing:border-box}.uc-limit-label,.uc-limit-label:before,.uc-limit-label:after{box-sizing:border-box}.uc-break,.uc-break:before,.uc-break:after{box-sizing:border-box}.uc-root{--uc-color-axis: var(--u-edge-color-strong, rgba(23, 23, 23, .17));--uc-color-grid: var(--u-hairline, rgba(23, 23, 23, .06));--uc-color-text: var(--u-color-text-muted, #71717a);--uc-color-bg: var(--u-color-surface, #ffffff);--uc-font: var( --u-font-sans, "Geist Sans", "Geist", -apple-system, "Segoe UI", system-ui, sans-serif );--uc-font-mono: var( --u-font-mono, "Geist Mono", ui-monospace, "Cascadia Mono", "Consolas", monospace );--uc-color-warning: var(--u-color-warning, #8a5c00);--uc-color-alarm: var(--u-color-danger, #b13636);--uc-color-ok: var(--u-color-success, #217a4b);--uc-series-1: var(--u-chart-1, #2563eb);--uc-series-2: var(--u-chart-2, #db2777);--uc-series-3: var(--u-chart-3, #059669);--uc-series-4: var(--u-chart-4, #d97706);--uc-series-5: var(--u-chart-5, #7c3aed);--uc-series-6: var(--u-chart-6, #0891b2);--uc-size-tick: 11.5px;--uc-size-title: 12px;--uc-size-legend: 12.5px;--uc-radius: 6px;--uc-shadow: 0 1px 2px rgba(0, 0, 0, .06), 0 4px 12px rgba(0, 0, 0, .08);position:relative;display:flex;flex-direction:column;font-family:var(--uc-font);color:var(--uc-color-text);font-variant-numeric:tabular-nums;font-feature-settings:"tnum" 1}.uc-plot{position:relative;flex:1 1 auto;min-height:0;min-width:0}.uc-plot>canvas{box-sizing:border-box}.uc-plot>canvas{position:absolute;top:0;right:0;bottom:0;left:0;display:block;pointer-events:none}.uc-axes{position:absolute;top:0;right:0;bottom:0;left:0;pointer-events:none}.uc-axis{position:absolute}.uc-axis-line{position:absolute;background:var(--uc-color-axis)}.uc-axis-y>.uc-axis-line{top:0;width:1px;height:100%}.uc-axis-left>.uc-axis-line{right:0}.uc-axis-right>.uc-axis-line{left:0}.uc-axis-x>.uc-axis-line{left:0;width:100%;height:1px}.uc-axis-bottom>.uc-axis-line{top:0}.uc-axis-top>.uc-axis-line{bottom:0}.uc-tick{position:absolute}.uc-axis-y>.uc-tick{left:0;right:0;height:1px}.uc-axis-x>.uc-tick{top:0;bottom:0;width:1px}.uc-tick-mark{position:absolute;background:var(--uc-color-axis)}.uc-axis-y>.uc-tick>.uc-tick-mark{top:0;width:5px;height:1px}.uc-axis-left>.uc-tick>.uc-tick-mark{right:0}.uc-axis-right>.uc-tick>.uc-tick-mark{left:0}.uc-axis-x>.uc-tick>.uc-tick-mark{left:0;width:1px;height:5px}.uc-axis-bottom>.uc-tick>.uc-tick-mark{top:0}.uc-axis-top>.uc-tick>.uc-tick-mark{bottom:0}.uc-tick-label{position:absolute;white-space:pre;font-size:var(--uc-size-tick);line-height:1.25;letter-spacing:.005em;color:var(--uc-color-text)}.uc-axis-y>.uc-tick>.uc-tick-label{top:50%;transform:translateY(-50%)}.uc-axis-left>.uc-tick>.uc-tick-label{text-align:right}.uc-axis-right>.uc-tick>.uc-tick-label{text-align:left}.uc-axis-title{position:absolute;white-space:pre;font-size:var(--uc-size-title);line-height:1.25;letter-spacing:.01em;color:var(--uc-color-text)}.uc-axis-x>.uc-axis-title{left:0;right:0;text-align:center}.uc-axis-bottom>.uc-axis-title{bottom:0}.uc-axis-top>.uc-axis-title{top:0}.uc-axis-y>.uc-axis-title{top:50%;writing-mode:vertical-rl}.uc-axis-left>.uc-axis-title{left:0;transform:translateY(-50%) rotate(180deg)}.uc-axis-right>.uc-axis-title{right:0;transform:translateY(-50%)}.uc-legend{display:flex;flex-wrap:wrap;gap:4px 14px;font-size:var(--uc-size-legend);line-height:1.35;color:var(--uc-color-text)}.uc-legend-top{order:-1;padding-bottom:8px}.uc-legend-bottom{order:1;padding-top:8px}.uc-legend-item{display:inline-flex;align-items:center;gap:6px;cursor:default}.uc-legend-chip{display:inline-block;width:10px;height:10px;border-radius:2px;corner-shape:squircle}.uc-tooltip{position:absolute;top:0;left:0;z-index:2;pointer-events:none;opacity:0;transition:opacity 80ms ease-out;min-width:96px;padding:7px 9px;border:1px solid var(--uc-color-axis);border-radius:var(--uc-radius);corner-shape:squircle;background:var(--uc-color-bg);box-shadow:var(--uc-shadow);font-size:12px;line-height:1.35;color:var(--uc-color-text)}.uc-tooltip-head{font-family:var(--uc-font-mono);font-size:11.5px;letter-spacing:.01em;padding-bottom:5px;margin-bottom:5px;border-bottom:1px solid var(--uc-color-grid)}.uc-tooltip-list{display:grid;grid-template-columns:auto 1fr auto;gap:3px 8px;align-items:center}.uc-tooltip-row{display:contents}.uc-tooltip-chip{width:8px;height:8px;border-radius:2px;corner-shape:squircle}.uc-tooltip-name{white-space:nowrap}.uc-tooltip-value{font-family:var(--uc-font-mono);text-align:right;white-space:nowrap}@media(prefers-reduced-motion:reduce){.uc-tooltip{transition:none}}.uc-measure{position:absolute;top:0;left:0;right:auto;bottom:auto;transform:none;visibility:hidden;pointer-events:none;white-space:pre;writing-mode:horizontal-tb}.uc-limit-label{position:absolute;font-size:var(--uc-size-tick);line-height:1.25;white-space:nowrap;font-variant-numeric:tabular-nums;background:var(--uc-color-bg);padding:0 2px}.uc-limit-label[data-severity=warning]{color:var(--uc-color-warning)}.uc-limit-label[data-severity=alarm]{color:var(--uc-color-alarm)}.uc-limit-label[data-role=control],.uc-limit-label[data-role=zone]{color:var(--uc-color-text)}.uc-axis-y .uc-limit-label{transform:translateY(-50%)}.uc-axis-left .uc-limit-label{right:9px}.uc-axis-right .uc-limit-label{left:9px}.uc-break{position:absolute;top:0;width:7px;height:9px;margin-left:-3.5px;color:var(--uc-color-text)}.uc-break:before,.uc-break:after{content:"";position:absolute;top:0;width:1px;height:9px;background:currentColor;opacity:.55;transform:skew(-20deg)}.uc-break:before{left:1px}.uc-break:after{left:4px}}