@vielzeug/codex 2.1.4 → 2.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/errors.js +0 -3
- package/dist/errors.js.map +1 -1
- package/dist/snapshot.js.map +1 -1
- package/dist/tools/packages.js +2 -3
- package/dist/tools/packages.js.map +1 -1
- package/dist/tools/refine.js +2 -2
- package/dist/tools/refine.js.map +1 -1
- package/dist/tools/schema.js +2 -0
- package/dist/tools/schema.js.map +1 -1
- package/package.json +6 -1
- package/data/catalog.json +0 -1689
- package/data/llms-full.txt +0 -25771
- package/data/llms.txt +0 -40
- package/data/manifest.json +0 -8
- package/data/packages/arsenal.json +0 -210
- package/data/packages/assay.json +0 -40
- package/data/packages/clockwork.json +0 -67
- package/data/packages/codex.json +0 -43
- package/data/packages/coins.json +0 -103
- package/data/packages/conduit.json +0 -60
- package/data/packages/courier.json +0 -58
- package/data/packages/dnd.json +0 -77
- package/data/packages/familiar.json +0 -40
- package/data/packages/flux.json +0 -93
- package/data/packages/forge.json +0 -84
- package/data/packages/herald.json +0 -108
- package/data/packages/keymap.json +0 -59
- package/data/packages/ledger.json +0 -57
- package/data/packages/lingua.json +0 -68
- package/data/packages/necromancer.json +0 -50
- package/data/packages/orbit.json +0 -107
- package/data/packages/ore.json +0 -73
- package/data/packages/prism.json +0 -67
- package/data/packages/pulse.json +0 -60
- package/data/packages/refine.json +0 -12
- package/data/packages/ripple.json +0 -83
- package/data/packages/rune.json +0 -80
- package/data/packages/sandbox.json +0 -40
- package/data/packages/scout.json +0 -60
- package/data/packages/scroll.json +0 -114
- package/data/packages/sourcerer.json +0 -74
- package/data/packages/spell.json +0 -134
- package/data/packages/tempo.json +0 -81
- package/data/packages/vault.json +0 -87
- package/data/packages/ward.json +0 -113
- package/data/packages/wayfinder.json +0 -113
- package/data/refine.json +0 -11926
- package/data/search.json +0 -1436
package/data/packages/prism.json
DELETED
|
@@ -1,67 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"apiSource": "// Public API — all exports for @vielzeug/prism\n\nexport type { EasingFn } from './animation/easing';\nexport type { AnimationTarget } from './animation/transition';\n// Animation utilities (for plugin authors)\nexport { animate } from './animation/transition';\n// Chart factories\nexport { createAreaChart } from './charts/area';\nexport { createBarChart } from './charts/bar';\nexport { createLineChart } from './charts/line';\nexport { createPieChart } from './charts/pie';\nexport { createSparkline } from './charts/sparkline';\n// Error classes\nexport { PrismDisposedError, PrismError, PrismRenderError } from './errors';\n// Interaction types (useful for plugin authors)\nexport type { LegendState } from './interaction/legend';\nexport type { TooltipState } from './interaction/tooltip';\n// Scale factories\nexport { bandScale } from './scales/band';\nexport { linearScale } from './scales/linear';\nexport { timeScale } from './scales/time';\n// SVG primitives (for plugin authors)\nexport type { Point } from './svg/path';\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 ChartPlugin,\n ChartPluginContext,\n CrosshairConfig,\n Datum,\n GridConfig,\n LegendConfig,\n LegendPosition,\n LineChartConfig,\n LineSeriesConfig,\n MaybeSignal,\n PieChartConfig,\n PieSliceConfig,\n PieVariant,\n PrismTheme,\n Scale,\n Series,\n SparklineConfig,\n SparklineVariant,\n StackSegment,\n TooltipConfig,\n TransitionConfig,\n} from './types';\n",
|
|
3
|
-
"docs": {
|
|
4
|
-
"index": "---\ntitle: Prism — Reactive SVG data visualization\ndescription: Reactive SVG charting library — line, bar, and area charts. Signal-driven updates, CSS-themeable, accessible.\npackage: prism\ncategory: ui\nkeywords: [chart, svg, visualization, reactive, line-chart, bar-chart, area-chart, signals, typescript]\nrelated: [ripple, refine, orbit]\nexports:\n [\n createLineChart,\n createBarChart,\n createAreaChart,\n createPieChart,\n createSparkline,\n linearScale,\n timeScale,\n bandScale,\n seriesColor,\n setTheme,\n resetTheme,\n animate,\n PrismError,\n AnimationTarget,\n EasingFn,\n LegendState,\n TooltipState,\n ChartPluginContext,\n Point,\n ScaffoldContext,\n ScaffoldGroups,\n ChartEventHandlers,\n StackSegment,\n ]\nenvironments: [browser]\n---\n\n<!-- markdownlint-disable MD025 MD033 MD060 -->\n\n<PackageHero package=\"prism\" />\n\n## Why Prism?\n\nCharting libraries typically require a framework binding, bundle heavy dependencies, or force canvas rendering that can't be styled with CSS. Prism takes a different approach:\n\n```ts\n// Before — Chart.js, imperative setup with a canvas you can't CSS-theme\nimport Chart from 'chart.js/auto';\nconst ctx = document.getElementById('myChart') as HTMLCanvasElement;\nnew Chart(ctx, {\n type: 'line',\n data: { labels, datasets: [{ data: values }] },\n // re-render manually when data changes, no signals, canvas not CSS-styleable\n});\n\n// After — Prism, declarative SVG chart driven by a signal\nimport { createLineChart } from '@vielzeug/prism';\nimport { signal } from '@vielzeug/ripple';\n\nconst data = signal([\n { key: 1, value: 12 },\n { key: 2, value: 40 },\n { key: 3, value: 28 },\n]);\nconst chart = createLineChart(document.getElementById('chart')!, {\n a11y: { ariaLabel: 'Users by day' },\n series: [{ name: 'Users', data }],\n tooltip: true,\n});\n// chart auto-updates when data.value changes — no manual re-render\ndata.value = [...data.value, { key: 4, value: 65 }];\n```\n\n| Feature | Prism | Chart.js | Lightweight Charts | D3 |\n| ------------------ | -------------------------------------------- | ---------------------------------------- | -------------------------------------------- | -------------------------------------------- |\n| Bundle size | <PackageInfo package=\"prism\" type=\"size\" /> | ~60 kB | ~45 kB | ~30 kB (core) |\n| Renderer | SVG | Canvas | Canvas | SVG/Canvas |\n| Reactive data model | Ripple signals | Plugin-specific | Plugin-specific | Manual |\n| CSS themeable | <ore-icon name=\"check\" size=\"16\"></ore-icon> | <ore-icon name=\"x\" size=\"16\"></ore-icon> | Limited | <ore-icon name=\"check\" size=\"16\"></ore-icon> |\n| Reactive (signals) | <ore-icon name=\"check\" size=\"16\"></ore-icon> | <ore-icon name=\"x\" size=\"16\"></ore-icon> | <ore-icon name=\"x\" size=\"16\"></ore-icon> | <ore-icon name=\"x\" size=\"16\"></ore-icon> |\n| Accessible SVG | <ore-icon name=\"check\" size=\"16\"></ore-icon> | <ore-icon name=\"x\" size=\"16\"></ore-icon> | <ore-icon name=\"x\" size=\"16\"></ore-icon> | Manual |\n| TypeScript-first | <ore-icon name=\"check\" size=\"16\"></ore-icon> | Partial | <ore-icon name=\"check\" size=\"16\"></ore-icon> | Types available |\n\n<div class=\"decision-callout\">\n\n**Use Prism when** you need lightweight, reactive charts that integrate with signal-based state and can be styled purely with CSS. Ideal for dashboards, admin panels, and data-heavy applications using Vielzeug.\n\n**Consider alternatives when** you need 50+ chart types (ECharts), financial trading charts (Lightweight Charts), or low-level visualization grammar (D3).\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\n```ts\nimport { createLineChart } from '@vielzeug/prism';\nimport { signal } from '@vielzeug/ripple';\nimport '@vielzeug/prism/theme';\n\nconst data = signal([\n { key: 1, value: 10 },\n { key: 2, value: 25 },\n { key: 3, value: 18 },\n { key: 4, value: 32 },\n]);\n\nconst chart = createLineChart(document.getElementById('chart')!, {\n a11y: { ariaLabel: 'Revenue by month' },\n series: [{ name: 'Revenue', data, color: '#3b82f6' }],\n xAxis: { position: 'bottom' },\n yAxis: { position: 'left', grid: true },\n tooltip: true,\n crosshair: true,\n onHover: (event) => console.log(event?.datum),\n});\n\n// Update data → chart re-renders automatically\ndata.value = [...data.value, { key: 5, value: 28 }];\n\n// Cleanup when done\nchart.dispose();\n```\n\n## Features\n\n<div class=\"features-grid\">\n\n- **`createLineChart(container, config)`** — line chart with linear, monotone, or step interpolation\n- **`createBarChart(container, config)`** — bar chart with four layout variants: grouped, stacked, grouped-horizontal, stacked-horizontal\n- **`createAreaChart(container, config)`** — filled area with configurable opacity\n- **`createSparkline(container, config)`** — minimal inline sparkline (line, area, or bar variant)\n- **`createPieChart(container, config)`** — pie, donut, or semi-circle donut chart\n- **`linearScale(config)`** — continuous numeric scale with nice tick generation\n- **`timeScale(config)`** — date/time scale with interval-based ticks\n- **`bandScale(config)`** — categorical scale for bar charts\n- **`MaybeSignal<T>`** — pass plain values or `@vielzeug/ripple` signals; both work seamlessly\n- **`seriesColor(index, override?)`** — resolve CSS palette color by series index\n- **`setTheme(theme)` / `resetTheme()`** — apply or clear custom colors, font, and grid tokens at runtime\n- **Event hooks** — `onClick` and `onHover` callbacks on every chart\n- **Plugin system** — extend charts with `ChartPlugin` (`install()`/`dispose()` lifecycle, each isolated from the other's failures); supported by all chart types including `createPieChart`\n- **Devtools** — `debugChart()` from `@vielzeug/prism/devtools` logs mount/resize/dispose to `console.debug`; tree-shaken from production unless imported\n- **CSS custom properties** — full theme control via `--prism-*` tokens\n- **Responsive** — auto-resizes via `ResizeObserver`\n- **Accessible** — ARIA labels and semantic SVG structure\n- **`Symbol.dispose`** — explicit resource management following TC39 proposal\n\n</div>\n\n## Sub-paths\n\n| Import | Purpose |\n| -------------------------- | ------------------------------------------------------------------------------------ |\n| `@vielzeug/prism` | All chart factories, scales, and types |\n| `@vielzeug/prism/theme` | Default CSS (custom properties + dark mode) |\n| `@vielzeug/prism/devtools` | `debugChart()` — opt-in `console.debug` lifecycle logging, tree-shaken in production |\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- [Ripple](/ripple/) — reactive signals that power Prism's auto-updating charts\n- [Refine](/refine/) — accessible web components that pair well with Prism for dashboards\n- [Orbit](/orbit/) — floating element positioning for chart tooltips and popovers\n\n</div>\n\n<!-- markdownlint-enable MD025 MD033 MD060 -->\n",
|
|
5
|
-
"api": "---\ntitle: Prism — API Reference\ndescription: Complete type signatures, parameter docs, and return values for every export in @vielzeug/prism.\n---\n\n[[toc]]\n\n## API Overview\n\n| Symbol | Purpose | Returns |\n| -------------------- | ----------------------------------------------------- | ------------------------------ |\n| `createLineChart()` | Reactive line chart with curves and interpolation | `ChartHandle` |\n| `createBarChart()` | Bar chart: grouped, stacked, horizontal variants | `ChartHandle` |\n| `createAreaChart()` | Filled area chart | `ChartHandle` |\n| `linearScale()` | Continuous numeric → pixel scale | `Scale<number>` |\n| `timeScale()` | Date → pixel scale | `Scale<Date>` |\n| `bandScale()` | Categorical → pixel band scale | `BandScale` |\n| `createSparkline()` | Minimal inline sparkline (line/area/bar) | `ChartHandle` |\n| `createPieChart()` | Pie, donut, or semi-circle donut chart | `ChartHandle` |\n| `seriesColor()` | CSS variable color for series index | `string` |\n| `setTheme()` | Apply custom palette / CSS tokens at runtime | `void` |\n| `resetTheme()` | Clear all custom theme overrides back to defaults | `void` |\n| `animate()` | Animate SVG element attributes via RAF | `() => void` (cancel function) |\n| `debugChart()` | Wrap a `ChartHandle` with lifecycle logging (`/devtools` subpath) | `ChartHandle` |\n| `PrismError` | Base class for all prism-originated errors | class |\n| `LegendState` | Live legend state object (plugin API) | type |\n| `TooltipState` | Live tooltip state object (plugin API) | type |\n| `ChartPluginContext` | Context object passed to `ChartPlugin.install()` | type |\n\n## Package Entry Points\n\n| Import | Purpose |\n| -------------------------- | --------------------------------------------------------------------------- |\n| `@vielzeug/prism` | All chart factories, scales, types, and utilities |\n| `@vielzeug/prism/theme` | Default CSS custom properties (light + dark) |\n| `@vielzeug/prism/devtools` | `debugChart()` — opt-in `console.debug` lifecycle logging, tree-shaken in production |\n\n---\n\n## Chart Factories\n\n### `createLineChart`\n\n```ts\nfunction createLineChart(container: HTMLElement, config: LineChartConfig): ChartHandle;\n```\n\nCreates a reactive line chart. Supports multiple series, curve interpolation, tooltips, crosshair, and event hooks.\n\n| Parameter | Type | Description |\n| ----------- | ----------------- | --------------------------------------------------- |\n| `container` | `HTMLElement` | DOM element to render into (must have width/height) |\n| `config` | `LineChartConfig` | Chart configuration |\n\n**Returns** — [`ChartHandle`](#charthandle)\n\n---\n\n### `createBarChart`\n\n```ts\nfunction createBarChart(container: HTMLElement, config: BarChartConfig): ChartHandle;\n```\n\nCreates a reactive bar chart. Use `variant` to switch between grouped, stacked, horizontal variants.\n\n| Parameter | Type | Description |\n| ----------- | ---------------- | -------------------------- |\n| `container` | `HTMLElement` | DOM element to render into |\n| `config` | `BarChartConfig` | Chart configuration |\n\n**Returns** — [`ChartHandle`](#charthandle)\n\n---\n\n### `createAreaChart`\n\n```ts\nfunction createAreaChart(container: HTMLElement, config: AreaChartConfig): ChartHandle;\n```\n\nCreates a reactive filled area chart with configurable opacity, curve, and event hooks.\n\n| Parameter | Type | Description |\n| ----------- | ----------------- | -------------------------- |\n| `container` | `HTMLElement` | DOM element to render into |\n| `config` | `AreaChartConfig` | Chart configuration |\n\n**Returns** — [`ChartHandle`](#charthandle)\n\n---\n\n### `createPieChart`\n\n```ts\nfunction createPieChart(container: HTMLElement, config: PieChartConfig): ChartHandle;\n```\n\nCreates a pie, donut, or semi-circle donut chart. All three variants share the same `PieChartConfig` — select via `variant`.\n\n| Parameter | Type | Description |\n| ----------- | ---------------- | ----------------------------------------- |\n| `container` | `HTMLElement` | DOM element to render into (sized by CSS) |\n| `config` | `PieChartConfig` | Chart configuration |\n\n**Returns** — [`ChartHandle`](#charthandle)\n\n---\n\n### `createSparkline`\n\n```ts\nfunction createSparkline(container: HTMLElement, config: SparklineConfig): ChartHandle;\n```\n\nCreates a minimal inline chart with no axes, no legend, and no margin. Designed for use in tables, cards, and inline data contexts.\n\n| Parameter | Type | Description |\n| ----------- | ----------------- | ----------------------------------------- |\n| `container` | `HTMLElement` | DOM element to render into (sized by CSS) |\n| `config` | `SparklineConfig` | Sparkline configuration |\n\n**Returns** — [`ChartHandle`](#charthandle)\n\n---\n\n## Scale Factories\n\n### `linearScale`\n\n```ts\nfunction linearScale(config: LinearScaleConfig): Scale<number>;\n```\n\nContinuous linear scale mapping a numeric domain to a pixel range. Unlike chart config fields, scale factory config is not `MaybeSignal` — pass plain values and call `linearScale()` again if the domain/range changes.\n\n| Field | Type | Default | Description |\n| --------------- | ------------------ | ------- | ----------------------------------------------------------------- |\n| `config.domain` | `[number, number]` | — | Input data range `[min, max]`. A reversed domain (`min > max`) is supported for inverted axes. |\n| `config.range` | `[number, number]` | — | Output pixel range `[min, max]` |\n| `config.nice` | `boolean` | `true` | Extend domain to nice round numbers |\n| `config.clamp` | `boolean` | `false` | Clamp output to range bounds |\n\n---\n\n### `timeScale`\n\n```ts\nfunction timeScale(config: TimeScaleConfig): Scale<Date>;\n```\n\nTime scale mapping `Date` values to pixels. Automatically selects tick intervals (seconds → years).\n\n| Field | Type | Default | Description |\n| --------------- | ----------------- | ------- | -------------------------------- |\n| `config.domain` | `[Date, Date]` | — | Input date range `[start, end]` |\n| `config.range` | `[number, number]` | — | Output pixel range |\n| `config.nice` | `boolean` | `true` | Extend domain to nice boundaries |\n\n---\n\n### `bandScale`\n\n```ts\nfunction bandScale(config: BandScaleConfig): BandScale;\n```\n\nCategorical scale dividing the range into equal bands with configurable padding.\n\n| Field | Type | Default | Description |\n| --------------------- | ------------------ | ----------------- | ------------------------- |\n| `config.domain` | `string[]` | — | Category names |\n| `config.range` | `[number, number]` | — | Output pixel range |\n| `config.padding` | `number` | `0.1` | Inner padding ratio (0–1) |\n| `config.paddingOuter` | `number` | same as `padding` | Outer edge padding ratio |\n\n---\n\n## Types\n\n### `ChartHandle`\n\nReturned by all chart factories.\n\n```ts\ninterface ChartHandle {\n readonly disposalSignal: AbortSignal;\n readonly disposed: boolean;\n readonly el: SVGSVGElement;\n dispose(): void;\n [Symbol.dispose](): void;\n}\n```\n\n| Member | Description |\n| -------------------- | ----------------------------------------------------------------------------------------------- |\n| `el` | The root `SVGSVGElement` (for styling or external manipulation) |\n| `disposed` | `true` once `dispose()` has run; useful for guarding late callbacks |\n| `disposalSignal` | Aborted when the chart is disposed — tie your own cleanup (RAF loops, observers) to this instead of overriding `dispose()` |\n| `dispose()` | Tear down all effects, observers, DOM nodes, tooltip, and legend. Calling it more than once is a no-op |\n| `[Symbol.dispose]()` | Same as `dispose()` — for TC39 `using` declarations |\n\n> **Note:** Charts re-render automatically when signal data changes. There is no `update()` method — reactivity is fully automatic.\n\n---\n\n### `ChartEvent`\n\nPassed to `onClick` and `onHover` callbacks.\n\n```ts\ninterface ChartEvent {\n datum: Datum;\n originalEvent: MouseEvent;\n series: Series;\n}\n```\n\n---\n\n### `ChartPlugin`\n\nInterface for extending charts with custom behavior. Plugins are installed after the chart is mounted and torn down on `dispose()`.\n\n```ts\ninterface ChartPlugin {\n install(ctx: ChartPluginContext): void;\n dispose(): void;\n}\n```\n\nSee [`ChartPluginContext`](#chartplugincontext) for the object passed to `install()`.\n\n---\n\n### `BaseChartConfig`\n\nShared configuration inherited by all chart config types.\n\n```ts\ninterface BaseChartConfig {\n ariaLabel?: string;\n legend?: boolean | LegendConfig;\n margin?: Partial<ChartMargin>;\n onClick?: (event: ChartEvent) => void;\n onHover?: (event: ChartEvent | null) => void;\n plugins?: ChartPlugin[];\n tooltip?: boolean | TooltipConfig;\n transition?: TransitionConfig;\n xAxis?: AxisConfig;\n yAxis?: AxisConfig;\n}\n```\n\n| Field | Type | Description |\n| ------------ | ------------------------------------- | --------------------------------------- |\n| `ariaLabel` | `string` | Accessible label on the SVG element |\n| `legend` | `boolean \\| LegendConfig` | Show a series legend |\n| `margin` | `Partial<ChartMargin>` | Override chart margins |\n| `onClick` | `(event: ChartEvent) => void` | Fired when a data point is clicked |\n| `onHover` | `(event: ChartEvent \\| null) => void` | Fired on mousemove (null on mouseleave) |\n| `plugins` | `ChartPlugin[]` | Extension plugins installed at mount |\n| `tooltip` | `boolean \\| TooltipConfig` | Hover tooltip |\n| `transition` | `TransitionConfig` | Enter/update animation |\n| `xAxis` | `AxisConfig` | X-axis configuration |\n| `yAxis` | `AxisConfig` | Y-axis configuration |\n\n---\n\n### `MaybeSignal<T>`\n\n```ts\ntype MaybeSignal<T> = Readable<T> | T;\n```\n\nAccepts either a plain value or a `@vielzeug/ripple` `Readable<T>` signal (e.g. one created with `signal()`). Used for `series`/`data` fields on chart configs — when a signal is passed, the chart re-renders automatically on `.value` changes. Not used by the scale factories (`linearScale`/`timeScale`/`bandScale`), whose config fields are always plain values.\n\n---\n\n### `Scale<T>`\n\n```ts\ninterface Scale<T> {\n readonly domain: readonly [T, T];\n readonly range: readonly [number, number];\n map(value: T): number;\n invert(pixel: number): T;\n ticks(count?: number): T[];\n}\n```\n\n| Member | Description |\n| --------------- | --------------------------------------------------- |\n| `domain` | Input domain `[min, max]` — readonly computed tuple |\n| `range` | Output pixel range — readonly computed tuple |\n| `map(value)` | Domain value → pixel position |\n| `invert(pixel)` | Pixel position → domain value |\n| `ticks(count?)` | Nicely-spaced tick values (default: 10) |\n\n---\n\n### `BandScale`\n\n```ts\ninterface BandScale {\n readonly domain: readonly string[];\n readonly range: readonly [number, number];\n map(value: string): number;\n bandwidth(): number;\n gap(): number;\n ticks(count?: number): string[];\n}\n```\n\n| Member | Description |\n| --------------- | --------------------------------------------------------------- |\n| `map(value)` | Left edge pixel position of a category's band |\n| `bandwidth()` | Width of each band in pixels |\n| `gap()` | Pixel gap between adjacent bands (`bandwidth × padding`) |\n| `ticks(count?)` | All domain categories, or at most `count` evenly sampled values |\n\n---\n\n### `Point`\n\n```ts\ninterface Point {\n x: number;\n y: number;\n}\n```\n\nA pixel-space 2D point used by path builders and area renderers. Exported for plugin authors who build custom SVG paths.\n\n---\n\n### `Datum`\n\nA single data point in a cartesian chart series.\n\n```ts\ninterface Datum {\n key: Date | number | string;\n value: number;\n meta?: Record<string, unknown>;\n}\n```\n\n| Field | Type | Description |\n| ------- | -------------------------- | ----------------------------------------------------------------------------------------- |\n| `key` | `Date \\| number \\| string` | X-axis identity. Use `number` or `Date` for line/area charts; `string` for bar categories |\n| `value` | `number` | Y-axis measured quantity |\n| `meta` | `Record<string, unknown>` | Optional arbitrary metadata (available in tooltip `render` callbacks) |\n\n---\n\n### `Series`\n\n```ts\ninterface Series {\n name: string;\n data: MaybeSignal<Datum[]>;\n color?: string;\n}\n```\n\n---\n\n### `ScaffoldContext`\n\nPassed to `renderFn` inside `createChartScaffold` — the internal building block behind `createLineChart`/`createBarChart`/`createAreaChart`. Relevant only if you're building a custom cartesian chart type on top of prism's scaffold, not to `ChartPlugin.install()` (see [`ChartPluginContext`](#chartplugincontext) for that).\n\n```ts\ninterface ScaffoldContext {\n chartArea: SVGGElement;\n container: HTMLElement;\n dimensions: Readable<ChartDimensions>;\n disposalSignal: AbortSignal;\n groups: ScaffoldGroups;\n legend: LegendState | null;\n svg: SVGSVGElement;\n tooltip: TooltipState | null;\n}\n```\n\n---\n\n### `RadialScaffoldContext`\n\nThe `createRadialScaffold` counterpart to `ScaffoldContext`, for chart types with no cartesian axis groups (pie, donut, semi). Backs `createPieChart`.\n\n```ts\ninterface RadialScaffoldContext {\n container: HTMLElement;\n dimensions: Readable<ChartDimensions>;\n disposalSignal: AbortSignal;\n legend: LegendState | null;\n svg: SVGSVGElement;\n tooltip: TooltipState | null;\n}\n```\n\n---\n\n### `ScaffoldGroups`\n\n```ts\ninterface ScaffoldGroups {\n grid: SVGGElement;\n series: SVGGElement;\n xAxis: SVGGElement;\n yAxis: SVGGElement;\n}\n```\n\nSVG `<g>` elements created by `createChartScaffold`. Children of `chartArea`, appended in render order: `grid` → `xAxis` → `yAxis` → `series`.\n\n---\n\n### `ChartEventHandlers`\n\n```ts\ninterface ChartEventHandlers {\n onClick?: (event: MouseEvent) => void;\n onMouseLeave?: (event: MouseEvent) => void;\n onMouseMove?: (event: MouseEvent) => void;\n}\n```\n\nReturned by the `renderFn` passed to `createChartScaffold`. The scaffold attaches and tears down these listeners automatically before each re-render.\n\n---\n\n### `AnimationTarget`\n\n```ts\ninterface AnimationTarget {\n attrs: Record<string, { from: number; to: number }>;\n el: SVGElement;\n}\n```\n\nOne element + attribute map for use with `animate()`. Each attribute entry specifies the start (`from`) and end (`to`) pixel value.\n\n---\n\n## Pie / Donut Types\n\n### `PieChartConfig`\n\nExtends [`BaseChartConfig`](#basechartconfig) (inherits `ariaLabel`, `legend`, `margin`, `plugins`, `tooltip`, `transition`). Overrides `onClick`/`onHover` with pie-specific slice signatures.\n\n```ts\ninterface PieChartConfig extends Omit<BaseChartConfig, 'onClick' | 'onHover' | 'xAxis' | 'yAxis'> {\n cornerRadius?: number;\n data: MaybeSignal<PieSliceConfig[]>;\n innerRadius?: number;\n onClick?: (slice: PieSliceConfig, index: number) => void;\n onHover?: (slice: PieSliceConfig | null, index: number | null) => void;\n padPixels?: number;\n variant?: PieVariant;\n}\n```\n\n| Field | Type | Default | Description |\n| -------------- | ------------------------------------ | -------------------------------------- | ------------------------------------------------------- |\n| `data` | `MaybeSignal<PieSliceConfig[]>` | — | Slice definitions |\n| `variant` | `PieVariant` | `'pie'` | Chart style: `'pie'`, `'donut'`, or `'semi'` |\n| `innerRadius` | `number` | `55%` of outer (donut/semi), `0` (pie) | Inner hole radius in pixels |\n| `padPixels` | `number` | `0` (pie), `8` (donut/semi) | Pixel gap between slices (uniform across arc thickness) |\n| `cornerRadius` | `number` | `0` (pie), `8` (donut/semi) | Rounded arc corners (pixels) |\n| `onClick` | `(slice, index) => void` | — | Fired on slice click |\n| `onHover` | `(slice\\|null, index\\|null) => void` | — | Fired on hover; `null` on mouseleave |\n\n> Inherited `BaseChartConfig` fields (`tooltip`, `transition`, `legend`, `margin`, `ariaLabel`, `plugins`) behave identically to other chart types.\n\n### `PieSliceConfig`\n\n```ts\ninterface PieSliceConfig {\n color?: string;\n label?: string;\n value: number;\n}\n```\n\n| Field | Type | Description |\n| ------- | -------- | ------------------------------------------------- |\n| `value` | `number` | Numeric weight of the slice |\n| `color` | `string` | Slice fill color; defaults to `--prism-color-{n}` |\n| `label` | `string` | Optional text rendered at the arc centroid |\n\n### `PieVariant`\n\n```ts\ntype PieVariant = 'donut' | 'pie' | 'semi';\n```\n\n- **`pie`** — full circle, no hole\n- **`donut`** — full circle with inner hole (~55% of outer radius by default)\n- **`semi`** — top-half semicircle with inner hole (useful for gauges/progress)\n\n---\n\n## Sparkline Types\n\n### `SparklineConfig`\n\n```ts\ninterface SparklineConfig {\n ariaLabel?: string;\n color?: string;\n cornerRadius?: number;\n curve?: 'linear' | 'monotone' | 'step';\n data: MaybeSignal<number[] | StackSegment[]>;\n fillOpacity?: number;\n onClick?: (index: number, value: number) => void;\n onHover?: (index: number | null, value: number | null) => void;\n padPixels?: number;\n strokeWidth?: number;\n transition?: TransitionConfig;\n variant?: SparklineVariant;\n}\n```\n\n| Field | Type | Default | Description |\n| -------------- | ----------------------------------------- | ---------------------- | -------------------------------------------------------------------------------------------------------------- |\n| `data` | `MaybeSignal<number[] \\| StackSegment[]>` | — | Numeric values, or `StackSegment[]` for `'stack'` variant |\n| `variant` | `SparklineVariant` | `'line'` | Chart style |\n| `color` | `string` | `var(--prism-color-1)` | Stroke/fill color (line/area/bar only) |\n| `curve` | `'linear' \\| 'monotone' \\| 'step'` | `'linear'` | Line interpolation (line/area only) |\n| `strokeWidth` | `number` | `1.5` | Line stroke width (line/area only) |\n| `fillOpacity` | `number` | `0.2` | Fill opacity (area only) |\n| `cornerRadius` | `number` | `4` | Rounded corners for stack segments in pixels. Stack variant only — no effect on line/area/bar |\n| `padPixels` | `number` | `0` | Gap between stack segments in pixels. Stack variant only — no effect on line/area/bar |\n| `ariaLabel` | `string` | — | Accessible label; sets `role=\"img\"` on the SVG. If omitted the SVG is marked `aria-hidden=\"true\"` (decorative) |\n| `transition` | `TransitionConfig` | — | Enter animation (bar/stack only; line/area use RAF interpolation) |\n| `onClick` | `(index, value) => void` | — | Called on click with nearest data index. Not fired for 0- or 1-point data |\n| `onHover` | `(index\\|null, value\\|null) => void` | — | Called on mousemove; `null` on mouseleave. Not fired for 0- or 1-point data |\n\n### `SparklineVariant`\n\n```ts\ntype SparklineVariant = 'area' | 'bar' | 'line' | 'stack';\n```\n\n- **`line`** — polyline path (default)\n- **`area`** — filled area + line overlay\n- **`bar`** — vertical bar per data point\n- **`stack`** — horizontal proportional segments; use `StackSegment[]` for `data` with per-segment colors\n\n### `StackSegment`\n\n```ts\ninterface StackSegment {\n color?: string;\n label?: string;\n value: number;\n}\n```\n\n> **Accessibility:** Without `ariaLabel` the SVG is marked `aria-hidden=\"true\"` (decorative). Set `ariaLabel` to expose the chart to assistive technology — the SVG will carry `role=\"img\"` and the provided label.\n\n---\n\n## Chart Config Types\n\n### `LineChartConfig`\n\nExtends [`BaseChartConfig`](#basechartconfig).\n\n```ts\ninterface LineChartConfig extends BaseChartConfig {\n series: MaybeSignal<LineSeriesConfig[]>;\n crosshair?: boolean | CrosshairConfig;\n}\n```\n\n### `LineSeriesConfig`\n\n```ts\ninterface LineSeriesConfig extends Series {\n curve?: 'linear' | 'monotone' | 'step'; // default: 'linear'\n strokeWidth?: number; // default: 2\n showPoints?: boolean; // default: false\n pointRadius?: number; // default: 3\n}\n```\n\n---\n\n### `BarChartConfig`\n\nExtends [`BaseChartConfig`](#basechartconfig).\n\n```ts\ntype BarVariant =\n | 'grouped' // vertical grouped (default)\n | 'stacked' // vertical stacked\n | 'grouped-horizontal' // horizontal grouped\n | 'stacked-horizontal'; // horizontal stacked\n\ninterface BarChartConfig extends BaseChartConfig {\n series: MaybeSignal<BarSeriesConfig[]>;\n variant?: BarVariant; // default: 'grouped'\n}\n```\n\n### `BarSeriesConfig`\n\n```ts\ninterface BarSeriesConfig extends Series {\n borderRadius?: number; // default: 0\n}\n```\n\n---\n\n### `AreaChartConfig`\n\nExtends [`BaseChartConfig`](#basechartconfig).\n\n```ts\ninterface AreaChartConfig extends BaseChartConfig {\n series: MaybeSignal<AreaSeriesConfig[]>;\n crosshair?: boolean | CrosshairConfig;\n}\n```\n\n### `AreaSeriesConfig`\n\n```ts\ninterface AreaSeriesConfig extends Series {\n curve?: 'linear' | 'monotone' | 'step'; // default: 'linear'\n fillOpacity?: number; // default: 0.3\n showLine?: boolean; // default: true\n}\n```\n\n---\n\n## Shared Config Types\n\n### `AxisConfig`\n\n```ts\ninterface AxisConfig {\n position: 'top' | 'bottom' | 'left' | 'right';\n tickCount?: number;\n tickFormat?: (value: Date | number | string) => string;\n label?: string;\n grid?: boolean | GridConfig;\n}\n```\n\n### `GridConfig`\n\n```ts\ninterface GridConfig {\n color?: string;\n dash?: string; // SVG stroke-dasharray value, e.g. '4 2'\n}\n```\n\n### `TooltipConfig`\n\n```ts\ninterface TooltipConfig {\n offset?: number; // default: 8\n render?: (datum: Datum, series: Series) => string; // returns HTML string\n sanitize?: (html: string) => string; // applied before innerHTML injection\n}\n```\n\nThe tooltip is appended inside the chart container (not `document.body`), so it is automatically scoped and cleaned up on `dispose()`.\n\n> ⚠️ **Security:** The string returned by `render` is injected via `innerHTML`. Pass `sanitize` to apply a sanitizer (e.g. DOMPurify) before injection, or ensure all user-supplied values are escaped before interpolation. A `warn` is emitted in development when `render` is set without `sanitize`.\n\n### `CrosshairConfig`\n\n```ts\ninterface CrosshairConfig {\n vertical?: boolean; // default: true\n horizontal?: boolean; // default: false\n snap?: boolean; // default: true\n}\n```\n\n### `LegendConfig`\n\n```ts\ninterface LegendConfig {\n position?: 'top' | 'bottom' | 'left' | 'right'; // default: 'bottom'\n}\n```\n\n### `TransitionConfig`\n\n```ts\ninterface TransitionConfig {\n duration?: number; // ms, default: 300\n easing?: 'linear' | 'ease-in' | 'ease-out' | 'ease-in-out' | ((t: number) => number);\n stagger?: number; // ms delay between bar enter animations, default: 0\n}\n```\n\n> **`stagger`** applies only to bar chart enter animations — new bars grow in sequence with a `stagger`ms delay between each one.\n\n### `ChartMargin`\n\n```ts\ninterface ChartMargin {\n top: number; // default: 20\n right: number; // default: 20\n bottom: number; // default: 40\n left: number; // default: 50\n}\n```\n\n---\n\n## Utilities\n\n### `seriesColor`\n\n```ts\nfunction seriesColor(index: number, override?: string): string;\n```\n\nReturns the CSS variable reference for palette color at `index` (wraps at 8). If `override` is provided it is returned as-is. Used internally by all chart factories.\n\n```ts\nimport { seriesColor } from '@vielzeug/prism';\n\nseriesColor(0); // 'var(--prism-color-1)'\nseriesColor(0, '#ff0'); // '#ff0'\n```\n\n### `setTheme`\n\n```ts\ninterface PrismTheme {\n colors?: string[]; // replaces --prism-color-1 … -8\n fontFamily?: string; // sets --prism-font-family\n gridColor?: string; // sets --prism-grid-color\n gridOpacity?: number; // sets --prism-grid-opacity\n}\n\nfunction setTheme(theme: PrismTheme): void;\n```\n\nApplies CSS custom properties to `document.documentElement`. Call once at app startup before mounting charts. Setting `colors` clears any unset color slots left over from a previous `setTheme()` call, so a theme with fewer colors than the last one doesn't leave stale high-index colors behind.\n\n```ts\nimport { setTheme } from '@vielzeug/prism';\n\nsetTheme({ colors: ['#6366f1', '#22d3ee', '#f59e0b', '#10b981'] });\n```\n\n### `resetTheme`\n\n```ts\nfunction resetTheme(): void;\n```\n\nClears every CSS custom property `setTheme()` can set, restoring prism's default theme (from `@vielzeug/prism/theme`). Useful for test teardown or a theme-switcher's \"reset to default\" action.\n\n```ts\nimport { resetTheme, setTheme } from '@vielzeug/prism';\n\nsetTheme({ colors: ['#6366f1'] });\nresetTheme(); // back to the default palette\n```\n\n> `seriesColor`, `setTheme`, and `resetTheme` are all exported from `@vielzeug/prism` (not from the `/theme` CSS subpath).\n\n---\n\n## Interaction Types\n\n> Exported from `@vielzeug/prism` for use in plugins and custom chart extensions. Both types reflect the live state object created internally; `el` is `null` when no legend/tooltip is configured.\n\n### `LegendState`\n\n```ts\ninterface LegendState {\n dispose(): void;\n [Symbol.dispose](): void;\n el: HTMLDivElement | null;\n update(series: { color: string; name: string }[]): void;\n}\n```\n\nThe live legend object available on `ctx.legend` inside `ChartPlugin.install`. Call `update()` to re-render legend items, `dispose()` to remove the element.\n\n### `TooltipState`\n\n```ts\ninterface TooltipState {\n dispose(): void;\n [Symbol.dispose](): void;\n el: HTMLElement | null;\n hide(): void;\n show(x: number, y: number, datum: Datum, series: Series): void;\n}\n```\n\nThe live tooltip object available on `ctx.tooltip` inside `ChartPlugin.install`. `x`/`y` are pixel coordinates relative to the chart area; `show()` positions and renders the tooltip.\n\n---\n\n### `ChartPluginContext`\n\n```ts\ninterface ChartPluginContext {\n container: HTMLElement;\n dimensions: Readable<ChartDimensions>;\n disposalSignal: AbortSignal;\n svg: SVGSVGElement;\n}\n```\n\nPassed to `ChartPlugin.install(ctx)`. Gives plugins access to the reactive `dimensions` signal, the host `container`, the root `svg` element, and a `disposalSignal` aborted when the chart is torn down.\n\n```ts\nimport type { ChartPlugin } from '@vielzeug/prism';\nimport { effect } from '@vielzeug/ripple';\n\nconst watermarkPlugin: ChartPlugin = {\n dispose() {},\n install(ctx) {\n // React to size changes\n effect(() => {\n const { width, height } = ctx.dimensions.value;\n /* re-layout watermark */\n });\n },\n};\n```\n\n> **Note:** To observe future resize events use `effect(() => { ctx.dimensions.value; })` from `@vielzeug/ripple` within a reactive scope. To run cleanup when the chart is disposed without relying on your own `dispose()` implementation being called, add a listener to `ctx.disposalSignal` instead: `ctx.disposalSignal.addEventListener('abort', cleanup)`.\n>\n> **Error isolation:** if a plugin's `install()` or `dispose()` throws, the error is logged (dev builds only) and the rest of the chart — and any other installed plugins — continues to work. A throwing plugin never aborts chart creation or teardown.\n\n---\n\n## Animation Utilities\n\n> Exported from `@vielzeug/prism` for use in plugins and custom chart extensions.\n\n### `animate`\n\n```ts\nfunction animate(\n targets: AnimationTarget[],\n config?: TransitionConfig,\n onComplete?: () => void,\n signal?: AbortSignal,\n): () => void;\n```\n\nAnimates SVG element attributes from `from` to `to` values over the given `TransitionConfig` duration. Calls `onComplete` when all animations finish. Returns a cancel function — call it to stop the in-flight animation early (its `requestAnimationFrame` loop is cancelled and `onComplete` is not called).\n\n- **Empty targets or `duration: 0`** — attributes are set immediately and `onComplete` is called synchronously; no RAF is scheduled. The returned cancel function is a no-op in this case.\n- **Negative `stagger`** — clamped to `0`; all elements animate in parallel.\n- **`signal`** — if provided and already aborted (or aborted mid-animation), the RAF loop stops rescheduling itself on its next frame, same effect as calling the returned cancel function.\n\n**Parameters — `AnimationTarget`:**\n\n| Field | Type | Description |\n| ------- | ---------------------------------------------- | --------------------------------- |\n| `el` | `SVGElement` | Target element |\n| `attrs` | `Record<string, { from: number; to: number }>` | Attribute name → start/end values |\n\n```ts\nimport { animate } from '@vielzeug/prism';\n\nconst cancel = animate([{ attrs: { opacity: { from: 0, to: 1 } }, el: rect }], { duration: 300, easing: 'ease-out' });\n\n// Stop early if the element is removed before the animation completes:\ncancel();\n```\n\n### `EasingFn`\n\n```ts\ntype EasingFn = (t: number) => number;\n```\n\nA custom easing function. Receives a normalised time value `t ∈ [0, 1]` and returns a progress value (also typically `[0, 1]`). Pass as `TransitionConfig.easing`. Unknown or invalid easing name strings fall back to `'ease-out'` rather than throwing.\n\n---\n\n## Devtools\n\n> **Import:** `@vielzeug/prism/devtools`\n\nOpt-in debug logging, separate from the internal dev-mode validation warnings in `_dev.ts` (those run automatically and need no import). Tree-shaken from production bundles when this sub-path isn't imported — there is no environment gate to configure.\n\n### `debugChart`\n\n```ts\ninterface DebugChartOptions {\n label?: string; // defaults to 'chart', producing log prefixes like [prism:chart]\n}\n\nfunction debugChart<T extends ChartHandle>(handle: T, options?: DebugChartOptions): T;\n```\n\nWraps an already-created `ChartHandle` with lifecycle logging to `console.debug`. Logs the chart's mount, every resize (via its own `ResizeObserver` on `handle.el`, independent of the chart's internal one), and disposal — each prefixed with `[prism:<label>]`. Returns the same handle unchanged, so it can wrap any `create*Chart()` call in place.\n\n```ts\nimport { createLineChart } from '@vielzeug/prism';\nimport { debugChart } from '@vielzeug/prism/devtools';\n\nconst chart = debugChart(createLineChart(container, config), { label: 'revenue' });\n// [prism:revenue] mounted\n// [prism:revenue] resized 600×300\nchart.dispose();\n// [prism:revenue] disposed\n```\n\n---\n\n## Errors\n\n### `PrismError`\n\nBase class for all prism errors. Use `instanceof PrismError` or `PrismError.is()` to catch any prism-originated error.\n\n```ts\nclass PrismError extends Error {\n static is(err: unknown): err is PrismError;\n}\n```\n\n**Named subclasses**\n\n| Class | Thrown when |\n| -------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| `PrismRenderError` | A chart is given a structurally invalid configuration it cannot render at all (e.g. a non-`Element` `container`). Recoverable issues like empty or malformed data emit a dev-mode warning instead — they do not throw. |\n| `PrismDisposedError` | Reserved for future disposal-sensitive APIs on `ChartHandle`. No code path throws this yet — calling `dispose()` more than once is currently a documented no-op, not an error. |\n",
|
|
6
|
-
"usage": "---\ntitle: Prism — Usage Guide\ndescription: Concepts, patterns, and best practices for @vielzeug/prism — reactive SVG charts.\n---\n\n[[toc]]\n\n## Basic Usage\n\nEvery chart needs a container element with defined dimensions and the theme CSS:\n\n```ts\nimport { createLineChart } from '@vielzeug/prism';\nimport '@vielzeug/prism/theme';\n\nconst container = document.querySelector<HTMLElement>('#chart')!;\nconst chart = createLineChart(container, {\n series: [\n {\n name: 'Revenue',\n data: [\n { key: 1, value: 10 },\n { key: 2, value: 16 },\n ],\n },\n ],\n});\n\nchart.dispose();\n```\n\n```html\n<div id=\"chart\" style=\"width: 100%; height: 300px;\"></div>\n```\n\nPrism observes the container size via `ResizeObserver` and re-renders automatically on resize. If the container has zero dimensions at mount time, a `warn` is emitted in development — ensure the container has layout before calling the chart factory.\n\n## Reactivity with Signals\n\nPrism accepts both plain values and `@vielzeug/ripple` signals for any data property. When a signal changes, the chart re-renders automatically in the next animation frame.\n\n### Static Data\n\n```ts\nimport { createLineChart } from '@vielzeug/prism';\n\nconst chart = createLineChart(container, {\n series: [\n {\n name: 'Static',\n data: [\n { key: 1, value: 10 },\n { key: 2, value: 20 },\n ],\n },\n ],\n});\n```\n\n### Reactive Data\n\n```ts\nimport { createLineChart } from '@vielzeug/prism';\nimport { signal } from '@vielzeug/ripple';\n\nconst data = signal([\n { key: 1, value: 10 },\n { key: 2, value: 20 },\n]);\n\nconst chart = createLineChart(container, {\n series: [{ name: 'Live', data }],\n});\n\n// Later — chart updates automatically\ndata.value = [...data.value, { key: 3, value: 30 }];\n```\n\n### The `MaybeSignal<T>` Pattern\n\nAll data-bearing config fields use the `MaybeSignal<T>` type:\n\n```ts\ntype MaybeSignal<T> = Readable<T> | T;\n```\n\nPass a plain value when data is fixed, or a `@vielzeug/ripple` signal when it changes dynamically. The chart handles both identically.\n\n## Line Charts\n\n```ts\nimport { createLineChart } from '@vielzeug/prism';\n\nconst chart = createLineChart(container, {\n series: [\n {\n name: 'Revenue',\n data: [\n { key: 1, value: 100 },\n { key: 2, value: 150 },\n { key: 3, value: 130 },\n ],\n color: '#3b82f6',\n curve: 'monotone', // 'linear' | 'monotone' | 'step'\n strokeWidth: 2,\n showPoints: true,\n pointRadius: 4,\n },\n ],\n xAxis: { position: 'bottom' },\n yAxis: { position: 'left', grid: true },\n tooltip: true,\n crosshair: true,\n});\n```\n\n### Multiple Series\n\n```ts\nconst chart = createLineChart(container, {\n series: [\n { name: 'Revenue', data: revenueData, color: '#3b82f6' },\n { name: 'Expenses', data: expenseData, color: '#ef4444' },\n ],\n xAxis: { position: 'bottom' },\n yAxis: { position: 'left', grid: true },\n});\n```\n\n### Time-based X Axis\n\nWhen data points use `Date` objects for `key`, Prism automatically applies a time scale:\n\n```ts\nconst chart = createLineChart(container, {\n series: [\n {\n name: 'Signups',\n data: [\n { key: new Date('2024-01-01'), value: 50 },\n { key: new Date('2024-02-01'), value: 80 },\n { key: new Date('2024-03-01'), value: 120 },\n ],\n },\n ],\n xAxis: { position: 'bottom', tickFormat: (d) => (d as Date).toLocaleDateString() },\n yAxis: { position: 'left' },\n});\n```\n\n## Bar Charts\n\n```ts\nimport { createBarChart } from '@vielzeug/prism';\n\nconst chart = createBarChart(container, {\n series: [\n {\n name: 'Sales',\n data: [\n { key: 'Q1', value: 200 },\n { key: 'Q2', value: 350 },\n { key: 'Q3', value: 280 },\n { key: 'Q4', value: 400 },\n ],\n borderRadius: 4,\n },\n ],\n xAxis: { position: 'bottom' },\n yAxis: { position: 'left', grid: true },\n tooltip: true,\n});\n```\n\n### Variants\n\nSelect the bar layout with `variant`:\n\n| Value | Layout |\n| ---------------------- | -------------------------- |\n| `'grouped'` | Vertical grouped (default) |\n| `'stacked'` | Vertical stacked |\n| `'grouped-horizontal'` | Horizontal grouped |\n| `'stacked-horizontal'` | Horizontal stacked |\n\n> **Note:** `tooltip` and `legend` are always available on the scaffold — omitting them uses a no-op null-object internally, so no conditional checks are needed in plugins or custom render logic.\n\n```ts\nconst chart = createBarChart(container, {\n variant: 'stacked',\n series: [\n { name: 'Mobile', data: mobileData, color: '#3b82f6', borderRadius: 0 },\n { name: 'Desktop', data: desktopData, color: '#10b981', borderRadius: 0 },\n ],\n xAxis: { position: 'bottom' },\n yAxis: { position: 'left', grid: true },\n tooltip: true,\n legend: true,\n});\n```\n\nFor horizontal layouts, categories appear on the Y axis and values on the X axis:\n\n```ts\nconst chart = createBarChart(container, {\n variant: 'grouped-horizontal',\n series: [{ name: 'Revenue', data, color: '#3b82f6' }],\n xAxis: { position: 'bottom', grid: true },\n yAxis: { position: 'left' },\n});\n```\n\n### Grouped Bars\n\nMultiple series with `variant: 'grouped'` (default) render side-by-side:\n\n```ts\nconst chart = createBarChart(container, {\n series: [\n { name: '2023', data: lastYearData, color: '#94a3b8' },\n { name: '2024', data: thisYearData, color: '#3b82f6' },\n ],\n});\n```\n\n## Area Charts\n\n```ts\nimport { createAreaChart } from '@vielzeug/prism';\n\nconst chart = createAreaChart(container, {\n series: [\n {\n name: 'Users',\n data: userData,\n curve: 'monotone',\n fillOpacity: 0.2,\n showLine: true,\n },\n ],\n xAxis: { position: 'bottom' },\n yAxis: { position: 'left', grid: true },\n crosshair: true,\n});\n```\n\n## Pie, Donut, and Semi-circle Charts\n\nAll three variants use `createPieChart` with the `variant` field:\n\n```ts\nimport { createPieChart } from '@vielzeug/prism';\n\nconst chart = createPieChart(container, {\n data: [\n { label: 'Direct', value: 42, color: '#3b82f6' },\n { label: 'Organic', value: 28, color: '#10b981' },\n { label: 'Referral', value: 18, color: '#f59e0b' },\n { label: 'Social', value: 12, color: '#8b5cf6' },\n ],\n variant: 'donut', // 'pie' | 'donut' | 'semi'\n tooltip: true,\n transition: { duration: 400, easing: 'ease-out' },\n});\n```\n\n### Variants\n\n| Value | Shape |\n| --------- | ------------------------------------------------------- |\n| `'pie'` | Full circle, no hole |\n| `'donut'` | Full circle with inner hole (~55% of outer by default) |\n| `'semi'` | Top-half semicircle with inner hole — useful for gauges |\n\n### Inner Radius\n\n`innerRadius` overrides the automatic calculation:\n\n```ts\ncreatePieChart(container, {\n data,\n variant: 'donut',\n innerRadius: 60, // explicit pixels\n});\n```\n\n### Slice Labels\n\nSet `label` on each `PieSliceConfig` to render text at the arc centroid:\n\n```ts\n{ value: 42, label: '42%' }\n```\n\nStyle labels via CSS:\n\n```css\n:root {\n --prism-pie-label-color: #fff;\n --prism-pie-label-size: 11px;\n}\n```\n\n### Reactive Data\n\n```ts\nimport { signal } from '@vielzeug/ripple';\n\nconst data = signal([\n { label: 'A', value: 40 },\n { label: 'B', value: 60 },\n]);\n\nconst chart = createPieChart(container, { data, variant: 'donut' });\n\ndata.value = [\n { label: 'A', value: 55 },\n { label: 'B', value: 45 },\n];\n```\n\n### Event Hooks\n\n```ts\ncreatePieChart(container, {\n data,\n onHover: (slice, index) => {\n // slice/index are null on mouseleave\n if (slice) console.log(slice.label, slice.value);\n },\n onClick: (slice, index) => {\n console.log('clicked', slice.label);\n },\n});\n```\n\n## Sparklines\n\nSparklines are minimal inline charts with no axes, no legend, and no margin — designed to live inline with text or inside table cells.\n\n```ts\nimport { createSparkline } from '@vielzeug/prism';\n\nconst spark = createSparkline(container, {\n data: [12, 18, 14, 22, 19, 28],\n variant: 'line', // 'line' | 'area' | 'bar' (default: 'line')\n color: '#3b82f6',\n curve: 'monotone',\n strokeWidth: 1.5,\n});\n\nspark.dispose();\n```\n\n### Variants\n\n- **`line`** — simple polyline path (default)\n- **`area`** — filled area + line overlay\n- **`bar`** — vertical bar for each data point\n- **`stack`** — horizontal proportional segments; use `StackSegment[]` for `data` with per-segment colors\n\n### Reactive Data\n\n```ts\nimport { signal } from '@vielzeug/ripple';\n\nconst data = signal([12, 18, 14, 22]);\n\nconst spark = createSparkline(container, { data, variant: 'area' });\n\ndata.value = [...data.value, 30]; // re-renders automatically\n```\n\n### Event Hooks\n\nSparklines use simplified hooks — index-based rather than full `ChartEvent`:\n\n```ts\nconst spark = createSparkline(container, {\n data: [10, 20, 30],\n onHover: (index, value) => {\n // index/value are null on mouseleave\n if (index !== null) console.log(`Hovering point ${index}: ${value}`);\n },\n onClick: (index, value) => {\n console.log(`Clicked point ${index}: ${value}`);\n },\n});\n```\n\n> **Note:** Sparkline SVGs are marked `aria-hidden=\"true\"` since they are decorative. Provide meaningful surrounding text context for accessibility.\n\n## Axes and Grid\n\n```ts\n{\n xAxis: {\n position: 'bottom', // 'top' | 'bottom'\n tickCount: 5,\n tickFormat: (v) => `$${v}`,\n label: 'Month',\n grid: true, // or { color: '#ddd', dash: '4 2' }\n },\n yAxis: {\n position: 'left', // 'left' | 'right'\n grid: { color: '#f0f0f0' },\n label: 'Revenue ($)',\n },\n}\n```\n\n## Tooltips\n\nEnable with `tooltip: true` for default rendering, or provide a custom `render` function returning an HTML string:\n\n```ts\n{\n tooltip: {\n offset: 12,\n render: (datum, series) => `\n <strong>${series.name}</strong><br/>\n Value: ${datum.value.toLocaleString()}\n `,\n },\n}\n```\n\nThe `render` output is injected via `innerHTML`. If you interpolate user-supplied data, pass a `sanitize` function to guard against XSS:\n\n```ts\nimport DOMPurify from 'dompurify';\n\n{\n tooltip: {\n render: (datum, series) => `<b>${series.name}</b>: ${datum.value}`,\n sanitize: (html) => DOMPurify.sanitize(html),\n },\n}\n```\n\nThe tooltip element is scoped inside the chart container (not `document.body`) and is removed automatically on `dispose()`.\n\n## Crosshair\n\nA vertical guide that snaps to the nearest data point:\n\n```ts\n{\n crosshair: true,\n // or configure:\n crosshair: { vertical: true, horizontal: true, snap: true },\n}\n```\n\n## Legend\n\nEnable with `legend: true` (defaults to `bottom`) or configure position:\n\n```ts\n{\n legend: true,\n // or:\n legend: { position: 'top' }, // 'top' | 'bottom' | 'left' | 'right'\n}\n```\n\nThe legend renders as a `div` placed outside the SVG. Each item shows a color swatch and the series `name`. Customize via CSS:\n\n```css\n:root {\n --prism-legend-gap: 1rem;\n --prism-legend-dot-size: 0.5rem;\n --prism-legend-font-size: 0.75rem;\n}\n```\n\n## Event Hooks\n\nAll charts expose `onClick` and `onHover` callbacks on the config:\n\n```ts\nconst chart = createLineChart(container, {\n series: [{ name: 'Revenue', data }],\n onHover: (event) => {\n // event is ChartEvent | null (null on mouseleave)\n if (event) console.log(event.datum, event.series);\n },\n onClick: (event) => {\n console.log('clicked', event.datum);\n },\n});\n```\n\n`ChartEvent` provides:\n\n- `datum` — the nearest `Datum`\n- `series` — the corresponding `Series` config\n- `originalEvent` — the raw `MouseEvent`\n\n> **Pie chart events differ** — `onHover` and `onClick` receive `(slice: PieSliceConfig, index: number)` instead of `ChartEvent`. See [`PieChartConfig`](./api.md#piechartconfig) for details.\n\n## Plugins\n\nExtend any chart with custom behavior using the `ChartPlugin` interface. All chart types — including `createPieChart` — support `plugins`.\n\n```ts\nimport type { ChartPlugin } from '@vielzeug/prism';\n\nfunction createClickLogger(): ChartPlugin {\n const handler = (e: MouseEvent) => console.log('chart clicked', e);\n // `dispose()` receives no arguments, so capture whatever `install()` needs\n // to clean up (here, the svg it attached the listener to) in this closure.\n let svg: SVGSVGElement | undefined;\n\n return {\n install(ctx) {\n svg = ctx.svg;\n svg.addEventListener('click', handler);\n },\n dispose() {\n svg?.removeEventListener('click', handler);\n },\n };\n}\n\nconst chart = createLineChart(container, {\n series: [{ name: 'Revenue', data }],\n plugins: [createClickLogger()],\n});\n\n// Works for pie charts too:\nconst pie = createPieChart(container, {\n data,\n plugins: [createClickLogger()],\n});\n```\n\n> **Alternative to `dispose()`:** `install(ctx)` can instead listen for `ctx.disposalSignal`'s `abort` event to run cleanup, without needing to capture anything for a separate `dispose()` implementation: `ctx.disposalSignal.addEventListener('abort', () => svg.removeEventListener('click', handler))`.\n>\n> **Error isolation:** if a plugin's `install()` or `dispose()` throws, the error is logged in development and the rest of the chart — plus any other installed plugins — keeps working. A throwing plugin never aborts chart creation or teardown.\n\n## Animations\n\nPass a `transition` config to animate enter and update transitions:\n\n```ts\n{\n transition: {\n duration: 400,\n easing: 'ease-out',\n stagger: 30, // bar charts only: ms delay between each bar's enter animation\n },\n}\n```\n\nAll chart types use requestAnimationFrame-based interpolation. Bar charts additionally support `stagger` — a per-bar delay that creates a cascade effect on first render.\n\n## Theming\n\nImport the default theme:\n\n```ts\nimport '@vielzeug/prism/theme';\n```\n\n### Programmatic Theme with `setTheme`\n\nCall `setTheme` once at app startup to apply custom tokens programmatically:\n\n```ts\nimport { setTheme } from '@vielzeug/prism';\n\nsetTheme({\n colors: ['#6366f1', '#22d3ee', '#f59e0b', '#10b981'], // replaces --prism-color-1 through -4\n fontFamily: 'Inter, system-ui, sans-serif', // sets --prism-font-family\n gridColor: '#e2e8f0', // sets --prism-grid-color\n gridOpacity: 0.6, // sets --prism-grid-opacity\n});\n```\n\n`setTheme` writes to `document.documentElement` style, so it takes precedence over CSS file defaults. Call `resetTheme()` to clear every custom property `setTheme` can set and restore the default theme — useful for a theme-switcher's \"reset\" action or test teardown:\n\n```ts\nimport { resetTheme } from '@vielzeug/prism';\n\nresetTheme();\n```\n\n### Custom Theme (CSS)\n\n```css\n:root {\n --prism-color-1: #6366f1;\n --prism-color-2: #22c55e;\n --prism-axis-color: #71717a;\n --prism-grid-color: #f4f4f5;\n --prism-text-color: #18181b;\n --prism-tooltip-bg: #27272a;\n --prism-font-family: 'Inter', system-ui, sans-serif;\n}\n```\n\n### Scoped Themes\n\nApply tokens to a specific container:\n\n```css\n.dark-dashboard {\n --prism-axis-color: #64748b;\n --prism-grid-color: #334155;\n --prism-text-color: #e2e8f0;\n}\n```\n\n### Available Tokens\n\n| Token | Default | Description |\n| ------------------------- | ---------------- | ---------------------- |\n| `--prism-color-{1-8}` | Tailwind palette | Series color palette |\n| `--prism-bg` | `transparent` | Chart background |\n| `--prism-axis-color` | `#94a3b8` | Axis lines and ticks |\n| `--prism-grid-color` | `#e2e8f0` | Grid lines |\n| `--prism-text-color` | `#334155` | Axis labels and text |\n| `--prism-font-family` | `system-ui` | Chart font |\n| `--prism-font-size` | `12px` | Label font size |\n| `--prism-tooltip-bg` | `#1e293b` | Tooltip background |\n| `--prism-tooltip-color` | `#f8fafc` | Tooltip text |\n| `--prism-tooltip-radius` | `6px` | Tooltip border radius |\n| `--prism-crosshair-color` | `#64748b` | Crosshair line |\n| `--prism-crosshair-dash` | `4 2` | Crosshair dash pattern |\n\n## Scales (Standalone)\n\nScales can be used independently for custom visualizations:\n\n```ts\nimport { linearScale, timeScale, bandScale } from '@vielzeug/prism';\n\nconst y = linearScale({ domain: [0, 100], range: [300, 0] });\ny.map(50); // → 150\ny.invert(150); // → 50\ny.ticks(5); // → [0, 20, 40, 60, 80, 100]\n\nconst x = bandScale({ domain: ['A', 'B', 'C'], range: [0, 300] });\nx.map('B'); // → pixel left edge of band B\nx.bandwidth(); // → width of each band\n```\n\n## Lifecycle and Cleanup\n\nEvery chart returns a `ChartHandle`. Always call `dispose()` when removing a chart:\n\n```ts\nconst chart = createLineChart(container, config);\n\n// When done:\nchart.dispose();\n\n// Or with TC39 explicit resource management:\n{\n using chart = createLineChart(container, config);\n // auto-disposed at block end\n}\n```\n\nCalling `dispose()`:\n\n- Cancels all reactive signal effects\n- Disconnects the `ResizeObserver`\n- Removes the SVG element, tooltip, and legend from the DOM\n- Calls `dispose()` on all plugins (a plugin that throws is logged and skipped — it never blocks the rest of teardown)\n- Is idempotent — safe to call multiple times\n\n> **Reactivity is automatic** — charts re-render whenever signal data changes. There is no manual `update()` call needed.\n\n## Responsive Behavior\n\nCharts resize automatically when the container dimensions change. Prism uses `ResizeObserver` internally — no manual `resize()` call is needed.\n\n## Devtools\n\nImport `debugChart()` from the `/devtools` subpath to log a chart's mount, resize, and dispose events to `console.debug`. It's separate from prism's internal validation warnings (those run automatically in development, no import needed) and is tree-shaken from production bundles when this subpath isn't imported.\n\n```ts\nimport { createLineChart } from '@vielzeug/prism';\nimport { debugChart } from '@vielzeug/prism/devtools';\n\nconst chart = debugChart(createLineChart(container, config), { label: 'revenue' });\n// [prism:revenue] mounted\n// [prism:revenue] resized 600×300\nchart.dispose();\n// [prism:revenue] disposed\n```\n\n> `debugChart()` wraps and returns the same `ChartHandle` unchanged, so it drops into any `create*Chart()` call without restructuring your code.\n\n## Framework Integration\n\nPrism renders into a plain DOM element. Attach charts inside mount/unmount lifecycle hooks for any framework.\n\n::: code-group\n\n```tsx [React]\nimport { useEffect, useRef } from 'react';\nimport { createLineChart, type Datum } from '@vielzeug/prism';\n\nfunction LineChart({ data }: { data: Datum[] }) {\n const containerRef = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n const chart = createLineChart(containerRef.current!, {\n series: [{ data, name: 'Series' }],\n });\n return () => chart.dispose();\n }, [data]);\n\n return <div ref={containerRef} style={{ width: '100%', height: 300 }} />;\n}\n```\n\n```ts [Vue 3]\nimport { onMounted, onUnmounted, ref } from 'vue';\nimport { createLineChart, type ChartHandle, type Datum } from '@vielzeug/prism';\n\nfunction useLineChart(data: Datum[]) {\n const containerRef = ref<HTMLElement | null>(null);\n let chart: ChartHandle | null = null;\n\n onMounted(() => {\n chart = createLineChart(containerRef.value!, { series: [{ data, name: 'Series' }] });\n });\n\n onUnmounted(() => chart?.dispose());\n return { containerRef };\n}\n```\n\n```svelte [Svelte]\n<script lang=\"ts\">\n import { onMount } from 'svelte';\n import { createLineChart, type Datum } from '@vielzeug/prism';\n\n export let data: Datum[] = [];\n let container: HTMLDivElement;\n\n onMount(() => {\n const chart = createLineChart(container, { series: [{ data, name: 'Series' }] });\n return () => chart.dispose();\n });\n</script>\n\n<div bind:this={container} style=\"width:100%;height:300px\"></div>\n```\n\n:::\n\n## Working with Other Vielzeug Libraries\n\n### With Ripple\n\nPass Ripple signals as chart data properties. Prism re-renders automatically when a signal changes.\n\n```ts\nimport { signal } from '@vielzeug/ripple';\nimport { createLineChart } from '@vielzeug/prism';\n\nconst data = signal([\n { key: 1, value: 10 },\n { key: 2, value: 20 },\n]);\n\nconst chart = createLineChart(container, {\n series: [{ data, name: 'Series' }], // signal passed directly\n});\n\n// Updating the signal triggers an automatic re-render:\ndata.value = [\n { key: 1, value: 15 },\n { key: 2, value: 25 },\n];\n```\n\n### With Sourcerer\n\nBind chart data to a Sourcerer remote source so charts update whenever the list refreshes.\n\n```ts\nimport { createPageSource } from '@vielzeug/sourcerer';\nimport { computed, signal } from '@vielzeug/ripple';\nimport { createBarChart } from '@vielzeug/prism';\n\nconst source = createPageSource({ load: ({ query, signal }) => api.stats.list(query, { signal }) });\nconst snapshot = signal(source.snapshot);\nsource.subscribe((next) => (snapshot.value = next));\n\nconst chartData = computed(() => snapshot.value.data.map((item) => ({ key: item.label, value: item.count })));\n\nconst chart = createBarChart(container, {\n series: [{ data: chartData, name: 'Series' }],\n});\n```\n\n## Best Practices\n\n- Ensure the container element has explicit dimensions before calling a chart factory — `ResizeObserver` needs a non-zero layout size to trigger the first render.\n- Call `chart.dispose()` in your framework's unmount/cleanup phase to cancel signal effects and remove DOM nodes.\n- Prefer `signal()` from Ripple for mutable data properties — charts re-render automatically when signals change, with no manual `update()` call.\n- Wrap a chart with `debugChart()` from the `/devtools` subpath only in development code paths; it is tree-shaken in production.\n- For SSR, skip chart creation server-side — Prism depends on DOM APIs and `ResizeObserver`. Render charts only after hydration in a `onMounted`/`useEffect` callback.\n",
|
|
7
|
-
"examples": "---\ntitle: Prism — Examples\ndescription: Interactive code examples for @vielzeug/prism charts.\n---\n\n[[toc]]\n\n## Line Chart\n\nBasic line chart with tooltip and crosshair:\n\n<ComponentPreview vertical height=\"320px\">\n\n```html\n<div id=\"ex-line\" style=\"width:100%;height:280px;\"></div>\n<script>\n const { createLineChart } = Prism;\n createLineChart(document.getElementById('ex-line'), {\n series: [\n {\n name: 'Revenue',\n data: [\n { key: 1, value: 120 },\n { key: 2, value: 180 },\n { key: 3, value: 150 },\n { key: 4, value: 220 },\n { key: 5, value: 195 },\n { key: 6, value: 280 },\n ],\n color: '#3b82f6',\n curve: 'monotone',\n strokeWidth: 2,\n showPoints: true,\n },\n ],\n xAxis: { position: 'bottom' },\n yAxis: { position: 'left', grid: true },\n tooltip: true,\n crosshair: true,\n });\n</script>\n```\n\n</ComponentPreview>\n\n## Multi-series Line Chart\n\nMultiple lines with different curves:\n\n<ComponentPreview vertical height=\"320px\">\n\n```html\n<div id=\"ex-multi-line\" style=\"width:100%;height:280px;\"></div>\n<script>\n const { createLineChart } = Prism;\n createLineChart(document.getElementById('ex-multi-line'), {\n series: [\n {\n name: 'Product A',\n data: [\n { key: 1, value: 40 },\n { key: 2, value: 65 },\n { key: 3, value: 55 },\n { key: 4, value: 80 },\n { key: 5, value: 72 },\n ],\n color: '#3b82f6',\n curve: 'monotone',\n },\n {\n name: 'Product B',\n data: [\n { key: 1, value: 20 },\n { key: 2, value: 35 },\n { key: 3, value: 60 },\n { key: 4, value: 45 },\n { key: 5, value: 90 },\n ],\n color: '#10b981',\n curve: 'monotone',\n },\n ],\n xAxis: { position: 'bottom' },\n yAxis: { position: 'left', grid: true },\n crosshair: true,\n });\n</script>\n```\n\n</ComponentPreview>\n\n## Legend — Line Chart\n\nAdd `legend: true` to label each series below the chart:\n\n<ComponentPreview vertical height=\"360px\">\n\n```html\n<div id=\"ex-legend-line\" style=\"width:100%;height:280px;\"></div>\n<script>\n const { createLineChart } = Prism;\n createLineChart(document.getElementById('ex-legend-line'), {\n series: [\n {\n name: 'Revenue',\n data: [\n { key: 1, value: 120 },\n { key: 2, value: 180 },\n { key: 3, value: 150 },\n { key: 4, value: 220 },\n { key: 5, value: 195 },\n ],\n color: '#3b82f6',\n curve: 'monotone',\n },\n {\n name: 'Expenses',\n data: [\n { key: 1, value: 80 },\n { key: 2, value: 95 },\n { key: 3, value: 110 },\n { key: 4, value: 130 },\n { key: 5, value: 125 },\n ],\n color: '#ef4444',\n curve: 'monotone',\n },\n ],\n xAxis: { position: 'bottom' },\n yAxis: { position: 'left', grid: true },\n tooltip: true,\n crosshair: true,\n legend: true,\n });\n</script>\n```\n\n</ComponentPreview>\n\n## Bar Chart\n\nGrouped bar chart comparing categories:\n\n<ComponentPreview vertical height=\"320px\">\n\n```html\n<div id=\"ex-bar\" style=\"width:100%;height:280px;\"></div>\n<script>\n const { createBarChart } = Prism;\n createBarChart(document.getElementById('ex-bar'), {\n series: [\n {\n name: '2023',\n data: [\n { key: 'Q1', value: 120 },\n { key: 'Q2', value: 180 },\n { key: 'Q3', value: 150 },\n { key: 'Q4', value: 210 },\n ],\n color: '#94a3b8',\n borderRadius: 4,\n },\n {\n name: '2024',\n data: [\n { key: 'Q1', value: 150 },\n { key: 'Q2', value: 220 },\n { key: 'Q3', value: 190 },\n { key: 'Q4', value: 280 },\n ],\n color: '#3b82f6',\n borderRadius: 4,\n },\n ],\n xAxis: { position: 'bottom' },\n yAxis: { position: 'left', grid: true },\n tooltip: true,\n });\n</script>\n```\n\n</ComponentPreview>\n\n## Stacked Bar Chart\n\nBar chart with `variant: 'stacked'` — series stack vertically per category:\n\n<ComponentPreview vertical height=\"320px\">\n\n```html\n<div id=\"ex-bar-stacked\" style=\"width:100%;height:280px;\"></div>\n<script>\n const { createBarChart } = Prism;\n createBarChart(document.getElementById('ex-bar-stacked'), {\n series: [\n {\n name: 'Mobile',\n data: [\n { key: 'Q1', value: 80 },\n { key: 'Q2', value: 110 },\n { key: 'Q3', value: 95 },\n { key: 'Q4', value: 130 },\n ],\n color: '#3b82f6',\n borderRadius: 0,\n },\n {\n name: 'Desktop',\n data: [\n { key: 'Q1', value: 60 },\n { key: 'Q2', value: 90 },\n { key: 'Q3', value: 75 },\n { key: 'Q4', value: 100 },\n ],\n color: '#10b981',\n borderRadius: 0,\n },\n {\n name: 'Tablet',\n data: [\n { key: 'Q1', value: 20 },\n { key: 'Q2', value: 30 },\n { key: 'Q3', value: 25 },\n { key: 'Q4', value: 35 },\n ],\n color: '#f59e0b',\n borderRadius: 0,\n },\n ],\n variant: 'stacked',\n xAxis: { position: 'bottom' },\n yAxis: { position: 'left', grid: true },\n tooltip: true,\n legend: true,\n });\n</script>\n```\n\n</ComponentPreview>\n\n## Horizontal Bar Chart\n\nBar chart with `variant: 'grouped-horizontal'` — categories on the Y axis, values on the X axis:\n\n<ComponentPreview vertical height=\"320px\">\n\n```html\n<div id=\"ex-bar-horizontal\" style=\"width:100%;height:280px;\"></div>\n<script>\n const { createBarChart } = Prism;\n createBarChart(document.getElementById('ex-bar-horizontal'), {\n variant: 'grouped-horizontal',\n series: [\n {\n name: 'Revenue',\n data: [\n { key: 'Q1', value: 80 },\n { key: 'Q2', value: 110 },\n { key: 'Q3', value: 95 },\n { key: 'Q4', value: 130 },\n ],\n color: '#3b82f6',\n },\n ],\n xAxis: { position: 'bottom', grid: true },\n yAxis: { position: 'left' },\n tooltip: true,\n });\n</script>\n```\n\n</ComponentPreview>\n\n## Horizontal Stacked Bar Chart\n\nUse `variant: 'stacked-horizontal'` — horizontal bars stacked per category:\n\n<ComponentPreview vertical height=\"320px\">\n\n```html\n<div id=\"ex-bar-h-stacked\" style=\"width:100%;height:280px;\"></div>\n<script>\n const { createBarChart } = Prism;\n createBarChart(document.getElementById('ex-bar-h-stacked'), {\n variant: 'stacked-horizontal',\n series: [\n {\n name: 'Mobile',\n data: [\n { key: 'Q1', value: 80 },\n { key: 'Q2', value: 110 },\n { key: 'Q3', value: 95 },\n { key: 'Q4', value: 130 },\n ],\n color: '#3b82f6',\n borderRadius: 0,\n },\n {\n name: 'Desktop',\n data: [\n { key: 'Q1', value: 60 },\n { key: 'Q2', value: 90 },\n { key: 'Q3', value: 75 },\n { key: 'Q4', value: 100 },\n ],\n color: '#10b981',\n borderRadius: 0,\n },\n ],\n xAxis: { position: 'bottom', grid: true },\n yAxis: { position: 'left' },\n tooltip: true,\n legend: true,\n });\n</script>\n```\n\n</ComponentPreview>\n\n## Legend — Bar Chart\n\nGrouped bar chart with a legend positioned at the top:\n\n<ComponentPreview vertical height=\"360px\">\n\n```html\n<div id=\"ex-legend-bar\" style=\"width:100%;height:280px;\"></div>\n<script>\n const { createBarChart } = Prism;\n createBarChart(document.getElementById('ex-legend-bar'), {\n series: [\n {\n name: '2023',\n data: [\n { key: 'Q1', value: 120 },\n { key: 'Q2', value: 180 },\n { key: 'Q3', value: 150 },\n { key: 'Q4', value: 210 },\n ],\n color: '#94a3b8',\n borderRadius: 4,\n },\n {\n name: '2024',\n data: [\n { key: 'Q1', value: 150 },\n { key: 'Q2', value: 220 },\n { key: 'Q3', value: 190 },\n { key: 'Q4', value: 280 },\n ],\n color: '#3b82f6',\n borderRadius: 4,\n },\n ],\n xAxis: { position: 'bottom' },\n yAxis: { position: 'left', grid: true },\n tooltip: true,\n legend: { position: 'top' },\n });\n</script>\n```\n\n</ComponentPreview>\n\n## Area Chart\n\nFilled area with monotone curve and low opacity:\n\n<ComponentPreview vertical height=\"320px\">\n\n```html\n<div id=\"ex-area\" style=\"width:100%;height:280px;\"></div>\n<script>\n const { createAreaChart } = Prism;\n createAreaChart(document.getElementById('ex-area'), {\n series: [\n {\n name: 'Signups',\n data: [\n { key: 1, value: 500 },\n { key: 2, value: 650 },\n { key: 3, value: 800 },\n { key: 4, value: 720 },\n { key: 5, value: 900 },\n { key: 6, value: 1100 },\n ],\n color: '#8b5cf6',\n curve: 'monotone',\n fillOpacity: 0.2,\n showLine: true,\n },\n ],\n xAxis: { position: 'bottom' },\n yAxis: { position: 'left', grid: { color: '#f1f5f9' } },\n crosshair: { vertical: true },\n });\n</script>\n```\n\n</ComponentPreview>\n\n## Legend — Area Chart\n\nMulti-series area chart with a bottom legend:\n\n<ComponentPreview vertical height=\"360px\">\n\n```html\n<div id=\"ex-legend-area\" style=\"width:100%;height:280px;\"></div>\n<script>\n const { createAreaChart } = Prism;\n createAreaChart(document.getElementById('ex-legend-area'), {\n series: [\n {\n name: 'Mobile',\n data: [\n { key: 1, value: 300 },\n { key: 2, value: 420 },\n { key: 3, value: 510 },\n { key: 4, value: 480 },\n { key: 5, value: 620 },\n { key: 6, value: 750 },\n ],\n color: '#8b5cf6',\n curve: 'monotone',\n fillOpacity: 0.25,\n },\n {\n name: 'Desktop',\n data: [\n { key: 1, value: 200 },\n { key: 2, value: 230 },\n { key: 3, value: 290 },\n { key: 4, value: 240 },\n { key: 5, value: 280 },\n { key: 6, value: 350 },\n ],\n color: '#06b6d4',\n curve: 'monotone',\n fillOpacity: 0.25,\n },\n ],\n xAxis: { position: 'bottom' },\n yAxis: { position: 'left', grid: true },\n crosshair: true,\n legend: true,\n });\n</script>\n```\n\n</ComponentPreview>\n\n## Step Line Chart\n\nLine chart with step interpolation:\n\n<ComponentPreview vertical height=\"320px\">\n\n```html\n<div id=\"ex-step\" style=\"width:100%;height:280px;\"></div>\n<script>\n const { createLineChart } = Prism;\n createLineChart(document.getElementById('ex-step'), {\n series: [\n {\n name: 'Status',\n data: [\n { key: 1, value: 0 },\n { key: 2, value: 1 },\n { key: 3, value: 1 },\n { key: 4, value: 0 },\n { key: 5, value: 1 },\n { key: 6, value: 0 },\n ],\n color: '#f59e0b',\n curve: 'step',\n strokeWidth: 3,\n },\n ],\n xAxis: { position: 'bottom' },\n yAxis: { position: 'left' },\n });\n</script>\n```\n\n</ComponentPreview>\n\n## Reactive Chart\n\nChart that updates when signal data changes:\n\n<ComponentPreview vertical height=\"320px\">\n\n```html\n<div style=\"margin-bottom:8px;\">\n <button id=\"ex-reactive-btn\" style=\"padding:4px 12px;border:1px solid #e2e8f0;border-radius:4px;cursor:pointer;\">\n Add Data Point\n </button>\n</div>\n<div id=\"ex-reactive\" style=\"width:100%;height:250px;\"></div>\n<script>\n const { createLineChart } = Prism;\n const { signal } = Ripple;\n\n const data = signal([\n { key: 1, value: 20 },\n { key: 2, value: 35 },\n { key: 3, value: 28 },\n { key: 4, value: 45 },\n ]);\n\n createLineChart(document.getElementById('ex-reactive'), {\n series: [{ name: 'Live', data, color: '#10b981', curve: 'monotone', showPoints: true }],\n xAxis: { position: 'bottom' },\n yAxis: { position: 'left', grid: true },\n crosshair: true,\n transition: { duration: 400, easing: 'ease-out' },\n });\n\n document.getElementById('ex-reactive-btn').addEventListener('click', function () {\n var prev = data.value;\n var nextX = prev.length + 1;\n var nextY = 20 + Math.floor(Math.random() * 40);\n data.value = prev.concat([{ key: nextX, value: nextY }]);\n });\n</script>\n```\n\n</ComponentPreview>\n\n## Reactive Bar Chart\n\nBar chart that updates when signal data changes, with stagger animation on new bars:\n\n<ComponentPreview vertical height=\"320px\">\n\n```html\n<div style=\"margin-bottom:8px;\">\n <button id=\"ex-reactive-bar-btn\" style=\"padding:4px 12px;border:1px solid #e2e8f0;border-radius:4px;cursor:pointer;\">\n Add Category\n </button>\n</div>\n<div id=\"ex-reactive-bar\" style=\"width:100%;height:250px;\"></div>\n<script>\n const { createBarChart } = Prism;\n const { signal } = Ripple;\n\n const barData = signal([\n { key: 'Q1', value: 120 },\n { key: 'Q2', value: 180 },\n { key: 'Q3', value: 150 },\n { key: 'Q4', value: 210 },\n ]);\n\n createBarChart(document.getElementById('ex-reactive-bar'), {\n series: [{ name: 'Revenue', data: barData, color: '#6366f1', borderRadius: 4 }],\n xAxis: { position: 'bottom' },\n yAxis: { position: 'left', grid: true },\n tooltip: true,\n transition: { duration: 400, easing: 'ease-out', stagger: 40 },\n });\n\n var quarters = ['Q5', 'Q6', 'Q7', 'Q8'];\n var qIdx = 0;\n document.getElementById('ex-reactive-bar-btn').addEventListener('click', function () {\n if (qIdx >= quarters.length) return;\n var nextY = 150 + Math.floor(Math.random() * 120);\n barData.value = barData.value.concat([{ key: quarters[qIdx++], value: nextY }]);\n });\n</script>\n```\n\n</ComponentPreview>\n\n## Event Hooks\n\nUsing `onHover` and `onClick` to react to chart interactions:\n\n<ComponentPreview vertical height=\"360px\">\n\n```html\n<div id=\"ex-events-info\" style=\"margin-bottom:8px;font-size:13px;color:#64748b;min-height:20px;\"></div>\n<div id=\"ex-events\" style=\"width:100%;height:280px;\"></div>\n<script>\n const { createLineChart } = Prism;\n\n const info = document.getElementById('ex-events-info');\n\n createLineChart(document.getElementById('ex-events'), {\n series: [\n {\n name: 'Revenue',\n data: [\n { key: 1, value: 120 },\n { key: 2, value: 180 },\n { key: 3, value: 150 },\n { key: 4, value: 220 },\n { key: 5, value: 195 },\n { key: 6, value: 280 },\n ],\n color: '#3b82f6',\n curve: 'monotone',\n showPoints: true,\n },\n ],\n xAxis: { position: 'bottom' },\n yAxis: { position: 'left', grid: true },\n onHover: function (event) {\n info.textContent = event ? 'Hovering key=' + event.datum.key + ' value=' + event.datum.value : '';\n },\n onClick: function (event) {\n info.textContent = 'Clicked key=' + event.datum.key + ' value=' + event.datum.value;\n },\n });\n</script>\n```\n\n</ComponentPreview>\n\n## Pie Chart\n\nBasic pie chart with labeled slices:\n\n<ComponentPreview vertical height=\"340px\">\n\n```html\n<div id=\"ex-pie\" style=\"width:300px;height:300px;\"></div>\n<script>\n const { createPieChart } = Prism;\n createPieChart(document.getElementById('ex-pie'), {\n data: [\n { label: 'Direct', value: 42, color: '#3b82f6' },\n { label: 'Organic', value: 28, color: '#10b981' },\n { label: 'Referral', value: 18, color: '#f59e0b' },\n { label: 'Social', value: 12, color: '#8b5cf6' },\n ],\n variant: 'pie',\n transition: { duration: 600, easing: 'ease-out' },\n });\n</script>\n```\n\n</ComponentPreview>\n\n## Donut Chart\n\nDonut chart with tooltip:\n\n<ComponentPreview vertical height=\"340px\">\n\n```html\n<div id=\"ex-donut\" style=\"width:300px;height:300px;\"></div>\n<script>\n const { createPieChart } = Prism;\n createPieChart(document.getElementById('ex-donut'), {\n data: [\n { label: 'Direct', value: 42, color: '#3b82f6' },\n { label: 'Organic', value: 28, color: '#10b981' },\n { label: 'Referral', value: 18, color: '#f59e0b' },\n { label: 'Social', value: 12, color: '#8b5cf6' },\n ],\n variant: 'donut',\n tooltip: true,\n transition: { duration: 600, easing: 'ease-out' },\n });\n</script>\n```\n\n</ComponentPreview>\n\n## Semi-circle Donut\n\nSemicircle donut — useful for gauges and progress indicators:\n\n<ComponentPreview vertical height=\"220px\">\n\n```html\n<div id=\"ex-semi\" style=\"width:300px;height:180px;\"></div>\n<script>\n const { createPieChart } = Prism;\n createPieChart(document.getElementById('ex-semi'), {\n data: [\n { label: 'Used', value: 68, color: '#3b82f6' },\n { label: 'Free', value: 32, color: '#e2e8f0' },\n ],\n variant: 'semi',\n transition: { duration: 800, easing: 'ease-out' },\n });\n</script>\n```\n\n</ComponentPreview>\n\n## Sparkline — Line\n\nMinimal inline sparkline inside a table cell or card:\n\n<ComponentPreview vertical height=\"80px\">\n\n```html\n<div id=\"ex-spark-line\" style=\"width:200px;height:40px;\"></div>\n<script>\n const { createSparkline } = Prism;\n createSparkline(document.getElementById('ex-spark-line'), {\n data: [12, 18, 14, 22, 19, 28, 24, 32],\n variant: 'line',\n color: '#3b82f6',\n curve: 'monotone',\n strokeWidth: 1.5,\n });\n</script>\n```\n\n</ComponentPreview>\n\n## Sparkline — Area\n\nArea variant with fill:\n\n<ComponentPreview vertical height=\"80px\">\n\n```html\n<div id=\"ex-spark-area\" style=\"width:200px;height:40px;\"></div>\n<script>\n const { createSparkline } = Prism;\n createSparkline(document.getElementById('ex-spark-area'), {\n data: [12, 18, 14, 22, 19, 28, 24, 32],\n variant: 'area',\n color: '#8b5cf6',\n curve: 'monotone',\n fillOpacity: 0.25,\n });\n</script>\n```\n\n</ComponentPreview>\n\n## Sparkline — Bar\n\nBar variant — one rect per value:\n\n<ComponentPreview vertical height=\"80px\">\n\n```html\n<div id=\"ex-spark-bar\" style=\"width:200px;height:40px;\"></div>\n<script>\n const { createSparkline } = Prism;\n createSparkline(document.getElementById('ex-spark-bar'), {\n data: [12, 18, 14, 22, 19, 28, 24, 32],\n variant: 'bar',\n color: '#10b981',\n transition: { duration: 400, easing: 'ease-out', stagger: 30 },\n });\n</script>\n```\n\n</ComponentPreview>\n\n## Sparkline — Reactive\n\nSparkline that updates when signal data changes:\n\n<ComponentPreview vertical height=\"120px\">\n\n```html\n<div style=\"margin-bottom:8px;\">\n <button id=\"ex-spark-btn\" style=\"padding:4px 12px;border:1px solid #e2e8f0;border-radius:4px;cursor:pointer;\">\n Add Point\n </button>\n</div>\n<div id=\"ex-spark-reactive\" style=\"width:200px;height:40px;\"></div>\n<script>\n const { createSparkline } = Prism;\n const { signal } = Ripple;\n\n const sparkData = signal([10, 15, 12, 18, 14]);\n\n createSparkline(document.getElementById('ex-spark-reactive'), {\n data: sparkData,\n variant: 'area',\n color: '#f59e0b',\n curve: 'monotone',\n fillOpacity: 0.2,\n transition: { duration: 300, easing: 'ease-out' },\n });\n\n document.getElementById('ex-spark-btn').addEventListener('click', function () {\n sparkData.value = sparkData.value.concat([10 + Math.floor(Math.random() * 25)]);\n });\n</script>\n```\n\n</ComponentPreview>\n\n## Sparkline — Stack\n\nHorizontal stacked bar — proportional segments with per-segment colors:\n\n<ComponentPreview vertical height=\"80px\">\n\n```html\n<div id=\"ex-spark-stack\" style=\"width:200px;height:40px;\"></div>\n<script>\n const { createSparkline } = Prism;\n createSparkline(document.getElementById('ex-spark-stack'), {\n variant: 'stack',\n data: [\n { label: 'Chrome', value: 341, color: '#3b82f6' },\n { label: 'Safari', value: 217, color: '#06b6d4' },\n { label: 'Firefox', value: 124, color: '#10b981' },\n { label: 'Edge', value: 53, color: '#f59e0b' },\n ],\n cornerRadius: 4,\n padPixels: 4,\n });\n</script>\n```\n\n</ComponentPreview>\n\n## Custom Tooltip\n\nRich HTML tooltip with custom formatting:\n\n<ComponentPreview vertical height=\"320px\">\n\n```html\n<div id=\"ex-tooltip\" style=\"width:100%;height:280px;\"></div>\n<script>\n const { createBarChart } = Prism;\n createBarChart(document.getElementById('ex-tooltip'), {\n series: [\n {\n name: 'Revenue',\n data: [\n { key: 'Jan', value: 4200 },\n { key: 'Feb', value: 5100 },\n { key: 'Mar', value: 4800 },\n { key: 'Apr', value: 6300 },\n { key: 'May', value: 5900 },\n { key: 'Jun', value: 7200 },\n ],\n color: '#6366f1',\n borderRadius: 6,\n },\n ],\n xAxis: { position: 'bottom' },\n yAxis: { position: 'left', grid: true },\n tooltip: {\n render: function (datum, series) {\n return (\n '<div style=\"font-weight:600\">' +\n series.name +\n '</div>' +\n '<div style=\"opacity:0.7;font-size:11px\">' +\n datum.key +\n '</div>' +\n '<div style=\"font-size:14px;margin-top:2px\">$' +\n datum.value.toLocaleString() +\n '</div>'\n );\n },\n },\n });\n</script>\n```\n\n</ComponentPreview>\n\n## Pie Chart with Plugin\n\nA donut chart that installs a custom plugin to draw a total count label in the center hole:\n\n<ComponentPreview vertical height=\"320px\">\n\n```html\n<div id=\"ex-pie-plugin\" style=\"width:100%;height:280px;\"></div>\n<script>\n const { createPieChart } = Prism;\n\n const data = [\n { label: 'Direct', value: 42, color: '#6366f1' },\n { label: 'Organic', value: 28, color: '#10b981' },\n { label: 'Social', value: 18, color: '#f59e0b' },\n { label: 'Referral', value: 12, color: '#8b5cf6' },\n ];\n\n const total = data.reduce((s, d) => s + d.value, 0);\n let centerLabel;\n\n const centerPlugin = {\n install(ctx) {\n const ns = 'http://www.w3.org/2000/svg';\n centerLabel = document.createElementNS(ns, 'text');\n centerLabel.setAttribute('text-anchor', 'middle');\n centerLabel.setAttribute('dominant-baseline', 'middle');\n centerLabel.setAttribute('font-size', '20');\n centerLabel.setAttribute('font-weight', '600');\n centerLabel.setAttribute('fill', 'var(--prism-text-color, #334155)');\n centerLabel.textContent = total;\n ctx.svg.appendChild(centerLabel);\n // Position at SVG center once dimensions are available\n requestAnimationFrame(() => {\n const { width, height } = ctx.dimensions.value;\n if (width && height) {\n centerLabel.setAttribute('x', String(width / 2));\n centerLabel.setAttribute('y', String(height / 2));\n }\n });\n },\n dispose() {\n centerLabel?.remove();\n },\n };\n\n createPieChart(document.getElementById('ex-pie-plugin'), {\n data,\n variant: 'donut',\n tooltip: true,\n transition: { duration: 400, easing: 'ease-out' },\n plugins: [centerPlugin],\n });\n</script>\n```\n\n</ComponentPreview>\n"
|
|
8
|
-
},
|
|
9
|
-
"examples": [],
|
|
10
|
-
"typeSignatures": {
|
|
11
|
-
"EasingFn": "export type { EasingFn } from './animation/easing';",
|
|
12
|
-
"AnimationTarget": "export type { AnimationTarget } from './animation/transition';",
|
|
13
|
-
"animate": "export { animate } from './animation/transition';",
|
|
14
|
-
"createAreaChart": "export { createAreaChart } from './charts/area';",
|
|
15
|
-
"createBarChart": "export { createBarChart } from './charts/bar';",
|
|
16
|
-
"createLineChart": "export { createLineChart } from './charts/line';",
|
|
17
|
-
"createPieChart": "export { createPieChart } from './charts/pie';",
|
|
18
|
-
"createSparkline": "export { createSparkline } from './charts/sparkline';",
|
|
19
|
-
"PrismDisposedError": "export { PrismDisposedError, PrismError, PrismRenderError } from './errors';",
|
|
20
|
-
"PrismError": "export { PrismDisposedError, PrismError, PrismRenderError } from './errors';",
|
|
21
|
-
"PrismRenderError": "export { PrismDisposedError, PrismError, PrismRenderError } from './errors';",
|
|
22
|
-
"LegendState": "export type { LegendState } from './interaction/legend';",
|
|
23
|
-
"TooltipState": "export type { TooltipState } from './interaction/tooltip';",
|
|
24
|
-
"bandScale": "export { bandScale } from './scales/band';",
|
|
25
|
-
"linearScale": "export { linearScale } from './scales/linear';",
|
|
26
|
-
"timeScale": "export { timeScale } from './scales/time';",
|
|
27
|
-
"Point": "export type { Point } from './svg/path';",
|
|
28
|
-
"resetTheme": "export { resetTheme, seriesColor, setTheme } from './theme';",
|
|
29
|
-
"seriesColor": "export { resetTheme, seriesColor, setTheme } from './theme';",
|
|
30
|
-
"setTheme": "export { resetTheme, seriesColor, setTheme } from './theme';",
|
|
31
|
-
"AreaChartConfig": "export 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 ChartPlugin,\n ChartPluginContext,\n CrosshairConfig,\n Datum,\n GridConfig,\n LegendConfig,\n LegendPosition,\n LineChartConfig,\n LineSeriesConfig,\n MaybeSignal,\n PieChartConfig,\n PieSliceConfig,\n PieVariant,\n PrismTheme,\n Scale,\n Series,\n SparklineConfig,\n SparklineVariant,\n StackSegment,\n TooltipConfig,\n TransitionConfig,\n} from './types';",
|
|
32
|
-
"AreaSeriesConfig": "export 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 ChartPlugin,\n ChartPluginContext,\n CrosshairConfig,\n Datum,\n GridConfig,\n LegendConfig,\n LegendPosition,\n LineChartConfig,\n LineSeriesConfig,\n MaybeSignal,\n PieChartConfig,\n PieSliceConfig,\n PieVariant,\n PrismTheme,\n Scale,\n Series,\n SparklineConfig,\n SparklineVariant,\n StackSegment,\n TooltipConfig,\n TransitionConfig,\n} from './types';",
|
|
33
|
-
"AxisConfig": "export 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 ChartPlugin,\n ChartPluginContext,\n CrosshairConfig,\n Datum,\n GridConfig,\n LegendConfig,\n LegendPosition,\n LineChartConfig,\n LineSeriesConfig,\n MaybeSignal,\n PieChartConfig,\n PieSliceConfig,\n PieVariant,\n PrismTheme,\n Scale,\n Series,\n SparklineConfig,\n SparklineVariant,\n StackSegment,\n TooltipConfig,\n TransitionConfig,\n} from './types';",
|
|
34
|
-
"AxisPosition": "export 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 ChartPlugin,\n ChartPluginContext,\n CrosshairConfig,\n Datum,\n GridConfig,\n LegendConfig,\n LegendPosition,\n LineChartConfig,\n LineSeriesConfig,\n MaybeSignal,\n PieChartConfig,\n PieSliceConfig,\n PieVariant,\n PrismTheme,\n Scale,\n Series,\n SparklineConfig,\n SparklineVariant,\n StackSegment,\n TooltipConfig,\n TransitionConfig,\n} from './types';",
|
|
35
|
-
"BandScale": "export 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 ChartPlugin,\n ChartPluginContext,\n CrosshairConfig,\n Datum,\n GridConfig,\n LegendConfig,\n LegendPosition,\n LineChartConfig,\n LineSeriesConfig,\n MaybeSignal,\n PieChartConfig,\n PieSliceConfig,\n PieVariant,\n PrismTheme,\n Scale,\n Series,\n SparklineConfig,\n SparklineVariant,\n StackSegment,\n TooltipConfig,\n TransitionConfig,\n} from './types';",
|
|
36
|
-
"BarChartConfig": "export 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 ChartPlugin,\n ChartPluginContext,\n CrosshairConfig,\n Datum,\n GridConfig,\n LegendConfig,\n LegendPosition,\n LineChartConfig,\n LineSeriesConfig,\n MaybeSignal,\n PieChartConfig,\n PieSliceConfig,\n PieVariant,\n PrismTheme,\n Scale,\n Series,\n SparklineConfig,\n SparklineVariant,\n StackSegment,\n TooltipConfig,\n TransitionConfig,\n} from './types';",
|
|
37
|
-
"BarSeriesConfig": "export 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 ChartPlugin,\n ChartPluginContext,\n CrosshairConfig,\n Datum,\n GridConfig,\n LegendConfig,\n LegendPosition,\n LineChartConfig,\n LineSeriesConfig,\n MaybeSignal,\n PieChartConfig,\n PieSliceConfig,\n PieVariant,\n PrismTheme,\n Scale,\n Series,\n SparklineConfig,\n SparklineVariant,\n StackSegment,\n TooltipConfig,\n TransitionConfig,\n} from './types';",
|
|
38
|
-
"BarVariant": "export 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 ChartPlugin,\n ChartPluginContext,\n CrosshairConfig,\n Datum,\n GridConfig,\n LegendConfig,\n LegendPosition,\n LineChartConfig,\n LineSeriesConfig,\n MaybeSignal,\n PieChartConfig,\n PieSliceConfig,\n PieVariant,\n PrismTheme,\n Scale,\n Series,\n SparklineConfig,\n SparklineVariant,\n StackSegment,\n TooltipConfig,\n TransitionConfig,\n} from './types';",
|
|
39
|
-
"BaseChartConfig": "export 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 ChartPlugin,\n ChartPluginContext,\n CrosshairConfig,\n Datum,\n GridConfig,\n LegendConfig,\n LegendPosition,\n LineChartConfig,\n LineSeriesConfig,\n MaybeSignal,\n PieChartConfig,\n PieSliceConfig,\n PieVariant,\n PrismTheme,\n Scale,\n Series,\n SparklineConfig,\n SparklineVariant,\n StackSegment,\n TooltipConfig,\n TransitionConfig,\n} from './types';",
|
|
40
|
-
"ChartA11y": "export 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 ChartPlugin,\n ChartPluginContext,\n CrosshairConfig,\n Datum,\n GridConfig,\n LegendConfig,\n LegendPosition,\n LineChartConfig,\n LineSeriesConfig,\n MaybeSignal,\n PieChartConfig,\n PieSliceConfig,\n PieVariant,\n PrismTheme,\n Scale,\n Series,\n SparklineConfig,\n SparklineVariant,\n StackSegment,\n TooltipConfig,\n TransitionConfig,\n} from './types';",
|
|
41
|
-
"ChartDimensions": "export 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 ChartPlugin,\n ChartPluginContext,\n CrosshairConfig,\n Datum,\n GridConfig,\n LegendConfig,\n LegendPosition,\n LineChartConfig,\n LineSeriesConfig,\n MaybeSignal,\n PieChartConfig,\n PieSliceConfig,\n PieVariant,\n PrismTheme,\n Scale,\n Series,\n SparklineConfig,\n SparklineVariant,\n StackSegment,\n TooltipConfig,\n TransitionConfig,\n} from './types';",
|
|
42
|
-
"ChartEvent": "export 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 ChartPlugin,\n ChartPluginContext,\n CrosshairConfig,\n Datum,\n GridConfig,\n LegendConfig,\n LegendPosition,\n LineChartConfig,\n LineSeriesConfig,\n MaybeSignal,\n PieChartConfig,\n PieSliceConfig,\n PieVariant,\n PrismTheme,\n Scale,\n Series,\n SparklineConfig,\n SparklineVariant,\n StackSegment,\n TooltipConfig,\n TransitionConfig,\n} from './types';",
|
|
43
|
-
"ChartHandle": "export 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 ChartPlugin,\n ChartPluginContext,\n CrosshairConfig,\n Datum,\n GridConfig,\n LegendConfig,\n LegendPosition,\n LineChartConfig,\n LineSeriesConfig,\n MaybeSignal,\n PieChartConfig,\n PieSliceConfig,\n PieVariant,\n PrismTheme,\n Scale,\n Series,\n SparklineConfig,\n SparklineVariant,\n StackSegment,\n TooltipConfig,\n TransitionConfig,\n} from './types';",
|
|
44
|
-
"ChartMargin": "export 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 ChartPlugin,\n ChartPluginContext,\n CrosshairConfig,\n Datum,\n GridConfig,\n LegendConfig,\n LegendPosition,\n LineChartConfig,\n LineSeriesConfig,\n MaybeSignal,\n PieChartConfig,\n PieSliceConfig,\n PieVariant,\n PrismTheme,\n Scale,\n Series,\n SparklineConfig,\n SparklineVariant,\n StackSegment,\n TooltipConfig,\n TransitionConfig,\n} from './types';",
|
|
45
|
-
"ChartPlugin": "export 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 ChartPlugin,\n ChartPluginContext,\n CrosshairConfig,\n Datum,\n GridConfig,\n LegendConfig,\n LegendPosition,\n LineChartConfig,\n LineSeriesConfig,\n MaybeSignal,\n PieChartConfig,\n PieSliceConfig,\n PieVariant,\n PrismTheme,\n Scale,\n Series,\n SparklineConfig,\n SparklineVariant,\n StackSegment,\n TooltipConfig,\n TransitionConfig,\n} from './types';",
|
|
46
|
-
"ChartPluginContext": "export 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 ChartPlugin,\n ChartPluginContext,\n CrosshairConfig,\n Datum,\n GridConfig,\n LegendConfig,\n LegendPosition,\n LineChartConfig,\n LineSeriesConfig,\n MaybeSignal,\n PieChartConfig,\n PieSliceConfig,\n PieVariant,\n PrismTheme,\n Scale,\n Series,\n SparklineConfig,\n SparklineVariant,\n StackSegment,\n TooltipConfig,\n TransitionConfig,\n} from './types';",
|
|
47
|
-
"CrosshairConfig": "export 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 ChartPlugin,\n ChartPluginContext,\n CrosshairConfig,\n Datum,\n GridConfig,\n LegendConfig,\n LegendPosition,\n LineChartConfig,\n LineSeriesConfig,\n MaybeSignal,\n PieChartConfig,\n PieSliceConfig,\n PieVariant,\n PrismTheme,\n Scale,\n Series,\n SparklineConfig,\n SparklineVariant,\n StackSegment,\n TooltipConfig,\n TransitionConfig,\n} from './types';",
|
|
48
|
-
"Datum": "export 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 ChartPlugin,\n ChartPluginContext,\n CrosshairConfig,\n Datum,\n GridConfig,\n LegendConfig,\n LegendPosition,\n LineChartConfig,\n LineSeriesConfig,\n MaybeSignal,\n PieChartConfig,\n PieSliceConfig,\n PieVariant,\n PrismTheme,\n Scale,\n Series,\n SparklineConfig,\n SparklineVariant,\n StackSegment,\n TooltipConfig,\n TransitionConfig,\n} from './types';",
|
|
49
|
-
"GridConfig": "export 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 ChartPlugin,\n ChartPluginContext,\n CrosshairConfig,\n Datum,\n GridConfig,\n LegendConfig,\n LegendPosition,\n LineChartConfig,\n LineSeriesConfig,\n MaybeSignal,\n PieChartConfig,\n PieSliceConfig,\n PieVariant,\n PrismTheme,\n Scale,\n Series,\n SparklineConfig,\n SparklineVariant,\n StackSegment,\n TooltipConfig,\n TransitionConfig,\n} from './types';",
|
|
50
|
-
"LegendConfig": "export 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 ChartPlugin,\n ChartPluginContext,\n CrosshairConfig,\n Datum,\n GridConfig,\n LegendConfig,\n LegendPosition,\n LineChartConfig,\n LineSeriesConfig,\n MaybeSignal,\n PieChartConfig,\n PieSliceConfig,\n PieVariant,\n PrismTheme,\n Scale,\n Series,\n SparklineConfig,\n SparklineVariant,\n StackSegment,\n TooltipConfig,\n TransitionConfig,\n} from './types';",
|
|
51
|
-
"LegendPosition": "export 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 ChartPlugin,\n ChartPluginContext,\n CrosshairConfig,\n Datum,\n GridConfig,\n LegendConfig,\n LegendPosition,\n LineChartConfig,\n LineSeriesConfig,\n MaybeSignal,\n PieChartConfig,\n PieSliceConfig,\n PieVariant,\n PrismTheme,\n Scale,\n Series,\n SparklineConfig,\n SparklineVariant,\n StackSegment,\n TooltipConfig,\n TransitionConfig,\n} from './types';",
|
|
52
|
-
"LineChartConfig": "export 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 ChartPlugin,\n ChartPluginContext,\n CrosshairConfig,\n Datum,\n GridConfig,\n LegendConfig,\n LegendPosition,\n LineChartConfig,\n LineSeriesConfig,\n MaybeSignal,\n PieChartConfig,\n PieSliceConfig,\n PieVariant,\n PrismTheme,\n Scale,\n Series,\n SparklineConfig,\n SparklineVariant,\n StackSegment,\n TooltipConfig,\n TransitionConfig,\n} from './types';",
|
|
53
|
-
"LineSeriesConfig": "export 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 ChartPlugin,\n ChartPluginContext,\n CrosshairConfig,\n Datum,\n GridConfig,\n LegendConfig,\n LegendPosition,\n LineChartConfig,\n LineSeriesConfig,\n MaybeSignal,\n PieChartConfig,\n PieSliceConfig,\n PieVariant,\n PrismTheme,\n Scale,\n Series,\n SparklineConfig,\n SparklineVariant,\n StackSegment,\n TooltipConfig,\n TransitionConfig,\n} from './types';",
|
|
54
|
-
"MaybeSignal": "export 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 ChartPlugin,\n ChartPluginContext,\n CrosshairConfig,\n Datum,\n GridConfig,\n LegendConfig,\n LegendPosition,\n LineChartConfig,\n LineSeriesConfig,\n MaybeSignal,\n PieChartConfig,\n PieSliceConfig,\n PieVariant,\n PrismTheme,\n Scale,\n Series,\n SparklineConfig,\n SparklineVariant,\n StackSegment,\n TooltipConfig,\n TransitionConfig,\n} from './types';",
|
|
55
|
-
"PieChartConfig": "export 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 ChartPlugin,\n ChartPluginContext,\n CrosshairConfig,\n Datum,\n GridConfig,\n LegendConfig,\n LegendPosition,\n LineChartConfig,\n LineSeriesConfig,\n MaybeSignal,\n PieChartConfig,\n PieSliceConfig,\n PieVariant,\n PrismTheme,\n Scale,\n Series,\n SparklineConfig,\n SparklineVariant,\n StackSegment,\n TooltipConfig,\n TransitionConfig,\n} from './types';",
|
|
56
|
-
"PieSliceConfig": "export 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 ChartPlugin,\n ChartPluginContext,\n CrosshairConfig,\n Datum,\n GridConfig,\n LegendConfig,\n LegendPosition,\n LineChartConfig,\n LineSeriesConfig,\n MaybeSignal,\n PieChartConfig,\n PieSliceConfig,\n PieVariant,\n PrismTheme,\n Scale,\n Series,\n SparklineConfig,\n SparklineVariant,\n StackSegment,\n TooltipConfig,\n TransitionConfig,\n} from './types';",
|
|
57
|
-
"PieVariant": "export 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 ChartPlugin,\n ChartPluginContext,\n CrosshairConfig,\n Datum,\n GridConfig,\n LegendConfig,\n LegendPosition,\n LineChartConfig,\n LineSeriesConfig,\n MaybeSignal,\n PieChartConfig,\n PieSliceConfig,\n PieVariant,\n PrismTheme,\n Scale,\n Series,\n SparklineConfig,\n SparklineVariant,\n StackSegment,\n TooltipConfig,\n TransitionConfig,\n} from './types';",
|
|
58
|
-
"PrismTheme": "export 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 ChartPlugin,\n ChartPluginContext,\n CrosshairConfig,\n Datum,\n GridConfig,\n LegendConfig,\n LegendPosition,\n LineChartConfig,\n LineSeriesConfig,\n MaybeSignal,\n PieChartConfig,\n PieSliceConfig,\n PieVariant,\n PrismTheme,\n Scale,\n Series,\n SparklineConfig,\n SparklineVariant,\n StackSegment,\n TooltipConfig,\n TransitionConfig,\n} from './types';",
|
|
59
|
-
"Scale": "export 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 ChartPlugin,\n ChartPluginContext,\n CrosshairConfig,\n Datum,\n GridConfig,\n LegendConfig,\n LegendPosition,\n LineChartConfig,\n LineSeriesConfig,\n MaybeSignal,\n PieChartConfig,\n PieSliceConfig,\n PieVariant,\n PrismTheme,\n Scale,\n Series,\n SparklineConfig,\n SparklineVariant,\n StackSegment,\n TooltipConfig,\n TransitionConfig,\n} from './types';",
|
|
60
|
-
"Series": "export 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 ChartPlugin,\n ChartPluginContext,\n CrosshairConfig,\n Datum,\n GridConfig,\n LegendConfig,\n LegendPosition,\n LineChartConfig,\n LineSeriesConfig,\n MaybeSignal,\n PieChartConfig,\n PieSliceConfig,\n PieVariant,\n PrismTheme,\n Scale,\n Series,\n SparklineConfig,\n SparklineVariant,\n StackSegment,\n TooltipConfig,\n TransitionConfig,\n} from './types';",
|
|
61
|
-
"SparklineConfig": "export 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 ChartPlugin,\n ChartPluginContext,\n CrosshairConfig,\n Datum,\n GridConfig,\n LegendConfig,\n LegendPosition,\n LineChartConfig,\n LineSeriesConfig,\n MaybeSignal,\n PieChartConfig,\n PieSliceConfig,\n PieVariant,\n PrismTheme,\n Scale,\n Series,\n SparklineConfig,\n SparklineVariant,\n StackSegment,\n TooltipConfig,\n TransitionConfig,\n} from './types';",
|
|
62
|
-
"SparklineVariant": "export 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 ChartPlugin,\n ChartPluginContext,\n CrosshairConfig,\n Datum,\n GridConfig,\n LegendConfig,\n LegendPosition,\n LineChartConfig,\n LineSeriesConfig,\n MaybeSignal,\n PieChartConfig,\n PieSliceConfig,\n PieVariant,\n PrismTheme,\n Scale,\n Series,\n SparklineConfig,\n SparklineVariant,\n StackSegment,\n TooltipConfig,\n TransitionConfig,\n} from './types';",
|
|
63
|
-
"StackSegment": "export 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 ChartPlugin,\n ChartPluginContext,\n CrosshairConfig,\n Datum,\n GridConfig,\n LegendConfig,\n LegendPosition,\n LineChartConfig,\n LineSeriesConfig,\n MaybeSignal,\n PieChartConfig,\n PieSliceConfig,\n PieVariant,\n PrismTheme,\n Scale,\n Series,\n SparklineConfig,\n SparklineVariant,\n StackSegment,\n TooltipConfig,\n TransitionConfig,\n} from './types';",
|
|
64
|
-
"TooltipConfig": "export 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 ChartPlugin,\n ChartPluginContext,\n CrosshairConfig,\n Datum,\n GridConfig,\n LegendConfig,\n LegendPosition,\n LineChartConfig,\n LineSeriesConfig,\n MaybeSignal,\n PieChartConfig,\n PieSliceConfig,\n PieVariant,\n PrismTheme,\n Scale,\n Series,\n SparklineConfig,\n SparklineVariant,\n StackSegment,\n TooltipConfig,\n TransitionConfig,\n} from './types';",
|
|
65
|
-
"TransitionConfig": "export 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 ChartPlugin,\n ChartPluginContext,\n CrosshairConfig,\n Datum,\n GridConfig,\n LegendConfig,\n LegendPosition,\n LineChartConfig,\n LineSeriesConfig,\n MaybeSignal,\n PieChartConfig,\n PieSliceConfig,\n PieVariant,\n PrismTheme,\n Scale,\n Series,\n SparklineConfig,\n SparklineVariant,\n StackSegment,\n TooltipConfig,\n TransitionConfig,\n} from './types';"
|
|
66
|
-
}
|
|
67
|
-
}
|
package/data/packages/pulse.json
DELETED
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"apiSource": "export {\n PulseAbortError,\n PulseConnectionError,\n PulseDisposedError,\n PulseError,\n PulseProtocolError,\n PulseTimeoutError,\n} from './errors';\nexport { createPulse } from './pulse';\nexport type {\n ChannelDefinition,\n ChannelDefinitions,\n EventKey,\n HeartbeatOptions,\n MessageMap,\n OutgoingMessage,\n OutgoingTransform,\n PresenceChannel,\n PresenceDefinitions,\n Pulse,\n PulseChannel,\n PulseOptions,\n PulseStatus,\n ReconnectOptions,\n Unsubscribe,\n} from './types';\n",
|
|
3
|
-
"docs": {
|
|
4
|
-
"index": "---\ntitle: Pulse — Typed WebSocket sessions\ndescription: Explicitly connected, typed WebSocket sessions with scoped channels, presence, reconnect restoration, and heartbeat.\npackage: pulse\ncategory: websockets\nkeywords: [websocket, realtime, channels, presence, reconnect, heartbeat, typed-messaging, ripple]\nrelated: [herald, ripple, courier, clockwork]\nexports:\n [\n createPulse,\n Pulse,\n PulseChannel,\n PresenceChannel,\n PulseOptions,\n ChannelDefinition,\n ChannelDefinitions,\n PresenceDefinitions,\n OutgoingMessage,\n OutgoingTransform,\n PulseError,\n PulseConnectionError,\n PulseTimeoutError,\n PulseAbortError,\n PulseDisposedError,\n PulseProtocolError,\n ]\nenvironments: [browser, node]\n---\n\n<!-- markdownlint-disable MD025 MD033 MD060 -->\n\n<PackageHero package=\"pulse\" />\n\n## Why Pulse?\n\nNative WebSocket leaves connection ownership, event routing, reconnect restoration, and cleanup to each application. Pulse provides those boundaries while making readiness explicit: applications connect before sending, and disconnected messages never disappear silently.\n\n```ts\n// Before\nconst socket = new WebSocket('wss://api.example.com/ws');\nsocket.addEventListener('message', (event) => route(JSON.parse(event.data)));\nsocket.addEventListener('close', () => setTimeout(() => reconnect(), 1_000));\n\n// After\nconst pulse = createPulse<ServerEvents, ClientEvents>('wss://api.example.com/ws', { reconnect: true });\ntry {\n await pulse.connect();\n pulse.on('chat:message', (message) => console.log(message.text));\n pulse.send('chat:send', { text: 'Hello!' });\n} catch (error) {\n console.error('Pulse connection failed:', error);\n}\n```\n\n| Feature | Pulse | Native WebSocket | socket.io-client |\n| --- | --- | --- | --- |\n| Bundle size | <PackageInfo package=\"pulse\" type=\"size\" /> | 0 B | ~44 kB gzip |\n| Explicit readiness | <ore-icon name=\"check\" size=\"16\"></ore-icon> | Manual | <ore-icon name=\"check\" size=\"16\"></ore-icon> |\n| Session restoration | <ore-icon name=\"check\" size=\"16\"></ore-icon> | <ore-icon name=\"x\" size=\"16\"></ore-icon> | Protocol-specific |\n| Typed scoped channels | <ore-icon name=\"check\" size=\"16\"></ore-icon> | <ore-icon name=\"x\" size=\"16\"></ore-icon> | Basic |\n| Zero runtime dependencies | <ore-icon name=\"triangle-alert\" size=\"16\"></ore-icon> ripple | <ore-icon name=\"check\" size=\"16\"></ore-icon> | <ore-icon name=\"x\" size=\"16\"></ore-icon> |\n\n<div class=\"decision-callout\">\n\n**Use Pulse when** you need a typed WebSocket session whose reconnect and cleanup behavior must be deterministic.\n\n**Consider native WebSocket when** a single untyped connection does not need retry, routing, or session restoration.\n\n</div>\n\n## Installation\n\n::: code-group\n\n```sh [pnpm]\npnpm add @vielzeug/pulse @vielzeug/ripple\n```\n\n```sh [npm]\nnpm install @vielzeug/pulse @vielzeug/ripple\n```\n\n```sh [yarn]\nyarn add @vielzeug/pulse @vielzeug/ripple\n```\n\n:::\n\n## Quick Start\n\nDefine the protocol at construction time, create scopes, then connect before sending.\n\n```ts\nimport { createPulse } from '@vielzeug/pulse';\n\ntype ServerEvents = { 'chat:message': { text: string } };\ntype ClientEvents = { 'chat:send': { text: string } };\ntype Channels = {\n chat: {\n client: { send: { text: string } };\n server: { message: { text: string } };\n };\n};\ntype Presence = { lobby: { name: string } };\n\nconst pulse = createPulse<ServerEvents, ClientEvents, Channels, Presence>('wss://api.example.com/ws', {\n reconnect: true,\n onError: (error) => console.error(error),\n});\nconst chat = pulse.channel('chat');\nconst lobby = pulse.presence('lobby');\n\ntry {\n await pulse.connect();\n chat.send('send', { text: 'Hello!' });\n lobby.update({ name: 'Ada' });\n} catch (error) {\n console.error('Pulse connection failed:', error);\n}\n\npulse.dispose();\n```\n\n## Features\n\n<div class=\"features-grid\">\n\n- **`connect()`** — explicit readiness; application messages throw while disconnected.\n- **`channel()`** — named, schema-bound scopes with independent disposal and reference-counted server subscriptions.\n- **`presence()`** — named, schema-bound reactive presence scopes with reference-counted room membership.\n- **`reconnect`** — ordered restoration of channel subscriptions, rooms, and local presence state.\n- **`transform`** — one synchronous transform or filter for application messages.\n- **`onError`** — typed connection and protocol errors.\n- **`heartbeat`** — ping/pong liveness detection that uses the same reconnect controller.\n- **`status` and `rooms`** — ripple readables for transport and confirmed membership state.\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- [Pulse 3.0 Migration](./migration.md)\n\n</div>\n\n## See Also\n\n<div class=\"see-also\">\n\n- [Ripple](/ripple/) — provides the reactive values exposed by Pulse.\n- [Herald](/herald/) — receives routed Pulse events in an in-process application bus.\n- [Courier](/courier/) — handles request/response traffic alongside a Pulse session.\n- [Clockwork](/clockwork/) — models application-level authentication or session workflows.\n\n</div>\n\n<!-- markdownlint-enable MD025 MD033 MD060 -->\n",
|
|
5
|
-
"api": "---\ntitle: Pulse — API Reference\ndescription: Complete API reference for @vielzeug/pulse.\n---\n\n[[toc]]\n\n## API Overview\n\n| Symbol | Purpose | Execution mode | Common gotcha |\n| --- | --- | --- | --- |\n| `createPulse()` | Creates an explicitly connected WebSocket session | Sync | Call `connect()` before sends |\n| `Pulse` | Root session API | Sync / Async | Named schemas are fixed at construction |\n| `PulseChannel` | Disposable channel listener scope | Sync / Async | Each call is a distinct scope |\n| `PresenceChannel` | Disposable reactive presence scope | Sync | `update()` requires an open connection |\n| `OutgoingTransform` | Transforms or filters application messages | Sync | Return `null` to filter |\n| `PulseError` types | Typed transport and protocol failures | Sync | Handle rejected promises as well as `onError` |\n\n## Package Entry Point\n\n| Import | Purpose |\n| --- | --- |\n| `@vielzeug/pulse` | All public values, errors, and types |\n\n## Core Functions\n\n### `createPulse()`\n\n```ts\ncreatePulse<\n TServer extends MessageMap = MessageMap,\n TClient extends MessageMap = MessageMap,\n TChannels extends ChannelDefinitions = ChannelDefinitions,\n TPresence extends PresenceDefinitions = PresenceDefinitions,\n>(url: string, options?: PulseOptions): Pulse<TServer, TClient, TChannels, TPresence>\n```\n\nCreates a closed session. `connect()` opens the socket and restores active session state.\n\n| Parameter | Type | Description |\n| --- | --- | --- |\n| `url` | `string` | WebSocket URL |\n| `options` | `PulseOptions` | Transport, error, reconnect, heartbeat, and transform configuration |\n\n**Returns:** `Pulse<TServer, TClient, TChannels, TPresence>`\n\n```ts\nimport { createPulse } from '@vielzeug/pulse';\n\ntype ServerEvents = { notice: string };\ntype ClientEvents = { acknowledge: { id: string } };\n\nconst pulse = createPulse<ServerEvents, ClientEvents>('wss://api.example.com/ws');\nawait pulse.connect();\n```\n\n## Session API\n\n| Member | Returns | Contract |\n| --- | --- | --- |\n| `connect()` | `Promise<void>` | Opens transport and restores session state |\n| `disconnect(code?, reason?)` | `void` | Cancels retry and closes transport |\n| `send(event, payload)` | `void` | Throws `PulseConnectionError` unless open |\n| `on()` / `once()` / `wait()` | `Unsubscribe` / `Promise` | Root server-event subscriptions |\n| `channel(name)` | `PulseChannel` | Creates a schema-bound disposable scope |\n| `join()` / `leave()` | `Promise<void>` | Require an open connection and server confirmation |\n| `presence(room)` | `PresenceChannel` | Creates a schema-bound reference-counted room scope |\n| `status` / `rooms` | `Readable` | Transport state and server-confirmed room membership |\n| `dispose()` | `void` | Releases the whole session |\n\n### `pulse.channel()`\n\n```ts\nchannel<K extends keyof TChannels & string>(name: K): PulseChannel<TChannels[K]['server'], TChannels[K]['client']>\n```\n\nEach call creates a separate scope. Pulse sends `subscribe` for the first active scope and `unsubscribe` after the last is disposed.\n\n### `pulse.presence()`\n\n```ts\npresence<K extends keyof TPresence & string>(room: K): PresenceChannel<TPresence[K]>\n```\n\nEach call creates a separate presence scope. Pulse keeps the room joined while at least one scope remains.\n\n### `pulse.send()`\n\n```ts\nsend<K extends EventKey<TClient>>(event: K, payload: TClient[K]): void\n```\n\nSends a root application message. Throws `PulseConnectionError` unless the socket is open.\n\n### `pulse.wait()`\n\n```ts\nwait<K extends EventKey<TServer>>(event: K, opts?: { signal?: AbortSignal; timeout?: number }): Promise<TServer[K]>\n```\n\nResolves with the next matching event. Rejects with `PulseAbortError` or `PulseTimeoutError`.\n\n### `pulse.join()` and `pulse.leave()`\n\n```ts\njoin(room: string, opts?: { signal?: AbortSignal; timeout?: number }): Promise<void>\nleave(room: string, opts?: { signal?: AbortSignal; timeout?: number }): Promise<void>\n```\n\nBoth methods require an open transport and resolve only after the matching server confirmation. Opposing in-flight requests are serialized, so the final confirmed state follows the last request.\n\n| Parameter | Type | Description |\n| --- | --- | --- |\n| `room` | `string` | Server room identifier |\n| `opts.signal` | `AbortSignal` | Cancels the caller's wait; Pulse reconciles any request already sent |\n| `opts.timeout` | `number` | Maximum confirmation wait in milliseconds |\n\n**Returns:** A promise that rejects with `PulseConnectionError`, `PulseAbortError`, `PulseTimeoutError`, or `PulseDisposedError` when applicable.\n\n### `pulse.disconnect()`\n\n```ts\ndisconnect(code?: number, reason?: string): void\n```\n\nCloses the current session, cancels scheduled reconnects, and clears confirmed remote room and presence state immediately. Calling `connect()` afterward starts a new session from the retained desired scopes.\n\n## Scoped Handles\n\n`PulseChannel` and `PresenceChannel` are independently disposable. Disposing one scope removes only that scope's listeners and ownership reference.\n\n## Types\n\n```ts\nimport type { Readable } from '@vielzeug/ripple';\n\ntype MessageMap = Record<string, unknown>;\ntype EventKey<T extends MessageMap> = keyof T & string;\ntype Unsubscribe = () => void;\ntype PulseStatus = 'connecting' | 'open' | 'reconnecting' | 'closed';\n\ntype ChannelDefinition = { client: MessageMap; server: MessageMap };\ntype ChannelDefinitions = Record<string, ChannelDefinition>;\ntype PresenceDefinitions = Record<string, unknown>;\n\ntype OutgoingMessage = { channel?: string; event: string; payload: unknown };\ntype OutgoingTransform = (message: Readonly<OutgoingMessage>) => OutgoingMessage | null;\n\ntype ReconnectOptions = {\n delay?: number | ((attempt: number) => number);\n maxAttempts?: number;\n};\n\ntype HeartbeatOptions = { interval?: number; timeout?: number };\n\ntype PulseOptions = {\n heartbeat?: boolean | HeartbeatOptions;\n onError?: (error: PulseError) => void;\n protocols?: string | string[];\n reconnect?: boolean | ReconnectOptions;\n transform?: OutgoingTransform;\n};\n```\n\n```ts\ntype PulseChannel<TServer extends MessageMap = MessageMap, TClient extends MessageMap = MessageMap> = {\n [Symbol.dispose](): void;\n readonly disposalSignal: AbortSignal;\n dispose(): void;\n readonly disposed: boolean;\n readonly name: string;\n on<K extends EventKey<TServer>>(event: K, handler: (payload: TServer[K]) => void): Unsubscribe;\n once<K extends EventKey<TServer>>(event: K, handler: (payload: TServer[K]) => void): Unsubscribe;\n send<K extends EventKey<TClient>>(event: K, payload: TClient[K]): void;\n wait<K extends EventKey<TServer>>(event: K, opts?: { signal?: AbortSignal; timeout?: number }): Promise<TServer[K]>;\n};\n\ntype PresenceChannel<T = unknown> = {\n [Symbol.dispose](): void;\n readonly disposalSignal: AbortSignal;\n dispose(): void;\n readonly disposed: boolean;\n onJoin(handler: (memberId: string, state: T) => void): Unsubscribe;\n onLeave(handler: (memberId: string) => void): Unsubscribe;\n readonly room: string;\n readonly state: Readable<ReadonlyMap<string, T>>;\n update(state: T): void;\n};\n```\n\n```ts\ntype Pulse<\n TServer extends MessageMap = MessageMap,\n TClient extends MessageMap = MessageMap,\n TChannels extends ChannelDefinitions = ChannelDefinitions,\n TPresence extends PresenceDefinitions = PresenceDefinitions,\n> = {\n [Symbol.dispose](): void;\n channel<K extends keyof TChannels & string>(name: K): PulseChannel<TChannels[K]['server'], TChannels[K]['client']>;\n connect(): Promise<void>;\n disconnect(code?: number, reason?: string): void;\n readonly disposalSignal: AbortSignal;\n dispose(): void;\n readonly disposed: boolean;\n join(room: string, opts?: { signal?: AbortSignal; timeout?: number }): Promise<void>;\n leave(room: string, opts?: { signal?: AbortSignal; timeout?: number }): Promise<void>;\n on<K extends EventKey<TServer>>(event: K, handler: (payload: TServer[K]) => void): Unsubscribe;\n once<K extends EventKey<TServer>>(event: K, handler: (payload: TServer[K]) => void): Unsubscribe;\n presence<K extends keyof TPresence & string>(room: K): PresenceChannel<TPresence[K]>;\n readonly rooms: Readable<ReadonlySet<string>>;\n send<K extends EventKey<TClient>>(event: K, payload: TClient[K]): void;\n readonly status: Readable<PulseStatus>;\n wait<K extends EventKey<TServer>>(event: K, opts?: { signal?: AbortSignal; timeout?: number }): Promise<TServer[K]>;\n};\n```\n\n## Errors\n\n| Class | Triggers | Notable properties |\n| --- | --- | --- |\n| `PulseError` | Base class for every Pulse error | `PulseError.is(error)` |\n| `PulseConnectionError` | Send before open, transport error, or exhausted reconnect | `url` |\n| `PulseTimeoutError` | A `wait()`, `join()`, or `leave()` timeout | `event` |\n| `PulseAbortError` | An abort signal cancels `wait()`, `join()`, or `leave()` | — |\n| `PulseDisposedError` | An operation targets a disposed scope or session | — |\n| `PulseProtocolError` | A malformed, unknown, server-error, or failed handler frame | `raw` |\n",
|
|
6
|
-
"usage": "---\ntitle: Pulse — Usage Guide\ndescription: Explicit connection, schema-bound scopes, rooms, presence, transforms, reconnect, and heartbeat for @vielzeug/pulse.\n---\n\n[[toc]]\n\n## Basic Usage\n\nDefine every event map at creation time. This lets named channels and presence rooms infer their types without per-call generic arguments.\n\n```ts\nimport { createPulse } from '@vielzeug/pulse';\n\ntype ServerEvents = { 'chat:message': { text: string } };\ntype ClientEvents = { 'chat:send': { text: string } };\ntype Channels = {\n chat: {\n client: { send: { text: string } };\n server: { message: { text: string } };\n };\n};\ntype Presence = { lobby: { name: string; status: 'online' | 'away' } };\n\nconst pulse = createPulse<ServerEvents, ClientEvents, Channels, Presence>('wss://api.example.com/ws', {\n reconnect: true,\n onError: (error) => console.error(error),\n});\n\npulse.on('chat:message', ({ text }) => console.log(text));\nconst chat = pulse.channel('chat');\nconst lobby = pulse.presence('lobby');\n\ntry {\n await pulse.connect();\n chat.send('send', { text: 'Hello!' });\n lobby.update({ name: 'Ada', status: 'online' });\n} catch (error) {\n console.error('Pulse connection failed:', error);\n}\n```\n\n## Connection Management\n\n`createPulse()` does not create a socket. `connect()` resolves only after the socket has opened and existing session state has been restored. Application sends and room operations throw `PulseConnectionError` until then.\n\n```ts\nawait pulse.connect();\nconsole.log(pulse.status.value); // 'open'\n\npulse.disconnect(1000, 'signed out');\nconsole.log(pulse.status.value); // 'closed'\n```\n\nObserve `status` with Ripple when UI needs to reflect reconnecting state.\n\n```ts\nimport { effect } from '@vielzeug/ripple';\n\neffect(() => {\n statusBadge.textContent = pulse.status.value;\n});\n```\n\n## Scoped Channels\n\nEach `channel(name)` call creates an independently disposable listener scope. Pulse sends one server `subscribe` frame for the name and unsubscribes only after the final scope is disposed.\n\n```ts\nconst composer = pulse.channel('chat');\nconst transcript = pulse.channel('chat');\n\ncomposer.send('send', { text: 'Hello!' });\ntranscript.on('message', ({ text }) => console.log(text));\n\ncomposer.dispose(); // transcript remains subscribed\ntranscript.dispose(); // now Pulse sends unsubscribe\n```\n\n## Rooms and Presence\n\n`join()` and `leave()` require an open connection and resolve after server confirmation. `presence(room)` acquires a reference-counted room scope; create it before or after `connect()`.\n\n```ts\nconst lobby = pulse.presence('lobby');\n\nawait pulse.connect();\nawait pulse.join('announcements');\nlobby.update({ name: 'Ada', status: 'online' });\n\nlobby.onJoin((memberId, member) => console.log('joined', memberId, member.name));\nlobby.onLeave((memberId) => console.log('left', memberId));\n\nawait pulse.leave('announcements');\nlobby.dispose();\n```\n\n`rooms` contains only server-confirmed membership. It clears immediately on transport loss and repopulates as the restored session receives `joined` frames.\n\n## Outgoing Transforms\n\nUse one `transform` to enrich or filter application messages. Internal `subscribe`, `join`, presence, and heartbeat frames bypass it.\n\n```ts\nconst pulse = createPulse<ServerEvents, ClientEvents>('wss://api.example.com/ws', {\n transform: (message) => {\n if (message.event.startsWith('debug:')) return null;\n\n return { ...message, payload: { sentAt: Date.now(), value: message.payload } };\n },\n});\n```\n\n## Reconnect and Heartbeat\n\nReconnect uses full-jitter exponential backoff by default. On a replacement socket, Pulse sends channel subscriptions, desired rooms, and local presence state in that order. Use `status` to render transport state; do not treat it as server confirmation of restored rooms.\n\n```ts\nconst pulse = createPulse('wss://api.example.com/ws', {\n heartbeat: { interval: 30_000, timeout: 5_000 },\n reconnect: { delay: (attempt) => Math.min(1_000 * 2 ** attempt, 30_000), maxAttempts: 5 },\n onError: console.error,\n});\n```\n\nWhen the reconnect budget is exhausted, `status` becomes `'closed'` and `onError` receives `PulseConnectionError`.\n\n## Framework Integration\n\n::: code-group\n\n```ts [React]\nuseEffect(() => {\n const pulse = createPulse(url, { reconnect: true });\n void pulse.connect().catch(console.error);\n return () => pulse.dispose();\n}, [url]);\n```\n\n```ts [Vue 3]\nconst pulse = createPulse(url, { reconnect: true });\nvoid pulse.connect().catch(console.error);\nonUnmounted(() => pulse.dispose());\n```\n\n```ts [Svelte]\nconst pulse = createPulse(url, { reconnect: true });\nvoid pulse.connect().catch(console.error);\nonDestroy(() => pulse.dispose());\n```\n\n:::\n\n## Working with Other Vielzeug Libraries\n\nBridge typed server events into Herald when the rest of the application should not depend on transport details.\n\n```ts\nimport { createBus } from '@vielzeug/herald';\n\nconst bus = createBus<ServerEvents>();\nconst stop = pulse.on('chat:message', (message) => bus.emit('chat:message', message));\n\npulse.disposalSignal.addEventListener('abort', stop, { once: true });\n```\n\n## Best Practices\n\n- Define named channel and presence schemas when creating Pulse.\n- Call and await `connect()` before every application send path becomes available.\n- Treat `PulseConnectionError` as a user-visible retry or offline state.\n- Create channel and presence scopes near their consumer, then dispose those scopes independently.\n- Subscribe to `status` and `rooms` instead of inferring transport state.\n- Use `transform` only for synchronous application-message policies.\n- Handle `onError` in production.\n- Dispose Pulse when its owning application session ends.\n",
|
|
7
|
-
"examples": "---\ntitle: Pulse — Examples\ndescription: Practical examples and recipes for @vielzeug/pulse.\n---\n\n## Examples\n\n- [Basic Connection](./examples/basic-connection.md)\n- [Channel Multiplexing](./examples/channels.md)\n- [Rooms and Presence](./examples/rooms-and-presence.md)\n- [Reconnect and Heartbeat](./examples/reconnect-and-heartbeat.md)\n- [Outgoing Transform](./examples/middleware.md)\n"
|
|
8
|
-
},
|
|
9
|
-
"examples": [
|
|
10
|
-
{
|
|
11
|
-
"id": "channels",
|
|
12
|
-
"code": "import { createPulse } from '@vielzeug/pulse'\n\n// Isolated channel namespace — listeners and sends are scoped to 'chat'\nconst pulse = createPulse('wss://api.example.com/ws')\nconst chat = pulse.channel('chat')\n\n// Listeners scoped to the channel\nchat.on('message', ({ from, text }) => {\n console.log('[chat] ' + from + ': ' + text)\n})\n\ntry {\n await pulse.connect()\n // Send scoped to the channel\n chat.send('send', { text: 'hey!' })\n} catch (err) {\n console.log('connect failed:', err.message)\n}\n\n// Wait with a per-event timeout\ntry {\n const msg = await chat.wait('message', { timeout: 3_000 })\n console.log('got:', msg.text)\n} catch (err) {\n console.log('channel wait timed out:', err.message)\n}\n\n// Disposing the channel removes all its listeners\n// but the underlying pulse connection stays open\nchat.dispose()\nconsole.log('channel disposed, pulse still open:', pulse.status.value)\n\npulse.dispose()",
|
|
13
|
-
"name": "Typed Channels"
|
|
14
|
-
},
|
|
15
|
-
{
|
|
16
|
-
"id": "connect-and-send",
|
|
17
|
-
"code": "import { createPulse } from '@vielzeug/pulse'\n\n// Typed WebSocket client: on(), once(), send(), wait()\nconst pulse = createPulse('wss://api.example.com/ws', {\n reconnect: { maxAttempts: 5 },\n onError: (error) => console.log('transport error:', error.message),\n})\n\n// Subscribe before connecting — listeners are synchronous\nconst unsub = pulse.on('chat:message', ({ from, text }) => {\n console.log('[' + from + '] ' + text)\n})\n\n// One-shot listener: fires once and auto-removes\npulse.once('chat:message', (msg) => {\n console.log('first message:', msg.text)\n})\n\n// Connect; send when open\ntry {\n await pulse.connect()\n pulse.send('chat:send', { text: 'Hello, world!' })\n} catch (err) {\n console.log('connect failed:', err.message)\n}\n\n// Await next server event with a 5 s deadline\ntry {\n const msg = await pulse.wait('chat:message', { timeout: 500 })\n console.log('received:', msg.text)\n} catch (err) {\n console.log('wait ended:', err.message)\n}\n\nunsub()\npulse.dispose()",
|
|
18
|
-
"name": "Connect & Send"
|
|
19
|
-
},
|
|
20
|
-
{
|
|
21
|
-
"id": "lifecycle",
|
|
22
|
-
"code": "import { createPulse, PulseDisposedError } from '@vielzeug/pulse'\n\n// Status signal, disposalSignal, and error handling on dispose\nconst pulse = createPulse('wss://api.example.com/ws', {\n reconnect: { delay: 1_000, maxAttempts: 3 },\n heartbeat: { interval: 30_000, timeout: 5_000 },\n onError: (error) => console.log('Pulse error:', error.message),\n})\n\n// Construction is closed. connect() makes the transport available.\nconsole.log('initial status:', pulse.status.value)\n\n// disposalSignal aborts when dispose() is called\npulse.disposalSignal.addEventListener('abort', () => {\n console.log('disposal signal fired')\n})\n\ntry {\n await pulse.connect()\n console.log('connected:', pulse.status.value)\n} catch (err) {\n console.log('connect failed:', err.message)\n}\n\n// dispose() is idempotent — safe to call multiple times\npulse.dispose()\npulse.dispose()\nconsole.log('disposed:', pulse.disposed)\n\n// Methods reject with PulseDisposedError after dispose\ntry {\n await pulse.connect()\n} catch (err) {\n if (err instanceof PulseDisposedError) {\n console.log('connect() rejected with PulseDisposedError — correct')\n }\n}",
|
|
23
|
-
"name": "Lifecycle & Disposal"
|
|
24
|
-
},
|
|
25
|
-
{
|
|
26
|
-
"id": "reconnect",
|
|
27
|
-
"code": "import { createPulse, PulseConnectionError } from '@vielzeug/pulse'\n\n// Channels, rooms, and local presence state are restored on reconnect.\nconst pulse = createPulse('wss://api.example.com/ws', {\n reconnect: { delay: 500, maxAttempts: 3 },\n onError: (error) => console.log('transport error:', error.message),\n})\n\n// Channel is tracked: re-subscribed automatically after every reconnect\nconst chat = pulse.channel('chat')\nchat.on('message', ({ from, text }) => console.log(from + ': ' + text))\n\n// Connect explicitly to observe the status\ntry {\n await pulse.connect()\n console.log('connected, status:', pulse.status.value)\n} catch (err) {\n if (err instanceof PulseConnectionError) {\n console.log('connection failed:', err.message)\n }\n}\n\nconsole.log('channel name:', chat.name)\nconsole.log('channel disposed?', chat.disposed)\n\n// Disposing a channel removes it from re-subscription tracking\nchat.dispose()\nconsole.log('channel disposed, pulse still running:', !pulse.disposed)\n\npulse.dispose()",
|
|
28
|
-
"name": "Reconnect & Restoration"
|
|
29
|
-
},
|
|
30
|
-
{
|
|
31
|
-
"id": "rooms-presence",
|
|
32
|
-
"code": "import { createPulse } from '@vielzeug/pulse'\n\n// Reactive presence channel — implicitly joins 'lobby'\nconst pulse = createPulse('wss://api.example.com/ws')\nconst lobby = pulse.presence('lobby')\n\ntry {\n await pulse.connect()\n\n // Broadcast our own presence\n lobby.update({ avatar: '/me.png', name: 'Alice', status: 'online' })\n\n // Explicit room management (join resolves on server confirmation)\n await pulse.join('game-room')\n console.log('rooms:', [...pulse.rooms.value])\n await pulse.leave('game-room')\n console.log('rooms after leave:', [...pulse.rooms.value])\n} catch (err) {\n console.log('connection or room operation failed:', err.message)\n}\n\n// Subscribe to state changes manually (state.value is a ReadonlyMap)\nconst printMembers = () => {\n for (const [id, state] of lobby.state.value) {\n console.log(' ' + id + ': ' + state.name + ' (' + state.status + ')')\n }\n}\n\n// React to individual joins and leaves\nlobby.onJoin((id, state) => console.log(state.name + ' joined'))\nlobby.onLeave((id) => console.log(id + ' left'))\n\nlobby.dispose()\npulse.dispose()",
|
|
33
|
-
"name": "Rooms & Presence"
|
|
34
|
-
}
|
|
35
|
-
],
|
|
36
|
-
"typeSignatures": {
|
|
37
|
-
"PulseAbortError": "export {\n PulseAbortError,\n PulseConnectionError,\n PulseDisposedError,\n PulseError,\n PulseProtocolError,\n PulseTimeoutError,\n} from './errors';",
|
|
38
|
-
"PulseConnectionError": "export {\n PulseAbortError,\n PulseConnectionError,\n PulseDisposedError,\n PulseError,\n PulseProtocolError,\n PulseTimeoutError,\n} from './errors';",
|
|
39
|
-
"PulseDisposedError": "export {\n PulseAbortError,\n PulseConnectionError,\n PulseDisposedError,\n PulseError,\n PulseProtocolError,\n PulseTimeoutError,\n} from './errors';",
|
|
40
|
-
"PulseError": "export {\n PulseAbortError,\n PulseConnectionError,\n PulseDisposedError,\n PulseError,\n PulseProtocolError,\n PulseTimeoutError,\n} from './errors';",
|
|
41
|
-
"PulseProtocolError": "export {\n PulseAbortError,\n PulseConnectionError,\n PulseDisposedError,\n PulseError,\n PulseProtocolError,\n PulseTimeoutError,\n} from './errors';",
|
|
42
|
-
"PulseTimeoutError": "export {\n PulseAbortError,\n PulseConnectionError,\n PulseDisposedError,\n PulseError,\n PulseProtocolError,\n PulseTimeoutError,\n} from './errors';",
|
|
43
|
-
"createPulse": "export { createPulse } from './pulse';",
|
|
44
|
-
"ChannelDefinition": "export type {\n ChannelDefinition,\n ChannelDefinitions,\n EventKey,\n HeartbeatOptions,\n MessageMap,\n OutgoingMessage,\n OutgoingTransform,\n PresenceChannel,\n PresenceDefinitions,\n Pulse,\n PulseChannel,\n PulseOptions,\n PulseStatus,\n ReconnectOptions,\n Unsubscribe,\n} from './types';",
|
|
45
|
-
"ChannelDefinitions": "export type {\n ChannelDefinition,\n ChannelDefinitions,\n EventKey,\n HeartbeatOptions,\n MessageMap,\n OutgoingMessage,\n OutgoingTransform,\n PresenceChannel,\n PresenceDefinitions,\n Pulse,\n PulseChannel,\n PulseOptions,\n PulseStatus,\n ReconnectOptions,\n Unsubscribe,\n} from './types';",
|
|
46
|
-
"EventKey": "export type {\n ChannelDefinition,\n ChannelDefinitions,\n EventKey,\n HeartbeatOptions,\n MessageMap,\n OutgoingMessage,\n OutgoingTransform,\n PresenceChannel,\n PresenceDefinitions,\n Pulse,\n PulseChannel,\n PulseOptions,\n PulseStatus,\n ReconnectOptions,\n Unsubscribe,\n} from './types';",
|
|
47
|
-
"HeartbeatOptions": "export type {\n ChannelDefinition,\n ChannelDefinitions,\n EventKey,\n HeartbeatOptions,\n MessageMap,\n OutgoingMessage,\n OutgoingTransform,\n PresenceChannel,\n PresenceDefinitions,\n Pulse,\n PulseChannel,\n PulseOptions,\n PulseStatus,\n ReconnectOptions,\n Unsubscribe,\n} from './types';",
|
|
48
|
-
"MessageMap": "export type {\n ChannelDefinition,\n ChannelDefinitions,\n EventKey,\n HeartbeatOptions,\n MessageMap,\n OutgoingMessage,\n OutgoingTransform,\n PresenceChannel,\n PresenceDefinitions,\n Pulse,\n PulseChannel,\n PulseOptions,\n PulseStatus,\n ReconnectOptions,\n Unsubscribe,\n} from './types';",
|
|
49
|
-
"OutgoingMessage": "export type {\n ChannelDefinition,\n ChannelDefinitions,\n EventKey,\n HeartbeatOptions,\n MessageMap,\n OutgoingMessage,\n OutgoingTransform,\n PresenceChannel,\n PresenceDefinitions,\n Pulse,\n PulseChannel,\n PulseOptions,\n PulseStatus,\n ReconnectOptions,\n Unsubscribe,\n} from './types';",
|
|
50
|
-
"OutgoingTransform": "export type {\n ChannelDefinition,\n ChannelDefinitions,\n EventKey,\n HeartbeatOptions,\n MessageMap,\n OutgoingMessage,\n OutgoingTransform,\n PresenceChannel,\n PresenceDefinitions,\n Pulse,\n PulseChannel,\n PulseOptions,\n PulseStatus,\n ReconnectOptions,\n Unsubscribe,\n} from './types';",
|
|
51
|
-
"PresenceChannel": "export type {\n ChannelDefinition,\n ChannelDefinitions,\n EventKey,\n HeartbeatOptions,\n MessageMap,\n OutgoingMessage,\n OutgoingTransform,\n PresenceChannel,\n PresenceDefinitions,\n Pulse,\n PulseChannel,\n PulseOptions,\n PulseStatus,\n ReconnectOptions,\n Unsubscribe,\n} from './types';",
|
|
52
|
-
"PresenceDefinitions": "export type {\n ChannelDefinition,\n ChannelDefinitions,\n EventKey,\n HeartbeatOptions,\n MessageMap,\n OutgoingMessage,\n OutgoingTransform,\n PresenceChannel,\n PresenceDefinitions,\n Pulse,\n PulseChannel,\n PulseOptions,\n PulseStatus,\n ReconnectOptions,\n Unsubscribe,\n} from './types';",
|
|
53
|
-
"Pulse": "export type {\n ChannelDefinition,\n ChannelDefinitions,\n EventKey,\n HeartbeatOptions,\n MessageMap,\n OutgoingMessage,\n OutgoingTransform,\n PresenceChannel,\n PresenceDefinitions,\n Pulse,\n PulseChannel,\n PulseOptions,\n PulseStatus,\n ReconnectOptions,\n Unsubscribe,\n} from './types';",
|
|
54
|
-
"PulseChannel": "export type {\n ChannelDefinition,\n ChannelDefinitions,\n EventKey,\n HeartbeatOptions,\n MessageMap,\n OutgoingMessage,\n OutgoingTransform,\n PresenceChannel,\n PresenceDefinitions,\n Pulse,\n PulseChannel,\n PulseOptions,\n PulseStatus,\n ReconnectOptions,\n Unsubscribe,\n} from './types';",
|
|
55
|
-
"PulseOptions": "export type {\n ChannelDefinition,\n ChannelDefinitions,\n EventKey,\n HeartbeatOptions,\n MessageMap,\n OutgoingMessage,\n OutgoingTransform,\n PresenceChannel,\n PresenceDefinitions,\n Pulse,\n PulseChannel,\n PulseOptions,\n PulseStatus,\n ReconnectOptions,\n Unsubscribe,\n} from './types';",
|
|
56
|
-
"PulseStatus": "export type {\n ChannelDefinition,\n ChannelDefinitions,\n EventKey,\n HeartbeatOptions,\n MessageMap,\n OutgoingMessage,\n OutgoingTransform,\n PresenceChannel,\n PresenceDefinitions,\n Pulse,\n PulseChannel,\n PulseOptions,\n PulseStatus,\n ReconnectOptions,\n Unsubscribe,\n} from './types';",
|
|
57
|
-
"ReconnectOptions": "export type {\n ChannelDefinition,\n ChannelDefinitions,\n EventKey,\n HeartbeatOptions,\n MessageMap,\n OutgoingMessage,\n OutgoingTransform,\n PresenceChannel,\n PresenceDefinitions,\n Pulse,\n PulseChannel,\n PulseOptions,\n PulseStatus,\n ReconnectOptions,\n Unsubscribe,\n} from './types';",
|
|
58
|
-
"Unsubscribe": "export type {\n ChannelDefinition,\n ChannelDefinitions,\n EventKey,\n HeartbeatOptions,\n MessageMap,\n OutgoingMessage,\n OutgoingTransform,\n PresenceChannel,\n PresenceDefinitions,\n Pulse,\n PulseChannel,\n PulseOptions,\n PulseStatus,\n ReconnectOptions,\n Unsubscribe,\n} from './types';"
|
|
59
|
-
}
|
|
60
|
-
}
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"apiSource": "/**\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 */\nexport { RefineError } from './errors';\n",
|
|
3
|
-
"docs": {
|
|
4
|
-
"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-chat-message,\n ore-checkbox,\n ore-checkbox-group,\n ore-chip,\n ore-combobox,\n ore-command-palette,\n ore-command-palette-item,\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-list,\n ore-list-item,\n ore-menu,\n ore-menu-item,\n ore-menu-separator,\n ore-message-composer,\n ore-navbar,\n ore-navbar-item,\n ore-number-input,\n ore-otp-input,\n ore-pagination,\n ore-password-strength,\n ore-popover,\n ore-progress,\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-step,\n ore-stepper,\n ore-switch,\n ore-tab-item,\n ore-tab-panel,\n ore-table,\n ore-tabs,\n ore-text,\n ore-textarea,\n ore-time-picker,\n ore-toast,\n ore-tooltip,\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=\"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| 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/tokens.css';\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/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/tokens.css` | Global design tokens and cascade layers |\n| `@vielzeug/refine/styles/preflight.css` | Optional browser-default reset |\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-list`, `ore-list-item`, `ore-marquee`, `ore-pagination`, `ore-separator`, `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-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-datagrid`, `ore-date-picker`, `ore-file-input`, `ore-input`, `ore-message-composer`, `ore-number-input`, `ore-otp-input`, `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-tooltip`\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- **Zero runtime deps** — <PackageInfo package=\"refine\" type=\"size\" /> gzipped\n\n</div>\n\n### Prerequisites\n\n- Browser runtime with Custom Elements support.\n- Import `@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",
|
|
5
|
-
"api": "---\ntitle: Refine — API Reference\ndescription: Published component registration and stylesheet entry points for @vielzeug/refine.\n---\n\n# API Reference\n\n[[toc]]\n\nRefine deliberately publishes components, not a second headless framework. Register each element through its component\nsubpath and import its types from the same path.\n\n## Styles\n\n```ts\nimport '@vielzeug/refine/tokens.css';\nimport '@vielzeug/refine/styles/preflight.css'; // Optional: normalizes browser defaults.\n```\n\n`tokens.css` defines Refine's design tokens, animations, and cascade-layer order without modifying global element\ndefaults. `preflight.css` is a separate opt-in reset.\n\nDirect CSS entry points are also available when needed:\n\n| Import path | Purpose |\n| --- | --- |\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-default reset |\n\n## Components\n\nEach component has a single registration and type entry point:\n\n```ts\nimport '@vielzeug/refine/button';\nimport type { OreButtonEvents, OreButtonProps } from '@vielzeug/refine/button';\n```\n\nThe package root only exports `RefineError`; it does not register elements. This keeps component ownership and bundle\ncontents explicit.\n\n| Area | Components |\n| --- | --- |\n| Content | `accordion`, `accordion-item`, `avatar`, `avatar-group`, `badge`, `breadcrumb`, `card`, `carousel`, `chat-message`, `code-window`, `copy-command`, `icon`, `list`, `list-item`, `marquee`, `pagination`, `separator`, `step`, `stepper`, `table`, `text` |\n| Feedback | `alert`, `async`, `chip`, `password-strength`, `progress`, `skeleton`, `toast`, `typing-indicator` |\n| Inputs | `button`, `button-group`, `calendar`, `checkbox`, `checkbox-group`, `combobox`, `datagrid`, `date-picker`, `file-input`, `input`, `message-composer`, `number-input`, `otp-input`, `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`, `popover`, `tooltip` |\n\nEach component's documentation page describes its attributes, properties, events, slots, parts, and custom properties.\n\n## Events and Form Controls\n\nForm controls expose their current `.value` or `.checked` property and dispatch standard `input` and `change` events.\nRead the property from `event.currentTarget`; do not rely on framework-specific custom-event casts.\n\nStateful overlays expose `open` and `default-open` properties/attributes and dispatch `open-change` with\n`{ open, reason }` detail. The per-component pages describe valid reasons and focus behavior.\n",
|
|
6
|
-
"usage": "---\ntitle: Refine — Usage Guide\ndescription: Installation, attributes, events, slots, and ecosystem integration for Refine components.\n---\n\n# Usage Guide\n\n[[toc]]\n\nRefine components are native Web Components. Once imported, they behave like regular HTML elements — set attributes, listen to DOM events, use slots for content projection.\n\n## Installation\n\nImport the global styles first, then register only the components you need:\n\n```ts\nimport '@vielzeug/refine/tokens.css';\nimport '@vielzeug/refine/button';\nimport '@vielzeug/refine/input';\nimport '@vielzeug/refine/dialog';\n```\n\nThe token stylesheet supplies Refine's design tokens and cascade layers without changing browser defaults. Add the reset only when your application explicitly wants it:\n\n```ts\nimport '@vielzeug/refine/styles/preflight.css';\n```\n\n## Attributes and Events\n\nSet attributes directly on the element. Attributes map to component props:\n\n```html\n<ore-button variant=\"outline\" color=\"secondary\" size=\"lg\" disabled>\n Large Outline Button\n</ore-button>\n```\n\nComponents emit standard DOM events. Common event names: `click`, `input`, `change`, and `open-change`. Custom events carry a `detail` object:\n\n```javascript\nconst input = document.querySelector('ore-input');\n\ninput.addEventListener('input', () => {\n console.log(input.value);\n});\n```\n\nNative browser events (`click`, `focus`, `blur`) work as normal. Custom events with `event.detail` require `addEventListener` in React 18 and earlier — see the [Framework Integration](./frameworks.md) guide.\n\n## Slots\n\nSlots let you pass HTML into named regions of a component without JavaScript.\n\nContent placed directly inside the element fills the default slot:\n\n```html\n<ore-button>Save Changes</ore-button>\n<ore-card>Any HTML content here</ore-card>\n```\n\nComponents with distinct regions expose named slots:\n\n```html\n<ore-card>\n <span slot=\"header\">Card Heading</span>\n <p>Main body content fills the default slot.</p>\n <div slot=\"footer\">\n <ore-button size=\"sm\" variant=\"outline\">Cancel</ore-button>\n <ore-button size=\"sm\">Confirm</ore-button>\n </div>\n</ore-card>\n```\n\nMany input components expose `prefix` and `suffix` slots for icons or actions:\n\n```html\n<ore-button>\n <ore-icon slot=\"prefix\" name=\"arrow-left\" size=\"18\"></ore-icon>\n Back\n</ore-button>\n\n<ore-input label=\"Search\">\n <ore-icon slot=\"suffix\" name=\"search\" size=\"18\" aria-hidden=\"true\"></ore-icon>\n</ore-input>\n```\n\nEach component's available slots are listed in its API Reference table.\n\n## Composing with Ore and Ripple\n\nRefine components are plain HTML elements — they compose naturally with [Ore](/ore/) custom elements and [Ripple](/ripple/) signals.\n\n**Build a custom component that wraps Refine elements:**\n\n```ts\nimport '@vielzeug/refine/button';\nimport '@vielzeug/refine/input';\nimport { define, html } from '@vielzeug/ore';\nimport { signal } from '@vielzeug/ripple';\n\ndefine('my-search-bar', () => {\n const query = signal('');\n return html`\n <ore-input\n .value=${query}\n @input=${(e) => (query.value = e.currentTarget.value)}\n label=\"Search\"\n />\n <ore-button @click=${() => search(query.value)} variant=\"solid\" color=\"primary\">\n Search\n </ore-button>\n `;\n});\n```\n\n**Drive component state from reactive signals:**\n\n```ts\nimport { signal, effect } from '@vielzeug/ripple';\n\nconst isLoading = signal(false);\nconst btn = document.querySelector('ore-button');\n\neffect(() => {\n btn.loading = isLoading.value;\n});\n```\n\n## Framework Integration\n\nFor React, Vue, Svelte, and Angular wiring — including event handling, TypeScript declarations, Vite setup, and SSR guards — see the [Framework Integration](./frameworks.md) guide.\n\n## Accessibility\n\nAll Refine components target WCAG 2.1 AA. ARIA roles and states are managed automatically. For the full compliance contract, per-component coverage, and testing strategy, see the [Accessibility](./accessibility.md) page.\n\nThe two things you always control:\n\n- **Icon-only buttons** require a `label` attribute — it becomes `aria-label`.\n- **Decorative icons** should have `aria-hidden=\"true\"` so screen readers skip them.\n"
|
|
7
|
-
},
|
|
8
|
-
"examples": [],
|
|
9
|
-
"typeSignatures": {
|
|
10
|
-
"RefineError": "export { RefineError } from './errors';"
|
|
11
|
-
}
|
|
12
|
-
}
|