@vielzeug/codex 26.10.20 → 26.10.22

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/data/search.json CHANGED
@@ -999,20 +999,20 @@
999
999
  },
1000
1000
  {
1001
1001
  "category": "ui",
1002
- "description": "responsive svg charts with explicit updates: line, bar, area, scatter, pie, radar, sparkline",
1002
+ "description": "responsive svg charts with explicit updates: line, bar, area, scatter, pie, radar, heatmap, sparkline",
1003
1003
  "docs": {
1004
- "index": " \ntitle: 'prism: responsive svg data visualization'\ndescription: 'responsive svg charts with explicit updates: line, bar, area, scatter, pie, radar, sparkline'\npackage: prism\ncategory: ui\nkeywords: [chart, svg, visualization, responsive, line chart, bar chart, area chart, scatter chart, pie chart, radar chart, sparkline, accessibility, typescript]\nrelated: [refine, orbit]\nexports: [createlinechart, createbarchart, createpiechart, charthandle]\nenvironments: [browser]\n \n\n<! markdownlint disable md025 md033 md060 >\n\n<packagehero package=\"prism\" />\n\n## why prism?\n\nprism renders charts as svg in a host element and keeps application state outside the chart. you can replace chart data explicitly, respond to container resizing, and style the output with css custom properties.\n\n```ts\nimport { createlinechart } from '@vielzeug/prism';\n\nconst host = document.createelement('div');\nhost.style.csstext = 'width:640px;height:320px';\ndocument.body.append(host);\n\n// before: replace a hand drawn svg each time values change.\nfunction drawline(values: number[]) {\n const path = document.createelementns('http://www.w3.org/2000/svg', 'path');\n const svg = document.createelementns('http://www.w3.org/2000/svg', 'svg');\n const low = math.min(...values);\n const span = math.max(...values) low || 1;\n const points = values.map((value, index) => {\n const x = (index / math.max(1, values.length 1)) * 640;\n const y = 320 ((value low) / span) * 320;\n return `${index === 0 ? 'm' : 'l'}${x},${y}`;\n });\n svg.setattribute('viewbox', '0 0 640 320');\n path.setattribute('d', points.join(' '));\n path.setattribute('fill', 'none');\n path.setattribute('stroke', 'currentcolor');\n svg.append(path);\n host.replacechildren(svg);\n}\ndrawline([10, 25, 18]);\ndrawline([10, 25, 18, 32]);\n\n// after: keep the chart instance and replace its series data.\nconst chart = createlinechart(host, {\n a11y: { arialabel: 'revenue by month' },\n series: [{ data: [{ key: 1, value: 10 }, { key: 2, value: 25 }, { key: 3, value: 18 }], name: 'revenue' }],\n});\nchart.update([{\n data: [{ key: 1, value: 10 }, { key: 2, value: 25 }, { key: 3, value: 18 }, { key: 4, value: 32 }],\n name: 'revenue',\n}]);\nchart.dispose();\n```\n\n| feature | prism | hand written svg |\n| | | |\n| bundle size | <packageinfo package=\"prism\" type=\"size\" /> | no chart package |\n| zero dependencies | <ore icon name=\"x\" size=\"16\"></ore icon> (uses orbit) | <ore icon name=\"check\" size=\"16\"></ore icon> |\n| data updates | `charthandle.update()` replaces chart data | you implement the update path |\n| responsive sizing | `resizeobserver` recalculates the chart layout | you implement the resize behavior |\n| chart interactions | built in pointer and keyboard interactions on supported charts | you implement them |\n| svg accessibility | informative charts support an accessible name and keyboard focus | you implement the accessible behavior |\n\n<div class=\"decision callout\">\n\n**use prism when** you need chart factories, responsive svg output, and an explicit data update boundary without adopting a charting framework.\n\n**consider hand written svg when** you need a single specialized graphic and prefer to own its scales, resizing, labels, and interactions directly.\n\n</div>\n\n## installation\n\n::: code group\n\n```sh [pnpm]\npnpm add @vielzeug/prism\n```\n\n```sh [npm]\nnpm install @vielzeug/prism\n```\n\n```sh [yarn]\nyarn add @vielzeug/prism\n```\n\n:::\n\n## quick start\n\ncreate and size a host element before creating the chart. import `theme.css` once to load prism's default styles and css custom properties.\n\n```ts\nimport { createlinechart } from '@vielzeug/prism';\nimport '@vielzeug/prism/theme.css';\n\nconst host = document.createelement('div');\nhost.style.csstext = 'width:640px;height:320px';\ndocument.body.append(host);\n\nconst chart = createlinechart(host, {\n a11y: { arialabel: 'revenue by month' },\n series: [{\n data: [{ key: 1, value: 10 }, { key: 2, value: 25 }, { key: 3, value: 18 }],\n name: 'revenue',\n }],\n tooltip: true,\n});\n\nchart.update([{\n data: [{ key: 1, value: 10 }, { key: 2, value: 25 }, { key: 3, value: 18 }, { key: 4, value: 32 }],\n name: 'revenue',\n}]);\n\nchart.dispose();\n```\n\n## features\n\n<div class=\"features grid\">\n\n **`createlinechart()` / `createareachart()`**: plot continuous numeric or date keyed series\n **`createbarchart()`**: compare categories with grouped, stacked, or horizontal bars\n **`createscatterchart()`**: plot independent numeric `(x, y)` points\n **`createpiechart()`**: render pie, donut, or semi circle slices\n **`createradarchart()`**: compare series across fixed, labelled axes\n **`createsparkline()`**: render compact line, area, bar, or stacked values without axes\n **`charthandle.update(data)`**: replace chart data without handing state ownership to prism\n **`charthandle.dispose()` / `symbol.dispose`**: release the svg, observer, overlays, and chart owned animation\n **`charthandle.tap()`**: observe resize and disposal events\n **`settheme()` / `resettheme()`**: set supported palette, typography, axis, grid, and tooltip tokens globally or on one element\n **css custom properties**: style the chart palette, marks, axes, labels, tooltip, legend, and motion\n **resize observation**: recalculate svg layout when the host element changes size\n **accessible interaction**: labelled interactive charts expose keyboard navigation and polite value announcements; sparklines are pointer only without value announcements\n\n</div>\n\n## documentation\n\n<div class=\"doc links\">\n\n [usage guide](./usage.md)\n [api reference](./api.md)\n [examples](./examples.md)\n [migration guide](./migration.md)\n\n</div>\n\n## see also\n\n<div class=\"see also\">\n\n [refine](/refine/): web components and theme tokens for building controls and layouts around chart hosts\n [orbit](/orbit/): floating element positioning used internally by prism's built in tooltip\n\n</div>\n\n<! markdownlint enable md025 md033 md060 >\n",
1005
- "api": " \ntitle: 'prism: api reference'\ndescription: complete reference for prism chart factories, scales, themes, types, and errors.\n \n\n[[toc]]\n\n## api overview\n\nall chart factories, scale utilities, theme helpers, and error classes are synchronous. charts render into an html element and return a `charthandle`; they do not return a promise.\n\n| symbol | purpose | execution mode | common gotcha |\n| | | | |\n| `createlinechart()` | render one or more continuous line series | sync | `key` values must be numbers or dates |\n| `createareachart()` | render continuous series with filled areas | sync | fills use a gradient by default |\n| `createscatterchart()` | plot independent `(x, y)` points | sync | `key` is the x value; the y domain is fitted to data |\n| `createbarchart()` | render categorical bars | sync | negative values in stacked variants are clamped to zero |\n| `createpiechart()` | render pie, donut, or semi circle slices | sync | `variant` is fixed at creation; `update()` replaces slices |\n| `createradarchart()` | compare series across fixed axes | sync | requires at least three axes to draw |\n| `createsparkline()` | render a compact line, area, bar, or stack | sync | has no axes, legend, or keyboard navigation |\n| `linearscale()` | create a numeric scale | sync | `nice` defaults to `true`; set `nice: false` to preserve the domain |\n| `timescale()` | create a date scale | sync | `nice` defaults to `true` |\n| `bandscale()` | create an ordered categorical scale | sync | unknown categories map to `0` and warn in development |\n| `settheme()` | set prism css custom properties | sync | writes inline styles to `document.documentelement` by default |\n| `resettheme()` | remove theme overrides set by `settheme()` | sync | only clears the selected target |\n| `seriescolor()` | resolve a palette css value | sync | palette positions wrap after eight |\n| `prismerror` | base class for prism errors | sync | use `instanceof` to catch any prism error |\n| `prismrendererror` | report an invalid chart container or failed chart operation | sync | also thrown by `update()` after disposal |\n\n## package entry point\n\n| import | purpose |\n| | |\n| `@vielzeug/prism` | chart factories, scale and theme functions, error classes, and public types |\n| `@vielzeug/prism/theme.css` | default chart styles, css custom properties, dark mode values, and reduced motion rules |\n\n## chart factories\n\neach factory appends an svg to `container`. a chart with no measurable container size uses a temporary `600 × 300` svg size and emits a development warning; `resizeobserver` applies later size changes. unless `a11y` is informative, the svg is hidden from the accessibility tree.\n\n### `createlinechart()`\n\n```ts\nfunction createlinechart(\n container: htmlelement,\n config: linechartconfig,\n): charthandle<lineseriesconfig[]>;\n```\n\nrenders line series and returns a handle whose `update()` argument replaces the complete series array. axes render by default; the value axis has grid lines by default. pass `false` to `xaxis` or `yaxis` to suppress that axis.\n\nseries use linear interpolation by default, omit point markers by default, and use a point radius of 3 when markers are enabled. `yaxis` defaults to `'left'`; crosshair, tooltip, and legend are disabled unless configured.\n\n| parameter | type | description |\n| | | |\n| `container` | `htmlelement` | host that receives the chart svg and optional overlays |\n| `config` | `linechartconfig` | series, axes, interaction, accessibility, and motion settings |\n\n**returns:** `charthandle<lineseriesconfig[]>`.\n\n```ts\nimport { createlinechart } from '@vielzeug/prism';\n\nconst host = document.createelement('div');\nhost.style.csstext = 'width:640px;height:320px';\ndocument.body.append(host);\n\nconst chart = createlinechart(host, {\n a11y: { arialabel: 'revenue by month' },\n series: [{ data: [{ key: 1, value: 10 }, { key: 2, value: 15 }], name: 'revenue' }],\n});\nchart.update([{ data: [{ key: 1, value: 10 }, { key: 2, value: 15 }, { key: 3, value: 18 }], name: 'revenue' }]);\nchart.dispose();\n```\n\n### `createareachart()`\n\n```ts\nfunction createareachart(\n container: htmlelement,\n config: areachartconfig,\n): charthandle<areaseriesconfig[]>;\n```\n\nrenders continuous area series with a gradient fill by default. `update()` replaces the complete series array.\n\narea series use linear interpolation by default and show their top line unless `showline: false` is set. axes render by default, with grid lines on the value axis.\n\n| parameter | type | description |\n| | | |\n| `container` | `htmlelement` | host that receives the chart svg and optional overlays |\n| `config` | `areachartconfig` | series, axes, interaction, accessibility, and motion settings |\n\n**returns:** `charthandle<areaseriesconfig[]>`.\n\n```ts\nimport { createareachart } from '@vielzeug/prism';\n\nconst host = document.createelement('div');\nhost.style.csstext = 'width:640px;height:320px';\ndocument.body.append(host);\n\nconst chart = createareachart(host, {\n a11y: { arialabel: 'visitors over time' },\n series: [{ data: [{ key: 1, value: 10 }, { key: 2, value: 18 }], name: 'visitors' }],\n});\nchart.dispose();\n```\n\n### `createscatterchart()`\n\n```ts\nfunction createscatterchart(\n container: htmlelement,\n config: scatterchartconfig,\n): charthandle<scatterseriesconfig[]>;\n```\n\nplots each datum independently: `key` is the numeric or date x value and `value` is the y value. points are not joined. `update()` replaces the complete series array.\n\naxes render by default, with grid lines on the value axis. the value scale is fitted to the observed data rather than forced to include zero. tooltip, crosshair, and legend are disabled unless configured.\n\n| parameter | type | description |\n| | | |\n| `container` | `htmlelement` | host that receives the chart svg and optional overlays |\n| `config` | `scatterchartconfig` | independent points, axes, interaction, accessibility, and motion settings |\n\n**returns:** `charthandle<scatterseriesconfig[]>`.\n\n```ts\nimport { createscatterchart } from '@vielzeug/prism';\n\nconst host = document.createelement('div');\nhost.style.csstext = 'width:640px;height:320px';\ndocument.body.append(host);\n\nconst chart = createscatterchart(host, {\n a11y: { arialabel: 'height against weight' },\n series: [{ data: [{ key: 160, value: 55 }, { key: 175, value: 70 }], name: 'cohort a' }],\n tooltip: true,\n});\nchart.dispose();\n```\n\nscatter interaction reports the datum and series of the point nearest the pointer in two dimensions, without a `values` array. keyboard navigation visits points across series in x order. tooltip `titleformat` receives the x value and `valueformat` the y value. on mount, points grow from radius zero at their final positions; updates slide existing points and grow new ones.\n\n### `createbarchart()`\n\n```ts\nfunction createbarchart(\n container: htmlelement,\n config: barchartconfig,\n): charthandle<barseriesconfig[]>;\n```\n\nrenders grouped, stacked, grouped horizontal, or stacked horizontal categories. `update()` replaces the complete series array; the variant is fixed at creation. axes render by default, with grid lines on the value axis.\n\nthe default variant is `grouped`; tooltip and legend are disabled unless configured.\n\n| parameter | type | description |\n| | | |\n| `container` | `htmlelement` | host that receives the chart svg and optional overlays |\n| `config` | `barchartconfig` | series, layout variant, axes, interaction, accessibility, and motion settings |\n\n**returns:** `charthandle<barseriesconfig[]>`.\n\n```ts\nimport { createbarchart } from '@vielzeug/prism';\n\nconst host = document.createelement('div');\nhost.style.csstext = 'width:640px;height:320px';\ndocument.body.append(host);\n\nconst chart = createbarchart(host, {\n a11y: { arialabel: 'tasks by status' },\n series: [{ data: [{ key: 'open', value: 12 }, { key: 'done', value: 8 }], name: 'tasks' }],\n});\nchart.dispose();\n```\n\nfor stacked variants, negative values are treated as zero and produce a development warning.\n\n### `createpiechart()`\n\n```ts\nfunction createpiechart(\n container: htmlelement,\n config: piechartconfig,\n): charthandle<piesliceconfig[]>;\n```\n\nrenders pie, donut, or semi circle slices. the default variant is `pie`; `update()` replaces the slice array. the default inner radius is zero for pies and 55% of the outer radius for donut and semi variants. pie slices default to no padding or rounded corners; donut and semi slices default to 8px padding and corner radius.\n\n| parameter | type | description |\n| | | |\n| `container` | `htmlelement` | host that receives the chart svg and optional overlays |\n| `config` | `piechartconfig` | slices, shape, geometry, legend, tooltip, and interaction settings |\n\n**returns:** `charthandle<piesliceconfig[]>`.\n\n```ts\nimport { createpiechart } from '@vielzeug/prism';\n\nconst host = document.createelement('div');\nhost.style.csstext = 'width:320px;height:240px';\ndocument.body.append(host);\n\nconst chart = createpiechart(host, {\n a11y: { arialabel: 'orders by channel' },\n data: [{ label: 'direct', value: 72 }, { label: 'referral', value: 28 }],\n variant: 'donut',\n});\nchart.dispose();\n```\n\n### `createradarchart()`\n\n```ts\nfunction createradarchart(\n container: htmlelement,\n config: radarchartconfig,\n): charthandle<radarseriesconfig[]>;\n```\n\nrenders one shape per series across the configured axes. `update()` replaces series data but not axes or other configuration. fewer than three axes warn in development and draw no chart. tooltip and legend are disabled unless configured.\n\n| parameter | type | description |\n| | | |\n| `container` | `htmlelement` | host that receives the chart svg and optional overlays |\n| `config` | `radarchartconfig` | fixed axes, series, scale, grid, appearance, and interaction settings |\n\n**returns:** `charthandle<radarseriesconfig[]>`.\n\n```ts\nimport { createradarchart } from '@vielzeug/prism';\n\nconst host = document.createelement('div');\nhost.style.csstext = 'width:400px;height:320px';\ndocument.body.append(host);\n\nconst chart = createradarchart(host, {\n a11y: { arialabel: 'hero stats' },\n axes: [{ key: 'str', label: 'strength' }, { key: 'agi', label: 'agility' }, { key: 'end', label: 'endurance' }],\n domain: [0, 10],\n series: [{ data: [{ key: 'str', value: 8 }, { key: 'agi', value: 6 }, { key: 'end', value: 9 }], name: 'adam' }],\n});\nchart.dispose();\n```\n\nradar defaults are a solid fill, linear curves, visible points, a four level polygon grid with bands, no grid labels, and a first axis angle of zero degrees. grid labels render only when all axes share a domain.\n\n### `createsparkline()`\n\n```ts\nfunction createsparkline(\n container: htmlelement,\n config: sparklineconfig,\n): charthandle<number[] | stacksegment[]>;\n```\n\nrenders compact data without axes, chart margins, or a legend. `update()` replaces the number or stack segment array. the default variant is `line`; only line and area variants draw the endpoint marker by default.\n\n| parameter | type | description |\n| | | |\n| `container` | `htmlelement` | host that receives the chart svg |\n| `config` | `sparklineconfig` | values, variant, appearance, accessibility, and pointer callbacks |\n\n**returns:** `charthandle<number[] | stacksegment[]>`.\n\n```ts\nimport { createsparkline } from '@vielzeug/prism';\n\nconst host = document.createelement('div');\nhost.style.csstext = 'width:240px;height:48px';\ndocument.body.append(host);\n\nconst chart = createsparkline(host, { data: [2, 5, 3, 8], variant: 'area' });\nchart.update([2, 5, 3, 8, 13]);\nchart.dispose();\n```\n\n`stacksegment[]` is for `variant: 'stack'`. pointer callbacks are available for numeric line, area, and bar sparklines; sparklines do not support keyboard navigation.\n\n## scale factories\n\n### `linearscale()`\n\n```ts\nfunction linearscale(config: linearscaleconfig): scale<number>;\n```\n\nmaps a numeric domain to a numeric range. `nice` defaults to `true`; `clamp` defaults to `false` and applies to `map()`, not `invert()`.\n\n| parameter | type | default | description |\n| | | | |\n| `config.domain` | `[number, number]` | required | input extent |\n| `config.range` | `[number, number]` | required | output extent |\n| `config.clamp` | `boolean` | `false` | clamp mapped values to the range |\n| `config.nice` | `boolean` | `true` | expand the domain to rounded boundaries |\n\n**returns:** `scale<number>`, with `map`, `invert`, `ticks`, `domain`, and `range`.\n\n```ts\nimport { linearscale } from '@vielzeug/prism';\n\nconst scale = linearscale({ domain: [0, 100], range: [0, 500] });\nscale.map(50); // 250\n```\n\n### `timescale()`\n\n```ts\nfunction timescale(config: timescaleconfig): scale<date>;\n```\n\nmaps date values to a numeric range. `nice` defaults to `true` and rounds the domain to a time interval.\n\n| parameter | type | default | description |\n| | | | |\n| `config.domain` | `[date, date]` | required | input date extent |\n| `config.range` | `[number, number]` | required | output extent |\n| `config.nice` | `boolean` | `true` | expand the domain to time interval boundaries |\n\n**returns:** `scale<date>`, with `map`, `invert`, `ticks`, `domain`, and `range`.\n\n```ts\nimport { timescale } from '@vielzeug/prism';\n\nconst scale = timescale({\n domain: [new date('2026 01 01'), new date('2026 12 31')],\n range: [0, 500],\n});\nscale.map(new date('2026 07 02'));\n```\n\n### `bandscale()`\n\n```ts\nfunction bandscale(config: bandscaleconfig): bandscale;\n```\n\nmaps ordered string categories to the start of each band. `padding` defaults to `0.1`; `paddingouter` defaults to the same value. mapping an unknown category returns `0` and warns in development.\n\n| parameter | type | default | description |\n| | | | |\n| `config.domain` | `string[]` | required | ordered categories |\n| `config.range` | `[number, number]` | required | output extent |\n| `config.padding` | `number` | `0.1` | inner gap as a ratio of bandwidth |\n| `config.paddingouter` | `number` | `padding` | outer gap as a ratio of bandwidth |\n\n**returns:** `bandscale`, with `map`, `ticks`, `bandwidth`, `gap`, `domain`, and `range`.\n\n```ts\nimport { bandscale } from '@vielzeug/prism';\n\nconst scale = bandscale({ domain: ['a', 'b'], range: [0, 200] });\nscale.bandwidth();\n```\n\n## theme utilities\n\n`theme.css` supplies the base css values and styles. `settheme()` writes inline custom properties, which take precedence over stylesheet declarations. for other visual controls, set css custom properties directly.\n\n### `settheme()`\n\n```ts\nfunction settheme(theme: prismtheme, options?: themescope): void;\n```\n\nsets the provided theme values on `options.scope`, or on `document.documentelement` when omitted. omitted scalar keys remain unchanged. providing `colors` replaces all eight palette slots, removing unused slots.\n\n| parameter | type | description |\n| | | |\n| `theme` | `prismtheme` | palette and supported axis, grid, text, font, and tooltip properties |\n| `options.scope` | `htmlelement` | element that scopes the inline custom properties |\n\n**returns:** `void`.\n\n```ts\nimport { settheme } from '@vielzeug/prism';\n\nconst host = document.createelement('div');\ndocument.body.append(host);\nsettheme({ colors: ['#2563eb', '#16a34a'], textcolor: '#111827' }, { scope: host });\n```\n\n### `resettheme()`\n\n```ts\nfunction resettheme(options?: themescope): void;\n```\n\nremoves every custom property managed by `settheme()` from the given scope or the document root. it does not remove css rules or change any other custom properties.\n\n| parameter | type | description |\n| | | |\n| `options` | `themescope` | optional target; defaults to `document.documentelement` |\n\n**returns:** `void`.\n\n```ts\nimport { resettheme, settheme } from '@vielzeug/prism';\n\nconst scope = document.createelement('div');\nsettheme({ textcolor: '#111827' }, { scope });\nresettheme({ scope });\n```\n\n### `seriescolor()`\n\n```ts\nfunction seriescolor(index: number, override?: string): string;\n```\n\nreturns `override` when it is provided; otherwise returns a `var( prism color n)` reference. the palette has eight positions and the index wraps around after the eighth.\n\n| parameter | type | description |\n| | | |\n| `index` | `number` | zero based palette position |\n| `override` | `string` | optional color returned instead of a css variable |\n\n**returns:** `string`.\n\n```ts\nimport { seriescolor } from '@vielzeug/prism';\n\nseriescolor(0); // 'var( prism color 1)'\nseriescolor(1, '#2563eb'); // '#2563eb'\n```\n\n## chart handle\n\n`charthandle<tdata>` is returned by every chart factory. `update()` synchronously rebuilds the chart from its new data; enabled motion may animate the resulting svg. `dispose()` is idempotent, removes the chart svg, observers, tooltip and legend, cancels chart owned animation, aborts `disposalsignal`, and emits one `dispose` tap event. `update()` after disposal throws `prismrendererror`.\n\n`tap()` observes `resize` and `dispose` events outside the render path. it returns an unsubscribe function; an optional abort signal removes the subscription. observer handler exceptions are swallowed so they cannot affect chart behavior. a tap added after disposal returns a no op unsubscribe function.\n\n`[symbol.dispose]()` delegates to `dispose()`, allowing explicit resource management where supported.\n\nall chart handles expose the same lifecycle members; interactive cartesian and pie/radar charts use a `.prism live` status region when no tooltip is enabled. a tooltip is itself a polite status region. sparklines have neither a tooltip nor a live value announcer.\n\n| method or property | contract |\n| | |\n| `el` | the chart's root `svgsvgelement` |\n| `update(data)` | replace chart data and render; throws `prismrendererror` after disposal |\n| `dispose()` | idempotently release chart owned dom, observation, and motion |\n| `disposed` | whether the handle has been disposed |\n| `disposalsignal` | `abortsignal` aborted during disposal |\n| `tap(handler, options?)` | observe resize/dispose events; returns an unsubscribe function |\n| `[symbol.dispose]()` | calls `dispose()` |\n\n`prismevent` reports a changed svg content size as `{ type: 'resize', width, height }`; the `dispose` event is emitted once before teardown completes.\n\n## types\n\nthe following are all types and interfaces exported from `@vielzeug/prism`. definitions mirror the package entry point contracts.\n\n### animation types\n\n```ts\nexport type easingfn = (t: number) => number;\nexport type easingname = 'back out' | 'ease in' | 'ease in out' | 'ease out' | 'expo out' | 'linear';\n\nexport interface transitionconfig {\n /** milliseconds per animated lane. defaults to 300 (420 for a line entrance, 400 for radar). */\n duration?: number;\n easing?: easingname | ((t: number) => number);\n /** `system` skips animation when reduced motion is preferred. */\n preference?: 'always' | 'never' | 'system';\n /** per bar delay on bar charts, per entering point delay (x order) on scatter charts, or per series delay on radar charts. bar and scatter charts cap the total added delay at about 400 ms. */\n stagger?: number;\n}\n\nexport type transitionoption = transitionconfig | boolean;\n```\n\n### theme types\n\n```ts\nexport interface prismtheme {\n axiscolor?: string;\n colors?: string[];\n fontfamily?: string;\n gridcolor?: string;\n gridopacity?: number;\n textcolor?: string;\n textcolorsecondary?: string;\n tooltipbg?: string;\n tooltipborder?: string;\n tooltipcolor?: string;\n}\n\nexport interface themescope {\n readonly scope?: htmlelement;\n}\n```\n\n`prismtheme.colors` writes up to eight palette slots. the scalar fields map as follows:\n\n| field | css custom property |\n| | |\n| `axiscolor` | ` prism axis color` |\n| `fontfamily` | ` prism font family` |\n| `gridcolor` | ` prism grid color` |\n| `gridopacity` | ` prism grid opacity` |\n| `textcolor` | ` prism text color` |\n| `textcolorsecondary` | ` prism text color secondary` |\n| `tooltipbg` | ` prism tooltip bg` |\n| `tooltipborder` | ` prism tooltip border` |\n| `tooltipcolor` | ` prism tooltip color` |\n\n### core and data types\n\n```ts\nexport interface chartmargin {\n bottom: number;\n left: number;\n right: number;\n top: number;\n}\n\nexport interface chartdimensions {\n height: number;\n margin: chartmargin;\n width: number;\n}\n\nexport type prismevent =\n | { readonly height: number; readonly type: 'resize'; readonly width: number }\n | { readonly type: 'dispose' };\n\nexport interface charthandle<tdata = unknown> {\n readonly disposalsignal: abortsignal;\n dispose(): void;\n readonly disposed: boolean;\n readonly el: svgsvgelement;\n tap(handler: (event: prismevent) => void, options?: { readonly signal?: abortsignal }): () => void;\n update(data: tdata): void;\n [symbol.dispose](): void;\n}\n\nexport type charta11y =\n | { readonly decorative: true }\n | { readonly arialabel: string; readonly decorative?: false };\n\nexport interface datum<tkey extends date | number | string = date | number | string> {\n dash?: string;\n key: tkey;\n meta?: record<string, unknown>;\n opacity?: number;\n value: number;\n}\n\nexport type continuousdatum = datum<date | number>;\n\nexport interface series<tdatum extends datum = datum> {\n color?: string;\n data: tdatum[];\n id?: string;\n name: string;\n}\n\nexport interface chartevent {\n datum: datum;\n originalevent: event;\n series: series;\n values?: seriesvalue[];\n}\n\nexport interface seriesvalue {\n datum: datum | undefined;\n series: series;\n}\n```\n\n`datum.dash` and `datum.opacity` affect rendered marks only on the chart types that support them. on bars, `dash` adds a 1px series color stroke so the dash is visible against the fill. `series.id` becomes a `data series id` attribute on a series group; characters outside `[a za z0 9_ ]` are replaced with ` `. when omitted, the id is based on the series index.\n\n| chart | `dash` | `opacity` |\n| | | |\n| bar | strokes that datum's bar | applies to that bar |\n| line | applies to the segment from this datum to the next | applies to that segment and its point marker |\n| area | applies to the top line segment from this datum to the next | applies to that segment |\n| scatter | ignored | applies to that point |\n| pie, radar, sparkline | ignored | ignored |\n\nfor line and area charts, the last datum has no following segment, so its `dash` value is ignored. the chart factories group adjacent segments with the same presentation values into path runs.\n\nfor line, area, and bar charts, `chartevent.values` lists each series at the active key in series order. its `datum` is `undefined` when that series has no matching key. `originalevent` is a pointer event or a keyboard event for keyboard activation. scatter events identify only the nearest independent point and omit `values`.\n\n### scale types\n\n```ts\nexport interface scale<t> {\n readonly domain: readonly [t, t];\n invert(pixel: number): t;\n map(value: t): number;\n readonly range: readonly [number, number];\n ticks(count?: number): t[];\n}\n\nexport interface bandscale {\n bandwidth(): number;\n readonly domain: readonly string[];\n gap(): number;\n map(value: string): number;\n readonly range: readonly [number, number];\n ticks(count?: number): string[];\n}\n\nexport interface linearscaleconfig {\n clamp?: boolean;\n domain: [number, number];\n nice?: boolean;\n range: [number, number];\n}\n\nexport interface timescaleconfig {\n domain: [date, date];\n nice?: boolean;\n range: [number, number];\n}\n\nexport interface bandscaleconfig {\n domain: string[];\n padding?: number;\n paddingouter?: number;\n range: [number, number];\n}\n```\n\n### axis and interaction types\n\n```ts\nexport type horizontalaxisposition = 'bottom' | 'top';\nexport type verticalaxisposition = 'left' | 'right';\nexport type axisposition = horizontalaxisposition | verticalaxisposition;\n\nexport interface gridconfig {\n color?: string;\n dash?: string;\n}\n\nexport interface axisconfig<tposition extends axisposition = axisposition> {\n grid?: gridconfig | boolean;\n label?: string;\n position?: tposition;\n tickcount?: number;\n tickformat?: (value: date | number | string) => string;\n tickvalues?: readonlyarray<date | number | string>;\n}\n\nexport type xaxisconfig = axisconfig<horizontalaxisposition>;\nexport type yaxisconfig = axisconfig<verticalaxisposition>;\n\nexport interface tooltipconfig {\n offset?: number;\n render?: (datum: datum, series: series) => node | string;\n titleformat?: (key: date | number | string) => string;\n valueformat?: (value: number, datum: datum, series: series) => string;\n}\n\nexport interface crosshairconfig {\n horizontal?: boolean;\n snap?: boolean;\n vertical?: boolean;\n}\n\nexport type legendposition = 'bottom' | 'left' | 'right' | 'top';\n\nexport interface legendconfig {\n position?: legendposition;\n}\n```\n\nthe crosshair defaults to a vertical line that snaps to the nearest datum; the horizontal line is hidden by default. with `snap: false`, only the guide follows the pointer—tooltip and callback data still refer to the nearest datum.\n\n`tickvalues` renders exactly the given ticks instead of scale generated ones, and gridlines follow the same list. values must match the axis's scale kind (numbers on a linear axis, `date`s on a time axis, category strings on a band axis); an off scale value warns in development. without it, ticks come from the scale as before.\n\nnumeric tick labels at a magnitude of 1e5 or above default to compact notation (`123k`, `1.23m`) so long numbers fit the default value axis margin; pass `tickformat: string` for raw labels. supplying a partial `yaxis` (or the value axis of a horizontal bar chart) merges over the default, so `{ tickformat }` alone keeps the default grid lines.\n\n`titleformat` and `valueformat` shape the default comparison tooltip on line, area, and bar charts—the title from the focused key and each row's value—and the same formatting is applied to the tooltip's spoken summary. `render` still replaces the whole tooltip body and takes precedence. tooltip strings are assigned as text, not parsed as html. for a radar chart, `tooltip.render` receives a datum whose `meta` contains the active axis, all series values, and the default announcement text.\n\n### chart configuration types\n\n```ts\nexport interface basechartconfig {\n a11y?: charta11y;\n legend?: legendconfig | boolean;\n margin?: partial<chartmargin>;\n onclick?: (event: chartevent) => void;\n onhover?: (event: chartevent | null) => void;\n tooltip?: tooltipconfig | boolean;\n transition?: transitionoption;\n xaxis?: xaxisconfig | false;\n yaxis?: yaxisconfig | false;\n}\n\nexport interface lineseriesconfig extends series<continuousdatum> {\n curve?: 'linear' | 'monotone' | 'step';\n pointradius?: number;\n showpoints?: boolean;\n strokewidth?: number;\n yaxis?: 'left' | 'right';\n}\n\nexport interface linechartconfig extends basechartconfig {\n crosshair?: crosshairconfig | boolean;\n rightyaxis?: omit<yaxisconfig, 'position' | 'grid'>;\n series: lineseriesconfig[];\n}\n\nexport interface areaseriesconfig extends series<continuousdatum> {\n curve?: 'linear' | 'monotone' | 'step';\n fill?: 'gradient' | 'solid';\n fillopacity?: number;\n showline?: boolean;\n}\n\nexport interface areachartconfig extends basechartconfig {\n crosshair?: crosshairconfig | boolean;\n series: areaseriesconfig[];\n}\n\nexport interface scatterseriesconfig extends series<continuousdatum> {\n pointradius?: number;\n}\n\nexport interface scatterchartconfig extends basechartconfig {\n crosshair?: crosshairconfig | boolean;\n series: scatterseriesconfig[];\n}\n\nexport interface barseriesconfig extends series {\n borderradius?: number;\n}\n\nexport type barvariant = 'grouped' | 'grouped horizontal' | 'stacked' | 'stacked horizontal';\n\nexport interface barchartconfig extends basechartconfig {\n series: barseriesconfig[];\n variant?: barvariant;\n}\n\nexport type pievariant = 'donut' | 'pie' | 'semi';\n\nexport interface piesliceconfig {\n color?: string;\n label?: string;\n value: number;\n}\n\nexport interface pieevent {\n index: number;\n originalevent: event;\n slice: piesliceconfig;\n}\n\nexport interface piechartconfig extends omit<basechartconfig, 'margin' | 'onclick' | 'onhover' | 'xaxis' | 'yaxis'> {\n cornerradius?: number;\n data: piesliceconfig[];\n innerradius?: number;\n onclick?: (event: pieevent) => void;\n onhover?: (event: pieevent | null) => void;\n padpixels?: number;\n variant?: pievariant;\n}\n\nexport interface radaraxisconfig {\n format?: (value: number) => string;\n key: string;\n label: string;\n max?: number;\n min?: number;\n}\n\nexport type radarseriesconfig = series<datum<string>>;\n\nexport interface radargridconfig {\n bands?: boolean;\n labels?: boolean;\n levels?: number;\n shape?: 'circle' | 'polygon';\n}\n\nexport interface radaraxisvalue {\n datum: datum<string> | undefined;\n series: radarseriesconfig;\n}\n\nexport interface radarevent {\n axis: radaraxisconfig;\n index: number;\n originalevent: event;\n values: radaraxisvalue[];\n}\n\nexport interface radarchartconfig extends omit<basechartconfig, 'margin' | 'onclick' | 'onhover' | 'xaxis' | 'yaxis'> {\n axes: radaraxisconfig[];\n curve?: 'linear' | 'rounded';\n domain?: [number, number];\n fill?: 'gradient' | 'none' | 'solid';\n grid?: radargridconfig | boolean;\n onclick?: (event: radarevent) => void;\n onhover?: (event: radarevent | null) => void;\n series: radarseriesconfig[];\n showpoints?: boolean;\n showvalues?: boolean;\n startangle?: number;\n}\n\nexport type sparklinevariant = 'area' | 'bar' | 'line' | 'stack';\n\nexport interface stacksegment {\n color?: string;\n label?: string;\n value: number;\n}\n\nexport interface sparklineevent {\n index: number;\n originalevent: event;\n value: number;\n}\n\nexport interface sparklineconfig {\n a11y?: charta11y;\n color?: string;\n cornerradius?: number;\n curve?: 'linear' | 'monotone' | 'step';\n data: number[] | stacksegment[];\n fillopacity?: number;\n onclick?: (event: sparklineevent) => void;\n onhover?: (event: sparklineevent | null) => void;\n padpixels?: number;\n showendpoint?: boolean;\n strokewidth?: number;\n transition?: transitionoption;\n variant?: sparklinevariant;\n}\n```\n\n## errors\n\n### `prismerror`\n\n```ts\nclass prismerror extends error {\n constructor(message: string, opts?: erroroptions);\n}\n```\n\nbase class for prism originated errors. its `name` is set to the concrete error class name, and it supports the standard `erroroptions` including `cause`.\n\n### `prismrendererror`\n\n```ts\nclass prismrendererror extends prismerror {}\n```\n\nthrown when a chart cannot be rendered because its container is not a dom element, when initial rendering fails (the original error is available as `cause`), or when `update()` is called after disposal. empty or malformed chart data may instead produce a development warning or an empty rendering, depending on the chart.\n",
1006
- "usage": " \ntitle: 'prism: usage guide'\ndescription: create responsive svg charts, update their data, handle interaction, and theme @vielzeug/prism.\n \n\n[[toc]]\n\n## basic usage\n\ncreate a host element with non zero dimensions, then pass it to a chart factory. this example creates the host in javascript so the snippet can run as written.\n\n```ts\nimport { createlinechart } from '@vielzeug/prism';\nimport '@vielzeug/prism/theme.css';\n\nconst container = document.createelement('div');\ncontainer.style.csstext = 'width:640px;height:320px';\ndocument.body.append(container);\n\nconst chart = createlinechart(container, {\n a11y: { arialabel: 'revenue by month' },\n series: [\n {\n name: 'revenue',\n data: [\n { key: 1, value: 10 },\n { key: 2, value: 16 },\n ],\n },\n ],\n tooltip: true,\n});\n\nchart.dispose();\n```\n\neach factory appends an svg to its container and returns a `charthandle`. prism observes the container with `resizeobserver`; if it has zero dimensions on creation, prism uses a temporary `600 × 300` size and warns in development. give the host its layout before creating the chart.\n\n## updating data\n\nkeep application state outside prism and pass the next complete data value to `update()`. the update method replaces chart data synchronously; the default transition may animate the resulting svg.\n\n```ts\nimport { createlinechart } from '@vielzeug/prism';\n\nconst container = document.createelement('div');\ncontainer.style.csstext = 'width:640px;height:320px';\ndocument.body.append(container);\n\nlet series = [{ data: [{ key: 1, value: 10 }], name: 'live' }];\nconst chart = createlinechart(container, { series });\n\nseries = [{ data: [{ key: 1, value: 10 }, { key: 2, value: 20 }], name: 'live' }];\nchart.update(series);\nchart.dispose();\n```\n\n`update()` accepts the type shown by that factory's handle: a complete series array for line, area, scatter, bar, and radar charts; a slice array for pie charts; and a number or stack segment array for sparklines. chart options such as axes, variant, callbacks, and accessibility are set at creation. for example, radar axes and a pie chart's variant do not change through `update()`.\n\n## line charts\n\nline and area series use number or `date` keys. all series in one chart must use the same key kind. use `curve` to choose interpolation, and enable markers with `showpoints`.\n\n```ts\nimport { createlinechart } from '@vielzeug/prism';\n\nconst container = document.createelement('div');\ncontainer.style.csstext = 'width:640px;height:320px';\ndocument.body.append(container);\n\nconst chart = createlinechart(container, {\n a11y: { arialabel: 'revenue and expenses' },\n series: [\n {\n curve: 'monotone',\n data: [{ key: 1, value: 100 }, { key: 2, value: 150 }, { key: 3, value: 130 }],\n name: 'revenue',\n showpoints: true,\n },\n {\n color: '#c2410c',\n data: [{ key: 1, value: 70 }, { key: 2, value: 95 }, { key: 3, value: 110 }],\n name: 'expenses',\n },\n ],\n tooltip: true,\n xaxis: { label: 'month' },\n yaxis: { grid: true, label: 'dollars' },\n});\n\nchart.dispose();\n```\n\n### independent value axes\n\nassign a line series to the right axis when it uses a different value range. both axes share the x scale; `rightyaxis` configures the second axis and cannot configure its position or grid.\n\n```ts\nimport { createlinechart } from '@vielzeug/prism';\n\nconst container = document.createelement('div');\ncontainer.style.csstext = 'width:640px;height:320px';\ndocument.body.append(container);\n\nconst chart = createlinechart(container, {\n a11y: { arialabel: 'health and damage by level' },\n rightyaxis: { label: 'damage' },\n series: [\n { data: [{ key: 1, value: 30 }, { key: 2, value: 20 }], name: 'health' },\n { data: [{ key: 1, value: 100 }, { key: 2, value: 300 }], name: 'damage', yaxis: 'right' },\n ],\n yaxis: { grid: true, label: 'health' },\n});\n\nchart.dispose();\n```\n\nwhen any series uses the right axis, the primary value axis is placed on the left. grid lines belong to the primary `yaxis`. the independent numeric scales mean that curve crossings do not imply equal values.\n\n### time based x axis\n\nuse `date` values for every key when plotting time. line and area charts use a time scale whose domain fits the data instead of rounding outward to tick boundaries.\n\n```ts\nimport { createlinechart } from '@vielzeug/prism';\n\nconst container = document.createelement('div');\ncontainer.style.csstext = 'width:640px;height:320px';\ndocument.body.append(container);\n\nconst formatter = new intl.datetimeformat(undefined, { month: 'short', day: 'numeric' });\nconst chart = createlinechart(container, {\n a11y: { arialabel: 'signups over time' },\n series: [{\n data: [\n { key: new date('2026 09 01'), value: 50 },\n { key: new date('2026 09 08'), value: 80 },\n { key: new date('2026 09 15'), value: 120 },\n ],\n name: 'signups',\n }],\n xaxis: { tickformat: (value) => value instanceof date ? formatter.format(value) : string(value) },\n});\n\nchart.dispose();\n```\n\n`tickformat` formats axis labels only. tooltip content and accessibility announcements use the underlying keys and values. to render an exact set of ticks instead of scale generated ones, pass `tickvalues`; gridlines follow the same list. values must match the axis's scale kind, and an off scale value warns in development:\n\n```ts\n// force a tick on the last month, which nice stepped ticks can skip.\nconst chart = createlinechart(container, {\n series: [{ data: [{ key: 0, value: 90 }, { key: 11, value: 128 }], name: 'costs' }],\n xaxis: { tickvalues: [0, 6, 11] },\n});\n```\n\nnumeric tick labels at a magnitude of `1e5` or above default to compact notation (`123k`, `1.23m`) so long numbers fit the default value axis margin; pass `tickformat: string` for raw labels. supplying a partial value axis config merges over its default, so `yaxis: { tickformat }` alone keeps the default grid lines.\n\n## bar charts\n\nbar chart keys are string categories. the default `grouped` variant puts series side by side; the horizontal variants put categories on the y axis and values on the x axis.\n\n```ts\nimport { createbarchart } from '@vielzeug/prism';\n\nconst container = document.createelement('div');\ncontainer.style.csstext = 'width:640px;height:320px';\ndocument.body.append(container);\n\nconst chart = createbarchart(container, {\n a11y: { arialabel: 'sales by quarter' },\n series: [{\n data: [{ key: 'q1', value: 200 }, { key: 'q2', value: 350 }, { key: 'q3', value: 280 }],\n name: 'sales',\n }],\n tooltip: true,\n});\n\nchart.dispose();\n```\n\nchoose `grouped`, `stacked`, `grouped horizontal`, or `stacked horizontal` in `variant`. negative values in a stacked chart are clamped to zero and produce a development warning. bars in stacked variants remain square; `borderradius` applies to grouped bars.\n\naxes render by default, with grid lines on the value axis. for horizontal variants, `xaxis` is the value axis and `yaxis` is the category axis. configure `grid` on the value axis.\n\n## area charts\n\narea series use a gradient fill by default. set `fill: 'solid'` for a flat fill, or set `fillopacity` to override the theme opacity for that series.\n\n```ts\nimport { createareachart } from '@vielzeug/prism';\n\nconst container = document.createelement('div');\ncontainer.style.csstext = 'width:640px;height:320px';\ndocument.body.append(container);\n\nconst chart = createareachart(container, {\n a11y: { arialabel: 'visitors over time' },\n crosshair: true,\n series: [{\n curve: 'monotone',\n data: [{ key: 1, value: 12 }, { key: 2, value: 18 }, { key: 3, value: 15 }],\n fill: 'solid',\n fillopacity: 0.2,\n name: 'visitors',\n showline: true,\n }],\n});\n\nchart.dispose();\n```\n\n## scatter charts\n\nscatter charts treat every datum as an independent point: `key` is the numeric or `date` x value and `value` is the y value. the scales fit the observed values rather than forcing the y domain to include zero. set `pointradius` on a series to change its marker size (default `3`).\n\n```ts\nimport { createscatterchart } from '@vielzeug/prism';\n\nconst container = document.createelement('div');\ncontainer.style.csstext = 'width:640px;height:320px';\ndocument.body.append(container);\n\nconst chart = createscatterchart(container, {\n a11y: { arialabel: 'height against weight' },\n series: [{\n data: [{ key: 160, value: 55 }, { key: 175, value: 70 }, { key: 190, value: 88 }],\n name: 'cohort a',\n pointradius: 5,\n }],\n tooltip: true,\n});\n\nchart.dispose();\n```\n\nscatter callbacks identify the nearest point in two dimensions and do not provide cross series `values`, because points do not share a category key. keyboard navigation visits every point across series in x order. with a tooltip, `titleformat` formats the x value and `valueformat` the y value, in both the visible row and the spoken summary.\n\n## forecast and emphasis styling\n\nadd `dash` or `opacity` to individual `datum` objects when one part of a series needs distinct styling. these fields do not change interaction, tooltip, or accessibility behavior.\n\n```ts\nimport { createlinechart } from '@vielzeug/prism';\n\nconst container = document.createelement('div');\ncontainer.style.csstext = 'width:640px;height:320px';\ndocument.body.append(container);\n\nconst values = [10, 13, 15, 18];\nconst chart = createlinechart(container, {\n series: [{\n data: values.map((value, index) => ({\n key: index + 1,\n value,\n ...(index >= 2 ? { dash: '5 5', opacity: 0.4 } : {}),\n })),\n name: 'forecast',\n showpoints: true,\n }],\n});\n\nchart.dispose();\n```\n\nfor line and area charts, each datum's `dash` styles the segment from that datum to the next; the final datum has no outgoing segment. line opacity also fades the datum's marker. area styling affects the top line, not the fill. bar opacity and dashes apply to the individual bar; scatter opacity applies to its point and scatter dashes are ignored. pie, radar, and sparkline ignore these two fields.\n\n## pie, donut, and semi charts\n\nuse `createpiechart()` for all three shapes. `variant` is fixed when the chart is created; `update()` replaces the slice data.\n\n```ts\nimport { createpiechart } from '@vielzeug/prism';\n\nconst container = document.createelement('div');\ncontainer.style.csstext = 'width:320px;height:240px';\ndocument.body.append(container);\n\nconst chart = createpiechart(container, {\n a11y: { arialabel: 'orders by channel' },\n data: [\n { label: 'direct', value: 42 },\n { label: 'organic', value: 28 },\n { label: 'referral', value: 18 },\n { label: 'social', value: 12 },\n ],\n legend: true,\n tooltip: true,\n variant: 'donut',\n});\n\nchart.dispose();\n```\n\nthe `pie` default has no inner radius. `donut` and `semi` default to an inner radius of 55% of the outer radius. `innerradius` overrides that size in pixels. slice labels are omitted when they do not fit; keep a tooltip or legend when small slices need identifying.\n\n## radar charts\n\ndefine at least three axes when creating a radar chart. series data uses string keys that match `radaraxisconfig.key`; `update()` replaces series but keeps axes and other configuration fixed.\n\n```ts\nimport { createradarchart } from '@vielzeug/prism';\n\nconst container = document.createelement('div');\ncontainer.style.csstext = 'width:400px;height:320px';\ndocument.body.append(container);\n\nconst axes = [\n { key: 'strength', label: 'strength' },\n { key: 'agility', label: 'agility' },\n { key: 'endurance', label: 'endurance' },\n];\nconst chart = createradarchart(container, {\n a11y: { arialabel: 'hero stats' },\n axes,\n domain: [0, 10],\n series: [{\n data: [{ key: 'strength', value: 8 }, { key: 'agility', value: 6 }, { key: 'endurance', value: 9 }],\n name: 'adam',\n }],\n tooltip: true,\n});\n\nchart.dispose();\n```\n\nthe default shared domain starts at zero and uses a nice maximum; set `domain` to compare series on a fixed range. per axis `min` and `max` override the chart domain for that axis. grid rings, bands, curves, fills, vertex dots, and values are configurable; see `radarchartconfig` and `radargridconfig` in the api reference.\n\n## sparklines\n\nsparklines omit axes, margins, and legends. choose `line`, `area`, or `bar` for numeric arrays, and `stack` for an array of `stacksegment` objects.\n\n```ts\nimport { createsparkline } from '@vielzeug/prism';\n\nconst container = document.createelement('div');\ncontainer.style.csstext = 'width:240px;height:48px';\ndocument.body.append(container);\n\nconst chart = createsparkline(container, {\n a11y: { arialabel: 'weekly orders' },\n data: [10, 14, 12, 18, 22],\n variant: 'area',\n});\n\nchart.update([10, 14, 12, 18, 22, 25]);\nchart.dispose();\n```\n\nfor a stacked sparkline, each segment can set `value`, `color`, and `label`. sparklines do not offer keyboard navigation, a tooltip, or a live value announcer. add a visible value or summary when the trend conveys important information.\n\n## interaction\n\nset `tooltip: true` to show prism's default tooltip, or pass a `tooltipconfig` to format its content. `titleformat` and `valueformat` shape the default comparison tooltip on line, area, and bar charts—the title from the focused key and each row's value—without rebuilding its markup, and the same formatting is applied to the tooltip's spoken summary. a `render` callback receives the active `datum` and `series` and replaces the whole body, taking precedence over the formatters. returned strings are inserted as text; return a dom `node` for structured content.\n\n```ts\nimport { createlinechart } from '@vielzeug/prism';\n\nconst container = document.createelement('div');\ncontainer.style.csstext = 'width:640px;height:320px';\ndocument.body.append(container);\n\nconst compact = new intl.numberformat(undefined, { notation: 'compact' });\nconst months = ['jan', 'feb', 'mar', 'apr', 'may', 'jun', 'jul', 'aug', 'sep', 'oct', 'nov', 'dec'];\n\nconst chart = createlinechart(container, {\n series: [{ data: [{ key: 11, value: 128000 }], name: 'ec2' }],\n tooltip: {\n titleformat: (key) => months[number(key)] ?? string(key),\n valueformat: (value) => compact.format(value),\n },\n});\n\nchart.dispose();\n```\n\n`onhover` receives an event while a point, category, slice, or radar axis is active, then `null` when the interaction clears. `onclick` receives the selected event. for line, area, and bar charts, `chartevent.values` contains each series' datum at that shared key; a missing datum is `undefined`. scatter events are `chartevent` objects without `values`; pie, radar, and sparkline use their chart specific event types.\n\n`crosshair` is available on line, area, and scatter charts. by default it shows a vertical guide and snaps the line to the nearest datum. set `horizontal: true` to add a horizontal guide or `vertical: false` to hide the vertical one. set `snap: false` to make the guide follow the pointer; tooltip and callback data still come from the nearest datum.\n\n### keyboard and announcements\n\nset `a11y: { arialabel }` on an informative chart. prism gives the svg `role=\"img\"`, an accessible name, and keyboard focus. arrow keys move among chart data; `home` and `end` move to the first and last item where supported; `enter` or `space` activates an item when an `onclick` callback is configured; `escape` clears the active selection. sparklines do not support keyboard navigation.\n\nwhen `a11y` is omitted, or set to `{ decorative: true }`, the svg is marked `aria hidden=\"true\"` and does not enter the keyboard tab order. only mark charts decorative when their information is available elsewhere. interactive cartesian and pie/radar charts use the tooltip as a polite live region when enabled; otherwise they announce active values in `.prism live`. sparklines have no live value announcements, so provide an equivalent visible value or summary.\n\n## animation\n\nchart motion is enabled by default, with a 300 ms duration per animated lane (radar uses 400 ms). pass `transition: false` to render updates synchronously, or pass `true` to state the default explicitly.\n\n```ts\nimport { createbarchart } from '@vielzeug/prism';\n\nconst container = document.createelement('div');\ncontainer.style.csstext = 'width:640px;height:320px';\ndocument.body.append(container);\n\nconst chart = createbarchart(container, {\n series: [{ data: [{ key: 'a', value: 4 }, { key: 'b', value: 7 }], name: 'count' }],\n transition: { duration: 500, easing: 'ease out', preference: 'system' },\n});\n\nchart.dispose();\n```\n\ncolumns grow together from their baseline by default over 300 ms. lines trace their final curve over 420 ms, uncovering point markers along the way without fading or shifting the series. line data updates retain the default 300 ms geometry transition; an explicit `duration` overrides both timings.\n\n`preference: 'system'` (the default) disables javascript motion when the user prefers reduced motion. use `'always'` to ignore that preference or `'never'` to disable motion. `stagger` sets an optional delay between bars, entering scatter points (in x order), or radar series; bar and scatter charts cap the effective delay so many marks do not add unbounded time. named easing values are `ease in`, `ease in out`, `ease out`, `back out`, `expo out`, and `linear`; you can also provide an easing function.\n\n## responsive layout and lifecycle\n\nsize the host with css. prism observes its content box and updates the svg dimensions and chart layout when it changes. bar, line, and scatter resize redraws apply immediately rather than animating between layout sizes; entrance animations and explicit data update transitions remain enabled. the legend is rendered as container chrome outside the svg and included in resize calculations.\n\ncall `dispose()` when the view no longer owns the chart. disposal is idempotent: it removes the svg, tooltip, legend, and resize observation, stops in flight chart motion, and aborts `disposalsignal`. `chart[symbol.dispose]()` calls the same cleanup method.\n\nuse `tap()` when external code needs resize or dispose notifications rather than observing the chart dom itself:\n\n```ts\nimport { createlinechart } from '@vielzeug/prism';\n\nconst container = document.createelement('div');\ncontainer.style.csstext = 'width:640px;height:320px';\ndocument.body.append(container);\n\nconst chart = createlinechart(container, {\n series: [{ data: [{ key: 1, value: 10 }], name: 'revenue' }],\n});\nconst stopobserving = chart.tap((event) => {\n if (event.type === 'resize') console.log(event.width, event.height);\n if (event.type === 'dispose') console.log('chart disposed');\n});\n\nstopobserving();\nchart.dispose();\n```\n\n`tap()` returns an unsubscribe function and accepts `{ signal }` for automatic unsubscription. a listener exception is swallowed by the observer so it cannot interrupt chart rendering.\n\n## theming\n\nimport the stylesheet once to load prism's structural styles, default tokens, dark mode rules, and reduced motion css. you can override any css custom property on an ancestor of the chart.\n\n```css\n.dashboard chart {\n prism color 1: #2563eb;\n prism color 2: #16a34a;\n prism grid color: #94a3b8;\n prism line width: 3;\n prism text color: #172033;\n prism tooltip bg: #111827;\n}\n```\n\n`settheme()` provides a typed subset of theme properties. a scoped call writes inline values on the provided element; omit `scope` to write them to `document.documentelement`. inline values override stylesheet tokens until reset.\n\n```ts\nimport { resettheme, settheme } from '@vielzeug/prism';\n\nconst container = document.createelement('div');\ncontainer.style.csstext = 'width:640px;height:320px';\ndocument.body.append(container);\n\nsettheme({ colors: ['#2563eb', '#16a34a'], fontfamily: 'inter, sans serif' }, { scope: container });\n// call resettheme({ scope: container }) when this scoped theme is no longer needed.\nresettheme({ scope: container });\n```\n\n### available tokens\n\nthe stylesheet defines defaults for the following token groups. pie label color and size are read with fallback values by the renderer but are not declared in the base token block. set a token on the chart container or an ancestor to scope an override.\n\n| group | css custom properties |\n| | |\n| palette and surfaces | ` prism color 1` through ` prism color 8`, ` prism bg`, ` prism border radius` |\n| axes and grid | ` prism axis color`, ` prism axis width`, ` prism grid color`, ` prism grid width`, ` prism grid dash`, ` prism grid opacity` |\n| text | ` prism font family`, ` prism font size`, ` prism font size label`, ` prism font size title`, ` prism font weight`, ` prism font weight title`, ` prism text color`, ` prism text color secondary` |\n| tooltip | ` prism tooltip bg`, ` prism tooltip color`, ` prism tooltip border`, ` prism tooltip radius`, ` prism tooltip padding`, ` prism tooltip shadow`, ` prism tooltip font size` |\n| crosshair | ` prism crosshair color`, ` prism crosshair width`, ` prism crosshair dash`, ` prism crosshair opacity` |\n| points | ` prism point radius`, ` prism point radius hover`, ` prism point stroke width`, ` prism point stroke` |\n| bars | ` prism bar radius`, ` prism bar hover opacity`, ` prism bar gap`, ` prism bar band fill`, ` prism bar band opacity`, ` prism bar dim opacity` |\n| areas and lines | ` prism area opacity`, ` prism area stroke width`, ` prism area gradient start`, ` prism area gradient end`, ` prism line width`, ` prism line width hover` |\n| interaction | ` prism dim opacity`, ` prism active point radius`, ` prism point ring`, ` prism focus color` |\n| sparklines | ` prism spark fill opacity`, ` prism spark gradient start`, ` prism spark gradient end` |\n| radar | ` prism radar grid color`, ` prism radar grid opacity`, ` prism radar band fill`, ` prism radar band opacity`, ` prism radar spoke color`, ` prism radar fill opacity`, ` prism radar stroke width`, ` prism radar point radius`, ` prism radar point radius active`, ` prism radar label color`, ` prism radar label size`, ` prism radar value color`, ` prism radar value size`, ` prism radar dim opacity` |\n| motion | ` prism duration fast`, ` prism duration`, ` prism duration slow`, ` prism ease`, ` prism ease spring`, ` prism transition`, ` prism transition fast` |\n| legend and pie labels | ` prism legend gap`, ` prism legend dot size`, ` prism legend font size`, ` prism pie label color`, ` prism pie label size` |\n\nthe default palette and structural colors adapt to `prefers color scheme: dark`, `html.dark`, or `[data prism theme='dark']` on an ancestor. scoped inline values set with `settheme()` take precedence in either mode. the stylesheet also provides `prefers reduced motion` overrides for css transitions.\n\n## errors and diagnostics\n\nprism throws `prismrendererror` when the container is not a dom element, when initial rendering fails, or when `update()` is called on a disposed chart. a wrapped initial render error exposes its cause. use `prismerror` to catch all prism originated errors.\n\nempty or malformed data is not always an exception. depending on the chart, prism may draw nothing or emit a development only `console.warn`; examples include an unknown `bandscale` category, negative values in stacked bars, and radar axes with fewer than three entries or duplicate keys. correct the input rather than relying on a warning for validation.\n\n## framework integration\n\nprism has no react, vue, or svelte adapter. in any framework, give prism a host element after it is mounted, call `update()` when data changes, and call `dispose()` before the host is removed. this plain dom pattern shows the ownership boundary without depending on a framework specific lifecycle api:\n\n```ts\nimport { createlinechart, type lineseriesconfig } from '@vielzeug/prism';\n\nfunction mountchart(host: htmlelement, series: lineseriesconfig[]) {\n const chart = createlinechart(host, { a11y: { arialabel: 'revenue' }, series });\n\n return {\n update(next: lineseriesconfig[]) {\n chart.update(next);\n },\n dispose() {\n chart.dispose();\n },\n };\n}\n\nconst host = document.createelement('div');\nhost.style.csstext = 'width:640px;height:320px';\ndocument.body.append(host);\nconst view = mountchart(host, [{ data: [{ key: 1, value: 10 }], name: 'revenue' }]);\nview.update([{ data: [{ key: 1, value: 10 }, { key: 2, value: 15 }], name: 'revenue' }]);\nview.dispose();\n```\n\nthe application owns its state and host; prism owns only the svg, observer, and optional overlay elements it creates.\n\n## working with other vielzeug libraries\n\nuse refine components for dashboard controls and keep prism in a sized host element. map refine theme tokens to prism css custom properties or call `settheme()` with a scoped element; prism does not require a refine adapter. prism uses orbit internally to place tooltips, so chart users do not need to create orbit floating elements for the built in tooltip.\n\n## best practices\n\n give the host a non zero size before creating a chart.\n set `a11y.arialabel` when a chart communicates information.\n use `date` or number keys consistently across each line or area chart.\n pass the complete new data value to `update()`.\n keep chart options fixed after creation; recreate the chart to change them.\n dispose the handle when its host leaves the owning view.\n use `transition: false` for deterministic synchronous rendering.\n prefer css custom properties for reusable theme overrides.\n",
1007
- "examples": " \ntitle: 'prism: examples'\ndescription: focused recipes for creating, updating, interacting with, and theming prism charts.\n \n\n [create a line chart](./examples/line chart.md)\n [plot a time series](./examples/time series.md)\n [plot a scatter chart](./examples/scatter chart.md)\n [compare categories with a bar chart](./examples/bar chart.md)\n [render compact charts](./examples/compact charts.md)\n [compare hero stats with a radar chart](./examples/radar chart.md)\n [update chart data](./examples/update data.md)\n [sync a details panel with hover](./examples/hover details.md)\n [render a custom tooltip](./examples/custom tooltip.md)\n [match charts to your design system](./examples/theming.md)\n"
1004
+ "index": " \ntitle: 'prism: responsive svg data visualization'\ndescription: 'responsive svg charts with explicit updates: line, bar, area, scatter, pie, radar, heatmap, sparkline'\npackage: prism\ncategory: ui\nkeywords: [chart, svg, visualization, responsive, line chart, bar chart, area chart, scatter chart, pie chart, radar chart, heatmap chart, sparkline, accessibility, typescript]\nrelated: [refine, orbit]\nexports: [createlinechart, createbarchart, createpiechart, charthandle]\nenvironments: [browser]\n \n\n<! markdownlint disable md025 md033 md060 >\n\n<packagehero package=\"prism\" />\n\n## why prism?\n\nprism renders charts as svg in a host element and keeps application state outside the chart. you can replace chart data explicitly, respond to container resizing, and style the output with css custom properties.\n\n```ts\nimport { createlinechart } from '@vielzeug/prism';\n\nconst host = document.createelement('div');\nhost.style.csstext = 'width:640px;height:320px';\ndocument.body.append(host);\n\n// before: replace a hand drawn svg each time values change.\nfunction drawline(values: number[]) {\n const path = document.createelementns('http://www.w3.org/2000/svg', 'path');\n const svg = document.createelementns('http://www.w3.org/2000/svg', 'svg');\n const low = math.min(...values);\n const span = math.max(...values) low || 1;\n const points = values.map((value, index) => {\n const x = (index / math.max(1, values.length 1)) * 640;\n const y = 320 ((value low) / span) * 320;\n return `${index === 0 ? 'm' : 'l'}${x},${y}`;\n });\n svg.setattribute('viewbox', '0 0 640 320');\n path.setattribute('d', points.join(' '));\n path.setattribute('fill', 'none');\n path.setattribute('stroke', 'currentcolor');\n svg.append(path);\n host.replacechildren(svg);\n}\ndrawline([10, 25, 18]);\ndrawline([10, 25, 18, 32]);\n\n// after: keep the chart instance and replace its series data.\nconst chart = createlinechart(host, {\n a11y: { arialabel: 'revenue by month' },\n series: [{ data: [{ key: 1, value: 10 }, { key: 2, value: 25 }, { key: 3, value: 18 }], name: 'revenue' }],\n});\nchart.update([{\n data: [{ key: 1, value: 10 }, { key: 2, value: 25 }, { key: 3, value: 18 }, { key: 4, value: 32 }],\n name: 'revenue',\n}]);\nchart.dispose();\n```\n\n| feature | prism | hand written svg |\n| | | |\n| bundle size | <packageinfo package=\"prism\" type=\"size\" /> | no chart package |\n| zero dependencies | <ore icon name=\"x\" size=\"16\"></ore icon> (uses orbit) | <ore icon name=\"check\" size=\"16\"></ore icon> |\n| data updates | `charthandle.update()` replaces chart data | you implement the update path |\n| responsive sizing | `resizeobserver` recalculates the chart layout | you implement the resize behavior |\n| chart interactions | built in pointer and keyboard interactions on supported charts | you implement them |\n| svg accessibility | informative charts support an accessible name and keyboard focus | you implement the accessible behavior |\n\n<div class=\"decision callout\">\n\n**use prism when** you need chart factories, responsive svg output, and an explicit data update boundary without adopting a charting framework.\n\n**consider hand written svg when** you need a single specialized graphic and prefer to own its scales, resizing, labels, and interactions directly.\n\n</div>\n\n## installation\n\n::: code group\n\n```sh [pnpm]\npnpm add @vielzeug/prism\n```\n\n```sh [npm]\nnpm install @vielzeug/prism\n```\n\n```sh [yarn]\nyarn add @vielzeug/prism\n```\n\n:::\n\n## quick start\n\ncreate and size a host element before creating the chart. import `theme.css` once to load prism's default styles and css custom properties.\n\n```ts\nimport { createlinechart } from '@vielzeug/prism';\nimport '@vielzeug/prism/theme.css';\n\nconst host = document.createelement('div');\nhost.style.csstext = 'width:640px;height:320px';\ndocument.body.append(host);\n\nconst chart = createlinechart(host, {\n a11y: { arialabel: 'revenue by month' },\n series: [{\n data: [{ key: 1, value: 10 }, { key: 2, value: 25 }, { key: 3, value: 18 }],\n name: 'revenue',\n }],\n tooltip: true,\n});\n\nchart.update([{\n data: [{ key: 1, value: 10 }, { key: 2, value: 25 }, { key: 3, value: 18 }, { key: 4, value: 32 }],\n name: 'revenue',\n}]);\n\nchart.dispose();\n```\n\n## features\n\n<div class=\"features grid\">\n\n **`createlinechart()` / `createareachart()`**: plot continuous numeric or date keyed series\n **`createbarchart()`**: compare categories with grouped, stacked, or horizontal bars\n **`createscatterchart()`**: plot independent numeric `(x, y)` points\n **`createpiechart()`**: render pie, donut, or semi circle slices\n **`createradarchart()`**: compare series across fixed, labelled axes\n **`createheatmapchart()`**: render a row/column matrix of colored cells with a continuous or binned ramp\n **`createsparkline()`**: render compact line, area, bar, or stacked values without axes\n **`charthandle.update(data)`**: replace chart data without handing state ownership to prism\n **`charthandle.dispose()` / `symbol.dispose`**: release the svg, observer, overlays, and chart owned animation\n **`charthandle.tap()`**: observe resize and disposal events\n **`settheme()` / `resettheme()`**: set supported palette, typography, axis, grid, and tooltip tokens globally or on one element\n **css custom properties**: style the chart palette, marks, axes, labels, tooltip, legend, and motion\n **resize observation**: recalculate svg layout when the host element changes size\n **accessible interaction**: labelled interactive charts expose keyboard navigation and polite value announcements; sparklines are pointer only without value announcements\n\n</div>\n\n## documentation\n\n<div class=\"doc links\">\n\n [usage guide](./usage.md)\n [api reference](./api.md)\n [examples](./examples.md)\n [migration guide](./migration.md)\n\n</div>\n\n## see also\n\n<div class=\"see also\">\n\n [refine](/refine/): web components and theme tokens for building controls and layouts around chart hosts\n [orbit](/orbit/): floating element positioning used internally by prism's built in tooltip\n\n</div>\n\n<! markdownlint enable md025 md033 md060 >\n",
1005
+ "api": " \ntitle: 'prism: api reference'\ndescription: complete reference for prism chart factories, scales, themes, types, and errors.\n \n\n[[toc]]\n\n## api overview\n\nall chart factories, scale utilities, theme helpers, and error classes are synchronous. charts render into an html element and return a `charthandle`; they do not return a promise.\n\n| symbol | purpose | execution mode | common gotcha |\n| | | | |\n| `createlinechart()` | render one or more continuous line series | sync | `key` values must be numbers or dates |\n| `createareachart()` | render continuous series with filled areas | sync | fills use a gradient by default |\n| `createscatterchart()` | plot independent `(x, y)` points | sync | `key` is the x value; the y domain is fitted to data |\n| `createbarchart()` | render categorical bars | sync | negative values in stacked variants are clamped to zero |\n| `createpiechart()` | render pie, donut, or semi circle slices | sync | `variant` is fixed at creation; `update()` replaces slices |\n| `createradarchart()` | compare series across fixed axes | sync | requires at least three axes to draw |\n| `createheatmapchart()` | render a row/column matrix of colored cells | sync | cells whose `row`/`column` match no label are skipped; unknown labels warn in development |\n| `createsparkline()` | render a compact line, area, bar, or stack | sync | has no axes, legend, or keyboard navigation |\n| `linearscale()` | create a numeric scale | sync | `nice` defaults to `true`; set `nice: false` to preserve the domain |\n| `timescale()` | create a date scale | sync | `nice` defaults to `true` |\n| `bandscale()` | create an ordered categorical scale | sync | unknown categories map to `0` and warn in development |\n| `settheme()` | set prism css custom properties | sync | writes inline styles to `document.documentelement` by default |\n| `resettheme()` | remove theme overrides set by `settheme()` | sync | only clears the selected target |\n| `seriescolor()` | resolve a palette css value | sync | palette positions wrap after eight |\n| `prismerror` | base class for prism errors | sync | use `instanceof` to catch any prism error |\n| `prismrendererror` | report an invalid chart container or failed chart operation | sync | also thrown by `update()` after disposal |\n\n## package entry point\n\n| import | purpose |\n| | |\n| `@vielzeug/prism` | chart factories, scale and theme functions, error classes, and public types |\n| `@vielzeug/prism/theme.css` | default chart styles, css custom properties, dark mode values, and reduced motion rules |\n\n## chart factories\n\neach factory appends an svg to `container`. a chart with no measurable container size uses a temporary `600 × 300` svg size and emits a development warning; `resizeobserver` applies later size changes. unless `a11y` is informative, the svg is hidden from the accessibility tree.\n\n### `createlinechart()`\n\n```ts\nfunction createlinechart(\n container: htmlelement,\n config: linechartconfig,\n): charthandle<lineseriesconfig[]>;\n```\n\nrenders line series and returns a handle whose `update()` argument replaces the complete series array. axes render by default; the value axis has grid lines by default. pass `false` to `xaxis` or `yaxis` to suppress that axis.\n\nseries use linear interpolation by default, omit point markers by default, and use a point radius of 3 when markers are enabled. `yaxis` defaults to `'left'`; crosshair, tooltip, and legend are disabled unless configured.\n\n| parameter | type | description |\n| | | |\n| `container` | `htmlelement` | host that receives the chart svg and optional overlays |\n| `config` | `linechartconfig` | series, axes, interaction, accessibility, and motion settings |\n\n**returns:** `charthandle<lineseriesconfig[]>`.\n\n```ts\nimport { createlinechart } from '@vielzeug/prism';\n\nconst host = document.createelement('div');\nhost.style.csstext = 'width:640px;height:320px';\ndocument.body.append(host);\n\nconst chart = createlinechart(host, {\n a11y: { arialabel: 'revenue by month' },\n series: [{ data: [{ key: 1, value: 10 }, { key: 2, value: 15 }], name: 'revenue' }],\n});\nchart.update([{ data: [{ key: 1, value: 10 }, { key: 2, value: 15 }, { key: 3, value: 18 }], name: 'revenue' }]);\nchart.dispose();\n```\n\n### `createareachart()`\n\n```ts\nfunction createareachart(\n container: htmlelement,\n config: areachartconfig,\n): charthandle<areaseriesconfig[]>;\n```\n\nrenders continuous area series with a gradient fill by default. `update()` replaces the complete series array.\n\narea series use linear interpolation by default and show their top line unless `showline: false` is set. axes render by default, with grid lines on the value axis.\n\n| parameter | type | description |\n| | | |\n| `container` | `htmlelement` | host that receives the chart svg and optional overlays |\n| `config` | `areachartconfig` | series, axes, interaction, accessibility, and motion settings |\n\n**returns:** `charthandle<areaseriesconfig[]>`.\n\n```ts\nimport { createareachart } from '@vielzeug/prism';\n\nconst host = document.createelement('div');\nhost.style.csstext = 'width:640px;height:320px';\ndocument.body.append(host);\n\nconst chart = createareachart(host, {\n a11y: { arialabel: 'visitors over time' },\n series: [{ data: [{ key: 1, value: 10 }, { key: 2, value: 18 }], name: 'visitors' }],\n});\nchart.dispose();\n```\n\n### `createscatterchart()`\n\n```ts\nfunction createscatterchart(\n container: htmlelement,\n config: scatterchartconfig,\n): charthandle<scatterseriesconfig[]>;\n```\n\nplots each datum independently: `key` is the numeric or date x value and `value` is the y value. points are not joined. `update()` replaces the complete series array.\n\naxes render by default, with grid lines on the value axis. the value scale is fitted to the observed data rather than forced to include zero. tooltip, crosshair, and legend are disabled unless configured.\n\n| parameter | type | description |\n| | | |\n| `container` | `htmlelement` | host that receives the chart svg and optional overlays |\n| `config` | `scatterchartconfig` | independent points, axes, interaction, accessibility, and motion settings |\n\n**returns:** `charthandle<scatterseriesconfig[]>`.\n\n```ts\nimport { createscatterchart } from '@vielzeug/prism';\n\nconst host = document.createelement('div');\nhost.style.csstext = 'width:640px;height:320px';\ndocument.body.append(host);\n\nconst chart = createscatterchart(host, {\n a11y: { arialabel: 'height against weight' },\n series: [{ data: [{ key: 160, value: 55 }, { key: 175, value: 70 }], name: 'cohort a' }],\n tooltip: true,\n});\nchart.dispose();\n```\n\nscatter interaction reports the datum and series of the point nearest the pointer in two dimensions, without a `values` array. keyboard navigation visits points across series in x order. tooltip `titleformat` receives the x value and `valueformat` the y value. on mount, points grow from radius zero at their final positions; updates slide existing points and grow new ones.\n\n### `createbarchart()`\n\n```ts\nfunction createbarchart(\n container: htmlelement,\n config: barchartconfig,\n): charthandle<barseriesconfig[]>;\n```\n\nrenders grouped, stacked, grouped horizontal, or stacked horizontal categories. `update()` replaces the complete series array; the variant is fixed at creation. axes render by default, with grid lines on the value axis.\n\nthe default variant is `grouped`; tooltip and legend are disabled unless configured.\n\n| parameter | type | description |\n| | | |\n| `container` | `htmlelement` | host that receives the chart svg and optional overlays |\n| `config` | `barchartconfig` | series, layout variant, axes, interaction, accessibility, and motion settings |\n\n**returns:** `charthandle<barseriesconfig[]>`.\n\n```ts\nimport { createbarchart } from '@vielzeug/prism';\n\nconst host = document.createelement('div');\nhost.style.csstext = 'width:640px;height:320px';\ndocument.body.append(host);\n\nconst chart = createbarchart(host, {\n a11y: { arialabel: 'tasks by status' },\n series: [{ data: [{ key: 'open', value: 12 }, { key: 'done', value: 8 }], name: 'tasks' }],\n});\nchart.dispose();\n```\n\nfor stacked variants, negative values are treated as zero and produce a development warning.\n\n### `createpiechart()`\n\n```ts\nfunction createpiechart(\n container: htmlelement,\n config: piechartconfig,\n): charthandle<piesliceconfig[]>;\n```\n\nrenders pie, donut, or semi circle slices. the default variant is `pie`; `update()` replaces the slice array. the default inner radius is zero for pies and 55% of the outer radius for donut and semi variants. pie slices default to no padding or rounded corners; donut and semi slices default to 8px padding and corner radius.\n\n| parameter | type | description |\n| | | |\n| `container` | `htmlelement` | host that receives the chart svg and optional overlays |\n| `config` | `piechartconfig` | slices, shape, geometry, legend, tooltip, and interaction settings |\n\n**returns:** `charthandle<piesliceconfig[]>`.\n\n```ts\nimport { createpiechart } from '@vielzeug/prism';\n\nconst host = document.createelement('div');\nhost.style.csstext = 'width:320px;height:240px';\ndocument.body.append(host);\n\nconst chart = createpiechart(host, {\n a11y: { arialabel: 'orders by channel' },\n data: [{ label: 'direct', value: 72 }, { label: 'referral', value: 28 }],\n variant: 'donut',\n});\nchart.dispose();\n```\n\n### `createradarchart()`\n\n```ts\nfunction createradarchart(\n container: htmlelement,\n config: radarchartconfig,\n): charthandle<radarseriesconfig[]>;\n```\n\nrenders one shape per series across the configured axes. `update()` replaces series data but not axes or other configuration. fewer than three axes warn in development and draw no chart. tooltip and legend are disabled unless configured.\n\n| parameter | type | description |\n| | | |\n| `container` | `htmlelement` | host that receives the chart svg and optional overlays |\n| `config` | `radarchartconfig` | fixed axes, series, scale, grid, appearance, and interaction settings |\n\n**returns:** `charthandle<radarseriesconfig[]>`.\n\n```ts\nimport { createradarchart } from '@vielzeug/prism';\n\nconst host = document.createelement('div');\nhost.style.csstext = 'width:400px;height:320px';\ndocument.body.append(host);\n\nconst chart = createradarchart(host, {\n a11y: { arialabel: 'hero stats' },\n axes: [{ key: 'str', label: 'strength' }, { key: 'agi', label: 'agility' }, { key: 'end', label: 'endurance' }],\n domain: [0, 10],\n series: [{ data: [{ key: 'str', value: 8 }, { key: 'agi', value: 6 }, { key: 'end', value: 9 }], name: 'adam' }],\n});\nchart.dispose();\n```\n\nradar defaults are a solid fill, linear curves, visible points, a four level polygon grid with bands, no grid labels, and a first axis angle of zero degrees. grid labels render only when all axes share a domain.\n\n### `createheatmapchart()`\n\n```ts\nfunction createheatmapchart(\n container: htmlelement,\n config: heatmapchartconfig,\n): charthandle<heatmapdata>;\n```\n\nrenders one colored cell per row/column pair: rows down the left, columns across the top. the color ramp is continuous by default; `bins` turns it into discrete steps and shows a swatch legend. cells show their formatted value when they are large enough, choosing dark or light text against the fill. `rowsummary` adds a right hand column of pre formatted per row texts (e.g. a win rate the cells alone cannot show). `update()` replaces cells and may replace `rows`, `columns`, `domain`, and `rowsummary`; other configuration is fixed at creation.\n\n| parameter | type | description |\n| | | |\n| `container` | `htmlelement` | host that receives the chart svg and optional overlays |\n| `config` | `heatmapchartconfig` | rows, columns, cells, ramp, bins, appearance, and interaction settings |\n\n**returns:** `charthandle<heatmapdata>`.\n\n```ts\nimport { createheatmapchart } from '@vielzeug/prism';\n\nconst host = document.createelement('div');\nhost.style.csstext = 'width:400px;height:320px';\ndocument.body.append(host);\n\nconst chart = createheatmapchart(host, {\n a11y: { arialabel: 'win rate by hero and region' },\n cells: [\n { column: 'forest', row: 'aria', value: 90 },\n { column: 'swamp', row: 'aria', value: 40 },\n { column: 'forest', row: 'brom', value: 20 },\n { column: 'swamp', row: 'brom', value: 75 },\n ],\n columns: ['forest', 'swamp'],\n rows: ['aria', 'brom'],\n});\nchart.dispose();\n```\n\nheatmap defaults are a light to deep blue ramp over the data's `[min, max]` domain, a 2 px cell gap, in cell values, and no legend. column headers rotate 45° when they do not fit their column. keyboard: arrows move the active cell, enter/space fires `oncellclick`, escape deactivates; the tooltip (or `.prism live` without one) describes the active cell.\n\n### `createsparkline()`\n\n```ts\nfunction createsparkline(\n container: htmlelement,\n config: sparklineconfig,\n): charthandle<number[] | stacksegment[]>;\n```\n\nrenders compact data without axes, chart margins, or a legend. `update()` replaces the number or stack segment array. the default variant is `line`; only line and area variants draw the endpoint marker by default.\n\n| parameter | type | description |\n| | | |\n| `container` | `htmlelement` | host that receives the chart svg |\n| `config` | `sparklineconfig` | values, variant, appearance, accessibility, and pointer callbacks |\n\n**returns:** `charthandle<number[] | stacksegment[]>`.\n\n```ts\nimport { createsparkline } from '@vielzeug/prism';\n\nconst host = document.createelement('div');\nhost.style.csstext = 'width:240px;height:48px';\ndocument.body.append(host);\n\nconst chart = createsparkline(host, { data: [2, 5, 3, 8], variant: 'area' });\nchart.update([2, 5, 3, 8, 13]);\nchart.dispose();\n```\n\n`stacksegment[]` is for `variant: 'stack'`. pointer callbacks are available for numeric line, area, and bar sparklines; sparklines do not support keyboard navigation.\n\n## scale factories\n\n### `linearscale()`\n\n```ts\nfunction linearscale(config: linearscaleconfig): scale<number>;\n```\n\nmaps a numeric domain to a numeric range. `nice` defaults to `true`; `clamp` defaults to `false` and applies to `map()`, not `invert()`.\n\n| parameter | type | default | description |\n| | | | |\n| `config.domain` | `[number, number]` | required | input extent |\n| `config.range` | `[number, number]` | required | output extent |\n| `config.clamp` | `boolean` | `false` | clamp mapped values to the range |\n| `config.nice` | `boolean` | `true` | expand the domain to rounded boundaries |\n\n**returns:** `scale<number>`, with `map`, `invert`, `ticks`, `domain`, and `range`.\n\n```ts\nimport { linearscale } from '@vielzeug/prism';\n\nconst scale = linearscale({ domain: [0, 100], range: [0, 500] });\nscale.map(50); // 250\n```\n\n### `timescale()`\n\n```ts\nfunction timescale(config: timescaleconfig): scale<date>;\n```\n\nmaps date values to a numeric range. `nice` defaults to `true` and rounds the domain to a time interval.\n\n| parameter | type | default | description |\n| | | | |\n| `config.domain` | `[date, date]` | required | input date extent |\n| `config.range` | `[number, number]` | required | output extent |\n| `config.nice` | `boolean` | `true` | expand the domain to time interval boundaries |\n\n**returns:** `scale<date>`, with `map`, `invert`, `ticks`, `domain`, and `range`.\n\n```ts\nimport { timescale } from '@vielzeug/prism';\n\nconst scale = timescale({\n domain: [new date('2026 01 01'), new date('2026 12 31')],\n range: [0, 500],\n});\nscale.map(new date('2026 07 02'));\n```\n\n### `bandscale()`\n\n```ts\nfunction bandscale(config: bandscaleconfig): bandscale;\n```\n\nmaps ordered string categories to the start of each band. `padding` defaults to `0.1`; `paddingouter` defaults to the same value. mapping an unknown category returns `0` and warns in development.\n\n| parameter | type | default | description |\n| | | | |\n| `config.domain` | `string[]` | required | ordered categories |\n| `config.range` | `[number, number]` | required | output extent |\n| `config.padding` | `number` | `0.1` | inner gap as a ratio of bandwidth |\n| `config.paddingouter` | `number` | `padding` | outer gap as a ratio of bandwidth |\n\n**returns:** `bandscale`, with `map`, `ticks`, `bandwidth`, `gap`, `domain`, and `range`.\n\n```ts\nimport { bandscale } from '@vielzeug/prism';\n\nconst scale = bandscale({ domain: ['a', 'b'], range: [0, 200] });\nscale.bandwidth();\n```\n\n## theme utilities\n\n`theme.css` supplies the base css values and styles. `settheme()` writes inline custom properties, which take precedence over stylesheet declarations. for other visual controls, set css custom properties directly.\n\n### `settheme()`\n\n```ts\nfunction settheme(theme: prismtheme, options?: themescope): void;\n```\n\nsets the provided theme values on `options.scope`, or on `document.documentelement` when omitted. omitted scalar keys remain unchanged. providing `colors` replaces all eight palette slots, removing unused slots.\n\n| parameter | type | description |\n| | | |\n| `theme` | `prismtheme` | palette and supported axis, grid, text, font, and tooltip properties |\n| `options.scope` | `htmlelement` | element that scopes the inline custom properties |\n\n**returns:** `void`.\n\n```ts\nimport { settheme } from '@vielzeug/prism';\n\nconst host = document.createelement('div');\ndocument.body.append(host);\nsettheme({ colors: ['#2563eb', '#16a34a'], textcolor: '#111827' }, { scope: host });\n```\n\n### `resettheme()`\n\n```ts\nfunction resettheme(options?: themescope): void;\n```\n\nremoves every custom property managed by `settheme()` from the given scope or the document root. it does not remove css rules or change any other custom properties.\n\n| parameter | type | description |\n| | | |\n| `options` | `themescope` | optional target; defaults to `document.documentelement` |\n\n**returns:** `void`.\n\n```ts\nimport { resettheme, settheme } from '@vielzeug/prism';\n\nconst scope = document.createelement('div');\nsettheme({ textcolor: '#111827' }, { scope });\nresettheme({ scope });\n```\n\n### `seriescolor()`\n\n```ts\nfunction seriescolor(index: number, override?: string): string;\n```\n\nreturns `override` when it is provided; otherwise returns a `var( prism color n)` reference. the palette has eight positions and the index wraps around after the eighth.\n\n| parameter | type | description |\n| | | |\n| `index` | `number` | zero based palette position |\n| `override` | `string` | optional color returned instead of a css variable |\n\n**returns:** `string`.\n\n```ts\nimport { seriescolor } from '@vielzeug/prism';\n\nseriescolor(0); // 'var( prism color 1)'\nseriescolor(1, '#2563eb'); // '#2563eb'\n```\n\n## chart handle\n\n`charthandle<tdata>` is returned by every chart factory. `update()` synchronously rebuilds the chart from its new data; enabled motion may animate the resulting svg. `dispose()` is idempotent, removes the chart svg, observers, tooltip and legend, cancels chart owned animation, aborts `disposalsignal`, and emits one `dispose` tap event. `update()` after disposal throws `prismrendererror`.\n\n`tap()` observes `resize` and `dispose` events outside the render path. it returns an unsubscribe function; an optional abort signal removes the subscription. observer handler exceptions are swallowed so they cannot affect chart behavior. a tap added after disposal returns a no op unsubscribe function.\n\n`[symbol.dispose]()` delegates to `dispose()`, allowing explicit resource management where supported.\n\nall chart handles expose the same lifecycle members; interactive cartesian, pie, radar, and heatmap charts use a `.prism live` status region when no tooltip is enabled. a tooltip is itself a polite status region. sparklines have neither a tooltip nor a live value announcer.\n\n| method or property | contract |\n| | |\n| `el` | the chart's root `svgsvgelement` |\n| `update(data)` | replace chart data and render; throws `prismrendererror` after disposal |\n| `dispose()` | idempotently release chart owned dom, observation, and motion |\n| `disposed` | whether the handle has been disposed |\n| `disposalsignal` | `abortsignal` aborted during disposal |\n| `tap(handler, options?)` | observe resize/dispose events; returns an unsubscribe function |\n| `[symbol.dispose]()` | calls `dispose()` |\n\n`prismevent` reports a changed svg content size as `{ type: 'resize', width, height }`; the `dispose` event is emitted once before teardown completes.\n\n## types\n\nthe following are all types and interfaces exported from `@vielzeug/prism`. definitions mirror the package entry point contracts.\n\n### animation types\n\n```ts\nexport type easingfn = (t: number) => number;\nexport type easingname = 'back out' | 'ease in' | 'ease in out' | 'ease out' | 'expo out' | 'linear';\n\nexport interface transitionconfig {\n /** milliseconds per animated lane. defaults to 300 (420 for a line entrance, 400 for radar). */\n duration?: number;\n easing?: easingname | ((t: number) => number);\n /** `system` skips animation when reduced motion is preferred. */\n preference?: 'always' | 'never' | 'system';\n /** per bar delay on bar charts, per entering point delay (x order) on scatter charts, or per series delay on radar charts. bar and scatter charts cap the total added delay at about 400 ms. */\n stagger?: number;\n}\n\nexport type transitionoption = transitionconfig | boolean;\n```\n\n### theme types\n\n```ts\nexport interface prismtheme {\n axiscolor?: string;\n colors?: string[];\n fontfamily?: string;\n gridcolor?: string;\n gridopacity?: number;\n textcolor?: string;\n textcolorsecondary?: string;\n tooltipbg?: string;\n tooltipborder?: string;\n tooltipcolor?: string;\n}\n\nexport interface themescope {\n readonly scope?: htmlelement;\n}\n```\n\n`prismtheme.colors` writes up to eight palette slots. the scalar fields map as follows:\n\n| field | css custom property |\n| | |\n| `axiscolor` | ` prism axis color` |\n| `fontfamily` | ` prism font family` |\n| `gridcolor` | ` prism grid color` |\n| `gridopacity` | ` prism grid opacity` |\n| `textcolor` | ` prism text color` |\n| `textcolorsecondary` | ` prism text color secondary` |\n| `tooltipbg` | ` prism tooltip bg` |\n| `tooltipborder` | ` prism tooltip border` |\n| `tooltipcolor` | ` prism tooltip color` |\n\n### core and data types\n\n```ts\nexport interface chartmargin {\n bottom: number;\n left: number;\n right: number;\n top: number;\n}\n\nexport interface chartdimensions {\n height: number;\n margin: chartmargin;\n width: number;\n}\n\nexport type prismevent =\n | { readonly height: number; readonly type: 'resize'; readonly width: number }\n | { readonly type: 'dispose' };\n\nexport interface charthandle<tdata = unknown> {\n readonly disposalsignal: abortsignal;\n dispose(): void;\n readonly disposed: boolean;\n readonly el: svgsvgelement;\n tap(handler: (event: prismevent) => void, options?: { readonly signal?: abortsignal }): () => void;\n update(data: tdata): void;\n [symbol.dispose](): void;\n}\n\nexport type charta11y =\n | { readonly decorative: true }\n | { readonly arialabel: string; readonly decorative?: false };\n\nexport interface datum<tkey extends date | number | string = date | number | string> {\n dash?: string;\n key: tkey;\n meta?: record<string, unknown>;\n opacity?: number;\n value: number;\n}\n\nexport type continuousdatum = datum<date | number>;\n\nexport interface series<tdatum extends datum = datum> {\n color?: string;\n data: tdatum[];\n id?: string;\n name: string;\n}\n\nexport interface chartevent {\n datum: datum;\n originalevent: event;\n series: series;\n values?: seriesvalue[];\n}\n\nexport interface seriesvalue {\n datum: datum | undefined;\n series: series;\n}\n```\n\n`datum.dash` and `datum.opacity` affect rendered marks only on the chart types that support them. on bars, `dash` adds a 1px series color stroke so the dash is visible against the fill. `series.id` becomes a `data series id` attribute on a series group; characters outside `[a za z0 9_ ]` are replaced with ` `. when omitted, the id is based on the series index.\n\n| chart | `dash` | `opacity` |\n| | | |\n| bar | strokes that datum's bar | applies to that bar |\n| line | applies to the segment from this datum to the next | applies to that segment and its point marker |\n| area | applies to the top line segment from this datum to the next | applies to that segment |\n| scatter | ignored | applies to that point |\n| pie, radar, heatmap, sparkline | ignored | ignored |\n\nfor line and area charts, the last datum has no following segment, so its `dash` value is ignored. the chart factories group adjacent segments with the same presentation values into path runs.\n\nfor line, area, and bar charts, `chartevent.values` lists each series at the active key in series order. its `datum` is `undefined` when that series has no matching key. `originalevent` is a pointer event or a keyboard event for keyboard activation. scatter events identify only the nearest independent point and omit `values`.\n\n### scale types\n\n```ts\nexport interface scale<t> {\n readonly domain: readonly [t, t];\n invert(pixel: number): t;\n map(value: t): number;\n readonly range: readonly [number, number];\n ticks(count?: number): t[];\n}\n\nexport interface bandscale {\n bandwidth(): number;\n readonly domain: readonly string[];\n gap(): number;\n map(value: string): number;\n readonly range: readonly [number, number];\n ticks(count?: number): string[];\n}\n\nexport interface linearscaleconfig {\n clamp?: boolean;\n domain: [number, number];\n nice?: boolean;\n range: [number, number];\n}\n\nexport interface timescaleconfig {\n domain: [date, date];\n nice?: boolean;\n range: [number, number];\n}\n\nexport interface bandscaleconfig {\n domain: string[];\n padding?: number;\n paddingouter?: number;\n range: [number, number];\n}\n```\n\n### axis and interaction types\n\n```ts\nexport type horizontalaxisposition = 'bottom' | 'top';\nexport type verticalaxisposition = 'left' | 'right';\nexport type axisposition = horizontalaxisposition | verticalaxisposition;\n\nexport interface gridconfig {\n color?: string;\n dash?: string;\n}\n\nexport interface axisconfig<tposition extends axisposition = axisposition> {\n grid?: gridconfig | boolean;\n label?: string;\n position?: tposition;\n tickcount?: number;\n tickformat?: (value: date | number | string) => string;\n tickvalues?: readonlyarray<date | number | string>;\n}\n\nexport type xaxisconfig = axisconfig<horizontalaxisposition>;\nexport type yaxisconfig = axisconfig<verticalaxisposition>;\n\nexport interface tooltipconfig {\n offset?: number;\n render?: (datum: datum, series: series) => node | string;\n titleformat?: (key: date | number | string) => string;\n valueformat?: (value: number, datum: datum, series: series) => string;\n}\n\nexport interface crosshairconfig {\n horizontal?: boolean;\n snap?: boolean;\n vertical?: boolean;\n}\n\nexport type legendposition = 'bottom' | 'left' | 'right' | 'top';\n\nexport interface legendconfig {\n position?: legendposition;\n}\n```\n\nthe crosshair defaults to a vertical line that snaps to the nearest datum; the horizontal line is hidden by default. with `snap: false`, only the guide follows the pointer—tooltip and callback data still refer to the nearest datum.\n\n`tickvalues` renders exactly the given ticks instead of scale generated ones, and gridlines follow the same list. values must match the axis's scale kind (numbers on a linear axis, `date`s on a time axis, category strings on a band axis); an off scale value warns in development. without it, ticks come from the scale as before.\n\nnumeric tick labels at a magnitude of 1e5 or above default to compact notation (`123k`, `1.23m`) so long numbers fit the default value axis margin; pass `tickformat: string` for raw labels. supplying a partial `yaxis` (or the value axis of a horizontal bar chart) merges over the default, so `{ tickformat }` alone keeps the default grid lines.\n\n`titleformat` and `valueformat` shape the default comparison tooltip on line, area, and bar charts—the title from the focused key and each row's value—and the same formatting is applied to the tooltip's spoken summary. `render` still replaces the whole tooltip body and takes precedence. tooltip strings are assigned as text, not parsed as html. for a radar chart, `tooltip.render` receives a datum whose `meta` contains the active axis, all series values, and the default announcement text.\n\n### chart configuration types\n\n```ts\nexport interface basechartconfig {\n a11y?: charta11y;\n legend?: legendconfig | boolean;\n margin?: partial<chartmargin>;\n onclick?: (event: chartevent) => void;\n onhover?: (event: chartevent | null) => void;\n tooltip?: tooltipconfig | boolean;\n transition?: transitionoption;\n xaxis?: xaxisconfig | false;\n yaxis?: yaxisconfig | false;\n}\n\nexport interface lineseriesconfig extends series<continuousdatum> {\n curve?: 'linear' | 'monotone' | 'step';\n pointradius?: number;\n showpoints?: boolean;\n strokewidth?: number;\n yaxis?: 'left' | 'right';\n}\n\nexport interface linechartconfig extends basechartconfig {\n crosshair?: crosshairconfig | boolean;\n rightyaxis?: omit<yaxisconfig, 'position' | 'grid'>;\n series: lineseriesconfig[];\n}\n\nexport interface areaseriesconfig extends series<continuousdatum> {\n curve?: 'linear' | 'monotone' | 'step';\n fill?: 'gradient' | 'solid';\n fillopacity?: number;\n showline?: boolean;\n}\n\nexport interface areachartconfig extends basechartconfig {\n crosshair?: crosshairconfig | boolean;\n series: areaseriesconfig[];\n}\n\nexport interface scatterseriesconfig extends series<continuousdatum> {\n pointradius?: number;\n}\n\nexport interface scatterchartconfig extends basechartconfig {\n crosshair?: crosshairconfig | boolean;\n series: scatterseriesconfig[];\n}\n\nexport interface barseriesconfig extends series {\n borderradius?: number;\n}\n\nexport type barvariant = 'grouped' | 'grouped horizontal' | 'stacked' | 'stacked horizontal';\n\nexport interface barchartconfig extends basechartconfig {\n series: barseriesconfig[];\n /** paints each bar's value at its end; stacked variants label the stack total. */\n showvalues?: boolean;\n /** formats the value labels. defaults to `string`. */\n valueformat?: (value: number) => string;\n variant?: barvariant;\n}\n\nexport type pievariant = 'donut' | 'pie' | 'semi';\n\nexport interface piesliceconfig {\n color?: string;\n label?: string;\n value: number;\n}\n\nexport interface pieevent {\n index: number;\n originalevent: event;\n slice: piesliceconfig;\n}\n\nexport interface piechartconfig extends omit<basechartconfig, 'margin' | 'onclick' | 'onhover' | 'xaxis' | 'yaxis'> {\n cornerradius?: number;\n data: piesliceconfig[];\n innerradius?: number;\n onclick?: (event: pieevent) => void;\n onhover?: (event: pieevent | null) => void;\n padpixels?: number;\n variant?: pievariant;\n}\n\nexport interface radaraxisconfig {\n format?: (value: number) => string;\n key: string;\n label: string;\n max?: number;\n min?: number;\n}\n\nexport type radarseriesconfig = series<datum<string>>;\n\nexport interface radargridconfig {\n bands?: boolean;\n labels?: boolean;\n levels?: number;\n shape?: 'circle' | 'polygon';\n}\n\nexport interface radaraxisvalue {\n datum: datum<string> | undefined;\n series: radarseriesconfig;\n}\n\nexport interface radarevent {\n axis: radaraxisconfig;\n index: number;\n originalevent: event;\n values: radaraxisvalue[];\n}\n\nexport interface radarchartconfig extends omit<basechartconfig, 'margin' | 'onclick' | 'onhover' | 'xaxis' | 'yaxis'> {\n axes: radaraxisconfig[];\n curve?: 'linear' | 'rounded';\n domain?: [number, number];\n fill?: 'gradient' | 'none' | 'solid';\n grid?: radargridconfig | boolean;\n onclick?: (event: radarevent) => void;\n onhover?: (event: radarevent | null) => void;\n series: radarseriesconfig[];\n showpoints?: boolean;\n showvalues?: boolean;\n startangle?: number;\n}\n\nexport interface heatmapcell {\n column: string;\n row: string;\n value: number | null;\n}\n\nexport interface heatmapevent {\n cell: heatmapcell | undefined;\n column: string;\n originalevent: event;\n row: string;\n}\n\nexport interface heatmapdata {\n cells: heatmapcell[];\n columns?: string[];\n domain?: [number, number];\n rows?: string[];\n rowsummary?: heatmapchartconfig['rowsummary'];\n}\n\nexport interface heatmapchartconfig\n extends omit<basechartconfig, 'legend' | 'onclick' | 'onhover' | 'transition' | 'xaxis' | 'yaxis'> {\n binlabel?: (from: number | null, to: number | null) => string;\n bins?: number[];\n cells: heatmapcell[];\n colorrange?: string[];\n columns: string[];\n domain?: [number, number];\n emptycolor?: string;\n emptylabel?: string;\n gap?: number;\n legend?: boolean;\n oncellclick?: (event: heatmapevent) => void;\n oncellhover?: (event: heatmapevent | null) => void;\n rows: string[];\n rowsummary?: { header?: string; values: (string | null)[] };\n showvalues?: boolean;\n valueformat?: (value: number) => string;\n}\n\nexport type sparklinevariant = 'area' | 'bar' | 'line' | 'stack';\n\nexport interface stacksegment {\n color?: string;\n label?: string;\n value: number;\n}\n\nexport interface sparklineevent {\n index: number;\n originalevent: event;\n value: number;\n}\n\nexport interface sparklineconfig {\n a11y?: charta11y;\n color?: string;\n cornerradius?: number;\n curve?: 'linear' | 'monotone' | 'step';\n data: number[] | stacksegment[];\n fillopacity?: number;\n onclick?: (event: sparklineevent) => void;\n onhover?: (event: sparklineevent | null) => void;\n padpixels?: number;\n showendpoint?: boolean;\n strokewidth?: number;\n transition?: transitionoption;\n variant?: sparklinevariant;\n}\n```\n\n## errors\n\n### `prismerror`\n\n```ts\nclass prismerror extends error {\n constructor(message: string, opts?: erroroptions);\n}\n```\n\nbase class for prism originated errors. its `name` is set to the concrete error class name, and it supports the standard `erroroptions` including `cause`.\n\n### `prismrendererror`\n\n```ts\nclass prismrendererror extends prismerror {}\n```\n\nthrown when a chart cannot be rendered because its container is not a dom element, when initial rendering fails (the original error is available as `cause`), or when `update()` is called after disposal. empty or malformed chart data may instead produce a development warning or an empty rendering, depending on the chart.\n",
1006
+ "usage": " \ntitle: 'prism: usage guide'\ndescription: create responsive svg charts, update their data, handle interaction, and theme @vielzeug/prism.\n \n\n[[toc]]\n\n## basic usage\n\ncreate a host element with non zero dimensions, then pass it to a chart factory. this example creates the host in javascript so the snippet can run as written.\n\n```ts\nimport { createlinechart } from '@vielzeug/prism';\nimport '@vielzeug/prism/theme.css';\n\nconst container = document.createelement('div');\ncontainer.style.csstext = 'width:640px;height:320px';\ndocument.body.append(container);\n\nconst chart = createlinechart(container, {\n a11y: { arialabel: 'revenue by month' },\n series: [\n {\n name: 'revenue',\n data: [\n { key: 1, value: 10 },\n { key: 2, value: 16 },\n ],\n },\n ],\n tooltip: true,\n});\n\nchart.dispose();\n```\n\neach factory appends an svg to its container and returns a `charthandle`. prism observes the container with `resizeobserver`; if it has zero dimensions on creation, prism uses a temporary `600 × 300` size and warns in development. give the host its layout before creating the chart.\n\n## updating data\n\nkeep application state outside prism and pass the next complete data value to `update()`. the update method replaces chart data synchronously; the default transition may animate the resulting svg.\n\n```ts\nimport { createlinechart } from '@vielzeug/prism';\n\nconst container = document.createelement('div');\ncontainer.style.csstext = 'width:640px;height:320px';\ndocument.body.append(container);\n\nlet series = [{ data: [{ key: 1, value: 10 }], name: 'live' }];\nconst chart = createlinechart(container, { series });\n\nseries = [{ data: [{ key: 1, value: 10 }, { key: 2, value: 20 }], name: 'live' }];\nchart.update(series);\nchart.dispose();\n```\n\n`update()` accepts the type shown by that factory's handle: a complete series array for line, area, scatter, bar, and radar charts; a slice array for pie charts; a `heatmapdata` object for heatmap charts; and a number or stack segment array for sparklines. chart options such as axes, variant, callbacks, and accessibility are set at creation. for example, radar axes and a pie chart's variant do not change through `update()`.\n\n## line charts\n\nline and area series use number or `date` keys. all series in one chart must use the same key kind. use `curve` to choose interpolation, and enable markers with `showpoints`.\n\n```ts\nimport { createlinechart } from '@vielzeug/prism';\n\nconst container = document.createelement('div');\ncontainer.style.csstext = 'width:640px;height:320px';\ndocument.body.append(container);\n\nconst chart = createlinechart(container, {\n a11y: { arialabel: 'revenue and expenses' },\n series: [\n {\n curve: 'monotone',\n data: [{ key: 1, value: 100 }, { key: 2, value: 150 }, { key: 3, value: 130 }],\n name: 'revenue',\n showpoints: true,\n },\n {\n color: '#c2410c',\n data: [{ key: 1, value: 70 }, { key: 2, value: 95 }, { key: 3, value: 110 }],\n name: 'expenses',\n },\n ],\n tooltip: true,\n xaxis: { label: 'month' },\n yaxis: { grid: true, label: 'dollars' },\n});\n\nchart.dispose();\n```\n\n### independent value axes\n\nassign a line series to the right axis when it uses a different value range. both axes share the x scale; `rightyaxis` configures the second axis and cannot configure its position or grid.\n\n```ts\nimport { createlinechart } from '@vielzeug/prism';\n\nconst container = document.createelement('div');\ncontainer.style.csstext = 'width:640px;height:320px';\ndocument.body.append(container);\n\nconst chart = createlinechart(container, {\n a11y: { arialabel: 'health and damage by level' },\n rightyaxis: { label: 'damage' },\n series: [\n { data: [{ key: 1, value: 30 }, { key: 2, value: 20 }], name: 'health' },\n { data: [{ key: 1, value: 100 }, { key: 2, value: 300 }], name: 'damage', yaxis: 'right' },\n ],\n yaxis: { grid: true, label: 'health' },\n});\n\nchart.dispose();\n```\n\nwhen any series uses the right axis, the primary value axis is placed on the left. grid lines belong to the primary `yaxis`. the independent numeric scales mean that curve crossings do not imply equal values.\n\n### time based x axis\n\nuse `date` values for every key when plotting time. line and area charts use a time scale whose domain fits the data instead of rounding outward to tick boundaries.\n\n```ts\nimport { createlinechart } from '@vielzeug/prism';\n\nconst container = document.createelement('div');\ncontainer.style.csstext = 'width:640px;height:320px';\ndocument.body.append(container);\n\nconst formatter = new intl.datetimeformat(undefined, { month: 'short', day: 'numeric' });\nconst chart = createlinechart(container, {\n a11y: { arialabel: 'signups over time' },\n series: [{\n data: [\n { key: new date('2026 09 01'), value: 50 },\n { key: new date('2026 09 08'), value: 80 },\n { key: new date('2026 09 15'), value: 120 },\n ],\n name: 'signups',\n }],\n xaxis: { tickformat: (value) => value instanceof date ? formatter.format(value) : string(value) },\n});\n\nchart.dispose();\n```\n\n`tickformat` formats axis labels only. tooltip content and accessibility announcements use the underlying keys and values. to render an exact set of ticks instead of scale generated ones, pass `tickvalues`; gridlines follow the same list. values must match the axis's scale kind, and an off scale value warns in development:\n\n```ts\n// force a tick on the last month, which nice stepped ticks can skip.\nconst chart = createlinechart(container, {\n series: [{ data: [{ key: 0, value: 90 }, { key: 11, value: 128 }], name: 'costs' }],\n xaxis: { tickvalues: [0, 6, 11] },\n});\n```\n\nnumeric tick labels at a magnitude of `1e5` or above default to compact notation (`123k`, `1.23m`) so long numbers fit the default value axis margin; pass `tickformat: string` for raw labels. supplying a partial value axis config merges over its default, so `yaxis: { tickformat }` alone keeps the default grid lines.\n\n## bar charts\n\nbar chart keys are string categories. the default `grouped` variant puts series side by side; the horizontal variants put categories on the y axis and values on the x axis.\n\n```ts\nimport { createbarchart } from '@vielzeug/prism';\n\nconst container = document.createelement('div');\ncontainer.style.csstext = 'width:640px;height:320px';\ndocument.body.append(container);\n\nconst chart = createbarchart(container, {\n a11y: { arialabel: 'sales by quarter' },\n series: [{\n data: [{ key: 'q1', value: 200 }, { key: 'q2', value: 350 }, { key: 'q3', value: 280 }],\n name: 'sales',\n }],\n tooltip: true,\n});\n\nchart.dispose();\n```\n\nchoose `grouped`, `stacked`, `grouped horizontal`, or `stacked horizontal` in `variant`. negative values in a stacked chart are clamped to zero and produce a development warning. bars in stacked variants remain square; `borderradius` applies to grouped bars.\n\naxes render by default, with grid lines on the value axis. for horizontal variants, `xaxis` is the value axis and `yaxis` is the category axis. configure `grid` on the value axis.\n\nset `showvalues: true` to paint each bar's value at its end so the chart reads without hover; `valueformat` shapes the label text. stacked variants label the stack total at the top of the stack, and labels that would overflow the plot flip inside the bar with a contrasting fill. the labels are decorative (`aria hidden`) — the accessible read stays with the chart's data table.\n\n## area charts\n\narea series use a gradient fill by default. set `fill: 'solid'` for a flat fill, or set `fillopacity` to override the theme opacity for that series.\n\n```ts\nimport { createareachart } from '@vielzeug/prism';\n\nconst container = document.createelement('div');\ncontainer.style.csstext = 'width:640px;height:320px';\ndocument.body.append(container);\n\nconst chart = createareachart(container, {\n a11y: { arialabel: 'visitors over time' },\n crosshair: true,\n series: [{\n curve: 'monotone',\n data: [{ key: 1, value: 12 }, { key: 2, value: 18 }, { key: 3, value: 15 }],\n fill: 'solid',\n fillopacity: 0.2,\n name: 'visitors',\n showline: true,\n }],\n});\n\nchart.dispose();\n```\n\n## scatter charts\n\nscatter charts treat every datum as an independent point: `key` is the numeric or `date` x value and `value` is the y value. the scales fit the observed values rather than forcing the y domain to include zero. set `pointradius` on a series to change its marker size (default `3`).\n\n```ts\nimport { createscatterchart } from '@vielzeug/prism';\n\nconst container = document.createelement('div');\ncontainer.style.csstext = 'width:640px;height:320px';\ndocument.body.append(container);\n\nconst chart = createscatterchart(container, {\n a11y: { arialabel: 'height against weight' },\n series: [{\n data: [{ key: 160, value: 55 }, { key: 175, value: 70 }, { key: 190, value: 88 }],\n name: 'cohort a',\n pointradius: 5,\n }],\n tooltip: true,\n});\n\nchart.dispose();\n```\n\nscatter callbacks identify the nearest point in two dimensions and do not provide cross series `values`, because points do not share a category key. keyboard navigation visits every point across series in x order. with a tooltip, `titleformat` formats the x value and `valueformat` the y value, in both the visible row and the spoken summary.\n\n## forecast and emphasis styling\n\nadd `dash` or `opacity` to individual `datum` objects when one part of a series needs distinct styling. these fields do not change interaction, tooltip, or accessibility behavior.\n\n```ts\nimport { createlinechart } from '@vielzeug/prism';\n\nconst container = document.createelement('div');\ncontainer.style.csstext = 'width:640px;height:320px';\ndocument.body.append(container);\n\nconst values = [10, 13, 15, 18];\nconst chart = createlinechart(container, {\n series: [{\n data: values.map((value, index) => ({\n key: index + 1,\n value,\n ...(index >= 2 ? { dash: '5 5', opacity: 0.4 } : {}),\n })),\n name: 'forecast',\n showpoints: true,\n }],\n});\n\nchart.dispose();\n```\n\nfor line and area charts, each datum's `dash` styles the segment from that datum to the next; the final datum has no outgoing segment. line opacity also fades the datum's marker. area styling affects the top line, not the fill. bar opacity and dashes apply to the individual bar; scatter opacity applies to its point and scatter dashes are ignored. pie, radar, and sparkline ignore these two fields.\n\n## pie, donut, and semi charts\n\nuse `createpiechart()` for all three shapes. `variant` is fixed when the chart is created; `update()` replaces the slice data.\n\n```ts\nimport { createpiechart } from '@vielzeug/prism';\n\nconst container = document.createelement('div');\ncontainer.style.csstext = 'width:320px;height:240px';\ndocument.body.append(container);\n\nconst chart = createpiechart(container, {\n a11y: { arialabel: 'orders by channel' },\n data: [\n { label: 'direct', value: 42 },\n { label: 'organic', value: 28 },\n { label: 'referral', value: 18 },\n { label: 'social', value: 12 },\n ],\n legend: true,\n tooltip: true,\n variant: 'donut',\n});\n\nchart.dispose();\n```\n\nthe `pie` default has no inner radius. `donut` and `semi` default to an inner radius of 55% of the outer radius. `innerradius` overrides that size in pixels. slice labels are omitted when they do not fit; keep a tooltip or legend when small slices need identifying.\n\n## radar charts\n\ndefine at least three axes when creating a radar chart. series data uses string keys that match `radaraxisconfig.key`; `update()` replaces series but keeps axes and other configuration fixed.\n\n```ts\nimport { createradarchart } from '@vielzeug/prism';\n\nconst container = document.createelement('div');\ncontainer.style.csstext = 'width:400px;height:320px';\ndocument.body.append(container);\n\nconst axes = [\n { key: 'strength', label: 'strength' },\n { key: 'agility', label: 'agility' },\n { key: 'endurance', label: 'endurance' },\n];\nconst chart = createradarchart(container, {\n a11y: { arialabel: 'hero stats' },\n axes,\n domain: [0, 10],\n series: [{\n data: [{ key: 'strength', value: 8 }, { key: 'agility', value: 6 }, { key: 'endurance', value: 9 }],\n name: 'adam',\n }],\n tooltip: true,\n});\n\nchart.dispose();\n```\n\nthe default shared domain starts at zero and uses a nice maximum; set `domain` to compare series on a fixed range. per axis `min` and `max` override the chart domain for that axis. grid rings, bands, curves, fills, vertex dots, and values are configurable; see `radarchartconfig` and `radargridconfig` in the api reference.\n\n## heatmaps\n\ndefine `rows`, `columns`, and `cells`; each cell names its `row` and `column` labels. a cell with `value: null` (or no matching cell at all) renders in `emptycolor` without in cell text. `rowsummary` adds a right hand column of pre formatted per row texts (aligned with `rows`, with an optional header) — useful for a per row rate the cells cannot show. `update()` replaces cells and may replace `rows`, `columns`, `domain`, and `rowsummary`.\n\n```ts\nimport { createheatmapchart } from '@vielzeug/prism';\n\nconst container = document.createelement('div');\ncontainer.style.csstext = 'width:400px;height:320px';\ndocument.body.append(container);\n\nconst chart = createheatmapchart(container, {\n a11y: { arialabel: 'win rate by hero and region' },\n bins: [50, 75],\n cells: [\n { column: 'forest', row: 'aria', value: 90 },\n { column: 'swamp', row: 'aria', value: 40 },\n { column: 'forest', row: 'brom', value: 20 },\n { column: 'swamp', row: 'brom', value: 75 },\n ],\n columns: ['forest', 'swamp'],\n rows: ['aria', 'brom'],\n tooltip: true,\n valueformat: (value) => `${value}%`,\n});\n\nchart.dispose();\n```\n\nwithout `bins` the ramp is continuous over the data's `[min, max]` domain (or an explicit `domain`); with `bins` each value maps to a discrete step and a swatch legend appears. `colorrange` sets the ramp low → high, `valueformat` shapes in cell values, tooltip values, and bin labels, and `showvalues: false` hides the in cell text.\n\n## sparklines\n\nsparklines omit axes, margins, and legends. choose `line`, `area`, or `bar` for numeric arrays, and `stack` for an array of `stacksegment` objects.\n\n```ts\nimport { createsparkline } from '@vielzeug/prism';\n\nconst container = document.createelement('div');\ncontainer.style.csstext = 'width:240px;height:48px';\ndocument.body.append(container);\n\nconst chart = createsparkline(container, {\n a11y: { arialabel: 'weekly orders' },\n data: [10, 14, 12, 18, 22],\n variant: 'area',\n});\n\nchart.update([10, 14, 12, 18, 22, 25]);\nchart.dispose();\n```\n\nfor a stacked sparkline, each segment can set `value`, `color`, and `label`. sparklines do not offer keyboard navigation, a tooltip, or a live value announcer. add a visible value or summary when the trend conveys important information.\n\n## interaction\n\nset `tooltip: true` to show prism's default tooltip, or pass a `tooltipconfig` to format its content. `titleformat` and `valueformat` shape the default comparison tooltip on line, area, and bar charts—the title from the focused key and each row's value—without rebuilding its markup, and the same formatting is applied to the tooltip's spoken summary. a `render` callback receives the active `datum` and `series` and replaces the whole body, taking precedence over the formatters. returned strings are inserted as text; return a dom `node` for structured content.\n\n```ts\nimport { createlinechart } from '@vielzeug/prism';\n\nconst container = document.createelement('div');\ncontainer.style.csstext = 'width:640px;height:320px';\ndocument.body.append(container);\n\nconst compact = new intl.numberformat(undefined, { notation: 'compact' });\nconst months = ['jan', 'feb', 'mar', 'apr', 'may', 'jun', 'jul', 'aug', 'sep', 'oct', 'nov', 'dec'];\n\nconst chart = createlinechart(container, {\n series: [{ data: [{ key: 11, value: 128000 }], name: 'ec2' }],\n tooltip: {\n titleformat: (key) => months[number(key)] ?? string(key),\n valueformat: (value) => compact.format(value),\n },\n});\n\nchart.dispose();\n```\n\n`onhover` receives an event while a point, category, slice, or radar axis is active, then `null` when the interaction clears. `onclick` receives the selected event. for line, area, and bar charts, `chartevent.values` contains each series' datum at that shared key; a missing datum is `undefined`. scatter events are `chartevent` objects without `values`; pie, radar, and sparkline use their chart specific event types.\n\n`crosshair` is available on line, area, and scatter charts. by default it shows a vertical guide and snaps the line to the nearest datum. set `horizontal: true` to add a horizontal guide or `vertical: false` to hide the vertical one. set `snap: false` to make the guide follow the pointer; tooltip and callback data still come from the nearest datum.\n\n### keyboard and announcements\n\nset `a11y: { arialabel }` on an informative chart. prism gives the svg `role=\"img\"`, an accessible name, and keyboard focus. arrow keys move among chart data; `home` and `end` move to the first and last item where supported; `enter` or `space` activates an item when an `onclick` callback is configured; `escape` clears the active selection. sparklines do not support keyboard navigation.\n\nwhen `a11y` is omitted, or set to `{ decorative: true }`, the svg is marked `aria hidden=\"true\"` and does not enter the keyboard tab order. only mark charts decorative when their information is available elsewhere. interactive cartesian, pie, radar, and heatmap charts use the tooltip as a polite live region when enabled; otherwise they announce active values in `.prism live`. sparklines have no live value announcements, so provide an equivalent visible value or summary.\n\n## animation\n\nchart motion is enabled by default, with a 300 ms duration per animated lane (radar uses 400 ms). pass `transition: false` to render updates synchronously, or pass `true` to state the default explicitly.\n\n```ts\nimport { createbarchart } from '@vielzeug/prism';\n\nconst container = document.createelement('div');\ncontainer.style.csstext = 'width:640px;height:320px';\ndocument.body.append(container);\n\nconst chart = createbarchart(container, {\n series: [{ data: [{ key: 'a', value: 4 }, { key: 'b', value: 7 }], name: 'count' }],\n transition: { duration: 500, easing: 'ease out', preference: 'system' },\n});\n\nchart.dispose();\n```\n\ncolumns grow together from their baseline by default over 300 ms. lines trace their final curve over 420 ms, uncovering point markers along the way without fading or shifting the series. line data updates retain the default 300 ms geometry transition; an explicit `duration` overrides both timings.\n\n`preference: 'system'` (the default) disables javascript motion when the user prefers reduced motion. use `'always'` to ignore that preference or `'never'` to disable motion. `stagger` sets an optional delay between bars, entering scatter points (in x order), or radar series; bar and scatter charts cap the effective delay so many marks do not add unbounded time. named easing values are `ease in`, `ease in out`, `ease out`, `back out`, `expo out`, and `linear`; you can also provide an easing function.\n\n## responsive layout and lifecycle\n\nsize the host with css. prism observes its content box and updates the svg dimensions and chart layout when it changes. bar, line, and scatter resize redraws apply immediately rather than animating between layout sizes; entrance animations and explicit data update transitions remain enabled. the legend is rendered as container chrome outside the svg and included in resize calculations.\n\ncall `dispose()` when the view no longer owns the chart. disposal is idempotent: it removes the svg, tooltip, legend, and resize observation, stops in flight chart motion, and aborts `disposalsignal`. `chart[symbol.dispose]()` calls the same cleanup method.\n\nuse `tap()` when external code needs resize or dispose notifications rather than observing the chart dom itself:\n\n```ts\nimport { createlinechart } from '@vielzeug/prism';\n\nconst container = document.createelement('div');\ncontainer.style.csstext = 'width:640px;height:320px';\ndocument.body.append(container);\n\nconst chart = createlinechart(container, {\n series: [{ data: [{ key: 1, value: 10 }], name: 'revenue' }],\n});\nconst stopobserving = chart.tap((event) => {\n if (event.type === 'resize') console.log(event.width, event.height);\n if (event.type === 'dispose') console.log('chart disposed');\n});\n\nstopobserving();\nchart.dispose();\n```\n\n`tap()` returns an unsubscribe function and accepts `{ signal }` for automatic unsubscription. a listener exception is swallowed by the observer so it cannot interrupt chart rendering.\n\n## theming\n\nimport the stylesheet once to load prism's structural styles, default tokens, dark mode rules, and reduced motion css. you can override any css custom property on an ancestor of the chart.\n\n```css\n.dashboard chart {\n prism color 1: #2563eb;\n prism color 2: #16a34a;\n prism grid color: #94a3b8;\n prism line width: 3;\n prism text color: #172033;\n prism tooltip bg: #111827;\n}\n```\n\n`settheme()` provides a typed subset of theme properties. a scoped call writes inline values on the provided element; omit `scope` to write them to `document.documentelement`. inline values override stylesheet tokens until reset.\n\n```ts\nimport { resettheme, settheme } from '@vielzeug/prism';\n\nconst container = document.createelement('div');\ncontainer.style.csstext = 'width:640px;height:320px';\ndocument.body.append(container);\n\nsettheme({ colors: ['#2563eb', '#16a34a'], fontfamily: 'inter, sans serif' }, { scope: container });\n// call resettheme({ scope: container }) when this scoped theme is no longer needed.\nresettheme({ scope: container });\n```\n\n### available tokens\n\nthe stylesheet defines defaults for the following token groups. pie label color and size are read with fallback values by the renderer but are not declared in the base token block. set a token on the chart container or an ancestor to scope an override.\n\n| group | css custom properties |\n| | |\n| palette and surfaces | ` prism color 1` through ` prism color 8`, ` prism bg`, ` prism border radius` |\n| axes and grid | ` prism axis color`, ` prism axis width`, ` prism grid color`, ` prism grid width`, ` prism grid dash`, ` prism grid opacity` |\n| text | ` prism font family`, ` prism font size`, ` prism font size label`, ` prism font size title`, ` prism font weight`, ` prism font weight title`, ` prism text color`, ` prism text color secondary` |\n| tooltip | ` prism tooltip bg`, ` prism tooltip color`, ` prism tooltip border`, ` prism tooltip radius`, ` prism tooltip padding`, ` prism tooltip shadow`, ` prism tooltip font size` |\n| crosshair | ` prism crosshair color`, ` prism crosshair width`, ` prism crosshair dash`, ` prism crosshair opacity` |\n| points | ` prism point radius`, ` prism point radius hover`, ` prism point stroke width`, ` prism point stroke` |\n| bars | ` prism bar radius`, ` prism bar hover opacity`, ` prism bar gap`, ` prism bar band fill`, ` prism bar band opacity`, ` prism bar dim opacity` |\n| areas and lines | ` prism area opacity`, ` prism area stroke width`, ` prism area gradient start`, ` prism area gradient end`, ` prism line width`, ` prism line width hover` |\n| interaction | ` prism dim opacity`, ` prism active point radius`, ` prism point ring`, ` prism focus color` |\n| sparklines | ` prism spark fill opacity`, ` prism spark gradient start`, ` prism spark gradient end` |\n| radar | ` prism radar grid color`, ` prism radar grid opacity`, ` prism radar band fill`, ` prism radar band opacity`, ` prism radar spoke color`, ` prism radar fill opacity`, ` prism radar stroke width`, ` prism radar point radius`, ` prism radar point radius active`, ` prism radar label color`, ` prism radar label size`, ` prism radar value color`, ` prism radar value size`, ` prism radar dim opacity` |\n| heatmap | ` prism heatmap label color`, ` prism heatmap label size`, ` prism heatmap value size`, ` prism heatmap highlight color` |\n| motion | ` prism duration fast`, ` prism duration`, ` prism duration slow`, ` prism ease`, ` prism ease spring`, ` prism transition`, ` prism transition fast` |\n| legend and pie labels | ` prism legend gap`, ` prism legend dot size`, ` prism legend font size`, ` prism pie label color`, ` prism pie label size` |\n\nthe default palette and structural colors adapt to `prefers color scheme: dark`, `html.dark`, or `[data prism theme='dark']` on an ancestor. scoped inline values set with `settheme()` take precedence in either mode. the stylesheet also provides `prefers reduced motion` overrides for css transitions.\n\n## errors and diagnostics\n\nprism throws `prismrendererror` when the container is not a dom element, when initial rendering fails, or when `update()` is called on a disposed chart. a wrapped initial render error exposes its cause. use `prismerror` to catch all prism originated errors.\n\nempty or malformed data is not always an exception. depending on the chart, prism may draw nothing or emit a development only `console.warn`; examples include an unknown `bandscale` category, negative values in stacked bars, and radar axes with fewer than three entries or duplicate keys. correct the input rather than relying on a warning for validation.\n\n## framework integration\n\nprism has no react, vue, or svelte adapter. in any framework, give prism a host element after it is mounted, call `update()` when data changes, and call `dispose()` before the host is removed. this plain dom pattern shows the ownership boundary without depending on a framework specific lifecycle api:\n\n```ts\nimport { createlinechart, type lineseriesconfig } from '@vielzeug/prism';\n\nfunction mountchart(host: htmlelement, series: lineseriesconfig[]) {\n const chart = createlinechart(host, { a11y: { arialabel: 'revenue' }, series });\n\n return {\n update(next: lineseriesconfig[]) {\n chart.update(next);\n },\n dispose() {\n chart.dispose();\n },\n };\n}\n\nconst host = document.createelement('div');\nhost.style.csstext = 'width:640px;height:320px';\ndocument.body.append(host);\nconst view = mountchart(host, [{ data: [{ key: 1, value: 10 }], name: 'revenue' }]);\nview.update([{ data: [{ key: 1, value: 10 }, { key: 2, value: 15 }], name: 'revenue' }]);\nview.dispose();\n```\n\nthe application owns its state and host; prism owns only the svg, observer, and optional overlay elements it creates.\n\n## working with other vielzeug libraries\n\nuse refine components for dashboard controls and keep prism in a sized host element. map refine theme tokens to prism css custom properties or call `settheme()` with a scoped element; prism does not require a refine adapter. prism uses orbit internally to place tooltips, so chart users do not need to create orbit floating elements for the built in tooltip.\n\n## best practices\n\n give the host a non zero size before creating a chart.\n set `a11y.arialabel` when a chart communicates information.\n use `date` or number keys consistently across each line or area chart.\n pass the complete new data value to `update()`.\n keep chart options fixed after creation; recreate the chart to change them.\n dispose the handle when its host leaves the owning view.\n use `transition: false` for deterministic synchronous rendering.\n prefer css custom properties for reusable theme overrides.\n",
1007
+ "examples": " \ntitle: 'prism: examples'\ndescription: focused recipes for creating, updating, interacting with, and theming prism charts.\n \n\n [create a line chart](./examples/line chart.md)\n [plot a time series](./examples/time series.md)\n [plot a scatter chart](./examples/scatter chart.md)\n [compare categories with a bar chart](./examples/bar chart.md)\n [render compact charts](./examples/compact charts.md)\n [compare hero stats with a radar chart](./examples/radar chart.md)\n [show a win rate matrix with a heatmap](./examples/heatmap chart.md)\n [update chart data](./examples/update data.md)\n [sync a details panel with hover](./examples/hover details.md)\n [render a custom tooltip](./examples/custom tooltip.md)\n [match charts to your design system](./examples/theming.md)\n"
1008
1008
  },
1009
1009
  "examples": [],
1010
1010
  "exports": "createlinechart createbarchart createpiechart charthandle",
1011
- "keywords": "chart svg visualization responsive line chart bar chart area chart scatter chart pie chart radar chart sparkline accessibility typescript",
1011
+ "keywords": "chart svg visualization responsive line chart bar chart area chart scatter chart pie chart radar chart heatmap chart sparkline accessibility typescript",
1012
1012
  "name": "@vielzeug/prism",
1013
1013
  "related": "refine orbit",
1014
1014
  "slug": "prism",
1015
- "source": "// public api: all exports for @vielzeug/prism\n\nexport type { easingfn, easingname } from './animation/easing';\n// chart factories\nexport { createareachart } from './charts/area';\nexport { createbarchart } from './charts/bar';\nexport { createlinechart } from './charts/line';\nexport { createpiechart } from './charts/pie';\nexport { createradarchart } from './charts/radar';\nexport { createscatterchart } from './charts/scatter';\nexport { createsparkline } from './charts/sparkline';\n// error classes\nexport { prismerror, prismrendererror } from './errors';\n// scale factories\nexport { bandscale } from './scales/band';\nexport { linearscale } from './scales/linear';\nexport { timescale } from './scales/time';\nexport type { bandscaleconfig, linearscaleconfig, timescaleconfig } from './scales/types';\n// theme utilities\nexport { resettheme, seriescolor, settheme } from './theme';\nexport type {\n areachartconfig,\n areaseriesconfig,\n axisconfig,\n axisposition,\n bandscale,\n barchartconfig,\n barseriesconfig,\n barvariant,\n basechartconfig,\n charta11y,\n chartdimensions,\n chartevent,\n charthandle,\n chartmargin,\n continuousdatum,\n crosshairconfig,\n datum,\n gridconfig,\n horizontalaxisposition,\n legendconfig,\n legendposition,\n linechartconfig,\n lineseriesconfig,\n piechartconfig,\n pieevent,\n piesliceconfig,\n pievariant,\n prismevent,\n prismtheme,\n radaraxisconfig,\n radaraxisvalue,\n radarchartconfig,\n radarevent,\n radargridconfig,\n radarseriesconfig,\n scale,\n scatterchartconfig,\n scatterseriesconfig,\n series,\n seriesvalue,\n sparklineconfig,\n sparklineevent,\n sparklinevariant,\n stacksegment,\n themescope,\n tooltipconfig,\n transitionconfig,\n transitionoption,\n verticalaxisposition,\n xaxisconfig,\n yaxisconfig,\n} from './types';\n"
1015
+ "source": "// public api: all exports for @vielzeug/prism\n\nexport type { easingfn, easingname } from './animation/easing';\n// chart factories\nexport { createareachart } from './charts/area';\nexport { createbarchart } from './charts/bar';\nexport { createheatmapchart } from './charts/heatmap';\nexport { createlinechart } from './charts/line';\nexport { createpiechart } from './charts/pie';\nexport { createradarchart } from './charts/radar';\nexport { createscatterchart } from './charts/scatter';\nexport { createsparkline } from './charts/sparkline';\n// error classes\nexport { prismerror, prismrendererror } from './errors';\n// scale factories\nexport { bandscale } from './scales/band';\nexport { linearscale } from './scales/linear';\nexport { timescale } from './scales/time';\nexport type { bandscaleconfig, linearscaleconfig, timescaleconfig } from './scales/types';\n// theme utilities\nexport { resettheme, seriescolor, settheme } from './theme';\nexport type {\n areachartconfig,\n areaseriesconfig,\n axisconfig,\n axisposition,\n bandscale,\n barchartconfig,\n barseriesconfig,\n barvariant,\n basechartconfig,\n charta11y,\n chartdimensions,\n chartevent,\n charthandle,\n chartmargin,\n continuousdatum,\n crosshairconfig,\n datum,\n gridconfig,\n heatmapcell,\n heatmapchartconfig,\n heatmapdata,\n heatmapevent,\n horizontalaxisposition,\n legendconfig,\n legendposition,\n linechartconfig,\n lineseriesconfig,\n piechartconfig,\n pieevent,\n piesliceconfig,\n pievariant,\n prismevent,\n prismtheme,\n radaraxisconfig,\n radaraxisvalue,\n radarchartconfig,\n radarevent,\n radargridconfig,\n radarseriesconfig,\n scale,\n scatterchartconfig,\n scatterseriesconfig,\n series,\n seriesvalue,\n sparklineconfig,\n sparklineevent,\n sparklinevariant,\n stacksegment,\n themescope,\n tooltipconfig,\n transitionconfig,\n transitionoption,\n verticalaxisposition,\n xaxisconfig,\n yaxisconfig,\n} from './types';\n"
1016
1016
  },
1017
1017
  {
1018
1018
  "category": "websockets",
@@ -1056,9 +1056,9 @@
1056
1056
  "category": "ui components",
1057
1057
  "description": "accessible, themeable web components built with ore for framework and vanilla dom apps.",
1058
1058
  "docs": {
1059
- "index": " \ntitle: 'refine: web component library'\ndescription: accessible, themeable web components built with ore for framework and vanilla dom apps.\npackage: refine\ncategory: ui components\nkeywords: [web components, accessible, themeable, ui, components, design system]\nrelated: [ore, orbit, forge, keymap]\nexports:\n [\n ore accordion,\n ore accordion item,\n ore alert,\n ore async,\n ore avatar,\n ore avatar group,\n ore badge,\n ore box,\n ore breadcrumb,\n ore breadcrumb item,\n ore button,\n ore button group,\n ore calendar,\n ore card,\n ore carousel,\n ore carousel slide,\n ore chat message,\n ore checkbox,\n ore checkbox group,\n ore chip,\n ore code window,\n ore column,\n ore combobox,\n ore combobox option,\n ore command palette,\n ore command palette item,\n ore cookie banner,\n ore copy command,\n ore counter,\n ore datagrid,\n ore date picker,\n ore dialog,\n ore drawer,\n ore file input,\n ore grid,\n ore grid item,\n ore icon,\n ore input,\n ore keyboard key,\n ore keyboard shortcut,\n ore list,\n ore list item,\n ore marquee,\n ore menu,\n ore menu item,\n ore menu separator,\n ore message composer,\n ore navbar,\n ore navbar item,\n ore navigation menu,\n ore navigation menu item,\n ore navigation menu panel,\n ore number input,\n ore otp input,\n ore pagination,\n ore password strength,\n ore popover,\n ore progress,\n ore qr code,\n ore qr scanner,\n ore query bar,\n ore radio,\n ore radio group,\n ore rating,\n ore select,\n ore separator,\n ore sidebar,\n ore sidebar group,\n ore sidebar item,\n ore skeleton,\n ore slider,\n ore speech player,\n ore speed reading,\n ore spotlight,\n ore stats,\n ore step,\n ore stepper,\n ore switch,\n ore tab item,\n ore tab panel,\n ore table,\n ore tabs,\n ore td,\n ore text,\n ore th,\n ore tr,\n ore textarea,\n ore time picker,\n ore toast,\n ore tooltip,\n ore tour,\n ore typing indicator,\n ]\nenvironments: [browser]\n \n\n<! markdownlint disable md025 md033 md060 >\n\n<packagehero package=\"refine\" />\n\n## why refine?\n\nevery project needs ui primitives. refine provides accessible web components that work natively anywhere html is rendered, no framework required.\n\n```html\n<! before: roll your own button with aria >\n<button class=\"btn btn primary\" role=\"button\" aria pressed=\"false\" tabindex=\"0\">\n <span class=\"btn spinner\" aria hidden=\"true\"></span>\n save\n</button>\n\n<! after: refine >\n<ore button variant=\"solid\" color=\"primary\" loading>save</ore button>\n```\n\n| feature | refine | shoelace | material web |\n| | | | |\n| bundle size | <packageinfo package=\"refine\" type=\"size\" /> | ~145 kb | ~200 kb |\n| built with | ore | lit | lit |\n| runtime dependencies | vielzeug ui primitives; lucide only for the opt in full library registrar | lit + utilities | lit + material foundations |\n| accessible | wcag aa | wcag aa | wcag aa |\n| framework agnostic | <ore icon name=\"check\" size=\"16\"></ore icon> | <ore icon name=\"check\" size=\"16\"></ore icon> | <ore icon name=\"check\" size=\"16\"></ore icon> |\n\n<div class=\"decision callout\">\n\n**use refine when** you want accessible web components that match the vielzeug design system without a heavy framework dependency.\n\n**consider shoelace or material web** if your team is already standardized on those ecosystems and you need their established component catalogs.\n\n</div>\n\n## installation\n\n::: code group\n\n```sh [pnpm]\npnpm add @vielzeug/refine\n```\n\n```sh [npm]\nnpm install @vielzeug/refine\n```\n\n```sh [yarn]\nyarn add @vielzeug/refine\n```\n\n:::\n\n## quick start\n\n```ts\n// 1. import global styles once\nimport '@vielzeug/refine/fouc.css'; // hide unupgraded custom elements until first paint\nimport '@vielzeug/refine/tokens.css'; // tokens, animations, cascade layers\n\n// 2. register only the elements you need\nimport '@vielzeug/refine/button';\nimport '@vielzeug/refine/input';\nimport '@vielzeug/refine/card';\n```\n\n```html\n<ore button variant=\"solid\" color=\"primary\">save</ore button>\n<ore input label=\"email\" type=\"email\" required></ore input>\n<ore card padding=\"lg\">\n <span slot=\"header\">account</span>\n <p>card content goes here.</p>\n</ore card>\n```\n\n```ts\n```\n\n### cdn / vanilla html\n\nuse the self contained iife bundle to load refine directly from a cdn in any html page: no build step required:\n\n```html\n<! 1. styles >\n<link rel=\"stylesheet\" href=\"https://unpkg.com/@vielzeug/refine/dist/styles/fouc.css\" />\n<link rel=\"stylesheet\" href=\"https://unpkg.com/@vielzeug/refine/dist/styles/tokens.css\" />\n\n<! 2. all components (iife: registers global refine namespace) >\n<script src=\"https://unpkg.com/@vielzeug/refine/dist/refine.iife.js\"></script>\n```\n\nfor bundler based projects that still want a cdn url, use the esm bundle via an import map:\n\n```html\n<script type=\"importmap\">\n {\n \"imports\": {\n \"@vielzeug/refine\": \"https://esm.sh/@vielzeug/refine\",\n \"@vielzeug/refine/button\": \"https://esm.sh/@vielzeug/refine/button\",\n \"@vielzeug/refine/input\": \"https://esm.sh/@vielzeug/refine/input\"\n }\n }\n</script>\n\n<script type=\"module\">\n import '@vielzeug/refine/button';\n import '@vielzeug/refine/input';\n</script>\n```\n\n### package entry points\n\n| import | purpose |\n| | |\n| `@vielzeug/refine/fouc.css` | fouc suppression for unupgraded custom elements |\n| `@vielzeug/refine/tokens.css` | global design tokens and cascade layers |\n| `@vielzeug/refine/styles/preflight.css` | optional browser default reset (includes fouc suppression) |\n\ncomponent registration happens through side effect imports such as `@vielzeug/refine/button` and `@vielzeug/refine/dialog`.\n\n### components\n\n**content:** `ore avatar`, `ore avatar group`, `ore breadcrumb`, `ore card`, `ore carousel`, `ore carousel slide`, `ore chat message`, `ore icon`, `ore keyboard key`, `ore keyboard shortcut`, `ore list`, `ore list item`, `ore marquee`, `ore pagination`, `ore qr code`, `ore separator`, `ore speed reading`, `ore stats`, `ore step`, `ore stepper`, `ore table`, `ore text`\n\n**disclosure:** `ore accordion`, `ore accordion item`, `ore tabs`, `ore tab item`, `ore tab panel`\n\n**feedback:** `ore alert`, `ore async`, `ore badge`, `ore chip`, `ore cookie banner`, `ore password strength`, `ore progress`, `ore skeleton`, `ore toast`, `ore typing indicator`\n\n**inputs:** `ore button`, `ore button group`, `ore calendar`, `ore checkbox`, `ore checkbox group`, `ore column`, `ore combobox`, `ore counter`, `ore datagrid`, `ore date picker`, `ore file input`, `ore input`, `ore message composer`, `ore number input`, `ore otp input`, `ore qr scanner`, `ore query bar`, `ore radio`, `ore radio group`, `ore rating`, `ore select`, `ore slider`, `ore switch`, `ore textarea`, `ore time picker`\n\n**layout:** `ore box`, `ore grid`, `ore grid item`, `ore navbar`, `ore sidebar`\n\n**overlay:** `ore command palette`, `ore command palette item`, `ore dialog`, `ore drawer`, `ore menu`, `ore popover`, `ore spotlight`, `ore tooltip`, `ore tour`\n\n## component portfolio\n\nrefine keeps one public package and classifies components by composition level rather than stability. all listed components remain supported and tested.\n\n **foundations**: buttons, inputs, selection controls, disclosure, dialogs, menus, tooltips, layout primitives, and feedback indicators. start here when building an application specific interface.\n **composed patterns**: data grids, command palettes, navigation menus, steppers, calendars, date/time pickers, file inputs, and message composers. these package recurring accessibility and interaction behavior that is costly to rebuild correctly.\n **presentation patterns**: cards, chat messages, code windows, stats, marquees, avatars, badges, and skeletons. use these when their product vocabulary matches the application; prefer foundations when it does not.\n\nclassification guides discovery and bundle selection. it is not a reason to remove working components or move them into unstable packages; per component subpath imports remain the tree shaking boundary.\n\n## features\n\n<div class=\"features grid\">\n\n **accessible**: keyboard navigation, aria wiring, and focus management across interactive components\n **themeable**: global tokens plus component level css custom properties\n **framework agnostic**: works anywhere html can be rendered\n **tree shakeable**: import only the component entry points you register\n **comprehensive surface**: inputs, content, disclosure, feedback, layout, and overlay primitives\n **native form integration**: form associated controls submit values, validate supported required constraints, and reset with their form\n **typed framework declarations**: dom, react, and vue tags derive from the component property contracts\n\n</div>\n\n### prerequisites\n\n browser runtime with custom elements support.\n import `@vielzeug/refine/fouc.css` and `@vielzeug/refine/tokens.css` before rendering components.\n for ssr, render placeholders server side and hydrate components only on the client.\n\n## documentation\n\n<div class=\"doc links\">\n\n [usage guide](./usage.md)\n [api reference](./api.md)\n [migration guide](./migration.md)\n\n</div>\n\n## see also\n\n<div class=\"see also\">\n\n [ore](/ore/): web component runtime that powers refine\n [orbit](/orbit/): floating ui positioning used in refine's overlays\n [forge](/forge/): form state management for use with refine inputs\n [keymap](/keymap/): keyboard shortcut manager that powers the command palette's global trigger\n\n</div>\n\n<! markdownlint enable md025 md033 md060 >\n",
1060
- "api": " \ntitle: 'refine: api reference'\ndescription: published component, stylesheet, framework type, and error entry points for @vielzeug/refine.\n \n\n[[toc]]\n\n## api overview\n\n| symbol | purpose | execution mode | common gotcha |\n| | | | |\n| `@vielzeug/refine/<component>` | register one custom element and export its public types | sync | importing a type alone does not register the element |\n| `@vielzeug/refine/tokens.css` | load required theme tokens, animations, and cascade layers | css | import once before components render |\n| `@vielzeug/refine/fouc.css` | hide unregistered `ore *` elements until upgrade | css | load before first paint |\n| `@vielzeug/refine/styles/preflight.css` | apply the optional browser reset | css | the reset affects global elements |\n| `@vielzeug/refine/frameworks/elements` | register typed dom tag mappings | types only | import for side effects in typescript |\n| `@vielzeug/refine/frameworks/react` | register typed react jsx elements | types only | does not provide runtime wrappers |\n| `@vielzeug/refine/frameworks/vue` | register typed vue global components | types only | does not install a vue plugin |\n| `@vielzeug/refine/theme` | `createthemecontroller()`: light/dark/system document theme | sync | does not persist the preference or set an accent color |\n| `eventfieldvalue()` / `eventfieldchecked()` | read a form control's value/checked from `event.currenttarget` | sync | exported from the package root; guards non field targets |\n| `refineerror` | base class for package defined public errors | sync | component configuration warnings do not throw this error |\n\n## package entry point\n\n| import | purpose |\n| | |\n| `@vielzeug/refine` | export `registericons`, icon definition types, `refineerror`, and the field readers without registering components |\n| `@vielzeug/refine/<component>` | register one component and export its tag constant, props, events, and related types |\n| `@vielzeug/refine/theme` | `createthemecontroller()` and its theme types |\n| `@vielzeug/refine/tokens.css` | required global design contract |\n| `@vielzeug/refine/fouc.css` | optional pre upgrade visibility rule |\n| `@vielzeug/refine/styles/*` | focused theme, animation, layer, and preflight stylesheets |\n| `@vielzeug/refine/frameworks/*` | typescript augmentations for dom, react, and vue |\n\n## icon registration and adapters\n\n`registericons(icons: readonly<record<string, icondefinition>>): void` is available from `@vielzeug/refine/icons`, `@vielzeug/refine`, and `@vielzeug/refine/icon`. the common `icons` entry and root remain free of component registration side effects.\n\n`icondefinition`, `iconelement`, and `iconattributes` are exported from all three entries. shared definition and registration modules live in `src/icons/`, alongside adapters and internal svg helpers/defaults. definitions contain a numeric `viewbox` tuple, optional presentation attributes, and recursive svg children; they do not require a provider identity. invalid registrations throw the root exported `refineerror` atomically.\n\n| entry | export | purpose |\n| | | |\n| `@vielzeug/refine/icons` | `registericons`, `icondefinition`, `iconelement`, `iconattributes` | common library neutral registration and definition api |\n| `@vielzeug/refine/icons/lucide` | `lucideicons`, `lucideicondata` | pure adapter for selected structural lucide svg data |\n| `@vielzeug/refine/icons/lucide/all` | side effect registration | explicitly register the full installed lucide library |\n| `@vielzeug/refine/icons/heroicons` | `heroiconsicons`, `iconifyicon` | convert a caller named map of individual heroicons iconify data |\n| `@vielzeug/refine/icons/tabler` | `tablericons`, `iconifyicon` | convert a caller named map of individual tabler iconify data |\n| `@vielzeug/refine/icons/mdi` | `mdiicons`, `iconifyicon` | convert a caller named map of individual mdi iconify data |\n| `@vielzeug/refine/icons/iconify` | `iconifyicon`, `iconifyicons` | convert individual iconify data or selected/complete collections |\n| `@vielzeug/refine/icons/iconify` | `iconifyicon`, `iconifyalias`, `iconifycollection`, `iconifytransform` | structural data types; no iconify dependency required |\n\nlucide is an optional peer, not a mandatory dependency. only `icons/lucide/all` requires an installed `lucide` package; consumers selecting that entry declare it themselves. the structural `icons/lucide` adapter accepts supplied data without importing lucide.\n\nthe standalone iife exposes `registericons`, `lucideicons`, `heroiconsicons`, `tablericons`, `mdiicons`, `iconifyicon`, and `iconifyicons` under `refine.components.content`. neither the iife nor component entries import lucide. iconify conversion drops provider `class` metadata, validates finite numeric offsets and positive finite dimensions before transforms, and retains the strict svg allowlist. see the [icon reference](./components/icon.md) for presentation overrides, local svg id rewriting, supported families, and licenses.\n\nthe three family adapters share this signature:\n\n```ts\nheroiconsicons(icons: readonly<record<string, iconifyicon>>): record<string, icondefinition>;\ntablericons(icons: readonly<record<string, iconifyicon>>): record<string, icondefinition>;\nmdiicons(icons: readonly<record<string, iconifyicon>>): record<string, icondefinition>;\n```\n\neach accepts individual iconify svg data, preserves input keys without adding a namespace, and returns definitions without registering them. they require `domparser`, preserve each icon's geometry/presentation/transforms, and throw `refineerror` for invalid iconify data. they do not accept react/vue components, collection json, or raw svg path strings. use `iconifyicons(collection, names?)` for collections and alias resolution.\n\n## styles\n\n```ts\nimport '@vielzeug/refine/fouc.css';\nimport '@vielzeug/refine/tokens.css';\nimport '@vielzeug/refine/styles/preflight.css';\n```\n\n`tokens.css` is required. it defines tokens, animations, and cascade layer order without resetting global elements. `preflight.css` is optional and includes fouc suppression.\n\n| import path | purpose |\n| | |\n| `@vielzeug/refine/fouc.css` | fouc suppression for unupgraded custom elements |\n| `@vielzeug/refine/tokens.css` | tokens, animation helpers, and cascade layers |\n| `@vielzeug/refine/styles/theme.css` | theme token declarations |\n| `@vielzeug/refine/styles/animation.css` | animation helpers |\n| `@vielzeug/refine/styles/layers.css` | cascade layer declarations |\n| `@vielzeug/refine/styles/preflight.css` | optional browser reset and fouc suppression |\n\n## components\n\neach component uses one registration and type entry point:\n\n```ts\nimport '@vielzeug/refine/button';\nimport type { orebuttonprops } from '@vielzeug/refine/button';\n```\n\n| area | components |\n| | |\n| content | `avatar`, `avatar group`, `breadcrumb`, `card`, `carousel`, `chat message`, `code window`, `copy command`, `icon`, `keyboard key`, `list`, `list item`, `marquee`, `pagination`, `separator`, `speech player`, `speed reading`, `stats`, `step`, `stepper`, `table`, `text` |\n| disclosure | `accordion`, `accordion item`, `tabs`, `tab item`, `tab panel` |\n| feedback | `alert`, `async`, `badge`, `chip`, `cookie banner`, `password strength`, `progress`, `skeleton`, `toast`, `typing indicator` |\n| inputs | `button`, `button group`, `calendar`, `checkbox`, `checkbox group`, `combobox`, `counter`, `datagrid`, `date picker`, `file input`, `input`, `message composer`, `number input`, `otp input`, `query bar`, `radio`, `radio group`, `rating`, `select`, `slider`, `switch`, `textarea`, `time picker` |\n| layout | `box`, `grid`, `grid item`, `navbar`, `sidebar` |\n| overlays | `command palette`, `dialog`, `drawer`, `menu`, `navigation menu`, `popover`, `tooltip` |\n\neach component page lists its attributes, javascript properties, events, slots, parts, and css custom properties.\n\nthe [`query bar`](./components/query bar.md) entry also exports `querystate`, `querytokendef`, `queryquickfilter`, `querybarlabels`, and pure grammar helpers. vocabulary entries default to single selection; `selection: 'multiple'` allows distinct values for the same key. `anylabel` customizes the unrestricted single selection choice, such as “default order” for sorting. options accept an optional `icon` (registered `ore icon` name), displayed beside their labels in the drawer. `tokenvalues(state, key)` reads all values, `removetoken(state, token)` removes an exact pair, and `cleartokens(state, key)` clears a group. its unified field contains applied filters, with a compact secondary row for filter entry, quick toggles, and a `toolbar end` slot for application content such as a result count. drawer selection uses the same state and vocabulary as typed suggestions. pending edits block incidental backdrop/swipe dismissal; explicit cancel, close, and escape discard them. search hidden selections remain visible in a summary.\n\n## framework types\n\n```ts\nimport type {} from '@vielzeug/refine/frameworks/elements';\nimport type {} from '@vielzeug/refine/frameworks/react';\nimport type {} from '@vielzeug/refine/frameworks/vue';\n```\n\nthe declarations cover every supported tag and derive component properties from refine's authoritative `htmlelementtagnamemap`. they provide types only; component registration still uses component subpaths.\n\n## events and form controls\n\nform controls expose `.value` or `.checked` and dispatch standard `input` and `change` events. read the property from `event.currenttarget`.\n\nfinite choice properties use ore's `prop.oneof()` parsing: values outside a component's documented options resolve to\nthe declared default, or `undefined` when no default is declared.\n\nform associated controls participate in native form submission, validity checks, and reset. a named control's value\nis available through `new formdata(form)`, and supported `required` constraints affect `form.checkvalidity()`,\n`form.reportvalidity()`, and submit blocking. the `error` property renders and announces feedback; it does not by\nitself set native constraint validity.\n\nstateful overlays expose controlled `open`, optional `default open`, and an `open change` custom event with `{ open, reason }` detail. component pages define additional detail fields and reasons.\n\n## utilities\n\n### `createthemecontroller(options?)`\n\n```ts\nimport { createthemecontroller } from '@vielzeug/refine/theme';\n\nconst theme = createthemecontroller(); // starts in 'system' mode\ntheme.setpreference('dark');\ntheme.dispose();\n```\n\nowns the light/dark/system theme for the document: a reactive `preference` signal, the effective `resolved` mode (`'dark' | 'light'` after resolving `system` against the os), and the dom application `styles/theme.css` expects: the `.dark` class plus the `color scheme` property on the root element, so every `light dark()` token resolves to the right branch. while in `system` mode the controller tracks the os `prefers color scheme` via sentinel's `createmediaquery`.\n\nthe controller does **not** persist the preference or expose an accent color: those are consumer concerns (wire `watch(controller.preference, save)` for persistence; set ` color primary hue` yourself). options: `initial` (starting preference, default `'system'`), `root` (element carrying the classes, default `document.documentelement`), `target` (window whose `matchmedia` backs `system`). the handle is disposable: `dispose()`, `disposed`, `disposalsignal`, `[symbol.dispose]`.\n\n### `eventfieldvalue(event)` / `eventfieldchecked(event)`\n\n```ts\nimport { eventfieldchecked, eventfieldvalue } from '@vielzeug/refine';\n\ninput.addeventlistener('input', (event) => {\n const value = eventfieldvalue(event); // string | undefined: never a blind cast\n});\n```\n\nguarded readers for the standard `input`/`change` event pattern above: they read `value`/`checked` from `event.currenttarget` only when the target actually carries it, so a handler wired to the wrong element yields `undefined`/`false` instead of a crash or a lie. exported from the package root, which registers no components.\n\n## types\n\ncomponent props follow the `ore<component>props` naming pattern. event maps follow `ore<component>events`. import both from the component subpath that owns them.\n\n`refineelementmap`, `refinereactintrinsicelements`, and `refinevueglobalcomponents` are exported from their respective `frameworks/*` type entry points.\n\n## errors\n\n### `refineerror`\n\n```ts\nclass refineerror extends error {\n constructor(message: string, opts?: erroroptions);\n}\n```\n\nbase class for public refine errors. it preserves `cause` through `erroroptions`.\n",
1061
- "usage": " \ntitle: 'refine: usage guide'\ndescription: register refine components, configure properties, handle events, compose slots, and integrate frameworks.\n \n\n[[toc]]\n\n## basic usage\n\nload the global design contract once, then register only the components used by the page.\n\n```ts\nimport '@vielzeug/refine/tokens.css';\nimport '@vielzeug/refine/button';\nimport '@vielzeug/refine/input';\nimport '@vielzeug/refine/dialog';\n\nconst input = document.queryselector('ore input');\nconst save = document.queryselector('ore button');\n\nif (!(input instanceof htmlelement) || !(save instanceof htmlelement)) {\n throw new error('expected refine controls');\n}\n\nsave.addeventlistener('click', () => {\n console.log((input as htmlelement & { value: string }).value);\n});\n```\n\nadd the browser reset only when the application owns global element styling:\n\n```ts\nimport '@vielzeug/refine/styles/preflight.css';\n```\n\n## choose an icon library\n\nrefine includes only its internal component icons. register application icons before mounting them: use `registericons` and neutral `icondefinition` data from `@vielzeug/refine/icons`, the pure `@vielzeug/refine/icons/lucide` adapter for selected lucide icons, or `@vielzeug/refine/icons/iconify` for local heroicons, tabler, and material design icons data. keep importing the component from `@vielzeug/refine/icon`. lucide is an optional peer: install `lucide` yourself only when choosing its data or `@vielzeug/refine/icons/lucide/all`; core and structural adapters do not require it. the [icon reference](./components/icon.md) covers imports, licenses, and presentation behavior.\n\nfor selected individual iconify data, use `heroiconsicons`, `tablericons`, or `mdiicons` from `@vielzeug/refine/icons/heroicons`, `/tabler`, or `/mdi`. for example, `registericons(heroiconsicons({ search, home }))` preserves your app keys. install the matching `@iconify icons/<family>` data package yourself; these helpers do not accept framework components. keep `iconifyicons` for collection json and aliases.\n\n## set attributes and properties\n\nuse attributes for serializable html state.\n\n```html\n<ore button variant=\"outline\" color=\"secondary\" size=\"lg\" disabled>\n save changes\n</ore button>\n```\n\nuse javascript properties for arrays, objects, callbacks, and controlled state.\n\n```ts\nimport '@vielzeug/refine/datagrid';\nimport type { oredatagridprops } from '@vielzeug/refine/datagrid';\n\nconst grid = document.queryselector('ore datagrid') as htmlelement & oredatagridprops;\ngrid.columns = [\n { key: 'name', label: 'name', sortable: true },\n { key: 'role', label: 'role' },\n];\ngrid.rows = [\n { id: '1', name: 'ada', role: 'admin' },\n { id: '2', name: 'linus', role: 'editor' },\n];\n```\n\nenumerated properties such as `variant`, `size`, and `color` accept the values listed on each component's reference\npage. an unsupported value resolves to the property's declared default (or `undefined` when it has no default).\n\nin an ore template, `model()` can bind a refine field's `value` to a ripple signal and write user input back:\n\n```ts\nimport { signal } from '@vielzeug/ripple';\nimport { html, model } from '@vielzeug/ore';\nimport '@vielzeug/refine/input';\n\nconst email = signal('');\nconst field = html`<ore input label=\"email\" type=\"email\" value=${model(email)} />`;\n```\n\n## handle events\n\nform controls dispatch standard `input` and `change` events. read their current property from `event.currenttarget`.\n\n```ts\nconst input = document.queryselector('ore input');\ninput?.addeventlistener('input', (event) => {\n const target = event.currenttarget as htmlelement & { value: string };\n console.log(target.value);\n});\n```\n\ncustom events use kebab case names and typed detail objects.\n\n```ts\nimport type { oredialogevents } from '@vielzeug/refine/dialog';\n\nconst dialog = document.queryselector('ore dialog');\ndialog?.addeventlistener('open change', (event: customevent<oredialogevents['open change']>) => {\n console.log(event.detail.open, event.detail.reason);\n});\n```\n\n## native form validation\n\nrefine's form associated controls integrate with native form submission, `formdata`, validity checks, and reset.\nuse `required` for a required value constraint; setting `error` displays and announces feedback but does not, by\nitself, invalidate the form.\n\n```html\n<form id=\"profile form\">\n <ore input name=\"email\" type=\"email\" label=\"email\" required></ore input>\n <ore select name=\"role\" label=\"role\" required>\n <option value=\"\">choose a role…</option>\n <option value=\"editor\">editor</option>\n <option value=\"admin\">admin</option>\n </ore select>\n <ore button type=\"submit\">save</ore button>\n</form>\n\n<script type=\"module\">\n import '@vielzeug/refine/input';\n import '@vielzeug/refine/select';\n import '@vielzeug/refine/button';\n\n const form = document.queryselector('#profile form');\n form.addeventlistener('submit', (event) => {\n event.preventdefault();\n console.log(new formdata(form).get('email'));\n });\n</script>\n```\n\nthe browser runs native validation before dispatching `submit`. call `form.reportvalidity()` to show validation\nfeedback directly, or `form.checkvalidity()` for a boolean check without the browser's validation ui.\n\n## compose slots\n\ndefault slots hold primary content. named slots identify component owned regions.\n\n```html\n<ore card>\n <span slot=\"header\">account</span>\n <p>profile settings</p>\n <div slot=\"footer\">\n <ore button variant=\"ghost\">cancel</ore button>\n <ore button>save</ore button>\n </div>\n</ore card>\n```\n\ninput components commonly expose `prefix`, `suffix`, `label`, `helper`, and `error` slots. each component reference lists its supported slots.\n\n## load typescript framework declarations\n\nimport the declaration matching the framework once in an application type entry point.\n\n::: code group\n\n```ts [dom]\nimport type {} from '@vielzeug/refine/frameworks/elements';\n```\n\n```ts [react]\nimport type {} from '@vielzeug/refine/frameworks/react';\n```\n\n```ts [vue]\nimport type {} from '@vielzeug/refine/frameworks/vue';\n```\n\n:::\n\nthese entry points provide typed tags and component properties. they do not register components or install runtime adapters.\n\n## framework integration\n\nrefine elements use native dom properties, events, and slots. frameworks differ only in how they forward custom element properties and events.\n\n::: code group\n\n```tsx [react 19]\nimport '@vielzeug/refine/button';\n\nexport function savebutton() {\n return <ore button variant=\"solid\">save</ore button>;\n}\n```\n\n```vue [vue 3]\n<script setup lang=\"ts\">\nimport '@vielzeug/refine/button';\n</script>\n\n<template>\n <ore button variant=\"solid\">save</ore button>\n</template>\n```\n\n```svelte [svelte]\n<script lang=\"ts\">\n import '@vielzeug/refine/button';\n</script>\n\n<ore button variant=\"solid\">save</ore button>\n```\n\n:::\n\nsee [framework integration](./frameworks.md) for custom events, controlled properties, ssr guards, and framework specific configuration.\n\n## working with other vielzeug libraries\n\n### ore\n\nuse ore when authoring a custom element that composes refine components.\n\n```ts\nimport '@vielzeug/refine/button';\nimport { define, html } from '@vielzeug/ore';\n\ndefine('save panel', {\n setup() {\n return html`<ore button @click=${() => console.log('save')}>save</ore button>`;\n },\n});\n```\n\n### ripple\n\nuse ripple to drive component properties from application state.\n\n```ts\nimport '@vielzeug/refine/button';\nimport { effect, signal } from '@vielzeug/ripple';\n\nconst loading = signal(false);\nconst button = document.queryselector('ore button') as htmlelement & { loading?: boolean };\nconst loadingeffect = effect(() => {\n button.loading = loading.value;\n});\n\nloadingeffect.dispose();\n```\n\n## best practices\n\n **import** `tokens.css` once before rendering components.\n **register** components through explicit subpaths.\n **set** structured data and callbacks as javascript properties.\n **read** form state from the event target instead of custom event payloads.\n **provide** accessible labels for icon only controls.\n **use** component reference pages for supported slots, parts, and css properties.\n **dispose** application owned ripple effects and service handles.\n **guard** dom dependent component registration during ssr.\n **working with ai agents?** install the `vielzeug` skill (`npx y @vielzeug/codex skills install`) so agents reach for refine components and tokens instead of custom widgets: see the [codex usage guide](../codex/usage.md#agent skill).\n"
1059
+ "index": " \ntitle: 'refine: web component library'\ndescription: accessible, themeable web components built with ore for framework and vanilla dom apps.\npackage: refine\ncategory: ui components\nkeywords: [web components, accessible, themeable, ui, components, design system]\nrelated: [ore, orbit, forge, keymap]\nexports:\n [\n ore accordion,\n ore accordion item,\n ore alert,\n ore async,\n ore avatar,\n ore avatar group,\n ore badge,\n ore box,\n ore breadcrumb,\n ore breadcrumb item,\n ore button,\n ore button group,\n ore calendar,\n ore card,\n ore carousel,\n ore carousel slide,\n ore chat message,\n ore checkbox,\n ore checkbox group,\n ore chip,\n ore code window,\n ore column,\n ore combobox,\n ore combobox option,\n ore command palette,\n ore command palette item,\n ore cookie banner,\n ore copy command,\n ore counter,\n ore datagrid,\n ore date picker,\n ore dialog,\n ore drawer,\n ore file input,\n ore grid,\n ore grid item,\n ore icon,\n ore input,\n ore keyboard key,\n ore keyboard shortcut,\n ore list,\n ore list item,\n ore marquee,\n ore menu,\n ore menu item,\n ore menu separator,\n ore message composer,\n ore navbar,\n ore navbar item,\n ore navigation menu,\n ore navigation menu item,\n ore navigation menu panel,\n ore number input,\n ore otp input,\n ore pagination,\n ore password strength,\n ore popover,\n ore progress,\n ore qr code,\n ore qr scanner,\n ore query bar,\n ore radio,\n ore radio group,\n ore rating,\n ore select,\n ore separator,\n ore sidebar,\n ore sidebar group,\n ore sidebar item,\n ore skeleton,\n ore slider,\n ore speech player,\n ore speed reading,\n ore spotlight,\n ore stats,\n ore step,\n ore stepper,\n ore switch,\n ore tab item,\n ore tab panel,\n ore table,\n ore tabs,\n ore td,\n ore text,\n ore th,\n ore tr,\n ore textarea,\n ore time picker,\n ore toast,\n ore tooltip,\n ore tour,\n ore typing indicator,\n ]\nenvironments: [browser]\n \n\n<! markdownlint disable md025 md033 md060 >\n\n<packagehero package=\"refine\" />\n\n## why refine?\n\nevery project needs ui primitives. refine provides accessible web components that work natively anywhere html is rendered, no framework required.\n\n```html\n<! before: roll your own button with aria >\n<button class=\"btn btn primary\" role=\"button\" aria pressed=\"false\" tabindex=\"0\">\n <span class=\"btn spinner\" aria hidden=\"true\"></span>\n save\n</button>\n\n<! after: refine >\n<ore button variant=\"solid\" color=\"primary\" loading>save</ore button>\n```\n\n| feature | refine | shoelace | material web |\n| | | | |\n| bundle size | <packageinfo package=\"refine\" type=\"size\" /> | ~145 kb | ~200 kb |\n| built with | ore | lit | lit |\n| runtime dependencies | vielzeug ui primitives; lucide only for the opt in full library registrar | lit + utilities | lit + material foundations |\n| accessible | wcag aa | wcag aa | wcag aa |\n| framework agnostic | <ore icon name=\"check\" size=\"16\"></ore icon> | <ore icon name=\"check\" size=\"16\"></ore icon> | <ore icon name=\"check\" size=\"16\"></ore icon> |\n\n<div class=\"decision callout\">\n\n**use refine when** you want accessible web components that match the vielzeug design system without a heavy framework dependency.\n\n**consider shoelace or material web** if your team is already standardized on those ecosystems and you need their established component catalogs.\n\n</div>\n\n## installation\n\n::: code group\n\n```sh [pnpm]\npnpm add @vielzeug/refine\n```\n\n```sh [npm]\nnpm install @vielzeug/refine\n```\n\n```sh [yarn]\nyarn add @vielzeug/refine\n```\n\n:::\n\n## quick start\n\n```ts\n// 1. import global styles once\nimport '@vielzeug/refine/fouc.css'; // hide unupgraded custom elements until first paint\nimport '@vielzeug/refine/tokens.css'; // tokens, animations, cascade layers\n\n// 2. register only the elements you need\nimport '@vielzeug/refine/button';\nimport '@vielzeug/refine/input';\nimport '@vielzeug/refine/card';\n```\n\n```html\n<ore button variant=\"solid\" color=\"primary\">save</ore button>\n<ore input label=\"email\" type=\"email\" required></ore input>\n<ore card padding=\"lg\">\n <span slot=\"header\">account</span>\n <p>card content goes here.</p>\n</ore card>\n```\n\n```ts\n```\n\n### cdn / vanilla html\n\nuse the self contained iife bundle to load refine directly from a cdn in any html page: no build step required:\n\n```html\n<! 1. styles >\n<link rel=\"stylesheet\" href=\"https://unpkg.com/@vielzeug/refine/dist/styles/fouc.css\" />\n<link rel=\"stylesheet\" href=\"https://unpkg.com/@vielzeug/refine/dist/styles/tokens.css\" />\n\n<! 2. all components (iife: registers global refine namespace) >\n<script src=\"https://unpkg.com/@vielzeug/refine/dist/refine.iife.js\"></script>\n```\n\nfor bundler based projects that still want a cdn url, use the esm bundle via an import map:\n\n```html\n<script type=\"importmap\">\n {\n \"imports\": {\n \"@vielzeug/refine\": \"https://esm.sh/@vielzeug/refine\",\n \"@vielzeug/refine/button\": \"https://esm.sh/@vielzeug/refine/button\",\n \"@vielzeug/refine/input\": \"https://esm.sh/@vielzeug/refine/input\"\n }\n }\n</script>\n\n<script type=\"module\">\n import '@vielzeug/refine/button';\n import '@vielzeug/refine/input';\n</script>\n```\n\n### package entry points\n\n| import | purpose |\n| | |\n| `@vielzeug/refine/fouc.css` | fouc suppression for unupgraded custom elements |\n| `@vielzeug/refine/tokens.css` | global design tokens and cascade layers |\n| `@vielzeug/refine/styles/preflight.css` | optional browser default reset (includes fouc suppression) |\n\ncomponent registration happens through side effect imports such as `@vielzeug/refine/button` and `@vielzeug/refine/dialog`.\n\n### components\n\neach entry below is a component with its own documentation page and registration subpath. sub element tags (`ore accordion item`, `ore tab item`, `ore avatar group`, and the rest) are documented on their parent's page and registered with it.\n\n**content:** `ore accordion`, `ore avatar`, `ore card`, `ore carousel`, `ore chat message`, `ore chat panel`, `ore code window`, `ore copy command`, `ore icon`, `ore keyboard key`, `ore list`, `ore marquee`, `ore qr code`, `ore rank list`, `ore speech player`, `ore speed reading`, `ore stats`, `ore table`, `ore text`\n\n**feedback:** `ore alert`, `ore async`, `ore badge`, `ore chip`, `ore cookie banner`, `ore password strength`, `ore progress`, `ore skeleton`, `ore toast`, `ore typing indicator`\n\n**inputs:** `ore button`, `ore calendar`, `ore checkbox`, `ore combobox`, `ore counter`, `ore datagrid`, `ore date picker`, `ore file input`, `ore input`, `ore message composer`, `ore number input`, `ore otp input`, `ore qr scanner`, `ore query bar`, `ore radio`, `ore rating`, `ore select`, `ore slider`, `ore switch`, `ore textarea`, `ore time picker`\n\n**layout:** `ore box`, `ore grid`, `ore navbar`, `ore separator`, `ore sidebar`\n\n**navigation:** `ore breadcrumb`, `ore navigation menu`, `ore pagination`, `ore stepper`, `ore tabs`\n\n**overlay:** `ore command palette`, `ore dialog`, `ore drawer`, `ore menu`, `ore popover`, `ore spotlight`, `ore tooltip`, `ore tour`\n\n## component portfolio\n\nrefine keeps one public package and classifies components by composition level rather than stability. all listed components remain supported and tested.\n\n **foundations**: buttons, inputs, selection controls, accordions, dialogs, menus, tooltips, layout primitives, and feedback indicators. start here when building an application specific interface.\n **composed patterns**: data grids, command palettes, navigation menus, steppers, calendars, date/time pickers, file inputs, and message composers. these package recurring accessibility and interaction behavior that is costly to rebuild correctly.\n **presentation patterns**: cards, chat messages, code windows, stats, marquees, avatars, badges, and skeletons. use these when their product vocabulary matches the application; prefer foundations when it does not.\n\nclassification guides discovery and bundle selection. it is not a reason to remove working components or move them into unstable packages; per component subpath imports remain the tree shaking boundary.\n\n## features\n\n<div class=\"features grid\">\n\n **accessible**: keyboard navigation, aria wiring, and focus management across interactive components\n **themeable**: global tokens plus component level css custom properties\n **motion safe**: every animation routes through duration tokens and honors motion mode (`setmotionmode`) with a reduced motion floor\n **framework agnostic**: works anywhere html can be rendered\n **tree shakeable**: import only the component entry points you register\n **comprehensive surface**: inputs, content, navigation, feedback, layout, and overlay primitives\n **native form integration**: form associated controls submit values, validate supported required constraints, and reset with their form\n **typed framework declarations**: dom, react, and vue tags derive from the component property contracts\n\n</div>\n\n### prerequisites\n\n browser runtime with custom elements support.\n import `@vielzeug/refine/fouc.css` and `@vielzeug/refine/tokens.css` before rendering components.\n for ssr, render placeholders server side and hydrate components only on the client.\n\n## documentation\n\n<div class=\"doc links\">\n\n [usage guide](./usage.md)\n [api reference](./api.md)\n [animation & motion](./animation.md)\n [migration guide](./migration.md)\n\n</div>\n\n## see also\n\n<div class=\"see also\">\n\n [ore](/ore/): web component runtime that powers refine\n [orbit](/orbit/): floating ui positioning used in refine's overlays\n [forge](/forge/): form state management for use with refine inputs\n [keymap](/keymap/): keyboard shortcut manager that powers the command palette's global trigger\n\n</div>\n\n<! markdownlint enable md025 md033 md060 >\n",
1060
+ "api": " \ntitle: 'refine: api reference'\ndescription: published component, stylesheet, framework type, and error entry points for @vielzeug/refine.\n \n\n[[toc]]\n\n## api overview\n\n| symbol | purpose | execution mode | common gotcha |\n| | | | |\n| `@vielzeug/refine/<component>` | register one custom element and export its public types | sync | importing a type alone does not register the element |\n| `@vielzeug/refine/tokens.css` | load required theme tokens, animations, and cascade layers | css | import once before components render |\n| `@vielzeug/refine/fouc.css` | hide unregistered `ore *` elements until upgrade | css | load before first paint |\n| `@vielzeug/refine/styles/preflight.css` | apply the optional browser reset | css | the reset affects global elements |\n| `@vielzeug/refine/frameworks/elements` | register typed dom tag mappings | types only | import for side effects in typescript |\n| `@vielzeug/refine/frameworks/react` | register typed react jsx elements | types only | does not provide runtime wrappers |\n| `@vielzeug/refine/frameworks/vue` | register typed vue global components | types only | does not install a vue plugin |\n| `@vielzeug/refine/theme` | `createthemecontroller()`: light/dark/system document theme | sync | does not persist the preference or set an accent color |\n| `eventfieldvalue()` / `eventfieldchecked()` | read a form control's value/checked from `event.currenttarget` | sync | exported from the package root; guards non field targets |\n| `animatereflow()` | token driven flip reflow for keyed lists | async (next frame) | exported from the package root; elements need stable keys or it correctly does nothing |\n| `setmotionmode()` / `getmotionmode()` | read/write the `data motion` attribute on `<html>` | sync | exported from the package root; an unknown mode throws `rangeerror` |\n| `refineerror` | base class for package defined public errors | sync | component configuration warnings do not throw this error |\n\n## package entry point\n\n| import | purpose |\n| | |\n| `@vielzeug/refine` | export `registericons`, icon definition types, `refineerror`, `animatereflow`, the motion mode functions, and the field readers without registering components |\n| `@vielzeug/refine/<component>` | register one component and export its tag constant, props, events, and related types |\n| `@vielzeug/refine/theme` | `createthemecontroller()` and its theme types |\n| `@vielzeug/refine/tokens.css` | required global design contract |\n| `@vielzeug/refine/fouc.css` | optional pre upgrade visibility rule |\n| `@vielzeug/refine/styles/*` | focused theme, animation, layer, and preflight stylesheets |\n| `@vielzeug/refine/frameworks/*` | typescript augmentations for dom, react, and vue |\n\n## icon registration and adapters\n\n`registericons(icons: readonly<record<string, icondefinition>>): void` is available from `@vielzeug/refine/icons`, `@vielzeug/refine`, and `@vielzeug/refine/icon`. the common `icons` entry and root remain free of component registration side effects.\n\n`icondefinition`, `iconelement`, and `iconattributes` are exported from all three entries. shared definition and registration modules live in `src/icons/`, alongside adapters and internal svg helpers/defaults. definitions contain a numeric `viewbox` tuple, optional presentation attributes, and recursive svg children; they do not require a provider identity. invalid registrations throw the root exported `refineerror` atomically.\n\n| entry | export | purpose |\n| | | |\n| `@vielzeug/refine/icons` | `registericons`, `icondefinition`, `iconelement`, `iconattributes` | common library neutral registration and definition api |\n| `@vielzeug/refine/icons/lucide` | `lucideicons`, `lucideicondata` | pure adapter for selected structural lucide svg data |\n| `@vielzeug/refine/icons/lucide/all` | side effect registration | explicitly register the full installed lucide library |\n| `@vielzeug/refine/icons/heroicons` | `heroiconsicons`, `iconifyicon` | convert a caller named map of individual heroicons iconify data |\n| `@vielzeug/refine/icons/tabler` | `tablericons`, `iconifyicon` | convert a caller named map of individual tabler iconify data |\n| `@vielzeug/refine/icons/mdi` | `mdiicons`, `iconifyicon` | convert a caller named map of individual mdi iconify data |\n| `@vielzeug/refine/icons/iconify` | `iconifyicon`, `iconifyicons` | convert individual iconify data or selected/complete collections |\n| `@vielzeug/refine/icons/iconify` | `iconifyicon`, `iconifyalias`, `iconifycollection`, `iconifytransform` | structural data types; no iconify dependency required |\n\nlucide is an optional peer, not a mandatory dependency. only `icons/lucide/all` requires an installed `lucide` package; consumers selecting that entry declare it themselves. the structural `icons/lucide` adapter accepts supplied data without importing lucide.\n\nthe standalone iife exposes `registericons`, `lucideicons`, `heroiconsicons`, `tablericons`, `mdiicons`, `iconifyicon`, and `iconifyicons` under `refine.components.content`. neither the iife nor component entries import lucide. iconify conversion drops provider `class` metadata, validates finite numeric offsets and positive finite dimensions before transforms, and retains the strict svg allowlist. see the [icon reference](./components/icon.md) for presentation overrides, local svg id rewriting, supported families, and licenses.\n\nthe three family adapters share this signature:\n\n```ts\nheroiconsicons(icons: readonly<record<string, iconifyicon>>): record<string, icondefinition>;\ntablericons(icons: readonly<record<string, iconifyicon>>): record<string, icondefinition>;\nmdiicons(icons: readonly<record<string, iconifyicon>>): record<string, icondefinition>;\n```\n\neach accepts individual iconify svg data, preserves input keys without adding a namespace, and returns definitions without registering them. they require `domparser`, preserve each icon's geometry/presentation/transforms, and throw `refineerror` for invalid iconify data. they do not accept react/vue components, collection json, or raw svg path strings. use `iconifyicons(collection, names?)` for collections and alias resolution.\n\n## styles\n\n```ts\nimport '@vielzeug/refine/fouc.css';\nimport '@vielzeug/refine/tokens.css';\nimport '@vielzeug/refine/styles/preflight.css';\n```\n\n`tokens.css` is required. it defines tokens, animations, and cascade layer order without resetting global elements. `preflight.css` is optional and includes fouc suppression.\n\n| import path | purpose |\n| | |\n| `@vielzeug/refine/fouc.css` | fouc suppression for unupgraded custom elements |\n| `@vielzeug/refine/tokens.css` | tokens, animation helpers, and cascade layers |\n| `@vielzeug/refine/styles/theme.css` | theme token declarations |\n| `@vielzeug/refine/styles/animation.css` | animation helpers |\n| `@vielzeug/refine/styles/layers.css` | cascade layer declarations |\n| `@vielzeug/refine/styles/preflight.css` | optional browser reset and fouc suppression |\n\n## components\n\neach component uses one registration and type entry point:\n\n```ts\nimport '@vielzeug/refine/button';\nimport type { orebuttonprops } from '@vielzeug/refine/button';\n```\n\n| area | components |\n| | |\n| content | `accordion`, `avatar`, `card`, `carousel`, `chat message`, `chat panel`, `code window`, `copy command`, `icon`, `keyboard key`, `list`, `marquee`, `qr code`, `rank list`, `speech player`, `speed reading`, `stats`, `table`, `text` |\n| feedback | `alert`, `async`, `badge`, `chip`, `cookie banner`, `password strength`, `progress`, `skeleton`, `toast`, `typing indicator` |\n| inputs | `button`, `calendar`, `checkbox`, `combobox`, `counter`, `datagrid`, `date picker`, `file input`, `input`, `message composer`, `number input`, `otp input`, `qr scanner`, `query bar`, `radio`, `rating`, `select`, `slider`, `switch`, `textarea`, `time picker` |\n| layout | `box`, `grid`, `navbar`, `separator`, `sidebar` |\n| navigation | `breadcrumb`, `navigation menu`, `pagination`, `stepper`, `tabs` |\n| overlay | `command palette`, `dialog`, `drawer`, `menu`, `popover`, `spotlight`, `tooltip`, `tour` |\n\neach row lists the entry points that own a documentation page. sub element entries (`accordion item`, `tab item`, `avatar group`, `list item`, `step`, and the rest) are documented on their parent's page and share its category.\n\neach component page lists its attributes, javascript properties, events, slots, parts, and css custom properties.\n\nthe [`query bar`](./components/query bar.md) entry also exports `querystate`, `querytokendef`, `queryquickfilter`, `querybarlabels`, and pure grammar helpers. vocabulary entries default to single selection; `selection: 'multiple'` allows distinct values for the same key. `anylabel` customizes the unrestricted single selection choice, such as “default order” for sorting. options accept an optional `icon` (registered `ore icon` name), displayed beside their labels in the drawer. `tokenvalues(state, key)` reads all values, `removetoken(state, token)` removes an exact pair, and `cleartokens(state, key)` clears a group. its unified field contains applied filters, with a compact secondary row for filter entry, quick toggles, and a `toolbar end` slot for application content such as a result count. drawer selection uses the same state and vocabulary as typed suggestions. pending edits block incidental backdrop/swipe dismissal; explicit cancel, close, and escape discard them. search hidden selections remain visible in a summary.\n\n## framework types\n\n```ts\nimport type {} from '@vielzeug/refine/frameworks/elements';\nimport type {} from '@vielzeug/refine/frameworks/react';\nimport type {} from '@vielzeug/refine/frameworks/vue';\n```\n\nthe declarations cover every supported tag and derive component properties from refine's authoritative `htmlelementtagnamemap`. they provide types only; component registration still uses component subpaths.\n\n## events and form controls\n\nform controls expose `.value` or `.checked` and dispatch standard `input` and `change` events. read the property from `event.currenttarget`.\n\nfinite choice properties use ore's `prop.oneof()` parsing: values outside a component's documented options resolve to\nthe declared default, or `undefined` when no default is declared.\n\nform associated controls participate in native form submission, validity checks, and reset. a named control's value\nis available through `new formdata(form)`, and supported `required` constraints affect `form.checkvalidity()`,\n`form.reportvalidity()`, and submit blocking. the `error` property renders and announces feedback; it does not by\nitself set native constraint validity.\n\nstateful overlays expose controlled `open`, optional `default open`, and an `open change` custom event with `{ open, reason }` detail. component pages define additional detail fields and reasons.\n\n## utilities\n\n### `createthemecontroller(options?)`\n\n```ts\nimport { createthemecontroller } from '@vielzeug/refine/theme';\n\nconst theme = createthemecontroller(); // starts in 'system' mode\ntheme.setpreference('dark');\ntheme.dispose();\n```\n\nowns the light/dark/system theme for the document: a reactive `preference` signal, the effective `resolved` mode (`'dark' | 'light'` after resolving `system` against the os), and the dom application `styles/theme.css` expects: the `.dark` class plus the `color scheme` property on the root element, so every `light dark()` token resolves to the right branch. while in `system` mode the controller tracks the os `prefers color scheme` via sentinel's `createmediaquery`.\n\nthe controller does **not** persist the preference or expose an accent color: those are consumer concerns (wire `watch(controller.preference, save)` for persistence; set ` color primary hue` yourself). options: `initial` (starting preference, default `'system'`), `root` (element carrying the classes, default `document.documentelement`), `target` (window whose `matchmedia` backs `system`). the handle is disposable: `dispose()`, `disposed`, `disposalsignal`, `[symbol.dispose]`.\n\n### `eventfieldvalue(event)` / `eventfieldchecked(event)`\n\n```ts\nimport { eventfieldchecked, eventfieldvalue } from '@vielzeug/refine';\n\ninput.addeventlistener('input', (event) => {\n const value = eventfieldvalue(event); // string | undefined: never a blind cast\n});\n```\n\nguarded readers for the standard `input`/`change` event pattern above: they read `value`/`checked` from `event.currenttarget` only when the target actually carries it, so a handler wired to the wrong element yields `undefined`/`false` instead of a crash or a lie. exported from the package root, which registers no components.\n\n \n\n### `animatereflow(host, signal, options)`\n\n```ts\nimport { animatereflow } from '@vielzeug/refine';\n\nconst reflow = animatereflow(list, abortcontroller.signal, {\n elements: () => [...list.queryselectorall('li')],\n getkey: (item) => item.dataset.id,\n});\nreflow.run(() => renderitems(nextitems));\n```\n\ntoken driven flip reflow for keyed lists: captures the current layout, runs `mutate`, then animates the tracked elements into their new positions on the next frame. the same helper the datagrid, command palette, and toast stack use.\n\n| parameter | type | description |\n| | | |\n| `host` | `htmlelement` | element whose computed style carries the timing tokens |\n| `signal` | `abortsignal` | aborting cancels in flight animations |\n| `options.elements` | `() => htmlelement[]` | tracked elements, read live on both sides of the mutation |\n| `options.getkey` | `(el) => string \\| undefined` | stable identity per element; all or nothing |\n| `options.durationtoken` | `string?` | duration token, default `' duration 200'` |\n| `options.easingtoken` | `string?` | easing token, default `' ease move'` |\n| `options.stagger` | `number?` | per element delay in ms, default `0` |\n\n**returns** a `reflow` handle with one method: `run(mutate)` (sync; the animation is fire and forget). timing is read from the tokens at animation time, so motion mode reduction skips the reflow instead of playing it instantly. every path that cannot animate (no elements, missing keys, zeroed tokens, aborted signal, no web animations api) still runs `mutate` exactly once and never throws. see [animation & motion → list reflow](./animation#list reflow animatereflow) for behavior details.\n\n \n\n### `setmotionmode(mode)` / `getmotionmode()`\n\n```ts\nimport { getmotionmode, setmotionmode } from '@vielzeug/refine';\n\nsetmotionmode('reduced'); // returns the applied mode\n```\n\nread/write the `data motion` attribute on `<html>` (`'full' | 'reduced' | 'system'`; `'system'` removes the attribute). an unknown mode throws `rangeerror`. the attribute drives the token layer: see [animation & motion → motion mode](./animation#motion mode).\n\n## types\n\ncomponent props follow the `ore<component>props` naming pattern. event maps follow `ore<component>events`. import both from the component subpath that owns them.\n\n`refineelementmap`, `refinereactintrinsicelements`, and `refinevueglobalcomponents` are exported from their respective `frameworks/*` type entry points.\n\nthe package root also exports `reflow` (the `run()` handle), `reflowoptions` (its options object), and `motionmode` (`'full' | 'reduced' | 'system'`).\n\n## errors\n\n### `refineerror`\n\n```ts\nclass refineerror extends error {\n constructor(message: string, opts?: erroroptions);\n}\n```\n\nbase class for public refine errors. it preserves `cause` through `erroroptions`.\n",
1061
+ "usage": " \ntitle: 'refine: usage guide'\ndescription: register refine components, configure properties, handle events, compose slots, and integrate frameworks.\n \n\n[[toc]]\n\n## basic usage\n\nload the global design contract once, then register only the components used by the page.\n\n```ts\nimport '@vielzeug/refine/tokens.css';\nimport '@vielzeug/refine/button';\nimport '@vielzeug/refine/input';\nimport '@vielzeug/refine/dialog';\n\nconst input = document.queryselector('ore input');\nconst save = document.queryselector('ore button');\n\nif (!(input instanceof htmlelement) || !(save instanceof htmlelement)) {\n throw new error('expected refine controls');\n}\n\nsave.addeventlistener('click', () => {\n console.log((input as htmlelement & { value: string }).value);\n});\n```\n\nadd the browser reset only when the application owns global element styling:\n\n```ts\nimport '@vielzeug/refine/styles/preflight.css';\n```\n\n## choose an icon library\n\nrefine includes only its internal component icons. register application icons before mounting them: use `registericons` and neutral `icondefinition` data from `@vielzeug/refine/icons`, the pure `@vielzeug/refine/icons/lucide` adapter for selected lucide icons, or `@vielzeug/refine/icons/iconify` for local heroicons, tabler, and material design icons data. keep importing the component from `@vielzeug/refine/icon`. lucide is an optional peer: install `lucide` yourself only when choosing its data or `@vielzeug/refine/icons/lucide/all`; core and structural adapters do not require it. the [icon reference](./components/icon.md) covers imports, licenses, and presentation behavior.\n\nfor selected individual iconify data, use `heroiconsicons`, `tablericons`, or `mdiicons` from `@vielzeug/refine/icons/heroicons`, `/tabler`, or `/mdi`. for example, `registericons(heroiconsicons({ search, home }))` preserves your app keys. install the matching `@iconify icons/<family>` data package yourself; these helpers do not accept framework components. keep `iconifyicons` for collection json and aliases.\n\n## set attributes and properties\n\nuse attributes for serializable html state.\n\n```html\n<ore button variant=\"outline\" color=\"secondary\" size=\"lg\" disabled>\n save changes\n</ore button>\n```\n\nuse javascript properties for arrays, objects, callbacks, and controlled state.\n\n```ts\nimport '@vielzeug/refine/datagrid';\nimport type { oredatagridprops } from '@vielzeug/refine/datagrid';\n\nconst grid = document.queryselector('ore datagrid') as htmlelement & oredatagridprops;\ngrid.columns = [\n { key: 'name', label: 'name', sortable: true },\n { key: 'role', label: 'role' },\n];\ngrid.rows = [\n { id: '1', name: 'ada', role: 'admin' },\n { id: '2', name: 'linus', role: 'editor' },\n];\n```\n\nenumerated properties such as `variant`, `size`, and `color` accept the values listed on each component's reference\npage. an unsupported value resolves to the property's declared default (or `undefined` when it has no default).\n\nin an ore template, `model()` can bind a refine field's `value` to a ripple signal and write user input back:\n\n```ts\nimport { signal } from '@vielzeug/ripple';\nimport { html, model } from '@vielzeug/ore';\nimport '@vielzeug/refine/input';\n\nconst email = signal('');\nconst field = html`<ore input label=\"email\" type=\"email\" value=${model(email)} />`;\n```\n\n## handle events\n\nform controls dispatch standard `input` and `change` events. read their current property from `event.currenttarget`.\n\n```ts\nconst input = document.queryselector('ore input');\ninput?.addeventlistener('input', (event) => {\n const target = event.currenttarget as htmlelement & { value: string };\n console.log(target.value);\n});\n```\n\ncustom events use kebab case names and typed detail objects.\n\n```ts\nimport type { oredialogevents } from '@vielzeug/refine/dialog';\n\nconst dialog = document.queryselector('ore dialog');\ndialog?.addeventlistener('open change', (event: customevent<oredialogevents['open change']>) => {\n console.log(event.detail.open, event.detail.reason);\n});\n```\n\n## native form validation\n\nrefine's form associated controls integrate with native form submission, `formdata`, validity checks, and reset.\nuse `required` for a required value constraint; setting `error` displays and announces feedback but does not, by\nitself, invalidate the form.\n\n```html\n<form id=\"profile form\">\n <ore input name=\"email\" type=\"email\" label=\"email\" required></ore input>\n <ore select name=\"role\" label=\"role\" required>\n <option value=\"\">choose a role…</option>\n <option value=\"editor\">editor</option>\n <option value=\"admin\">admin</option>\n </ore select>\n <ore button type=\"submit\">save</ore button>\n</form>\n\n<script type=\"module\">\n import '@vielzeug/refine/input';\n import '@vielzeug/refine/select';\n import '@vielzeug/refine/button';\n\n const form = document.queryselector('#profile form');\n form.addeventlistener('submit', (event) => {\n event.preventdefault();\n console.log(new formdata(form).get('email'));\n });\n</script>\n```\n\nthe browser runs native validation before dispatching `submit`. call `form.reportvalidity()` to show validation\nfeedback directly, or `form.checkvalidity()` for a boolean check without the browser's validation ui.\n\n## compose slots\n\ndefault slots hold primary content. named slots identify component owned regions.\n\n```html\n<ore card>\n <span slot=\"header\">account</span>\n <p>profile settings</p>\n <div slot=\"footer\">\n <ore button variant=\"ghost\">cancel</ore button>\n <ore button>save</ore button>\n </div>\n</ore card>\n```\n\ninput components commonly expose `prefix`, `suffix`, `label`, `helper`, and `error` slots. each component reference lists its supported slots.\n\n## load typescript framework declarations\n\nimport the declaration matching the framework once in an application type entry point.\n\n::: code group\n\n```ts [dom]\nimport type {} from '@vielzeug/refine/frameworks/elements';\n```\n\n```ts [react]\nimport type {} from '@vielzeug/refine/frameworks/react';\n```\n\n```ts [vue]\nimport type {} from '@vielzeug/refine/frameworks/vue';\n```\n\n:::\n\nthese entry points provide typed tags and component properties. they do not register components or install runtime adapters.\n\n## framework integration\n\nrefine elements use native dom properties, events, and slots. frameworks differ only in how they forward custom element properties and events.\n\n::: code group\n\n```tsx [react 19]\nimport '@vielzeug/refine/button';\n\nexport function savebutton() {\n return <ore button variant=\"solid\">save</ore button>;\n}\n```\n\n```vue [vue 3]\n<script setup lang=\"ts\">\nimport '@vielzeug/refine/button';\n</script>\n\n<template>\n <ore button variant=\"solid\">save</ore button>\n</template>\n```\n\n```svelte [svelte]\n<script lang=\"ts\">\n import '@vielzeug/refine/button';\n</script>\n\n<ore button variant=\"solid\">save</ore button>\n```\n\n:::\n\nsee [framework integration](./frameworks.md) for custom events, controlled properties, ssr guards, and framework specific configuration.\n\n## working with other vielzeug libraries\n\n### ore\n\nuse ore when authoring a custom element that composes refine components.\n\n```ts\nimport '@vielzeug/refine/button';\nimport { define, html } from '@vielzeug/ore';\n\ndefine('save panel', {\n setup() {\n return html`<ore button @click=${() => console.log('save')}>save</ore button>`;\n },\n});\n```\n\n### ripple\n\nuse ripple to drive component properties from application state.\n\n```ts\nimport '@vielzeug/refine/button';\nimport { effect, signal } from '@vielzeug/ripple';\n\nconst loading = signal(false);\nconst button = document.queryselector('ore button') as htmlelement & { loading?: boolean };\nconst loadingeffect = effect(() => {\n button.loading = loading.value;\n});\n\nloadingeffect.dispose();\n```\n\n### necromancer\n\nuse necromancer directly when you need animation handles, groups, or explicit keyframes. refine's [`animatereflow`](./animation#list reflow animatereflow) is the token driven wrapper over its flip primitive and is enough for keyed lists that reflow.\n\n## best practices\n\n **import** `tokens.css` once before rendering components.\n **register** components through explicit subpaths.\n **set** structured data and callbacks as javascript properties.\n **read** form state from the event target instead of custom event payloads.\n **provide** accessible labels for icon only controls.\n **use** component reference pages for supported slots, parts, and css properties.\n **dispose** application owned ripple effects and service handles.\n **guard** dom dependent component registration during ssr.\n **working with ai agents?** install the `vielzeug` skill (`npx y @vielzeug/codex skills install`) so agents reach for refine components and tokens instead of custom widgets: see the [codex usage guide](../codex/usage.md#agent skill).\n"
1062
1062
  },
1063
1063
  "examples": [],
1064
1064
  "exports": "ore accordion ore accordion item ore alert ore async ore avatar ore avatar group ore badge ore box ore breadcrumb ore breadcrumb item ore button ore button group ore calendar ore card ore carousel ore carousel slide ore chat message ore checkbox ore checkbox group ore chip ore code window ore column ore combobox ore combobox option ore command palette ore command palette item ore cookie banner ore copy command ore counter ore datagrid ore date picker ore dialog ore drawer ore file input ore grid ore grid item ore icon ore input ore keyboard key ore keyboard shortcut ore list ore list item ore marquee ore menu ore menu item ore menu separator ore message composer ore navbar ore navbar item ore navigation menu ore navigation menu item ore navigation menu panel ore number input ore otp input ore pagination ore password strength ore popover ore progress ore qr code ore qr scanner ore query bar ore radio ore radio group ore rating ore select ore separator ore sidebar ore sidebar group ore sidebar item ore skeleton ore slider ore speech player ore speed reading ore spotlight ore stats ore step ore stepper ore switch ore tab item ore tab panel ore table ore tabs ore td ore text ore th ore tr ore textarea ore time picker ore toast ore tooltip ore tour ore typing indicator",
@@ -1066,7 +1066,7 @@
1066
1066
  "name": "@vielzeug/refine",
1067
1067
  "related": "ore orbit forge keymap",
1068
1068
  "slug": "refine",
1069
- "source": "/**\n * refine components register through their explicit component entry points.\n *\n * keeping the package root free of registration side effects makes dependency\n * ownership and bundle contents obvious to application code.\n */\n\nexport { refineerror } from './errors';\nexport type { iconattributes, icondefinition, iconelement } from './icons';\nexport { registericons } from './icons';\nexport { eventfieldchecked, eventfieldvalue } from './inputs/shared/native field event';\nexport { getmotionmode, motion_modes, type motionmode, setmotionmode } from './motion';\n"
1069
+ "source": "/**\n * refine components register through their explicit component entry points.\n *\n * keeping the package root free of registration side effects makes dependency\n * ownership and bundle contents obvious to application code.\n */\n\nexport { refineerror } from './errors';\nexport type { iconattributes, icondefinition, iconelement } from './icons';\nexport { registericons } from './icons';\nexport { eventfieldchecked, eventfieldvalue } from './inputs/shared/native field event';\nexport { getmotionmode, motion_modes, type motionmode, setmotionmode } from './motion';\nexport type { reflow, reflowoptions } from './reflow';\nexport { animatereflow } from './reflow';\n"
1070
1070
  },
1071
1071
  {
1072
1072
  "category": "state",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vielzeug/codex",
3
- "version": "26.10.20",
3
+ "version": "26.10.22",
4
4
  "description": "MCP server exposing all Vielzeug docs to AI clients",
5
5
  "repository": {
6
6
  "type": "git",
@@ -63,7 +63,7 @@
63
63
  },
64
64
  "devDependencies": {
65
65
  "@types/node": "^26.6.5",
66
- "@vielzeug/refine": "26.10.20",
66
+ "@vielzeug/refine": "26.10.22",
67
67
  "typescript": "^6.0.3",
68
68
  "vitest": "^5.0.5"
69
69
  }
@@ -61,7 +61,7 @@ If a need matches a package below, use that package. Do not reimplement signals,
61
61
  - `@vielzeug/orbit`: Floating UI positioning with lifecycle-owned geometry and middleware
62
62
  - `@vielzeug/ore`: Functional web-component authoring on top of ripple
63
63
  - `@vielzeug/postmaster`: Typed durable job outbox with leased processing, retries, and dead-letter recovery
64
- - `@vielzeug/prism`: Responsive SVG charts with explicit updates: line, bar, area, scatter, pie, radar, sparkline
64
+ - `@vielzeug/prism`: Responsive SVG charts with explicit updates: line, bar, area, scatter, pie, radar, heatmap, sparkline
65
65
  - `@vielzeug/pulse`: Typed WebSocket client with channels, rooms, presence, reconnect
66
66
  - `@vielzeug/refine`: Accessible, themeable web components built on ore
67
67
  - `@vielzeug/ripple`: Reactive runtime primitives: signals, derived values, effects, scopes, watchers, and async resources