@pixerate/editor-react 0.35.0 → 0.35.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/chart/index.cjs
CHANGED
|
@@ -145,6 +145,7 @@ function ChartCanvas({ controller, width = 640, height = 400, responsive = true,
|
|
|
145
145
|
const svg = (0, import_react2.useRef)(null);
|
|
146
146
|
const drag = (0, import_react2.useRef)(null);
|
|
147
147
|
const [measured, setMeasured] = (0, import_react2.useState)(null);
|
|
148
|
+
const [valueDomain, setValueDomain] = (0, import_react2.useState)(null);
|
|
148
149
|
(0, import_react2.useEffect)(() => {
|
|
149
150
|
const el = wrapper.current;
|
|
150
151
|
if (!responsive || !el || typeof ResizeObserver === "undefined") return;
|
|
@@ -158,8 +159,8 @@ function ChartCanvas({ controller, width = 640, height = 400, responsive = true,
|
|
|
158
159
|
const sceneWidth = responsive && measured || width;
|
|
159
160
|
const fullTheme = (0, import_react2.useMemo)(() => ({ ...import_chart2.CSS_VARIABLE_CHART_THEME, ...theme }), [theme]);
|
|
160
161
|
const scene = (0, import_react2.useMemo)(
|
|
161
|
-
() => (0, import_chart2.layoutChart)(state.spec, { width: sceneWidth, height, theme: fullTheme, selection: editable ? state.selection : null, measureText, emptyMessage }),
|
|
162
|
-
[state.spec, state.selection, sceneWidth, height, fullTheme, editable, measureText, emptyMessage]
|
|
162
|
+
() => (0, import_chart2.layoutChart)(state.spec, { width: sceneWidth, height, theme: fullTheme, selection: editable ? state.selection : null, measureText, emptyMessage, valueDomain }),
|
|
163
|
+
[state.spec, state.selection, sceneWidth, height, fullTheme, editable, measureText, emptyMessage, valueDomain]
|
|
163
164
|
);
|
|
164
165
|
const byKey = (0, import_react2.useMemo)(() => new Map(scene.marks.map((m) => [m.key, m])), [scene]);
|
|
165
166
|
(0, import_react2.useEffect)(() => () => drag.current?.end(), []);
|
|
@@ -170,7 +171,10 @@ function ChartCanvas({ controller, width = 640, height = 400, responsive = true,
|
|
|
170
171
|
const target = key ? byKey.get(key)?.target : void 0;
|
|
171
172
|
controller.select(target ?? null);
|
|
172
173
|
drag.current = (0, import_chart2.startChartPointDrag)(controller, scene, target, scenePoint(e));
|
|
173
|
-
if (drag.current)
|
|
174
|
+
if (drag.current) {
|
|
175
|
+
setValueDomain(drag.current.valueDomain);
|
|
176
|
+
svg.current?.setPointerCapture?.(e.pointerId);
|
|
177
|
+
}
|
|
174
178
|
};
|
|
175
179
|
const onPointerMove = (e) => {
|
|
176
180
|
if (drag.current) drag.current.move(scenePoint(e));
|
|
@@ -178,6 +182,7 @@ function ChartCanvas({ controller, width = 640, height = 400, responsive = true,
|
|
|
178
182
|
const endDrag = () => {
|
|
179
183
|
drag.current?.end();
|
|
180
184
|
drag.current = null;
|
|
185
|
+
setValueDomain(null);
|
|
181
186
|
};
|
|
182
187
|
const onKeyDown = (e) => {
|
|
183
188
|
if (editable && (0, import_chart2.handleChartKey)(controller, scene, e)) e.preventDefault();
|
package/dist/chart/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/chart/index.ts","../../src/chart/useChartEditor.ts","../../src/chart/styles.ts","../../src/chart/ChartCanvas.tsx","../../src/chart/ChartDataGrid.tsx","../../src/chart/ChartInspector.tsx","../../src/chart/ChartEditor.tsx"],"sourcesContent":["export * from './useChartEditor';\nexport * from './styles';\nexport * from './ChartCanvas';\nexport * from './ChartDataGrid';\nexport * from './ChartInspector';\nexport * from './ChartEditor';\n","import { useEffect, useMemo, useRef, useSyncExternalStore } from 'react';\nimport {\n ChartController,\n createChartCommands,\n type ChartActionResult,\n type ChartCommandOptions,\n type ChartControllerOptions,\n type ChartSelection,\n type ChartSpecPatch,\n type ChartState,\n type ChartType,\n} from '@pixerate/editor/chart';\n\n/** A `ChartController` created once for the component's lifetime. */\nexport function useChartController(options: ChartControllerOptions = {}): ChartController {\n const ref = useRef<ChartController | null>(null);\n if (!ref.current) ref.current = new ChartController(options);\n return ref.current;\n}\n\n/** The controller's state (re-renders on every change). */\nexport function useChartState(controller: ChartController): ChartState {\n return useSyncExternalStore(controller.subscribe, controller.getState, controller.getState);\n}\n\nexport interface UseChartEditorResult {\n controller: ChartController;\n state: ChartState;\n spec: ChartState['spec'];\n selection: ChartSelection | null;\n update: (patch: ChartSpecPatch) => ChartActionResult;\n setType: (type: ChartType) => ChartActionResult;\n setValue: (seriesId: string, index: number, value: unknown) => ChartActionResult;\n select: (selection: ChartSelection | null) => void;\n undo: () => void;\n redo: () => void;\n}\n\n/**\n * Subscribes to a chart controller and exposes its state with bound actions. Pass options\n * instead of a controller to create one for the component's lifetime.\n */\nexport function useChartEditor(controllerOrOptions: ChartController | ChartControllerOptions = {}): UseChartEditorResult {\n const own = useRef<ChartController | null>(null);\n let controller: ChartController;\n if (controllerOrOptions instanceof ChartController) controller = controllerOrOptions;\n else {\n if (!own.current) own.current = new ChartController(controllerOrOptions);\n controller = own.current;\n }\n const state = useChartState(controller);\n const actions = useMemo(\n () => ({\n update: (patch: ChartSpecPatch) => controller.update(patch),\n setType: (type: ChartType) => controller.setType(type),\n setValue: (seriesId: string, index: number, value: unknown) => controller.setValue(seriesId, index, value),\n select: (selection: ChartSelection | null) => controller.select(selection),\n undo: () => void controller.undo(),\n redo: () => void controller.redo(),\n }),\n [controller],\n );\n return { controller, state, spec: state.spec, selection: state.selection, ...actions };\n}\n\n/** Anything with `register(specs) → unregister` (a `CommandRegistry`). */\nexport interface ChartCommandTarget {\n register(specs: any): () => void;\n}\n\n/**\n * Registers the controller's palette / agent commands (`chart.describe`, `chart.update`,\n * `chart.setValues`, …) in `registry` while mounted.\n */\nexport function useChartCommands(registry: ChartCommandTarget | null | undefined, controller: ChartController, options: ChartCommandOptions = {}): void {\n const { prefix, group, scope } = options;\n useEffect(() => {\n if (!registry) return;\n return registry.register(createChartCommands(controller, { prefix, group, scope }));\n }, [registry, controller, prefix, group, scope]);\n}\n","// Class names shared by the chart components (the same as the Svelte package's).\nexport const chartInputClass =\n 'h-7 w-full min-w-0 rounded-md border border-input bg-background px-2 text-xs text-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-primary disabled:cursor-not-allowed disabled:opacity-50';\nexport const chartButtonClass =\n 'inline-flex h-7 items-center justify-center gap-1 rounded-md border border-input bg-background px-2 text-xs text-foreground hover:bg-muted focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-primary disabled:pointer-events-none disabled:opacity-50';\nexport const chartIconButtonClass =\n 'inline-flex h-6 w-6 shrink-0 items-center justify-center rounded text-xs text-muted-foreground hover:bg-muted hover:text-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-primary disabled:pointer-events-none disabled:opacity-40';\nexport const chartSegmentClass = (active: boolean) =>\n `inline-flex h-7 flex-1 items-center justify-center rounded px-2 text-xs focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-primary ${\n active ? 'bg-background text-foreground shadow-sm' : 'text-muted-foreground hover:text-foreground'\n }`;\nexport const chartLabelClass = 'text-[11px] font-medium text-muted-foreground';\nexport const chartSectionClass = 'space-y-2 border-b border-border pb-3 last:border-b-0';\nexport const chartCellClass =\n 'h-7 w-full min-w-[4.5rem] bg-transparent px-2 text-right text-xs tabular-nums text-foreground focus-visible:bg-background focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-inset focus-visible:ring-primary';\n","import React, { useEffect, useMemo, useRef, useState } from 'react';\nimport {\n CSS_VARIABLE_CHART_THEME,\n chartClientToScene,\n chartTextBaseline,\n chartTextTransform,\n describeChartSelection,\n handleChartKey,\n layoutChart,\n startChartPointDrag,\n type ChartController,\n type ChartMark,\n type ChartPointDrag,\n type ChartTextMeasure,\n type ChartTheme,\n} from '@pixerate/editor/chart';\nimport { useChartState } from './useChartEditor';\n\nexport interface ChartCanvasProps {\n controller: ChartController;\n /** Scene width; with `responsive` this is only the fallback before the container is measured (default 640). */\n width?: number;\n /** Scene height in pixels (default 400). */\n height?: number;\n /** Follow the container's width (default `true`). */\n responsive?: boolean;\n /** Colours and type (default: shadcn-style CSS variables). */\n theme?: Partial<ChartTheme>;\n /** Click to select, drag bars and points, keyboard editing (default `true`). */\n editable?: boolean;\n /** Text width for layout (default: an estimate). */\n measureText?: ChartTextMeasure;\n emptyMessage?: string;\n className?: string;\n}\n\n/** SVG attributes for one mark (colours go in `style` so CSS variables work). */\nfunction renderMark(mark: ChartMark, fontFamily: string, interactive: boolean): React.ReactNode {\n const common = {\n 'data-role': mark.role,\n 'data-chart-key': mark.target ? mark.key : undefined,\n 'data-selected': mark.selected ? '' : undefined,\n opacity: mark.opacity,\n pointerEvents: mark.role === 'selection' || (!mark.target && mark.role !== 'background') ? ('none' as const) : undefined,\n cursor: interactive && mark.target && mark.role !== 'background' ? 'pointer' : undefined,\n };\n switch (mark.kind) {\n case 'rect':\n return <rect key={mark.key} {...common} x={mark.x} y={mark.y} width={mark.width} height={mark.height} rx={mark.radius} style={{ fill: mark.fill, stroke: mark.stroke, strokeWidth: mark.strokeWidth }} />;\n case 'path':\n return (\n <path\n key={mark.key}\n {...common}\n d={mark.d}\n strokeLinejoin=\"round\"\n strokeLinecap=\"round\"\n strokeDasharray={mark.dash}\n style={{ fill: mark.fill ?? 'none', stroke: mark.stroke, strokeWidth: mark.strokeWidth }}\n />\n );\n case 'circle':\n return <circle key={mark.key} {...common} cx={mark.cx} cy={mark.cy} r={mark.r} style={{ fill: mark.fill, stroke: mark.stroke, strokeWidth: mark.strokeWidth }} />;\n case 'line':\n return <line key={mark.key} {...common} x1={mark.x1} y1={mark.y1} x2={mark.x2} y2={mark.y2} strokeDasharray={mark.dash} style={{ stroke: mark.stroke, strokeWidth: mark.strokeWidth }} />;\n case 'text':\n return (\n <text\n key={mark.key}\n {...common}\n x={mark.x}\n y={mark.y}\n textAnchor={mark.anchor}\n dominantBaseline={chartTextBaseline(mark.baseline)}\n transform={chartTextTransform(mark)}\n style={{ fill: mark.fill, fontSize: mark.size, fontWeight: mark.weight, fontFamily, userSelect: 'none' }}\n >\n {mark.text}\n </text>\n );\n }\n}\n\n/**\n * Draws a chart controller's spec as SVG. Click a mark to select it, drag a bar or point to\n * change its value (one undo step), and with the chart focused use ← → ↑ ↓, Delete and\n * Escape (see `handleChartKey`).\n */\nexport function ChartCanvas({ controller, width = 640, height = 400, responsive = true, theme, editable = true, measureText, emptyMessage, className }: ChartCanvasProps) {\n const state = useChartState(controller);\n const wrapper = useRef<HTMLDivElement>(null);\n const svg = useRef<SVGSVGElement>(null);\n const drag = useRef<ChartPointDrag | null>(null);\n const [measured, setMeasured] = useState<number | null>(null);\n\n useEffect(() => {\n const el = wrapper.current;\n if (!responsive || !el || typeof ResizeObserver === 'undefined') return;\n const observer = new ResizeObserver(([entry]) => {\n const w = Math.round(entry.contentRect.width);\n if (w > 0) setMeasured(w);\n });\n observer.observe(el);\n return () => observer.disconnect();\n }, [responsive]);\n\n const sceneWidth = (responsive && measured) || width;\n const fullTheme = useMemo(() => ({ ...CSS_VARIABLE_CHART_THEME, ...theme }), [theme]);\n const scene = useMemo(\n () => layoutChart(state.spec, { width: sceneWidth, height, theme: fullTheme, selection: editable ? state.selection : null, measureText, emptyMessage }),\n [state.spec, state.selection, sceneWidth, height, fullTheme, editable, measureText, emptyMessage],\n );\n const byKey = useMemo(() => new Map(scene.marks.map((m) => [m.key, m])), [scene]);\n\n useEffect(() => () => drag.current?.end(), []);\n\n const scenePoint = (e: React.PointerEvent) => chartClientToScene(scene, svg.current!.getBoundingClientRect(), e.clientX, e.clientY);\n\n const onPointerDown = (e: React.PointerEvent<SVGSVGElement>) => {\n if (!editable || e.button !== 0) return;\n const key = (e.target as Element).closest?.('[data-chart-key]')?.getAttribute('data-chart-key');\n const target = key ? byKey.get(key)?.target : undefined;\n controller.select(target ?? null);\n drag.current = startChartPointDrag(controller, scene, target, scenePoint(e));\n if (drag.current) svg.current?.setPointerCapture?.(e.pointerId);\n };\n const onPointerMove = (e: React.PointerEvent<SVGSVGElement>) => {\n if (drag.current) drag.current.move(scenePoint(e));\n };\n const endDrag = () => {\n drag.current?.end();\n drag.current = null;\n };\n const onKeyDown = (e: React.KeyboardEvent<SVGSVGElement>) => {\n if (editable && handleChartKey(controller, scene, e)) e.preventDefault();\n };\n\n const label = state.spec.title || 'Chart';\n return (\n <div ref={wrapper} className={`w-full ${className ?? ''}`} data-chart-canvas=\"\">\n <svg\n ref={svg}\n width={sceneWidth}\n height={height}\n viewBox={`0 0 ${scene.width} ${scene.height}`}\n role=\"img\"\n aria-label={editable ? `${label}. ${describeChartSelection(controller, state.selection)}` : label}\n tabIndex={editable ? 0 : undefined}\n className=\"block max-w-full touch-none select-none rounded-md focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary\"\n onPointerDown={onPointerDown}\n onPointerMove={onPointerMove}\n onPointerUp={endDrag}\n onPointerCancel={endDrag}\n onKeyDown={onKeyDown}\n >\n {scene.marks.map((m) => renderMark(m, scene.theme.fontFamily, editable))}\n </svg>\n </div>\n );\n}\n","import React, { useEffect, useRef, useState } from 'react';\nimport { chartColorInputValue, chartSeriesColor, formatChartNumber, type ChartController } from '@pixerate/editor/chart';\nimport { useChartState } from './useChartEditor';\nimport { chartButtonClass, chartCellClass, chartIconButtonClass, chartInputClass } from './styles';\n\ntype CommitInputProps = {\n value: string;\n /** Called with the typed text. Return `false` to show the stored value again (a refused edit). */\n onCommit: (value: string) => boolean | void;\n} & Omit<React.InputHTMLAttributes<HTMLInputElement>, 'value' | 'onChange' | 'defaultValue'>;\n\n/** A text box that commits on blur or Enter and resets on Escape. Follows `value` unless the user is typing. */\nexport function ChartCommitInput({ value, onCommit, onKeyDown, onBlur, ...rest }: CommitInputProps) {\n const [draft, setDraft] = useState(value);\n const typing = useRef(false);\n useEffect(() => {\n if (!typing.current) setDraft(value);\n }, [value]);\n const commit = () => {\n if (!typing.current) return;\n typing.current = false;\n if (draft === value) return;\n if (onCommit(draft) === false) setDraft(value);\n };\n return (\n <input\n {...rest}\n value={draft}\n onChange={(e) => {\n typing.current = true;\n setDraft(e.currentTarget.value);\n }}\n onBlur={(e) => {\n onBlur?.(e);\n commit();\n }}\n onKeyDown={(e) => {\n onKeyDown?.(e);\n if (e.defaultPrevented) return;\n if (e.key === 'Enter') {\n e.preventDefault();\n commit();\n } else if (e.key === 'Escape') {\n typing.current = false;\n setDraft(value);\n }\n }}\n />\n );\n}\n\nexport interface ChartDataGridProps {\n controller: ChartController;\n /** Header of the category column (default \"Category\"). */\n categoryHeader?: string;\n /** Hide the add / delete buttons. */\n readOnly?: boolean;\n className?: string;\n}\n\n/**\n * The chart's data as an editable grid: categories down the side, one column per series\n * (name, colour, show / hide, delete). Cells take numbers as people type them (`1,200`,\n * `12%`, blank for a gap); pasting TSV or CSV fills and grows the grid from the cell.\n */\nexport function ChartDataGrid({ controller, categoryHeader = 'Category', readOnly = false, className }: ChartDataGridProps) {\n const { spec, selection } = useChartState(controller);\n const paste = (row: number, column: number) => (e: React.ClipboardEvent<HTMLInputElement>) => {\n const text = e.clipboardData?.getData('text/plain') ?? '';\n if (!/[\\t\\n]/.test(text.replace(/\\n$/, ''))) return;\n e.preventDefault();\n controller.pasteCells(row, column, text);\n };\n return (\n <div className={`overflow-auto rounded-md border border-border ${className ?? ''}`} data-chart-grid=\"\">\n <table className=\"w-full border-collapse text-xs\">\n <thead className=\"bg-muted/50\">\n <tr>\n <th className=\"border-b border-r border-border px-2 py-1 text-left font-medium text-muted-foreground\">{categoryHeader}</th>\n {spec.series.map((s, si) => {\n const color = chartSeriesColor(spec, si);\n const selected = selection?.kind === 'series' && selection.seriesId === s.id;\n return (\n <th key={s.id} data-series-id={s.id} className={`border-b border-r border-border px-1 py-1 font-medium ${selected ? 'bg-primary/10' : ''}`}>\n <div className=\"flex items-center gap-1\">\n <input\n type=\"color\"\n aria-label={`${s.name} colour`}\n value={chartColorInputValue(color)}\n disabled={readOnly}\n onPointerDown={() => controller.beginGesture(`color:${s.id}`)}\n onChange={(e) => controller.updateSeries(s.id, { color: e.currentTarget.value })}\n onBlur={() => controller.endGesture()}\n className=\"h-5 w-5 shrink-0 cursor-pointer rounded border-0 bg-transparent p-0\"\n />\n <ChartCommitInput\n value={s.name}\n aria-label=\"Series name\"\n onFocus={() => controller.select({ kind: 'series', seriesId: s.id })}\n onCommit={(name) => void controller.updateSeries(s.id, { name })}\n className={`${chartInputClass} h-6 min-w-[5rem] border-transparent bg-transparent font-medium ${s.hidden ? 'text-muted-foreground line-through' : ''}`}\n />\n {!readOnly && (\n <>\n <button\n type=\"button\"\n className={chartIconButtonClass}\n title={s.hidden ? 'Show series' : 'Hide series'}\n aria-label={s.hidden ? `Show ${s.name}` : `Hide ${s.name}`}\n aria-pressed={!s.hidden}\n data-action=\"toggle-series\"\n onClick={() => controller.toggleSeries(s.id)}\n >\n {s.hidden ? '○' : '●'}\n </button>\n <button type=\"button\" className={chartIconButtonClass} title=\"Delete series\" aria-label={`Delete ${s.name}`} data-action=\"remove-series\" onClick={() => controller.removeSeries(s.id)}>\n ×\n </button>\n </>\n )}\n </div>\n </th>\n );\n })}\n {!readOnly && (\n <th className=\"w-8 border-b border-border px-1\">\n <button type=\"button\" className={chartIconButtonClass} title=\"Add series\" aria-label=\"Add series\" data-action=\"add-series\" onClick={() => controller.addSeries()}>\n +\n </button>\n </th>\n )}\n </tr>\n </thead>\n <tbody>\n {spec.categories.map((category, i) => {\n const rowSelected = selection?.kind === 'category' && selection.index === i;\n return (\n <tr key={i} data-category-index={i} className={rowSelected ? 'bg-primary/10' : undefined}>\n <th className=\"border-b border-r border-border p-0 text-left font-normal\">\n <ChartCommitInput\n value={category}\n aria-label={`Category ${i + 1}`}\n onFocus={() => controller.select({ kind: 'category', index: i })}\n onPaste={paste(i, -1)}\n onCommit={(label) => void controller.renameCategory(i, label)}\n className={`${chartCellClass} text-left`}\n />\n </th>\n {spec.series.map((s) => {\n const value = s.values[i];\n const selected = selection?.kind === 'point' && selection.seriesId === s.id && selection.index === i;\n return (\n <td key={s.id} className={`border-b border-r border-border p-0 ${selected ? 'bg-primary/10' : ''}`}>\n <ChartCommitInput\n value={value === null || value === undefined ? '' : String(value)}\n inputMode=\"decimal\"\n aria-label={`${s.name}, ${category}`}\n title={value === null ? undefined : formatChartNumber(value, spec.yAxis.format)}\n data-cell={`${s.id}:${i}`}\n onFocus={() => controller.select({ kind: 'point', seriesId: s.id, index: i })}\n onPaste={paste(i, spec.series.indexOf(s))}\n onCommit={(text) => controller.setValue(s.id, i, text).ok}\n className={chartCellClass}\n />\n </td>\n );\n })}\n {!readOnly && (\n <td className=\"border-b border-border px-1\">\n <button type=\"button\" className={chartIconButtonClass} title=\"Delete category\" aria-label={`Delete ${category}`} data-action=\"remove-category\" onClick={() => controller.removeCategory(i)}>\n ×\n </button>\n </td>\n )}\n </tr>\n );\n })}\n </tbody>\n </table>\n {!readOnly && (\n <div className=\"p-1\">\n <button type=\"button\" className={`${chartButtonClass} h-6 border-dashed`} data-action=\"add-category\" onClick={() => controller.addCategory()}>\n + Add category\n </button>\n </div>\n )}\n </div>\n );\n}\n","import React, { useId } from 'react';\nimport {\n CHART_CURVES,\n CHART_LEGEND_POSITIONS,\n CHART_NUMBER_STYLES,\n CHART_SERIES_TYPES,\n CHART_STACKINGS,\n CHART_TYPE_LABELS,\n CHART_TYPES,\n chartColorInputValue,\n chartSeriesColor,\n chartSeriesType,\n isCartesianChart,\n type ChartAxis,\n type ChartController,\n type ChartNumberFormat,\n} from '@pixerate/editor/chart';\nimport { useChartState } from './useChartEditor';\nimport { ChartCommitInput } from './ChartDataGrid';\nimport { chartButtonClass, chartInputClass, chartLabelClass, chartSectionClass, chartSegmentClass } from './styles';\n\nexport interface ChartInspectorProps {\n controller: ChartController;\n /** Which sections to show (default: all that apply to the chart). */\n sections?: readonly ChartInspectorSection[];\n className?: string;\n}\n\nexport type ChartInspectorSection = 'type' | 'titles' | 'options' | 'legend' | 'axes' | 'series';\n\nconst cap = (s: string) => s.charAt(0).toUpperCase() + s.slice(1);\n\nfunction Field({ label, htmlFor, children }: { label: string; htmlFor?: string; children: React.ReactNode }) {\n return (\n <div className=\"flex items-center gap-2\">\n <label htmlFor={htmlFor} className={`${chartLabelClass} w-20 shrink-0`}>\n {label}\n </label>\n <div className=\"min-w-0 flex-1\">{children}</div>\n </div>\n );\n}\n\nfunction Toggle({ label, checked, onChange, name }: { label: string; checked: boolean; onChange: (checked: boolean) => void; name: string }) {\n return (\n <label className=\"flex cursor-pointer items-center gap-2 text-xs text-foreground\">\n <input type=\"checkbox\" className=\"h-3.5 w-3.5 accent-primary\" checked={checked} data-option={name} onChange={(e) => onChange(e.currentTarget.checked)} />\n {label}\n </label>\n );\n}\n\nfunction Select<T extends string>({ id, value, options, onChange, name, labels }: { id?: string; value: T; options: readonly T[]; onChange: (value: T) => void; name: string; labels?: Partial<Record<T, string>> }) {\n return (\n <select id={id} className={chartInputClass} value={value} data-option={name} onChange={(e) => onChange(e.currentTarget.value as T)}>\n {options.map((o) => (\n <option key={o} value={o}>\n {labels?.[o] ?? cap(o)}\n </option>\n ))}\n </select>\n );\n}\n\nfunction AxisSection({ controller, axis, value, idBase, horizontal }: { controller: ChartController; axis: 'x' | 'y'; value: ChartAxis; idBase: string; horizontal: boolean }) {\n const set = (patch: Partial<ChartAxis>) => controller.setAxis(axis, patch);\n const setFormat = (patch: Partial<ChartNumberFormat>) => set({ format: { ...value.format, ...patch } });\n const bound = (key: 'min' | 'max') => (\n <ChartCommitInput\n id={`${idBase}-${axis}-${key}`}\n value={value[key] === null ? '' : String(value[key])}\n placeholder=\"Auto\"\n inputMode=\"decimal\"\n data-option={`${axis}Axis.${key}`}\n className={chartInputClass}\n onCommit={(text) => set({ [key]: text.trim() === '' ? null : Number(text) }).ok}\n />\n );\n const name = axis === 'x' ? 'Category axis' : 'Value axis';\n return (\n <div className={chartSectionClass} data-section={`axis-${axis}`}>\n <div className=\"flex items-center justify-between\">\n <h4 className=\"text-xs font-semibold text-foreground\">\n {name}\n <span className=\"ml-1 font-normal text-muted-foreground\">({axis === 'x' ? (horizontal ? 'left' : 'bottom') : horizontal ? 'bottom' : 'left'})</span>\n </h4>\n <Toggle label=\"Show\" name={`${axis}Axis.show`} checked={value.show} onChange={(show) => set({ show })} />\n </div>\n <Field label=\"Title\" htmlFor={`${idBase}-${axis}-title`}>\n <ChartCommitInput id={`${idBase}-${axis}-title`} value={value.title} data-option={`${axis}Axis.title`} className={chartInputClass} onCommit={(title) => void set({ title })} />\n </Field>\n <Toggle label=\"Grid lines\" name={`${axis}Axis.gridlines`} checked={value.gridlines} onChange={(gridlines) => set({ gridlines })} />\n {axis === 'y' && (\n <>\n <Field label=\"Min / max\">\n <div className=\"flex gap-1\">\n {bound('min')}\n {bound('max')}\n </div>\n </Field>\n <Field label=\"Format\" htmlFor={`${idBase}-y-format`}>\n <div className=\"flex gap-1\">\n <Select id={`${idBase}-y-format`} name=\"yAxis.format.style\" value={value.format.style ?? 'number'} options={CHART_NUMBER_STYLES} onChange={(style) => setFormat({ style })} />\n <ChartCommitInput\n value={value.format.decimals === undefined ? '' : String(value.format.decimals)}\n placeholder=\"Auto\"\n aria-label=\"Decimals\"\n title=\"Decimals\"\n inputMode=\"numeric\"\n data-option=\"yAxis.format.decimals\"\n className={`${chartInputClass} w-14 shrink-0`}\n onCommit={(text) => {\n const format = { ...value.format };\n if (text.trim() === '') delete format.decimals;\n else format.decimals = Number(text);\n return set({ format }).ok;\n }}\n />\n </div>\n </Field>\n {value.format.style === 'currency' && (\n <Field label=\"Currency\" htmlFor={`${idBase}-y-currency`}>\n <ChartCommitInput id={`${idBase}-y-currency`} value={value.format.currency ?? 'USD'} data-option=\"yAxis.format.currency\" className={chartInputClass} onCommit={(currency) => void setFormat({ currency: currency.toUpperCase() })} />\n </Field>\n )}\n </>\n )}\n </div>\n );\n}\n\n/**\n * Settings for a chart controller: type, titles, stacking and line options, legend, both\n * axes and the selected series. Every change is one undo step.\n */\nexport function ChartInspector({ controller, sections, className }: ChartInspectorProps) {\n const { spec, selectedSeries } = useChartState(controller);\n const idBase = useId();\n const show = (section: ChartInspectorSection) => !sections || sections.includes(section);\n const cartesian = isCartesianChart(spec.type);\n const types = spec.series.map((s) => chartSeriesType(spec, s));\n const hasBars = cartesian && types.includes('bar');\n const hasLines = cartesian && types.some((t) => t === 'line' || t === 'area');\n const seriesIndex = selectedSeries ? spec.series.findIndex((s) => s.id === selectedSeries.id) : -1;\n\n return (\n <div className={`space-y-3 text-xs ${className ?? ''}`} data-chart-inspector=\"\">\n {show('type') && (\n <div className={chartSectionClass} data-section=\"type\">\n <div className=\"grid grid-cols-3 gap-0.5 rounded-md bg-muted p-0.5\" role=\"radiogroup\" aria-label=\"Chart type\">\n {CHART_TYPES.map((type) => (\n <button key={type} type=\"button\" role=\"radio\" aria-checked={spec.type === type} data-chart-type={type} className={chartSegmentClass(spec.type === type)} onClick={() => controller.setType(type)}>\n {CHART_TYPE_LABELS[type]}\n </button>\n ))}\n </div>\n </div>\n )}\n\n {show('titles') && (\n <div className={chartSectionClass} data-section=\"titles\">\n <Field label=\"Title\" htmlFor={`${idBase}-title`}>\n <ChartCommitInput id={`${idBase}-title`} value={spec.title} data-option=\"title\" className={chartInputClass} onCommit={(title) => void controller.setTitle(title)} />\n </Field>\n <Field label=\"Subtitle\" htmlFor={`${idBase}-subtitle`}>\n <ChartCommitInput id={`${idBase}-subtitle`} value={spec.subtitle} data-option=\"subtitle\" className={chartInputClass} onCommit={(subtitle) => void controller.setSubtitle(subtitle)} />\n </Field>\n </div>\n )}\n\n {show('options') && (\n <div className={chartSectionClass} data-section=\"options\">\n {cartesian && (\n <Field label=\"Stacking\" htmlFor={`${idBase}-stacking`}>\n <Select id={`${idBase}-stacking`} name=\"stacking\" value={spec.stacking} options={CHART_STACKINGS} labels={{ none: 'None', stacked: 'Stacked', percent: '100%' }} onChange={(stacking) => controller.update({ stacking })} />\n </Field>\n )}\n {hasBars && (\n <Field label=\"Bars\">\n <div className=\"flex gap-0.5 rounded-md bg-muted p-0.5\">\n {(['vertical', 'horizontal'] as const).map((o) => (\n <button key={o} type=\"button\" aria-pressed={spec.orientation === o} data-option={`orientation.${o}`} className={chartSegmentClass(spec.orientation === o)} onClick={() => controller.update({ orientation: o })}>\n {cap(o)}\n </button>\n ))}\n </div>\n </Field>\n )}\n {hasLines && (\n <Field label=\"Lines\" htmlFor={`${idBase}-curve`}>\n <Select id={`${idBase}-curve`} name=\"curve\" value={spec.curve} options={CHART_CURVES} onChange={(curve) => controller.update({ curve })} />\n </Field>\n )}\n {spec.type === 'donut' && (\n <Field label=\"Hole\" htmlFor={`${idBase}-hole`}>\n <input\n id={`${idBase}-hole`}\n type=\"range\"\n min={0}\n max={0.9}\n step={0.05}\n value={spec.innerRadius}\n data-option=\"innerRadius\"\n className=\"w-full accent-primary\"\n onPointerDown={() => controller.beginGesture('innerRadius')}\n onPointerUp={() => controller.endGesture()}\n onChange={(e) => controller.update({ innerRadius: Number(e.currentTarget.value) })}\n />\n </Field>\n )}\n <div className=\"flex flex-wrap gap-x-4 gap-y-1\">\n {hasLines && <Toggle label=\"Points\" name=\"points\" checked={spec.points} onChange={(points) => controller.update({ points })} />}\n <Toggle label=\"Data labels\" name=\"dataLabels\" checked={spec.dataLabels} onChange={(dataLabels) => controller.update({ dataLabels })} />\n </div>\n </div>\n )}\n\n {show('legend') && (\n <div className={chartSectionClass} data-section=\"legend\">\n <div className=\"flex items-center justify-between\">\n <h4 className=\"text-xs font-semibold text-foreground\">Legend</h4>\n <Toggle label=\"Show\" name=\"legend.show\" checked={spec.legend.show} onChange={(v) => controller.setLegend({ show: v })} />\n </div>\n {spec.legend.show && (\n <div className=\"flex gap-0.5 rounded-md bg-muted p-0.5\">\n {CHART_LEGEND_POSITIONS.map((p) => (\n <button key={p} type=\"button\" aria-pressed={spec.legend.position === p} data-option={`legend.${p}`} className={chartSegmentClass(spec.legend.position === p)} onClick={() => controller.setLegend({ position: p })}>\n {cap(p)}\n </button>\n ))}\n </div>\n )}\n </div>\n )}\n\n {show('axes') && cartesian && (\n <>\n <AxisSection controller={controller} axis=\"x\" value={spec.xAxis} idBase={idBase} horizontal={spec.orientation === 'horizontal'} />\n <AxisSection controller={controller} axis=\"y\" value={spec.yAxis} idBase={idBase} horizontal={spec.orientation === 'horizontal'} />\n </>\n )}\n\n {show('series') && selectedSeries && (\n <div className={chartSectionClass} data-section=\"series\" data-series-id={selectedSeries.id}>\n <h4 className=\"text-xs font-semibold text-foreground\">Series</h4>\n <Field label=\"Name\" htmlFor={`${idBase}-series-name`}>\n <ChartCommitInput id={`${idBase}-series-name`} value={selectedSeries.name} data-option=\"series.name\" className={chartInputClass} onCommit={(name) => void controller.updateSeries(selectedSeries.id, { name })} />\n </Field>\n <Field label=\"Colour\" htmlFor={`${idBase}-series-color`}>\n <div className=\"flex items-center gap-1\">\n <input\n id={`${idBase}-series-color`}\n type=\"color\"\n value={chartColorInputValue(chartSeriesColor(spec, seriesIndex))}\n data-option=\"series.color\"\n className=\"h-7 w-9 shrink-0 cursor-pointer rounded border border-input bg-background p-0.5\"\n onPointerDown={() => controller.beginGesture(`color:${selectedSeries.id}`)}\n onBlur={() => controller.endGesture()}\n onChange={(e) => controller.updateSeries(selectedSeries.id, { color: e.currentTarget.value })}\n />\n {selectedSeries.color && (\n <button type=\"button\" className={chartButtonClass} data-action=\"reset-color\" onClick={() => controller.updateSeries(selectedSeries.id, { color: null })}>\n Palette\n </button>\n )}\n </div>\n </Field>\n {cartesian && (\n <Field label=\"Draw as\" htmlFor={`${idBase}-series-type`}>\n <select\n id={`${idBase}-series-type`}\n className={chartInputClass}\n value={selectedSeries.type ?? ''}\n data-option=\"series.type\"\n onChange={(e) => controller.updateSeries(selectedSeries.id, { type: (e.currentTarget.value || null) as any })}\n >\n <option value=\"\">Chart type</option>\n {CHART_SERIES_TYPES.map((t) => (\n <option key={t} value={t}>\n {CHART_TYPE_LABELS[t]}\n </option>\n ))}\n </select>\n </Field>\n )}\n <div className=\"flex flex-wrap items-center gap-1\">\n <Toggle label=\"Hidden\" name=\"series.hidden\" checked={!!selectedSeries.hidden} onChange={(hidden) => controller.updateSeries(selectedSeries.id, { hidden })} />\n <span className=\"flex-1\" />\n <button type=\"button\" className={chartButtonClass} disabled={seriesIndex <= 0} aria-label=\"Move series earlier\" data-action=\"series-up\" onClick={() => controller.moveSeries(selectedSeries.id, seriesIndex - 1)}>\n ↑\n </button>\n <button type=\"button\" className={chartButtonClass} disabled={seriesIndex >= spec.series.length - 1} aria-label=\"Move series later\" data-action=\"series-down\" onClick={() => controller.moveSeries(selectedSeries.id, seriesIndex + 1)}>\n ↓\n </button>\n <button type=\"button\" className={`${chartButtonClass} text-destructive`} data-action=\"series-delete\" onClick={() => controller.removeSeries(selectedSeries.id)}>\n Delete\n </button>\n </div>\n </div>\n )}\n </div>\n );\n}\n","import React from 'react';\nimport { describeChartSelection, type ChartController } from '@pixerate/editor/chart';\nimport { ChartCanvas, type ChartCanvasProps } from './ChartCanvas';\nimport { ChartDataGrid } from './ChartDataGrid';\nimport { ChartInspector } from './ChartInspector';\nimport { useChartState } from './useChartEditor';\nimport { chartButtonClass } from './styles';\n\nexport interface ChartEditorProps {\n controller: ChartController;\n /** The settings sidebar (default `true`). */\n showInspector?: boolean;\n /** The data grid under the chart (default `true`). */\n showDataGrid?: boolean;\n /** Undo / redo and the selection readout (default `true`). */\n showToolbar?: boolean;\n /** Chart height in pixels (default 380). */\n height?: number;\n canvasProps?: Omit<ChartCanvasProps, 'controller' | 'height'>;\n className?: string;\n}\n\n/** Toolbar, chart, settings sidebar and data grid for a `ChartController`. */\nexport function ChartEditor({ controller, showInspector = true, showDataGrid = true, showToolbar = true, height = 380, canvasProps, className }: ChartEditorProps) {\n const state = useChartState(controller);\n return (\n <div className={`flex flex-col gap-2 ${className ?? ''}`} data-chart-editor=\"\">\n {showToolbar && (\n <div className=\"flex items-center gap-1\" data-chart-toolbar=\"\">\n <button type=\"button\" className={chartButtonClass} disabled={!state.canUndo} title={state.undoLabel ? `Undo ${state.undoLabel}` : 'Undo'} data-action=\"undo\" onClick={() => controller.undo()}>\n Undo\n </button>\n <button type=\"button\" className={chartButtonClass} disabled={!state.canRedo} title={state.redoLabel ? `Redo ${state.redoLabel}` : 'Redo'} data-action=\"redo\" onClick={() => controller.redo()}>\n Redo\n </button>\n <span className=\"ml-2 truncate text-xs text-muted-foreground\" data-chart-selection=\"\" aria-live=\"polite\">\n {describeChartSelection(controller, state.selection)}\n </span>\n </div>\n )}\n {state.issues.length > 0 && (\n <p role=\"alert\" className=\"rounded-md border border-destructive/40 bg-destructive/10 px-2 py-1 text-xs text-destructive\" data-chart-issues=\"\">\n {state.issues.map((i) => i.message).join(' ')}\n </p>\n )}\n <div className=\"flex min-h-0 flex-col gap-2 md:flex-row\">\n <div className=\"min-w-0 flex-1 rounded-md border border-border bg-background p-1\">\n <ChartCanvas controller={controller} height={height} {...canvasProps} />\n </div>\n {showInspector && <ChartInspector controller={controller} className=\"w-full shrink-0 overflow-y-auto rounded-md border border-border p-3 md:w-64\" />}\n </div>\n {showDataGrid && <ChartDataGrid controller={controller} />}\n </div>\n );\n}\n"],"mappings":"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","names":["import_react","import_chart","import_react","import_chart","import_jsx_runtime","import_react","import_chart","import_jsx_runtime","import_chart","import_jsx_runtime"]}
|
|
1
|
+
{"version":3,"sources":["../../src/chart/index.ts","../../src/chart/useChartEditor.ts","../../src/chart/styles.ts","../../src/chart/ChartCanvas.tsx","../../src/chart/ChartDataGrid.tsx","../../src/chart/ChartInspector.tsx","../../src/chart/ChartEditor.tsx"],"sourcesContent":["export * from './useChartEditor';\nexport * from './styles';\nexport * from './ChartCanvas';\nexport * from './ChartDataGrid';\nexport * from './ChartInspector';\nexport * from './ChartEditor';\n","import { useEffect, useMemo, useRef, useSyncExternalStore } from 'react';\nimport {\n ChartController,\n createChartCommands,\n type ChartActionResult,\n type ChartCommandOptions,\n type ChartControllerOptions,\n type ChartSelection,\n type ChartSpecPatch,\n type ChartState,\n type ChartType,\n} from '@pixerate/editor/chart';\n\n/** A `ChartController` created once for the component's lifetime. */\nexport function useChartController(options: ChartControllerOptions = {}): ChartController {\n const ref = useRef<ChartController | null>(null);\n if (!ref.current) ref.current = new ChartController(options);\n return ref.current;\n}\n\n/** The controller's state (re-renders on every change). */\nexport function useChartState(controller: ChartController): ChartState {\n return useSyncExternalStore(controller.subscribe, controller.getState, controller.getState);\n}\n\nexport interface UseChartEditorResult {\n controller: ChartController;\n state: ChartState;\n spec: ChartState['spec'];\n selection: ChartSelection | null;\n update: (patch: ChartSpecPatch) => ChartActionResult;\n setType: (type: ChartType) => ChartActionResult;\n setValue: (seriesId: string, index: number, value: unknown) => ChartActionResult;\n select: (selection: ChartSelection | null) => void;\n undo: () => void;\n redo: () => void;\n}\n\n/**\n * Subscribes to a chart controller and exposes its state with bound actions. Pass options\n * instead of a controller to create one for the component's lifetime.\n */\nexport function useChartEditor(controllerOrOptions: ChartController | ChartControllerOptions = {}): UseChartEditorResult {\n const own = useRef<ChartController | null>(null);\n let controller: ChartController;\n if (controllerOrOptions instanceof ChartController) controller = controllerOrOptions;\n else {\n if (!own.current) own.current = new ChartController(controllerOrOptions);\n controller = own.current;\n }\n const state = useChartState(controller);\n const actions = useMemo(\n () => ({\n update: (patch: ChartSpecPatch) => controller.update(patch),\n setType: (type: ChartType) => controller.setType(type),\n setValue: (seriesId: string, index: number, value: unknown) => controller.setValue(seriesId, index, value),\n select: (selection: ChartSelection | null) => controller.select(selection),\n undo: () => void controller.undo(),\n redo: () => void controller.redo(),\n }),\n [controller],\n );\n return { controller, state, spec: state.spec, selection: state.selection, ...actions };\n}\n\n/** Anything with `register(specs) → unregister` (a `CommandRegistry`). */\nexport interface ChartCommandTarget {\n register(specs: any): () => void;\n}\n\n/**\n * Registers the controller's palette / agent commands (`chart.describe`, `chart.update`,\n * `chart.setValues`, …) in `registry` while mounted.\n */\nexport function useChartCommands(registry: ChartCommandTarget | null | undefined, controller: ChartController, options: ChartCommandOptions = {}): void {\n const { prefix, group, scope } = options;\n useEffect(() => {\n if (!registry) return;\n return registry.register(createChartCommands(controller, { prefix, group, scope }));\n }, [registry, controller, prefix, group, scope]);\n}\n","// Class names shared by the chart components (the same as the Svelte package's).\nexport const chartInputClass =\n 'h-7 w-full min-w-0 rounded-md border border-input bg-background px-2 text-xs text-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-primary disabled:cursor-not-allowed disabled:opacity-50';\nexport const chartButtonClass =\n 'inline-flex h-7 items-center justify-center gap-1 rounded-md border border-input bg-background px-2 text-xs text-foreground hover:bg-muted focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-primary disabled:pointer-events-none disabled:opacity-50';\nexport const chartIconButtonClass =\n 'inline-flex h-6 w-6 shrink-0 items-center justify-center rounded text-xs text-muted-foreground hover:bg-muted hover:text-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-primary disabled:pointer-events-none disabled:opacity-40';\nexport const chartSegmentClass = (active: boolean) =>\n `inline-flex h-7 flex-1 items-center justify-center rounded px-2 text-xs focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-primary ${\n active ? 'bg-background text-foreground shadow-sm' : 'text-muted-foreground hover:text-foreground'\n }`;\nexport const chartLabelClass = 'text-[11px] font-medium text-muted-foreground';\nexport const chartSectionClass = 'space-y-2 border-b border-border pb-3 last:border-b-0';\nexport const chartCellClass =\n 'h-7 w-full min-w-[4.5rem] bg-transparent px-2 text-right text-xs tabular-nums text-foreground focus-visible:bg-background focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-inset focus-visible:ring-primary';\n","import React, { useEffect, useMemo, useRef, useState } from 'react';\nimport {\n CSS_VARIABLE_CHART_THEME,\n chartClientToScene,\n chartTextBaseline,\n chartTextTransform,\n describeChartSelection,\n handleChartKey,\n layoutChart,\n startChartPointDrag,\n type ChartController,\n type ChartMark,\n type ChartPointDrag,\n type ChartTextMeasure,\n type ChartTheme,\n} from '@pixerate/editor/chart';\nimport { useChartState } from './useChartEditor';\n\nexport interface ChartCanvasProps {\n controller: ChartController;\n /** Scene width; with `responsive` this is only the fallback before the container is measured (default 640). */\n width?: number;\n /** Scene height in pixels (default 400). */\n height?: number;\n /** Follow the container's width (default `true`). */\n responsive?: boolean;\n /** Colours and type (default: shadcn-style CSS variables). */\n theme?: Partial<ChartTheme>;\n /** Click to select, drag bars and points, keyboard editing (default `true`). */\n editable?: boolean;\n /** Text width for layout (default: an estimate). */\n measureText?: ChartTextMeasure;\n emptyMessage?: string;\n className?: string;\n}\n\n/** SVG attributes for one mark (colours go in `style` so CSS variables work). */\nfunction renderMark(mark: ChartMark, fontFamily: string, interactive: boolean): React.ReactNode {\n const common = {\n 'data-role': mark.role,\n 'data-chart-key': mark.target ? mark.key : undefined,\n 'data-selected': mark.selected ? '' : undefined,\n opacity: mark.opacity,\n pointerEvents: mark.role === 'selection' || (!mark.target && mark.role !== 'background') ? ('none' as const) : undefined,\n cursor: interactive && mark.target && mark.role !== 'background' ? 'pointer' : undefined,\n };\n switch (mark.kind) {\n case 'rect':\n return <rect key={mark.key} {...common} x={mark.x} y={mark.y} width={mark.width} height={mark.height} rx={mark.radius} style={{ fill: mark.fill, stroke: mark.stroke, strokeWidth: mark.strokeWidth }} />;\n case 'path':\n return (\n <path\n key={mark.key}\n {...common}\n d={mark.d}\n strokeLinejoin=\"round\"\n strokeLinecap=\"round\"\n strokeDasharray={mark.dash}\n style={{ fill: mark.fill ?? 'none', stroke: mark.stroke, strokeWidth: mark.strokeWidth }}\n />\n );\n case 'circle':\n return <circle key={mark.key} {...common} cx={mark.cx} cy={mark.cy} r={mark.r} style={{ fill: mark.fill, stroke: mark.stroke, strokeWidth: mark.strokeWidth }} />;\n case 'line':\n return <line key={mark.key} {...common} x1={mark.x1} y1={mark.y1} x2={mark.x2} y2={mark.y2} strokeDasharray={mark.dash} style={{ stroke: mark.stroke, strokeWidth: mark.strokeWidth }} />;\n case 'text':\n return (\n <text\n key={mark.key}\n {...common}\n x={mark.x}\n y={mark.y}\n textAnchor={mark.anchor}\n dominantBaseline={chartTextBaseline(mark.baseline)}\n transform={chartTextTransform(mark)}\n style={{ fill: mark.fill, fontSize: mark.size, fontWeight: mark.weight, fontFamily, userSelect: 'none' }}\n >\n {mark.text}\n </text>\n );\n }\n}\n\n/**\n * Draws a chart controller's spec as SVG. Click a mark to select it, drag a bar or point to\n * change its value (one undo step), and with the chart focused use ← → ↑ ↓, Delete and\n * Escape (see `handleChartKey`).\n */\nexport function ChartCanvas({ controller, width = 640, height = 400, responsive = true, theme, editable = true, measureText, emptyMessage, className }: ChartCanvasProps) {\n const state = useChartState(controller);\n const wrapper = useRef<HTMLDivElement>(null);\n const svg = useRef<SVGSVGElement>(null);\n const drag = useRef<ChartPointDrag | null>(null);\n const [measured, setMeasured] = useState<number | null>(null);\n // Frozen while a point is dragged so the value axis does not rescale under the pointer.\n const [valueDomain, setValueDomain] = useState<ChartPointDrag['valueDomain'] | null>(null);\n\n useEffect(() => {\n const el = wrapper.current;\n if (!responsive || !el || typeof ResizeObserver === 'undefined') return;\n const observer = new ResizeObserver(([entry]) => {\n const w = Math.round(entry.contentRect.width);\n if (w > 0) setMeasured(w);\n });\n observer.observe(el);\n return () => observer.disconnect();\n }, [responsive]);\n\n const sceneWidth = (responsive && measured) || width;\n const fullTheme = useMemo(() => ({ ...CSS_VARIABLE_CHART_THEME, ...theme }), [theme]);\n const scene = useMemo(\n () => layoutChart(state.spec, { width: sceneWidth, height, theme: fullTheme, selection: editable ? state.selection : null, measureText, emptyMessage, valueDomain }),\n [state.spec, state.selection, sceneWidth, height, fullTheme, editable, measureText, emptyMessage, valueDomain],\n );\n const byKey = useMemo(() => new Map(scene.marks.map((m) => [m.key, m])), [scene]);\n\n useEffect(() => () => drag.current?.end(), []);\n\n const scenePoint = (e: React.PointerEvent) => chartClientToScene(scene, svg.current!.getBoundingClientRect(), e.clientX, e.clientY);\n\n const onPointerDown = (e: React.PointerEvent<SVGSVGElement>) => {\n if (!editable || e.button !== 0) return;\n const key = (e.target as Element).closest?.('[data-chart-key]')?.getAttribute('data-chart-key');\n const target = key ? byKey.get(key)?.target : undefined;\n controller.select(target ?? null);\n drag.current = startChartPointDrag(controller, scene, target, scenePoint(e));\n if (drag.current) {\n setValueDomain(drag.current.valueDomain);\n svg.current?.setPointerCapture?.(e.pointerId);\n }\n };\n const onPointerMove = (e: React.PointerEvent<SVGSVGElement>) => {\n if (drag.current) drag.current.move(scenePoint(e));\n };\n const endDrag = () => {\n drag.current?.end();\n drag.current = null;\n setValueDomain(null);\n };\n const onKeyDown = (e: React.KeyboardEvent<SVGSVGElement>) => {\n if (editable && handleChartKey(controller, scene, e)) e.preventDefault();\n };\n\n const label = state.spec.title || 'Chart';\n return (\n <div ref={wrapper} className={`w-full ${className ?? ''}`} data-chart-canvas=\"\">\n <svg\n ref={svg}\n width={sceneWidth}\n height={height}\n viewBox={`0 0 ${scene.width} ${scene.height}`}\n role=\"img\"\n aria-label={editable ? `${label}. ${describeChartSelection(controller, state.selection)}` : label}\n tabIndex={editable ? 0 : undefined}\n className=\"block max-w-full touch-none select-none rounded-md focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary\"\n onPointerDown={onPointerDown}\n onPointerMove={onPointerMove}\n onPointerUp={endDrag}\n onPointerCancel={endDrag}\n onKeyDown={onKeyDown}\n >\n {scene.marks.map((m) => renderMark(m, scene.theme.fontFamily, editable))}\n </svg>\n </div>\n );\n}\n","import React, { useEffect, useRef, useState } from 'react';\nimport { chartColorInputValue, chartSeriesColor, formatChartNumber, type ChartController } from '@pixerate/editor/chart';\nimport { useChartState } from './useChartEditor';\nimport { chartButtonClass, chartCellClass, chartIconButtonClass, chartInputClass } from './styles';\n\ntype CommitInputProps = {\n value: string;\n /** Called with the typed text. Return `false` to show the stored value again (a refused edit). */\n onCommit: (value: string) => boolean | void;\n} & Omit<React.InputHTMLAttributes<HTMLInputElement>, 'value' | 'onChange' | 'defaultValue'>;\n\n/** A text box that commits on blur or Enter and resets on Escape. Follows `value` unless the user is typing. */\nexport function ChartCommitInput({ value, onCommit, onKeyDown, onBlur, ...rest }: CommitInputProps) {\n const [draft, setDraft] = useState(value);\n const typing = useRef(false);\n useEffect(() => {\n if (!typing.current) setDraft(value);\n }, [value]);\n const commit = () => {\n if (!typing.current) return;\n typing.current = false;\n if (draft === value) return;\n if (onCommit(draft) === false) setDraft(value);\n };\n return (\n <input\n {...rest}\n value={draft}\n onChange={(e) => {\n typing.current = true;\n setDraft(e.currentTarget.value);\n }}\n onBlur={(e) => {\n onBlur?.(e);\n commit();\n }}\n onKeyDown={(e) => {\n onKeyDown?.(e);\n if (e.defaultPrevented) return;\n if (e.key === 'Enter') {\n e.preventDefault();\n commit();\n } else if (e.key === 'Escape') {\n typing.current = false;\n setDraft(value);\n }\n }}\n />\n );\n}\n\nexport interface ChartDataGridProps {\n controller: ChartController;\n /** Header of the category column (default \"Category\"). */\n categoryHeader?: string;\n /** Hide the add / delete buttons. */\n readOnly?: boolean;\n className?: string;\n}\n\n/**\n * The chart's data as an editable grid: categories down the side, one column per series\n * (name, colour, show / hide, delete). Cells take numbers as people type them (`1,200`,\n * `12%`, blank for a gap); pasting TSV or CSV fills and grows the grid from the cell.\n */\nexport function ChartDataGrid({ controller, categoryHeader = 'Category', readOnly = false, className }: ChartDataGridProps) {\n const { spec, selection } = useChartState(controller);\n const paste = (row: number, column: number) => (e: React.ClipboardEvent<HTMLInputElement>) => {\n const text = e.clipboardData?.getData('text/plain') ?? '';\n if (!/[\\t\\n]/.test(text.replace(/\\n$/, ''))) return;\n e.preventDefault();\n controller.pasteCells(row, column, text);\n };\n return (\n <div className={`overflow-auto rounded-md border border-border ${className ?? ''}`} data-chart-grid=\"\">\n <table className=\"w-full border-collapse text-xs\">\n <thead className=\"bg-muted/50\">\n <tr>\n <th className=\"border-b border-r border-border px-2 py-1 text-left font-medium text-muted-foreground\">{categoryHeader}</th>\n {spec.series.map((s, si) => {\n const color = chartSeriesColor(spec, si);\n const selected = selection?.kind === 'series' && selection.seriesId === s.id;\n return (\n <th key={s.id} data-series-id={s.id} className={`border-b border-r border-border px-1 py-1 font-medium ${selected ? 'bg-primary/10' : ''}`}>\n <div className=\"flex items-center gap-1\">\n <input\n type=\"color\"\n aria-label={`${s.name} colour`}\n value={chartColorInputValue(color)}\n disabled={readOnly}\n onPointerDown={() => controller.beginGesture(`color:${s.id}`)}\n onChange={(e) => controller.updateSeries(s.id, { color: e.currentTarget.value })}\n onBlur={() => controller.endGesture()}\n className=\"h-5 w-5 shrink-0 cursor-pointer rounded border-0 bg-transparent p-0\"\n />\n <ChartCommitInput\n value={s.name}\n aria-label=\"Series name\"\n onFocus={() => controller.select({ kind: 'series', seriesId: s.id })}\n onCommit={(name) => void controller.updateSeries(s.id, { name })}\n className={`${chartInputClass} h-6 min-w-[5rem] border-transparent bg-transparent font-medium ${s.hidden ? 'text-muted-foreground line-through' : ''}`}\n />\n {!readOnly && (\n <>\n <button\n type=\"button\"\n className={chartIconButtonClass}\n title={s.hidden ? 'Show series' : 'Hide series'}\n aria-label={s.hidden ? `Show ${s.name}` : `Hide ${s.name}`}\n aria-pressed={!s.hidden}\n data-action=\"toggle-series\"\n onClick={() => controller.toggleSeries(s.id)}\n >\n {s.hidden ? '○' : '●'}\n </button>\n <button type=\"button\" className={chartIconButtonClass} title=\"Delete series\" aria-label={`Delete ${s.name}`} data-action=\"remove-series\" onClick={() => controller.removeSeries(s.id)}>\n ×\n </button>\n </>\n )}\n </div>\n </th>\n );\n })}\n {!readOnly && (\n <th className=\"w-8 border-b border-border px-1\">\n <button type=\"button\" className={chartIconButtonClass} title=\"Add series\" aria-label=\"Add series\" data-action=\"add-series\" onClick={() => controller.addSeries()}>\n +\n </button>\n </th>\n )}\n </tr>\n </thead>\n <tbody>\n {spec.categories.map((category, i) => {\n const rowSelected = selection?.kind === 'category' && selection.index === i;\n return (\n <tr key={i} data-category-index={i} className={rowSelected ? 'bg-primary/10' : undefined}>\n <th className=\"border-b border-r border-border p-0 text-left font-normal\">\n <ChartCommitInput\n value={category}\n aria-label={`Category ${i + 1}`}\n onFocus={() => controller.select({ kind: 'category', index: i })}\n onPaste={paste(i, -1)}\n onCommit={(label) => void controller.renameCategory(i, label)}\n className={`${chartCellClass} text-left`}\n />\n </th>\n {spec.series.map((s) => {\n const value = s.values[i];\n const selected = selection?.kind === 'point' && selection.seriesId === s.id && selection.index === i;\n return (\n <td key={s.id} className={`border-b border-r border-border p-0 ${selected ? 'bg-primary/10' : ''}`}>\n <ChartCommitInput\n value={value === null || value === undefined ? '' : String(value)}\n inputMode=\"decimal\"\n aria-label={`${s.name}, ${category}`}\n title={value === null ? undefined : formatChartNumber(value, spec.yAxis.format)}\n data-cell={`${s.id}:${i}`}\n onFocus={() => controller.select({ kind: 'point', seriesId: s.id, index: i })}\n onPaste={paste(i, spec.series.indexOf(s))}\n onCommit={(text) => controller.setValue(s.id, i, text).ok}\n className={chartCellClass}\n />\n </td>\n );\n })}\n {!readOnly && (\n <td className=\"border-b border-border px-1\">\n <button type=\"button\" className={chartIconButtonClass} title=\"Delete category\" aria-label={`Delete ${category}`} data-action=\"remove-category\" onClick={() => controller.removeCategory(i)}>\n ×\n </button>\n </td>\n )}\n </tr>\n );\n })}\n </tbody>\n </table>\n {!readOnly && (\n <div className=\"p-1\">\n <button type=\"button\" className={`${chartButtonClass} h-6 border-dashed`} data-action=\"add-category\" onClick={() => controller.addCategory()}>\n + Add category\n </button>\n </div>\n )}\n </div>\n );\n}\n","import React, { useId } from 'react';\nimport {\n CHART_CURVES,\n CHART_LEGEND_POSITIONS,\n CHART_NUMBER_STYLES,\n CHART_SERIES_TYPES,\n CHART_STACKINGS,\n CHART_TYPE_LABELS,\n CHART_TYPES,\n chartColorInputValue,\n chartSeriesColor,\n chartSeriesType,\n isCartesianChart,\n type ChartAxis,\n type ChartController,\n type ChartNumberFormat,\n} from '@pixerate/editor/chart';\nimport { useChartState } from './useChartEditor';\nimport { ChartCommitInput } from './ChartDataGrid';\nimport { chartButtonClass, chartInputClass, chartLabelClass, chartSectionClass, chartSegmentClass } from './styles';\n\nexport interface ChartInspectorProps {\n controller: ChartController;\n /** Which sections to show (default: all that apply to the chart). */\n sections?: readonly ChartInspectorSection[];\n className?: string;\n}\n\nexport type ChartInspectorSection = 'type' | 'titles' | 'options' | 'legend' | 'axes' | 'series';\n\nconst cap = (s: string) => s.charAt(0).toUpperCase() + s.slice(1);\n\nfunction Field({ label, htmlFor, children }: { label: string; htmlFor?: string; children: React.ReactNode }) {\n return (\n <div className=\"flex items-center gap-2\">\n <label htmlFor={htmlFor} className={`${chartLabelClass} w-20 shrink-0`}>\n {label}\n </label>\n <div className=\"min-w-0 flex-1\">{children}</div>\n </div>\n );\n}\n\nfunction Toggle({ label, checked, onChange, name }: { label: string; checked: boolean; onChange: (checked: boolean) => void; name: string }) {\n return (\n <label className=\"flex cursor-pointer items-center gap-2 text-xs text-foreground\">\n <input type=\"checkbox\" className=\"h-3.5 w-3.5 accent-primary\" checked={checked} data-option={name} onChange={(e) => onChange(e.currentTarget.checked)} />\n {label}\n </label>\n );\n}\n\nfunction Select<T extends string>({ id, value, options, onChange, name, labels }: { id?: string; value: T; options: readonly T[]; onChange: (value: T) => void; name: string; labels?: Partial<Record<T, string>> }) {\n return (\n <select id={id} className={chartInputClass} value={value} data-option={name} onChange={(e) => onChange(e.currentTarget.value as T)}>\n {options.map((o) => (\n <option key={o} value={o}>\n {labels?.[o] ?? cap(o)}\n </option>\n ))}\n </select>\n );\n}\n\nfunction AxisSection({ controller, axis, value, idBase, horizontal }: { controller: ChartController; axis: 'x' | 'y'; value: ChartAxis; idBase: string; horizontal: boolean }) {\n const set = (patch: Partial<ChartAxis>) => controller.setAxis(axis, patch);\n const setFormat = (patch: Partial<ChartNumberFormat>) => set({ format: { ...value.format, ...patch } });\n const bound = (key: 'min' | 'max') => (\n <ChartCommitInput\n id={`${idBase}-${axis}-${key}`}\n value={value[key] === null ? '' : String(value[key])}\n placeholder=\"Auto\"\n inputMode=\"decimal\"\n data-option={`${axis}Axis.${key}`}\n className={chartInputClass}\n onCommit={(text) => set({ [key]: text.trim() === '' ? null : Number(text) }).ok}\n />\n );\n const name = axis === 'x' ? 'Category axis' : 'Value axis';\n return (\n <div className={chartSectionClass} data-section={`axis-${axis}`}>\n <div className=\"flex items-center justify-between\">\n <h4 className=\"text-xs font-semibold text-foreground\">\n {name}\n <span className=\"ml-1 font-normal text-muted-foreground\">({axis === 'x' ? (horizontal ? 'left' : 'bottom') : horizontal ? 'bottom' : 'left'})</span>\n </h4>\n <Toggle label=\"Show\" name={`${axis}Axis.show`} checked={value.show} onChange={(show) => set({ show })} />\n </div>\n <Field label=\"Title\" htmlFor={`${idBase}-${axis}-title`}>\n <ChartCommitInput id={`${idBase}-${axis}-title`} value={value.title} data-option={`${axis}Axis.title`} className={chartInputClass} onCommit={(title) => void set({ title })} />\n </Field>\n <Toggle label=\"Grid lines\" name={`${axis}Axis.gridlines`} checked={value.gridlines} onChange={(gridlines) => set({ gridlines })} />\n {axis === 'y' && (\n <>\n <Field label=\"Min / max\">\n <div className=\"flex gap-1\">\n {bound('min')}\n {bound('max')}\n </div>\n </Field>\n <Field label=\"Format\" htmlFor={`${idBase}-y-format`}>\n <div className=\"flex gap-1\">\n <Select id={`${idBase}-y-format`} name=\"yAxis.format.style\" value={value.format.style ?? 'number'} options={CHART_NUMBER_STYLES} onChange={(style) => setFormat({ style })} />\n <ChartCommitInput\n value={value.format.decimals === undefined ? '' : String(value.format.decimals)}\n placeholder=\"Auto\"\n aria-label=\"Decimals\"\n title=\"Decimals\"\n inputMode=\"numeric\"\n data-option=\"yAxis.format.decimals\"\n className={`${chartInputClass} w-14 shrink-0`}\n onCommit={(text) => {\n const format = { ...value.format };\n if (text.trim() === '') delete format.decimals;\n else format.decimals = Number(text);\n return set({ format }).ok;\n }}\n />\n </div>\n </Field>\n {value.format.style === 'currency' && (\n <Field label=\"Currency\" htmlFor={`${idBase}-y-currency`}>\n <ChartCommitInput id={`${idBase}-y-currency`} value={value.format.currency ?? 'USD'} data-option=\"yAxis.format.currency\" className={chartInputClass} onCommit={(currency) => void setFormat({ currency: currency.toUpperCase() })} />\n </Field>\n )}\n </>\n )}\n </div>\n );\n}\n\n/**\n * Settings for a chart controller: type, titles, stacking and line options, legend, both\n * axes and the selected series. Every change is one undo step.\n */\nexport function ChartInspector({ controller, sections, className }: ChartInspectorProps) {\n const { spec, selectedSeries } = useChartState(controller);\n const idBase = useId();\n const show = (section: ChartInspectorSection) => !sections || sections.includes(section);\n const cartesian = isCartesianChart(spec.type);\n const types = spec.series.map((s) => chartSeriesType(spec, s));\n const hasBars = cartesian && types.includes('bar');\n const hasLines = cartesian && types.some((t) => t === 'line' || t === 'area');\n const seriesIndex = selectedSeries ? spec.series.findIndex((s) => s.id === selectedSeries.id) : -1;\n\n return (\n <div className={`space-y-3 text-xs ${className ?? ''}`} data-chart-inspector=\"\">\n {show('type') && (\n <div className={chartSectionClass} data-section=\"type\">\n <div className=\"grid grid-cols-3 gap-0.5 rounded-md bg-muted p-0.5\" role=\"radiogroup\" aria-label=\"Chart type\">\n {CHART_TYPES.map((type) => (\n <button key={type} type=\"button\" role=\"radio\" aria-checked={spec.type === type} data-chart-type={type} className={chartSegmentClass(spec.type === type)} onClick={() => controller.setType(type)}>\n {CHART_TYPE_LABELS[type]}\n </button>\n ))}\n </div>\n </div>\n )}\n\n {show('titles') && (\n <div className={chartSectionClass} data-section=\"titles\">\n <Field label=\"Title\" htmlFor={`${idBase}-title`}>\n <ChartCommitInput id={`${idBase}-title`} value={spec.title} data-option=\"title\" className={chartInputClass} onCommit={(title) => void controller.setTitle(title)} />\n </Field>\n <Field label=\"Subtitle\" htmlFor={`${idBase}-subtitle`}>\n <ChartCommitInput id={`${idBase}-subtitle`} value={spec.subtitle} data-option=\"subtitle\" className={chartInputClass} onCommit={(subtitle) => void controller.setSubtitle(subtitle)} />\n </Field>\n </div>\n )}\n\n {show('options') && (\n <div className={chartSectionClass} data-section=\"options\">\n {cartesian && (\n <Field label=\"Stacking\" htmlFor={`${idBase}-stacking`}>\n <Select id={`${idBase}-stacking`} name=\"stacking\" value={spec.stacking} options={CHART_STACKINGS} labels={{ none: 'None', stacked: 'Stacked', percent: '100%' }} onChange={(stacking) => controller.update({ stacking })} />\n </Field>\n )}\n {hasBars && (\n <Field label=\"Bars\">\n <div className=\"flex gap-0.5 rounded-md bg-muted p-0.5\">\n {(['vertical', 'horizontal'] as const).map((o) => (\n <button key={o} type=\"button\" aria-pressed={spec.orientation === o} data-option={`orientation.${o}`} className={chartSegmentClass(spec.orientation === o)} onClick={() => controller.update({ orientation: o })}>\n {cap(o)}\n </button>\n ))}\n </div>\n </Field>\n )}\n {hasLines && (\n <Field label=\"Lines\" htmlFor={`${idBase}-curve`}>\n <Select id={`${idBase}-curve`} name=\"curve\" value={spec.curve} options={CHART_CURVES} onChange={(curve) => controller.update({ curve })} />\n </Field>\n )}\n {spec.type === 'donut' && (\n <Field label=\"Hole\" htmlFor={`${idBase}-hole`}>\n <input\n id={`${idBase}-hole`}\n type=\"range\"\n min={0}\n max={0.9}\n step={0.05}\n value={spec.innerRadius}\n data-option=\"innerRadius\"\n className=\"w-full accent-primary\"\n onPointerDown={() => controller.beginGesture('innerRadius')}\n onPointerUp={() => controller.endGesture()}\n onChange={(e) => controller.update({ innerRadius: Number(e.currentTarget.value) })}\n />\n </Field>\n )}\n <div className=\"flex flex-wrap gap-x-4 gap-y-1\">\n {hasLines && <Toggle label=\"Points\" name=\"points\" checked={spec.points} onChange={(points) => controller.update({ points })} />}\n <Toggle label=\"Data labels\" name=\"dataLabels\" checked={spec.dataLabels} onChange={(dataLabels) => controller.update({ dataLabels })} />\n </div>\n </div>\n )}\n\n {show('legend') && (\n <div className={chartSectionClass} data-section=\"legend\">\n <div className=\"flex items-center justify-between\">\n <h4 className=\"text-xs font-semibold text-foreground\">Legend</h4>\n <Toggle label=\"Show\" name=\"legend.show\" checked={spec.legend.show} onChange={(v) => controller.setLegend({ show: v })} />\n </div>\n {spec.legend.show && (\n <div className=\"flex gap-0.5 rounded-md bg-muted p-0.5\">\n {CHART_LEGEND_POSITIONS.map((p) => (\n <button key={p} type=\"button\" aria-pressed={spec.legend.position === p} data-option={`legend.${p}`} className={chartSegmentClass(spec.legend.position === p)} onClick={() => controller.setLegend({ position: p })}>\n {cap(p)}\n </button>\n ))}\n </div>\n )}\n </div>\n )}\n\n {show('axes') && cartesian && (\n <>\n <AxisSection controller={controller} axis=\"x\" value={spec.xAxis} idBase={idBase} horizontal={spec.orientation === 'horizontal'} />\n <AxisSection controller={controller} axis=\"y\" value={spec.yAxis} idBase={idBase} horizontal={spec.orientation === 'horizontal'} />\n </>\n )}\n\n {show('series') && selectedSeries && (\n <div className={chartSectionClass} data-section=\"series\" data-series-id={selectedSeries.id}>\n <h4 className=\"text-xs font-semibold text-foreground\">Series</h4>\n <Field label=\"Name\" htmlFor={`${idBase}-series-name`}>\n <ChartCommitInput id={`${idBase}-series-name`} value={selectedSeries.name} data-option=\"series.name\" className={chartInputClass} onCommit={(name) => void controller.updateSeries(selectedSeries.id, { name })} />\n </Field>\n <Field label=\"Colour\" htmlFor={`${idBase}-series-color`}>\n <div className=\"flex items-center gap-1\">\n <input\n id={`${idBase}-series-color`}\n type=\"color\"\n value={chartColorInputValue(chartSeriesColor(spec, seriesIndex))}\n data-option=\"series.color\"\n className=\"h-7 w-9 shrink-0 cursor-pointer rounded border border-input bg-background p-0.5\"\n onPointerDown={() => controller.beginGesture(`color:${selectedSeries.id}`)}\n onBlur={() => controller.endGesture()}\n onChange={(e) => controller.updateSeries(selectedSeries.id, { color: e.currentTarget.value })}\n />\n {selectedSeries.color && (\n <button type=\"button\" className={chartButtonClass} data-action=\"reset-color\" onClick={() => controller.updateSeries(selectedSeries.id, { color: null })}>\n Palette\n </button>\n )}\n </div>\n </Field>\n {cartesian && (\n <Field label=\"Draw as\" htmlFor={`${idBase}-series-type`}>\n <select\n id={`${idBase}-series-type`}\n className={chartInputClass}\n value={selectedSeries.type ?? ''}\n data-option=\"series.type\"\n onChange={(e) => controller.updateSeries(selectedSeries.id, { type: (e.currentTarget.value || null) as any })}\n >\n <option value=\"\">Chart type</option>\n {CHART_SERIES_TYPES.map((t) => (\n <option key={t} value={t}>\n {CHART_TYPE_LABELS[t]}\n </option>\n ))}\n </select>\n </Field>\n )}\n <div className=\"flex flex-wrap items-center gap-1\">\n <Toggle label=\"Hidden\" name=\"series.hidden\" checked={!!selectedSeries.hidden} onChange={(hidden) => controller.updateSeries(selectedSeries.id, { hidden })} />\n <span className=\"flex-1\" />\n <button type=\"button\" className={chartButtonClass} disabled={seriesIndex <= 0} aria-label=\"Move series earlier\" data-action=\"series-up\" onClick={() => controller.moveSeries(selectedSeries.id, seriesIndex - 1)}>\n ↑\n </button>\n <button type=\"button\" className={chartButtonClass} disabled={seriesIndex >= spec.series.length - 1} aria-label=\"Move series later\" data-action=\"series-down\" onClick={() => controller.moveSeries(selectedSeries.id, seriesIndex + 1)}>\n ↓\n </button>\n <button type=\"button\" className={`${chartButtonClass} text-destructive`} data-action=\"series-delete\" onClick={() => controller.removeSeries(selectedSeries.id)}>\n Delete\n </button>\n </div>\n </div>\n )}\n </div>\n );\n}\n","import React from 'react';\nimport { describeChartSelection, type ChartController } from '@pixerate/editor/chart';\nimport { ChartCanvas, type ChartCanvasProps } from './ChartCanvas';\nimport { ChartDataGrid } from './ChartDataGrid';\nimport { ChartInspector } from './ChartInspector';\nimport { useChartState } from './useChartEditor';\nimport { chartButtonClass } from './styles';\n\nexport interface ChartEditorProps {\n controller: ChartController;\n /** The settings sidebar (default `true`). */\n showInspector?: boolean;\n /** The data grid under the chart (default `true`). */\n showDataGrid?: boolean;\n /** Undo / redo and the selection readout (default `true`). */\n showToolbar?: boolean;\n /** Chart height in pixels (default 380). */\n height?: number;\n canvasProps?: Omit<ChartCanvasProps, 'controller' | 'height'>;\n className?: string;\n}\n\n/** Toolbar, chart, settings sidebar and data grid for a `ChartController`. */\nexport function ChartEditor({ controller, showInspector = true, showDataGrid = true, showToolbar = true, height = 380, canvasProps, className }: ChartEditorProps) {\n const state = useChartState(controller);\n return (\n <div className={`flex flex-col gap-2 ${className ?? ''}`} data-chart-editor=\"\">\n {showToolbar && (\n <div className=\"flex items-center gap-1\" data-chart-toolbar=\"\">\n <button type=\"button\" className={chartButtonClass} disabled={!state.canUndo} title={state.undoLabel ? `Undo ${state.undoLabel}` : 'Undo'} data-action=\"undo\" onClick={() => controller.undo()}>\n Undo\n </button>\n <button type=\"button\" className={chartButtonClass} disabled={!state.canRedo} title={state.redoLabel ? `Redo ${state.redoLabel}` : 'Redo'} data-action=\"redo\" onClick={() => controller.redo()}>\n Redo\n </button>\n <span className=\"ml-2 truncate text-xs text-muted-foreground\" data-chart-selection=\"\" aria-live=\"polite\">\n {describeChartSelection(controller, state.selection)}\n </span>\n </div>\n )}\n {state.issues.length > 0 && (\n <p role=\"alert\" className=\"rounded-md border border-destructive/40 bg-destructive/10 px-2 py-1 text-xs text-destructive\" data-chart-issues=\"\">\n {state.issues.map((i) => i.message).join(' ')}\n </p>\n )}\n <div className=\"flex min-h-0 flex-col gap-2 md:flex-row\">\n <div className=\"min-w-0 flex-1 rounded-md border border-border bg-background p-1\">\n <ChartCanvas controller={controller} height={height} {...canvasProps} />\n </div>\n {showInspector && <ChartInspector controller={controller} className=\"w-full shrink-0 overflow-y-auto rounded-md border border-border p-3 md:w-64\" />}\n </div>\n {showDataGrid && <ChartDataGrid controller={controller} />}\n </div>\n );\n}\n"],"mappings":"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","names":["import_react","import_chart","import_react","import_chart","import_jsx_runtime","import_react","import_chart","import_jsx_runtime","import_chart","import_jsx_runtime"]}
|
package/dist/chart/index.js
CHANGED
|
@@ -116,6 +116,7 @@ function ChartCanvas({ controller, width = 640, height = 400, responsive = true,
|
|
|
116
116
|
const svg = useRef2(null);
|
|
117
117
|
const drag = useRef2(null);
|
|
118
118
|
const [measured, setMeasured] = useState(null);
|
|
119
|
+
const [valueDomain, setValueDomain] = useState(null);
|
|
119
120
|
useEffect2(() => {
|
|
120
121
|
const el = wrapper.current;
|
|
121
122
|
if (!responsive || !el || typeof ResizeObserver === "undefined") return;
|
|
@@ -129,8 +130,8 @@ function ChartCanvas({ controller, width = 640, height = 400, responsive = true,
|
|
|
129
130
|
const sceneWidth = responsive && measured || width;
|
|
130
131
|
const fullTheme = useMemo2(() => ({ ...CSS_VARIABLE_CHART_THEME, ...theme }), [theme]);
|
|
131
132
|
const scene = useMemo2(
|
|
132
|
-
() => layoutChart(state.spec, { width: sceneWidth, height, theme: fullTheme, selection: editable ? state.selection : null, measureText, emptyMessage }),
|
|
133
|
-
[state.spec, state.selection, sceneWidth, height, fullTheme, editable, measureText, emptyMessage]
|
|
133
|
+
() => layoutChart(state.spec, { width: sceneWidth, height, theme: fullTheme, selection: editable ? state.selection : null, measureText, emptyMessage, valueDomain }),
|
|
134
|
+
[state.spec, state.selection, sceneWidth, height, fullTheme, editable, measureText, emptyMessage, valueDomain]
|
|
134
135
|
);
|
|
135
136
|
const byKey = useMemo2(() => new Map(scene.marks.map((m) => [m.key, m])), [scene]);
|
|
136
137
|
useEffect2(() => () => drag.current?.end(), []);
|
|
@@ -141,7 +142,10 @@ function ChartCanvas({ controller, width = 640, height = 400, responsive = true,
|
|
|
141
142
|
const target = key ? byKey.get(key)?.target : void 0;
|
|
142
143
|
controller.select(target ?? null);
|
|
143
144
|
drag.current = startChartPointDrag(controller, scene, target, scenePoint(e));
|
|
144
|
-
if (drag.current)
|
|
145
|
+
if (drag.current) {
|
|
146
|
+
setValueDomain(drag.current.valueDomain);
|
|
147
|
+
svg.current?.setPointerCapture?.(e.pointerId);
|
|
148
|
+
}
|
|
145
149
|
};
|
|
146
150
|
const onPointerMove = (e) => {
|
|
147
151
|
if (drag.current) drag.current.move(scenePoint(e));
|
|
@@ -149,6 +153,7 @@ function ChartCanvas({ controller, width = 640, height = 400, responsive = true,
|
|
|
149
153
|
const endDrag = () => {
|
|
150
154
|
drag.current?.end();
|
|
151
155
|
drag.current = null;
|
|
156
|
+
setValueDomain(null);
|
|
152
157
|
};
|
|
153
158
|
const onKeyDown = (e) => {
|
|
154
159
|
if (editable && handleChartKey(controller, scene, e)) e.preventDefault();
|
package/dist/chart/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/chart/useChartEditor.ts","../../src/chart/styles.ts","../../src/chart/ChartCanvas.tsx","../../src/chart/ChartDataGrid.tsx","../../src/chart/ChartInspector.tsx","../../src/chart/ChartEditor.tsx"],"sourcesContent":["import { useEffect, useMemo, useRef, useSyncExternalStore } from 'react';\nimport {\n ChartController,\n createChartCommands,\n type ChartActionResult,\n type ChartCommandOptions,\n type ChartControllerOptions,\n type ChartSelection,\n type ChartSpecPatch,\n type ChartState,\n type ChartType,\n} from '@pixerate/editor/chart';\n\n/** A `ChartController` created once for the component's lifetime. */\nexport function useChartController(options: ChartControllerOptions = {}): ChartController {\n const ref = useRef<ChartController | null>(null);\n if (!ref.current) ref.current = new ChartController(options);\n return ref.current;\n}\n\n/** The controller's state (re-renders on every change). */\nexport function useChartState(controller: ChartController): ChartState {\n return useSyncExternalStore(controller.subscribe, controller.getState, controller.getState);\n}\n\nexport interface UseChartEditorResult {\n controller: ChartController;\n state: ChartState;\n spec: ChartState['spec'];\n selection: ChartSelection | null;\n update: (patch: ChartSpecPatch) => ChartActionResult;\n setType: (type: ChartType) => ChartActionResult;\n setValue: (seriesId: string, index: number, value: unknown) => ChartActionResult;\n select: (selection: ChartSelection | null) => void;\n undo: () => void;\n redo: () => void;\n}\n\n/**\n * Subscribes to a chart controller and exposes its state with bound actions. Pass options\n * instead of a controller to create one for the component's lifetime.\n */\nexport function useChartEditor(controllerOrOptions: ChartController | ChartControllerOptions = {}): UseChartEditorResult {\n const own = useRef<ChartController | null>(null);\n let controller: ChartController;\n if (controllerOrOptions instanceof ChartController) controller = controllerOrOptions;\n else {\n if (!own.current) own.current = new ChartController(controllerOrOptions);\n controller = own.current;\n }\n const state = useChartState(controller);\n const actions = useMemo(\n () => ({\n update: (patch: ChartSpecPatch) => controller.update(patch),\n setType: (type: ChartType) => controller.setType(type),\n setValue: (seriesId: string, index: number, value: unknown) => controller.setValue(seriesId, index, value),\n select: (selection: ChartSelection | null) => controller.select(selection),\n undo: () => void controller.undo(),\n redo: () => void controller.redo(),\n }),\n [controller],\n );\n return { controller, state, spec: state.spec, selection: state.selection, ...actions };\n}\n\n/** Anything with `register(specs) → unregister` (a `CommandRegistry`). */\nexport interface ChartCommandTarget {\n register(specs: any): () => void;\n}\n\n/**\n * Registers the controller's palette / agent commands (`chart.describe`, `chart.update`,\n * `chart.setValues`, …) in `registry` while mounted.\n */\nexport function useChartCommands(registry: ChartCommandTarget | null | undefined, controller: ChartController, options: ChartCommandOptions = {}): void {\n const { prefix, group, scope } = options;\n useEffect(() => {\n if (!registry) return;\n return registry.register(createChartCommands(controller, { prefix, group, scope }));\n }, [registry, controller, prefix, group, scope]);\n}\n","// Class names shared by the chart components (the same as the Svelte package's).\nexport const chartInputClass =\n 'h-7 w-full min-w-0 rounded-md border border-input bg-background px-2 text-xs text-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-primary disabled:cursor-not-allowed disabled:opacity-50';\nexport const chartButtonClass =\n 'inline-flex h-7 items-center justify-center gap-1 rounded-md border border-input bg-background px-2 text-xs text-foreground hover:bg-muted focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-primary disabled:pointer-events-none disabled:opacity-50';\nexport const chartIconButtonClass =\n 'inline-flex h-6 w-6 shrink-0 items-center justify-center rounded text-xs text-muted-foreground hover:bg-muted hover:text-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-primary disabled:pointer-events-none disabled:opacity-40';\nexport const chartSegmentClass = (active: boolean) =>\n `inline-flex h-7 flex-1 items-center justify-center rounded px-2 text-xs focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-primary ${\n active ? 'bg-background text-foreground shadow-sm' : 'text-muted-foreground hover:text-foreground'\n }`;\nexport const chartLabelClass = 'text-[11px] font-medium text-muted-foreground';\nexport const chartSectionClass = 'space-y-2 border-b border-border pb-3 last:border-b-0';\nexport const chartCellClass =\n 'h-7 w-full min-w-[4.5rem] bg-transparent px-2 text-right text-xs tabular-nums text-foreground focus-visible:bg-background focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-inset focus-visible:ring-primary';\n","import React, { useEffect, useMemo, useRef, useState } from 'react';\nimport {\n CSS_VARIABLE_CHART_THEME,\n chartClientToScene,\n chartTextBaseline,\n chartTextTransform,\n describeChartSelection,\n handleChartKey,\n layoutChart,\n startChartPointDrag,\n type ChartController,\n type ChartMark,\n type ChartPointDrag,\n type ChartTextMeasure,\n type ChartTheme,\n} from '@pixerate/editor/chart';\nimport { useChartState } from './useChartEditor';\n\nexport interface ChartCanvasProps {\n controller: ChartController;\n /** Scene width; with `responsive` this is only the fallback before the container is measured (default 640). */\n width?: number;\n /** Scene height in pixels (default 400). */\n height?: number;\n /** Follow the container's width (default `true`). */\n responsive?: boolean;\n /** Colours and type (default: shadcn-style CSS variables). */\n theme?: Partial<ChartTheme>;\n /** Click to select, drag bars and points, keyboard editing (default `true`). */\n editable?: boolean;\n /** Text width for layout (default: an estimate). */\n measureText?: ChartTextMeasure;\n emptyMessage?: string;\n className?: string;\n}\n\n/** SVG attributes for one mark (colours go in `style` so CSS variables work). */\nfunction renderMark(mark: ChartMark, fontFamily: string, interactive: boolean): React.ReactNode {\n const common = {\n 'data-role': mark.role,\n 'data-chart-key': mark.target ? mark.key : undefined,\n 'data-selected': mark.selected ? '' : undefined,\n opacity: mark.opacity,\n pointerEvents: mark.role === 'selection' || (!mark.target && mark.role !== 'background') ? ('none' as const) : undefined,\n cursor: interactive && mark.target && mark.role !== 'background' ? 'pointer' : undefined,\n };\n switch (mark.kind) {\n case 'rect':\n return <rect key={mark.key} {...common} x={mark.x} y={mark.y} width={mark.width} height={mark.height} rx={mark.radius} style={{ fill: mark.fill, stroke: mark.stroke, strokeWidth: mark.strokeWidth }} />;\n case 'path':\n return (\n <path\n key={mark.key}\n {...common}\n d={mark.d}\n strokeLinejoin=\"round\"\n strokeLinecap=\"round\"\n strokeDasharray={mark.dash}\n style={{ fill: mark.fill ?? 'none', stroke: mark.stroke, strokeWidth: mark.strokeWidth }}\n />\n );\n case 'circle':\n return <circle key={mark.key} {...common} cx={mark.cx} cy={mark.cy} r={mark.r} style={{ fill: mark.fill, stroke: mark.stroke, strokeWidth: mark.strokeWidth }} />;\n case 'line':\n return <line key={mark.key} {...common} x1={mark.x1} y1={mark.y1} x2={mark.x2} y2={mark.y2} strokeDasharray={mark.dash} style={{ stroke: mark.stroke, strokeWidth: mark.strokeWidth }} />;\n case 'text':\n return (\n <text\n key={mark.key}\n {...common}\n x={mark.x}\n y={mark.y}\n textAnchor={mark.anchor}\n dominantBaseline={chartTextBaseline(mark.baseline)}\n transform={chartTextTransform(mark)}\n style={{ fill: mark.fill, fontSize: mark.size, fontWeight: mark.weight, fontFamily, userSelect: 'none' }}\n >\n {mark.text}\n </text>\n );\n }\n}\n\n/**\n * Draws a chart controller's spec as SVG. Click a mark to select it, drag a bar or point to\n * change its value (one undo step), and with the chart focused use ← → ↑ ↓, Delete and\n * Escape (see `handleChartKey`).\n */\nexport function ChartCanvas({ controller, width = 640, height = 400, responsive = true, theme, editable = true, measureText, emptyMessage, className }: ChartCanvasProps) {\n const state = useChartState(controller);\n const wrapper = useRef<HTMLDivElement>(null);\n const svg = useRef<SVGSVGElement>(null);\n const drag = useRef<ChartPointDrag | null>(null);\n const [measured, setMeasured] = useState<number | null>(null);\n\n useEffect(() => {\n const el = wrapper.current;\n if (!responsive || !el || typeof ResizeObserver === 'undefined') return;\n const observer = new ResizeObserver(([entry]) => {\n const w = Math.round(entry.contentRect.width);\n if (w > 0) setMeasured(w);\n });\n observer.observe(el);\n return () => observer.disconnect();\n }, [responsive]);\n\n const sceneWidth = (responsive && measured) || width;\n const fullTheme = useMemo(() => ({ ...CSS_VARIABLE_CHART_THEME, ...theme }), [theme]);\n const scene = useMemo(\n () => layoutChart(state.spec, { width: sceneWidth, height, theme: fullTheme, selection: editable ? state.selection : null, measureText, emptyMessage }),\n [state.spec, state.selection, sceneWidth, height, fullTheme, editable, measureText, emptyMessage],\n );\n const byKey = useMemo(() => new Map(scene.marks.map((m) => [m.key, m])), [scene]);\n\n useEffect(() => () => drag.current?.end(), []);\n\n const scenePoint = (e: React.PointerEvent) => chartClientToScene(scene, svg.current!.getBoundingClientRect(), e.clientX, e.clientY);\n\n const onPointerDown = (e: React.PointerEvent<SVGSVGElement>) => {\n if (!editable || e.button !== 0) return;\n const key = (e.target as Element).closest?.('[data-chart-key]')?.getAttribute('data-chart-key');\n const target = key ? byKey.get(key)?.target : undefined;\n controller.select(target ?? null);\n drag.current = startChartPointDrag(controller, scene, target, scenePoint(e));\n if (drag.current) svg.current?.setPointerCapture?.(e.pointerId);\n };\n const onPointerMove = (e: React.PointerEvent<SVGSVGElement>) => {\n if (drag.current) drag.current.move(scenePoint(e));\n };\n const endDrag = () => {\n drag.current?.end();\n drag.current = null;\n };\n const onKeyDown = (e: React.KeyboardEvent<SVGSVGElement>) => {\n if (editable && handleChartKey(controller, scene, e)) e.preventDefault();\n };\n\n const label = state.spec.title || 'Chart';\n return (\n <div ref={wrapper} className={`w-full ${className ?? ''}`} data-chart-canvas=\"\">\n <svg\n ref={svg}\n width={sceneWidth}\n height={height}\n viewBox={`0 0 ${scene.width} ${scene.height}`}\n role=\"img\"\n aria-label={editable ? `${label}. ${describeChartSelection(controller, state.selection)}` : label}\n tabIndex={editable ? 0 : undefined}\n className=\"block max-w-full touch-none select-none rounded-md focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary\"\n onPointerDown={onPointerDown}\n onPointerMove={onPointerMove}\n onPointerUp={endDrag}\n onPointerCancel={endDrag}\n onKeyDown={onKeyDown}\n >\n {scene.marks.map((m) => renderMark(m, scene.theme.fontFamily, editable))}\n </svg>\n </div>\n );\n}\n","import React, { useEffect, useRef, useState } from 'react';\nimport { chartColorInputValue, chartSeriesColor, formatChartNumber, type ChartController } from '@pixerate/editor/chart';\nimport { useChartState } from './useChartEditor';\nimport { chartButtonClass, chartCellClass, chartIconButtonClass, chartInputClass } from './styles';\n\ntype CommitInputProps = {\n value: string;\n /** Called with the typed text. Return `false` to show the stored value again (a refused edit). */\n onCommit: (value: string) => boolean | void;\n} & Omit<React.InputHTMLAttributes<HTMLInputElement>, 'value' | 'onChange' | 'defaultValue'>;\n\n/** A text box that commits on blur or Enter and resets on Escape. Follows `value` unless the user is typing. */\nexport function ChartCommitInput({ value, onCommit, onKeyDown, onBlur, ...rest }: CommitInputProps) {\n const [draft, setDraft] = useState(value);\n const typing = useRef(false);\n useEffect(() => {\n if (!typing.current) setDraft(value);\n }, [value]);\n const commit = () => {\n if (!typing.current) return;\n typing.current = false;\n if (draft === value) return;\n if (onCommit(draft) === false) setDraft(value);\n };\n return (\n <input\n {...rest}\n value={draft}\n onChange={(e) => {\n typing.current = true;\n setDraft(e.currentTarget.value);\n }}\n onBlur={(e) => {\n onBlur?.(e);\n commit();\n }}\n onKeyDown={(e) => {\n onKeyDown?.(e);\n if (e.defaultPrevented) return;\n if (e.key === 'Enter') {\n e.preventDefault();\n commit();\n } else if (e.key === 'Escape') {\n typing.current = false;\n setDraft(value);\n }\n }}\n />\n );\n}\n\nexport interface ChartDataGridProps {\n controller: ChartController;\n /** Header of the category column (default \"Category\"). */\n categoryHeader?: string;\n /** Hide the add / delete buttons. */\n readOnly?: boolean;\n className?: string;\n}\n\n/**\n * The chart's data as an editable grid: categories down the side, one column per series\n * (name, colour, show / hide, delete). Cells take numbers as people type them (`1,200`,\n * `12%`, blank for a gap); pasting TSV or CSV fills and grows the grid from the cell.\n */\nexport function ChartDataGrid({ controller, categoryHeader = 'Category', readOnly = false, className }: ChartDataGridProps) {\n const { spec, selection } = useChartState(controller);\n const paste = (row: number, column: number) => (e: React.ClipboardEvent<HTMLInputElement>) => {\n const text = e.clipboardData?.getData('text/plain') ?? '';\n if (!/[\\t\\n]/.test(text.replace(/\\n$/, ''))) return;\n e.preventDefault();\n controller.pasteCells(row, column, text);\n };\n return (\n <div className={`overflow-auto rounded-md border border-border ${className ?? ''}`} data-chart-grid=\"\">\n <table className=\"w-full border-collapse text-xs\">\n <thead className=\"bg-muted/50\">\n <tr>\n <th className=\"border-b border-r border-border px-2 py-1 text-left font-medium text-muted-foreground\">{categoryHeader}</th>\n {spec.series.map((s, si) => {\n const color = chartSeriesColor(spec, si);\n const selected = selection?.kind === 'series' && selection.seriesId === s.id;\n return (\n <th key={s.id} data-series-id={s.id} className={`border-b border-r border-border px-1 py-1 font-medium ${selected ? 'bg-primary/10' : ''}`}>\n <div className=\"flex items-center gap-1\">\n <input\n type=\"color\"\n aria-label={`${s.name} colour`}\n value={chartColorInputValue(color)}\n disabled={readOnly}\n onPointerDown={() => controller.beginGesture(`color:${s.id}`)}\n onChange={(e) => controller.updateSeries(s.id, { color: e.currentTarget.value })}\n onBlur={() => controller.endGesture()}\n className=\"h-5 w-5 shrink-0 cursor-pointer rounded border-0 bg-transparent p-0\"\n />\n <ChartCommitInput\n value={s.name}\n aria-label=\"Series name\"\n onFocus={() => controller.select({ kind: 'series', seriesId: s.id })}\n onCommit={(name) => void controller.updateSeries(s.id, { name })}\n className={`${chartInputClass} h-6 min-w-[5rem] border-transparent bg-transparent font-medium ${s.hidden ? 'text-muted-foreground line-through' : ''}`}\n />\n {!readOnly && (\n <>\n <button\n type=\"button\"\n className={chartIconButtonClass}\n title={s.hidden ? 'Show series' : 'Hide series'}\n aria-label={s.hidden ? `Show ${s.name}` : `Hide ${s.name}`}\n aria-pressed={!s.hidden}\n data-action=\"toggle-series\"\n onClick={() => controller.toggleSeries(s.id)}\n >\n {s.hidden ? '○' : '●'}\n </button>\n <button type=\"button\" className={chartIconButtonClass} title=\"Delete series\" aria-label={`Delete ${s.name}`} data-action=\"remove-series\" onClick={() => controller.removeSeries(s.id)}>\n ×\n </button>\n </>\n )}\n </div>\n </th>\n );\n })}\n {!readOnly && (\n <th className=\"w-8 border-b border-border px-1\">\n <button type=\"button\" className={chartIconButtonClass} title=\"Add series\" aria-label=\"Add series\" data-action=\"add-series\" onClick={() => controller.addSeries()}>\n +\n </button>\n </th>\n )}\n </tr>\n </thead>\n <tbody>\n {spec.categories.map((category, i) => {\n const rowSelected = selection?.kind === 'category' && selection.index === i;\n return (\n <tr key={i} data-category-index={i} className={rowSelected ? 'bg-primary/10' : undefined}>\n <th className=\"border-b border-r border-border p-0 text-left font-normal\">\n <ChartCommitInput\n value={category}\n aria-label={`Category ${i + 1}`}\n onFocus={() => controller.select({ kind: 'category', index: i })}\n onPaste={paste(i, -1)}\n onCommit={(label) => void controller.renameCategory(i, label)}\n className={`${chartCellClass} text-left`}\n />\n </th>\n {spec.series.map((s) => {\n const value = s.values[i];\n const selected = selection?.kind === 'point' && selection.seriesId === s.id && selection.index === i;\n return (\n <td key={s.id} className={`border-b border-r border-border p-0 ${selected ? 'bg-primary/10' : ''}`}>\n <ChartCommitInput\n value={value === null || value === undefined ? '' : String(value)}\n inputMode=\"decimal\"\n aria-label={`${s.name}, ${category}`}\n title={value === null ? undefined : formatChartNumber(value, spec.yAxis.format)}\n data-cell={`${s.id}:${i}`}\n onFocus={() => controller.select({ kind: 'point', seriesId: s.id, index: i })}\n onPaste={paste(i, spec.series.indexOf(s))}\n onCommit={(text) => controller.setValue(s.id, i, text).ok}\n className={chartCellClass}\n />\n </td>\n );\n })}\n {!readOnly && (\n <td className=\"border-b border-border px-1\">\n <button type=\"button\" className={chartIconButtonClass} title=\"Delete category\" aria-label={`Delete ${category}`} data-action=\"remove-category\" onClick={() => controller.removeCategory(i)}>\n ×\n </button>\n </td>\n )}\n </tr>\n );\n })}\n </tbody>\n </table>\n {!readOnly && (\n <div className=\"p-1\">\n <button type=\"button\" className={`${chartButtonClass} h-6 border-dashed`} data-action=\"add-category\" onClick={() => controller.addCategory()}>\n + Add category\n </button>\n </div>\n )}\n </div>\n );\n}\n","import React, { useId } from 'react';\nimport {\n CHART_CURVES,\n CHART_LEGEND_POSITIONS,\n CHART_NUMBER_STYLES,\n CHART_SERIES_TYPES,\n CHART_STACKINGS,\n CHART_TYPE_LABELS,\n CHART_TYPES,\n chartColorInputValue,\n chartSeriesColor,\n chartSeriesType,\n isCartesianChart,\n type ChartAxis,\n type ChartController,\n type ChartNumberFormat,\n} from '@pixerate/editor/chart';\nimport { useChartState } from './useChartEditor';\nimport { ChartCommitInput } from './ChartDataGrid';\nimport { chartButtonClass, chartInputClass, chartLabelClass, chartSectionClass, chartSegmentClass } from './styles';\n\nexport interface ChartInspectorProps {\n controller: ChartController;\n /** Which sections to show (default: all that apply to the chart). */\n sections?: readonly ChartInspectorSection[];\n className?: string;\n}\n\nexport type ChartInspectorSection = 'type' | 'titles' | 'options' | 'legend' | 'axes' | 'series';\n\nconst cap = (s: string) => s.charAt(0).toUpperCase() + s.slice(1);\n\nfunction Field({ label, htmlFor, children }: { label: string; htmlFor?: string; children: React.ReactNode }) {\n return (\n <div className=\"flex items-center gap-2\">\n <label htmlFor={htmlFor} className={`${chartLabelClass} w-20 shrink-0`}>\n {label}\n </label>\n <div className=\"min-w-0 flex-1\">{children}</div>\n </div>\n );\n}\n\nfunction Toggle({ label, checked, onChange, name }: { label: string; checked: boolean; onChange: (checked: boolean) => void; name: string }) {\n return (\n <label className=\"flex cursor-pointer items-center gap-2 text-xs text-foreground\">\n <input type=\"checkbox\" className=\"h-3.5 w-3.5 accent-primary\" checked={checked} data-option={name} onChange={(e) => onChange(e.currentTarget.checked)} />\n {label}\n </label>\n );\n}\n\nfunction Select<T extends string>({ id, value, options, onChange, name, labels }: { id?: string; value: T; options: readonly T[]; onChange: (value: T) => void; name: string; labels?: Partial<Record<T, string>> }) {\n return (\n <select id={id} className={chartInputClass} value={value} data-option={name} onChange={(e) => onChange(e.currentTarget.value as T)}>\n {options.map((o) => (\n <option key={o} value={o}>\n {labels?.[o] ?? cap(o)}\n </option>\n ))}\n </select>\n );\n}\n\nfunction AxisSection({ controller, axis, value, idBase, horizontal }: { controller: ChartController; axis: 'x' | 'y'; value: ChartAxis; idBase: string; horizontal: boolean }) {\n const set = (patch: Partial<ChartAxis>) => controller.setAxis(axis, patch);\n const setFormat = (patch: Partial<ChartNumberFormat>) => set({ format: { ...value.format, ...patch } });\n const bound = (key: 'min' | 'max') => (\n <ChartCommitInput\n id={`${idBase}-${axis}-${key}`}\n value={value[key] === null ? '' : String(value[key])}\n placeholder=\"Auto\"\n inputMode=\"decimal\"\n data-option={`${axis}Axis.${key}`}\n className={chartInputClass}\n onCommit={(text) => set({ [key]: text.trim() === '' ? null : Number(text) }).ok}\n />\n );\n const name = axis === 'x' ? 'Category axis' : 'Value axis';\n return (\n <div className={chartSectionClass} data-section={`axis-${axis}`}>\n <div className=\"flex items-center justify-between\">\n <h4 className=\"text-xs font-semibold text-foreground\">\n {name}\n <span className=\"ml-1 font-normal text-muted-foreground\">({axis === 'x' ? (horizontal ? 'left' : 'bottom') : horizontal ? 'bottom' : 'left'})</span>\n </h4>\n <Toggle label=\"Show\" name={`${axis}Axis.show`} checked={value.show} onChange={(show) => set({ show })} />\n </div>\n <Field label=\"Title\" htmlFor={`${idBase}-${axis}-title`}>\n <ChartCommitInput id={`${idBase}-${axis}-title`} value={value.title} data-option={`${axis}Axis.title`} className={chartInputClass} onCommit={(title) => void set({ title })} />\n </Field>\n <Toggle label=\"Grid lines\" name={`${axis}Axis.gridlines`} checked={value.gridlines} onChange={(gridlines) => set({ gridlines })} />\n {axis === 'y' && (\n <>\n <Field label=\"Min / max\">\n <div className=\"flex gap-1\">\n {bound('min')}\n {bound('max')}\n </div>\n </Field>\n <Field label=\"Format\" htmlFor={`${idBase}-y-format`}>\n <div className=\"flex gap-1\">\n <Select id={`${idBase}-y-format`} name=\"yAxis.format.style\" value={value.format.style ?? 'number'} options={CHART_NUMBER_STYLES} onChange={(style) => setFormat({ style })} />\n <ChartCommitInput\n value={value.format.decimals === undefined ? '' : String(value.format.decimals)}\n placeholder=\"Auto\"\n aria-label=\"Decimals\"\n title=\"Decimals\"\n inputMode=\"numeric\"\n data-option=\"yAxis.format.decimals\"\n className={`${chartInputClass} w-14 shrink-0`}\n onCommit={(text) => {\n const format = { ...value.format };\n if (text.trim() === '') delete format.decimals;\n else format.decimals = Number(text);\n return set({ format }).ok;\n }}\n />\n </div>\n </Field>\n {value.format.style === 'currency' && (\n <Field label=\"Currency\" htmlFor={`${idBase}-y-currency`}>\n <ChartCommitInput id={`${idBase}-y-currency`} value={value.format.currency ?? 'USD'} data-option=\"yAxis.format.currency\" className={chartInputClass} onCommit={(currency) => void setFormat({ currency: currency.toUpperCase() })} />\n </Field>\n )}\n </>\n )}\n </div>\n );\n}\n\n/**\n * Settings for a chart controller: type, titles, stacking and line options, legend, both\n * axes and the selected series. Every change is one undo step.\n */\nexport function ChartInspector({ controller, sections, className }: ChartInspectorProps) {\n const { spec, selectedSeries } = useChartState(controller);\n const idBase = useId();\n const show = (section: ChartInspectorSection) => !sections || sections.includes(section);\n const cartesian = isCartesianChart(spec.type);\n const types = spec.series.map((s) => chartSeriesType(spec, s));\n const hasBars = cartesian && types.includes('bar');\n const hasLines = cartesian && types.some((t) => t === 'line' || t === 'area');\n const seriesIndex = selectedSeries ? spec.series.findIndex((s) => s.id === selectedSeries.id) : -1;\n\n return (\n <div className={`space-y-3 text-xs ${className ?? ''}`} data-chart-inspector=\"\">\n {show('type') && (\n <div className={chartSectionClass} data-section=\"type\">\n <div className=\"grid grid-cols-3 gap-0.5 rounded-md bg-muted p-0.5\" role=\"radiogroup\" aria-label=\"Chart type\">\n {CHART_TYPES.map((type) => (\n <button key={type} type=\"button\" role=\"radio\" aria-checked={spec.type === type} data-chart-type={type} className={chartSegmentClass(spec.type === type)} onClick={() => controller.setType(type)}>\n {CHART_TYPE_LABELS[type]}\n </button>\n ))}\n </div>\n </div>\n )}\n\n {show('titles') && (\n <div className={chartSectionClass} data-section=\"titles\">\n <Field label=\"Title\" htmlFor={`${idBase}-title`}>\n <ChartCommitInput id={`${idBase}-title`} value={spec.title} data-option=\"title\" className={chartInputClass} onCommit={(title) => void controller.setTitle(title)} />\n </Field>\n <Field label=\"Subtitle\" htmlFor={`${idBase}-subtitle`}>\n <ChartCommitInput id={`${idBase}-subtitle`} value={spec.subtitle} data-option=\"subtitle\" className={chartInputClass} onCommit={(subtitle) => void controller.setSubtitle(subtitle)} />\n </Field>\n </div>\n )}\n\n {show('options') && (\n <div className={chartSectionClass} data-section=\"options\">\n {cartesian && (\n <Field label=\"Stacking\" htmlFor={`${idBase}-stacking`}>\n <Select id={`${idBase}-stacking`} name=\"stacking\" value={spec.stacking} options={CHART_STACKINGS} labels={{ none: 'None', stacked: 'Stacked', percent: '100%' }} onChange={(stacking) => controller.update({ stacking })} />\n </Field>\n )}\n {hasBars && (\n <Field label=\"Bars\">\n <div className=\"flex gap-0.5 rounded-md bg-muted p-0.5\">\n {(['vertical', 'horizontal'] as const).map((o) => (\n <button key={o} type=\"button\" aria-pressed={spec.orientation === o} data-option={`orientation.${o}`} className={chartSegmentClass(spec.orientation === o)} onClick={() => controller.update({ orientation: o })}>\n {cap(o)}\n </button>\n ))}\n </div>\n </Field>\n )}\n {hasLines && (\n <Field label=\"Lines\" htmlFor={`${idBase}-curve`}>\n <Select id={`${idBase}-curve`} name=\"curve\" value={spec.curve} options={CHART_CURVES} onChange={(curve) => controller.update({ curve })} />\n </Field>\n )}\n {spec.type === 'donut' && (\n <Field label=\"Hole\" htmlFor={`${idBase}-hole`}>\n <input\n id={`${idBase}-hole`}\n type=\"range\"\n min={0}\n max={0.9}\n step={0.05}\n value={spec.innerRadius}\n data-option=\"innerRadius\"\n className=\"w-full accent-primary\"\n onPointerDown={() => controller.beginGesture('innerRadius')}\n onPointerUp={() => controller.endGesture()}\n onChange={(e) => controller.update({ innerRadius: Number(e.currentTarget.value) })}\n />\n </Field>\n )}\n <div className=\"flex flex-wrap gap-x-4 gap-y-1\">\n {hasLines && <Toggle label=\"Points\" name=\"points\" checked={spec.points} onChange={(points) => controller.update({ points })} />}\n <Toggle label=\"Data labels\" name=\"dataLabels\" checked={spec.dataLabels} onChange={(dataLabels) => controller.update({ dataLabels })} />\n </div>\n </div>\n )}\n\n {show('legend') && (\n <div className={chartSectionClass} data-section=\"legend\">\n <div className=\"flex items-center justify-between\">\n <h4 className=\"text-xs font-semibold text-foreground\">Legend</h4>\n <Toggle label=\"Show\" name=\"legend.show\" checked={spec.legend.show} onChange={(v) => controller.setLegend({ show: v })} />\n </div>\n {spec.legend.show && (\n <div className=\"flex gap-0.5 rounded-md bg-muted p-0.5\">\n {CHART_LEGEND_POSITIONS.map((p) => (\n <button key={p} type=\"button\" aria-pressed={spec.legend.position === p} data-option={`legend.${p}`} className={chartSegmentClass(spec.legend.position === p)} onClick={() => controller.setLegend({ position: p })}>\n {cap(p)}\n </button>\n ))}\n </div>\n )}\n </div>\n )}\n\n {show('axes') && cartesian && (\n <>\n <AxisSection controller={controller} axis=\"x\" value={spec.xAxis} idBase={idBase} horizontal={spec.orientation === 'horizontal'} />\n <AxisSection controller={controller} axis=\"y\" value={spec.yAxis} idBase={idBase} horizontal={spec.orientation === 'horizontal'} />\n </>\n )}\n\n {show('series') && selectedSeries && (\n <div className={chartSectionClass} data-section=\"series\" data-series-id={selectedSeries.id}>\n <h4 className=\"text-xs font-semibold text-foreground\">Series</h4>\n <Field label=\"Name\" htmlFor={`${idBase}-series-name`}>\n <ChartCommitInput id={`${idBase}-series-name`} value={selectedSeries.name} data-option=\"series.name\" className={chartInputClass} onCommit={(name) => void controller.updateSeries(selectedSeries.id, { name })} />\n </Field>\n <Field label=\"Colour\" htmlFor={`${idBase}-series-color`}>\n <div className=\"flex items-center gap-1\">\n <input\n id={`${idBase}-series-color`}\n type=\"color\"\n value={chartColorInputValue(chartSeriesColor(spec, seriesIndex))}\n data-option=\"series.color\"\n className=\"h-7 w-9 shrink-0 cursor-pointer rounded border border-input bg-background p-0.5\"\n onPointerDown={() => controller.beginGesture(`color:${selectedSeries.id}`)}\n onBlur={() => controller.endGesture()}\n onChange={(e) => controller.updateSeries(selectedSeries.id, { color: e.currentTarget.value })}\n />\n {selectedSeries.color && (\n <button type=\"button\" className={chartButtonClass} data-action=\"reset-color\" onClick={() => controller.updateSeries(selectedSeries.id, { color: null })}>\n Palette\n </button>\n )}\n </div>\n </Field>\n {cartesian && (\n <Field label=\"Draw as\" htmlFor={`${idBase}-series-type`}>\n <select\n id={`${idBase}-series-type`}\n className={chartInputClass}\n value={selectedSeries.type ?? ''}\n data-option=\"series.type\"\n onChange={(e) => controller.updateSeries(selectedSeries.id, { type: (e.currentTarget.value || null) as any })}\n >\n <option value=\"\">Chart type</option>\n {CHART_SERIES_TYPES.map((t) => (\n <option key={t} value={t}>\n {CHART_TYPE_LABELS[t]}\n </option>\n ))}\n </select>\n </Field>\n )}\n <div className=\"flex flex-wrap items-center gap-1\">\n <Toggle label=\"Hidden\" name=\"series.hidden\" checked={!!selectedSeries.hidden} onChange={(hidden) => controller.updateSeries(selectedSeries.id, { hidden })} />\n <span className=\"flex-1\" />\n <button type=\"button\" className={chartButtonClass} disabled={seriesIndex <= 0} aria-label=\"Move series earlier\" data-action=\"series-up\" onClick={() => controller.moveSeries(selectedSeries.id, seriesIndex - 1)}>\n ↑\n </button>\n <button type=\"button\" className={chartButtonClass} disabled={seriesIndex >= spec.series.length - 1} aria-label=\"Move series later\" data-action=\"series-down\" onClick={() => controller.moveSeries(selectedSeries.id, seriesIndex + 1)}>\n ↓\n </button>\n <button type=\"button\" className={`${chartButtonClass} text-destructive`} data-action=\"series-delete\" onClick={() => controller.removeSeries(selectedSeries.id)}>\n Delete\n </button>\n </div>\n </div>\n )}\n </div>\n );\n}\n","import React from 'react';\nimport { describeChartSelection, type ChartController } from '@pixerate/editor/chart';\nimport { ChartCanvas, type ChartCanvasProps } from './ChartCanvas';\nimport { ChartDataGrid } from './ChartDataGrid';\nimport { ChartInspector } from './ChartInspector';\nimport { useChartState } from './useChartEditor';\nimport { chartButtonClass } from './styles';\n\nexport interface ChartEditorProps {\n controller: ChartController;\n /** The settings sidebar (default `true`). */\n showInspector?: boolean;\n /** The data grid under the chart (default `true`). */\n showDataGrid?: boolean;\n /** Undo / redo and the selection readout (default `true`). */\n showToolbar?: boolean;\n /** Chart height in pixels (default 380). */\n height?: number;\n canvasProps?: Omit<ChartCanvasProps, 'controller' | 'height'>;\n className?: string;\n}\n\n/** Toolbar, chart, settings sidebar and data grid for a `ChartController`. */\nexport function ChartEditor({ controller, showInspector = true, showDataGrid = true, showToolbar = true, height = 380, canvasProps, className }: ChartEditorProps) {\n const state = useChartState(controller);\n return (\n <div className={`flex flex-col gap-2 ${className ?? ''}`} data-chart-editor=\"\">\n {showToolbar && (\n <div className=\"flex items-center gap-1\" data-chart-toolbar=\"\">\n <button type=\"button\" className={chartButtonClass} disabled={!state.canUndo} title={state.undoLabel ? `Undo ${state.undoLabel}` : 'Undo'} data-action=\"undo\" onClick={() => controller.undo()}>\n Undo\n </button>\n <button type=\"button\" className={chartButtonClass} disabled={!state.canRedo} title={state.redoLabel ? `Redo ${state.redoLabel}` : 'Redo'} data-action=\"redo\" onClick={() => controller.redo()}>\n Redo\n </button>\n <span className=\"ml-2 truncate text-xs text-muted-foreground\" data-chart-selection=\"\" aria-live=\"polite\">\n {describeChartSelection(controller, state.selection)}\n </span>\n </div>\n )}\n {state.issues.length > 0 && (\n <p role=\"alert\" className=\"rounded-md border border-destructive/40 bg-destructive/10 px-2 py-1 text-xs text-destructive\" data-chart-issues=\"\">\n {state.issues.map((i) => i.message).join(' ')}\n </p>\n )}\n <div className=\"flex min-h-0 flex-col gap-2 md:flex-row\">\n <div className=\"min-w-0 flex-1 rounded-md border border-border bg-background p-1\">\n <ChartCanvas controller={controller} height={height} {...canvasProps} />\n </div>\n {showInspector && <ChartInspector controller={controller} className=\"w-full shrink-0 overflow-y-auto rounded-md border border-border p-3 md:w-64\" />}\n </div>\n {showDataGrid && <ChartDataGrid controller={controller} />}\n </div>\n );\n}\n"],"mappings":";AAAA,SAAS,WAAW,SAAS,QAAQ,4BAA4B;AACjE;AAAA,EACE;AAAA,EACA;AAAA,OAQK;AAGA,SAAS,mBAAmB,UAAkC,CAAC,GAAoB;AACxF,QAAM,MAAM,OAA+B,IAAI;AAC/C,MAAI,CAAC,IAAI,QAAS,KAAI,UAAU,IAAI,gBAAgB,OAAO;AAC3D,SAAO,IAAI;AACb;AAGO,SAAS,cAAc,YAAyC;AACrE,SAAO,qBAAqB,WAAW,WAAW,WAAW,UAAU,WAAW,QAAQ;AAC5F;AAmBO,SAAS,eAAe,sBAAgE,CAAC,GAAyB;AACvH,QAAM,MAAM,OAA+B,IAAI;AAC/C,MAAI;AACJ,MAAI,+BAA+B,gBAAiB,cAAa;AAAA,OAC5D;AACH,QAAI,CAAC,IAAI,QAAS,KAAI,UAAU,IAAI,gBAAgB,mBAAmB;AACvE,iBAAa,IAAI;AAAA,EACnB;AACA,QAAM,QAAQ,cAAc,UAAU;AACtC,QAAM,UAAU;AAAA,IACd,OAAO;AAAA,MACL,QAAQ,CAAC,UAA0B,WAAW,OAAO,KAAK;AAAA,MAC1D,SAAS,CAAC,SAAoB,WAAW,QAAQ,IAAI;AAAA,MACrD,UAAU,CAAC,UAAkB,OAAe,UAAmB,WAAW,SAAS,UAAU,OAAO,KAAK;AAAA,MACzG,QAAQ,CAAC,cAAqC,WAAW,OAAO,SAAS;AAAA,MACzE,MAAM,MAAM,KAAK,WAAW,KAAK;AAAA,MACjC,MAAM,MAAM,KAAK,WAAW,KAAK;AAAA,IACnC;AAAA,IACA,CAAC,UAAU;AAAA,EACb;AACA,SAAO,EAAE,YAAY,OAAO,MAAM,MAAM,MAAM,WAAW,MAAM,WAAW,GAAG,QAAQ;AACvF;AAWO,SAAS,iBAAiB,UAAiD,YAA6B,UAA+B,CAAC,GAAS;AACtJ,QAAM,EAAE,QAAQ,OAAO,MAAM,IAAI;AACjC,YAAU,MAAM;AACd,QAAI,CAAC,SAAU;AACf,WAAO,SAAS,SAAS,oBAAoB,YAAY,EAAE,QAAQ,OAAO,MAAM,CAAC,CAAC;AAAA,EACpF,GAAG,CAAC,UAAU,YAAY,QAAQ,OAAO,KAAK,CAAC;AACjD;;;AC/EO,IAAM,kBACX;AACK,IAAM,mBACX;AACK,IAAM,uBACX;AACK,IAAM,oBAAoB,CAAC,WAChC,sJACE,SAAS,4CAA4C,6CACvD;AACK,IAAM,kBAAkB;AACxB,IAAM,oBAAoB;AAC1B,IAAM,iBACX;;;ACdF,SAAgB,aAAAA,YAAW,WAAAC,UAAS,UAAAC,SAAQ,gBAAgB;AAC5D;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OAMK;AAiCM;AAXb,SAAS,WAAW,MAAiB,YAAoB,aAAuC;AAC9F,QAAM,SAAS;AAAA,IACb,aAAa,KAAK;AAAA,IAClB,kBAAkB,KAAK,SAAS,KAAK,MAAM;AAAA,IAC3C,iBAAiB,KAAK,WAAW,KAAK;AAAA,IACtC,SAAS,KAAK;AAAA,IACd,eAAe,KAAK,SAAS,eAAgB,CAAC,KAAK,UAAU,KAAK,SAAS,eAAiB,SAAmB;AAAA,IAC/G,QAAQ,eAAe,KAAK,UAAU,KAAK,SAAS,eAAe,YAAY;AAAA,EACjF;AACA,UAAQ,KAAK,MAAM;AAAA,IACjB,KAAK;AACH,aAAO,oBAAC,UAAqB,GAAG,QAAQ,GAAG,KAAK,GAAG,GAAG,KAAK,GAAG,OAAO,KAAK,OAAO,QAAQ,KAAK,QAAQ,IAAI,KAAK,QAAQ,OAAO,EAAE,MAAM,KAAK,MAAM,QAAQ,KAAK,QAAQ,aAAa,KAAK,YAAY,KAAlL,KAAK,GAAgL;AAAA,IACzM,KAAK;AACH,aACE;AAAA,QAAC;AAAA;AAAA,UAEE,GAAG;AAAA,UACJ,GAAG,KAAK;AAAA,UACR,gBAAe;AAAA,UACf,eAAc;AAAA,UACd,iBAAiB,KAAK;AAAA,UACtB,OAAO,EAAE,MAAM,KAAK,QAAQ,QAAQ,QAAQ,KAAK,QAAQ,aAAa,KAAK,YAAY;AAAA;AAAA,QANlF,KAAK;AAAA,MAOZ;AAAA,IAEJ,KAAK;AACH,aAAO,oBAAC,YAAuB,GAAG,QAAQ,IAAI,KAAK,IAAI,IAAI,KAAK,IAAI,GAAG,KAAK,GAAG,OAAO,EAAE,MAAM,KAAK,MAAM,QAAQ,KAAK,QAAQ,aAAa,KAAK,YAAY,KAAxI,KAAK,GAAsI;AAAA,IACjK,KAAK;AACH,aAAO,oBAAC,UAAqB,GAAG,QAAQ,IAAI,KAAK,IAAI,IAAI,KAAK,IAAI,IAAI,KAAK,IAAI,IAAI,KAAK,IAAI,iBAAiB,KAAK,MAAM,OAAO,EAAE,QAAQ,KAAK,QAAQ,aAAa,KAAK,YAAY,KAAlK,KAAK,GAAgK;AAAA,IACzL,KAAK;AACH,aACE;AAAA,QAAC;AAAA;AAAA,UAEE,GAAG;AAAA,UACJ,GAAG,KAAK;AAAA,UACR,GAAG,KAAK;AAAA,UACR,YAAY,KAAK;AAAA,UACjB,kBAAkB,kBAAkB,KAAK,QAAQ;AAAA,UACjD,WAAW,mBAAmB,IAAI;AAAA,UAClC,OAAO,EAAE,MAAM,KAAK,MAAM,UAAU,KAAK,MAAM,YAAY,KAAK,QAAQ,YAAY,YAAY,OAAO;AAAA,UAEtG,eAAK;AAAA;AAAA,QATD,KAAK;AAAA,MAUZ;AAAA,EAEN;AACF;AAOO,SAAS,YAAY,EAAE,YAAY,QAAQ,KAAK,SAAS,KAAK,aAAa,MAAM,OAAO,WAAW,MAAM,aAAa,cAAc,UAAU,GAAqB;AACxK,QAAM,QAAQ,cAAc,UAAU;AACtC,QAAM,UAAUC,QAAuB,IAAI;AAC3C,QAAM,MAAMA,QAAsB,IAAI;AACtC,QAAM,OAAOA,QAA8B,IAAI;AAC/C,QAAM,CAAC,UAAU,WAAW,IAAI,SAAwB,IAAI;AAE5D,EAAAC,WAAU,MAAM;AACd,UAAM,KAAK,QAAQ;AACnB,QAAI,CAAC,cAAc,CAAC,MAAM,OAAO,mBAAmB,YAAa;AACjE,UAAM,WAAW,IAAI,eAAe,CAAC,CAAC,KAAK,MAAM;AAC/C,YAAM,IAAI,KAAK,MAAM,MAAM,YAAY,KAAK;AAC5C,UAAI,IAAI,EAAG,aAAY,CAAC;AAAA,IAC1B,CAAC;AACD,aAAS,QAAQ,EAAE;AACnB,WAAO,MAAM,SAAS,WAAW;AAAA,EACnC,GAAG,CAAC,UAAU,CAAC;AAEf,QAAM,aAAc,cAAc,YAAa;AAC/C,QAAM,YAAYC,SAAQ,OAAO,EAAE,GAAG,0BAA0B,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC;AACpF,QAAM,QAAQA;AAAA,IACZ,MAAM,YAAY,MAAM,MAAM,EAAE,OAAO,YAAY,QAAQ,OAAO,WAAW,WAAW,WAAW,MAAM,YAAY,MAAM,aAAa,aAAa,CAAC;AAAA,IACtJ,CAAC,MAAM,MAAM,MAAM,WAAW,YAAY,QAAQ,WAAW,UAAU,aAAa,YAAY;AAAA,EAClG;AACA,QAAM,QAAQA,SAAQ,MAAM,IAAI,IAAI,MAAM,MAAM,IAAI,CAAC,MAAM,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC;AAEhF,EAAAD,WAAU,MAAM,MAAM,KAAK,SAAS,IAAI,GAAG,CAAC,CAAC;AAE7C,QAAM,aAAa,CAAC,MAA0B,mBAAmB,OAAO,IAAI,QAAS,sBAAsB,GAAG,EAAE,SAAS,EAAE,OAAO;AAElI,QAAM,gBAAgB,CAAC,MAAyC;AAC9D,QAAI,CAAC,YAAY,EAAE,WAAW,EAAG;AACjC,UAAM,MAAO,EAAE,OAAmB,UAAU,kBAAkB,GAAG,aAAa,gBAAgB;AAC9F,UAAM,SAAS,MAAM,MAAM,IAAI,GAAG,GAAG,SAAS;AAC9C,eAAW,OAAO,UAAU,IAAI;AAChC,SAAK,UAAU,oBAAoB,YAAY,OAAO,QAAQ,WAAW,CAAC,CAAC;AAC3E,QAAI,KAAK,QAAS,KAAI,SAAS,oBAAoB,EAAE,SAAS;AAAA,EAChE;AACA,QAAM,gBAAgB,CAAC,MAAyC;AAC9D,QAAI,KAAK,QAAS,MAAK,QAAQ,KAAK,WAAW,CAAC,CAAC;AAAA,EACnD;AACA,QAAM,UAAU,MAAM;AACpB,SAAK,SAAS,IAAI;AAClB,SAAK,UAAU;AAAA,EACjB;AACA,QAAM,YAAY,CAAC,MAA0C;AAC3D,QAAI,YAAY,eAAe,YAAY,OAAO,CAAC,EAAG,GAAE,eAAe;AAAA,EACzE;AAEA,QAAM,QAAQ,MAAM,KAAK,SAAS;AAClC,SACE,oBAAC,SAAI,KAAK,SAAS,WAAW,UAAU,aAAa,EAAE,IAAI,qBAAkB,IAC3E;AAAA,IAAC;AAAA;AAAA,MACC,KAAK;AAAA,MACL,OAAO;AAAA,MACP;AAAA,MACA,SAAS,OAAO,MAAM,KAAK,IAAI,MAAM,MAAM;AAAA,MAC3C,MAAK;AAAA,MACL,cAAY,WAAW,GAAG,KAAK,KAAK,uBAAuB,YAAY,MAAM,SAAS,CAAC,KAAK;AAAA,MAC5F,UAAU,WAAW,IAAI;AAAA,MACzB,WAAU;AAAA,MACV;AAAA,MACA;AAAA,MACA,aAAa;AAAA,MACb,iBAAiB;AAAA,MACjB;AAAA,MAEC,gBAAM,MAAM,IAAI,CAAC,MAAM,WAAW,GAAG,MAAM,MAAM,YAAY,QAAQ,CAAC;AAAA;AAAA,EACzE,GACF;AAEJ;;;AC/JA,SAAgB,aAAAE,YAAW,UAAAC,SAAQ,YAAAC,iBAAgB;AACnD,SAAS,sBAAsB,kBAAkB,yBAA+C;AAwB5F,SA8EkB,UA9ElB,OAAAC,MA8EkB,YA9ElB;AAbG,SAAS,iBAAiB,EAAE,OAAO,UAAU,WAAW,QAAQ,GAAG,KAAK,GAAqB;AAClG,QAAM,CAAC,OAAO,QAAQ,IAAIC,UAAS,KAAK;AACxC,QAAM,SAASC,QAAO,KAAK;AAC3B,EAAAC,WAAU,MAAM;AACd,QAAI,CAAC,OAAO,QAAS,UAAS,KAAK;AAAA,EACrC,GAAG,CAAC,KAAK,CAAC;AACV,QAAM,SAAS,MAAM;AACnB,QAAI,CAAC,OAAO,QAAS;AACrB,WAAO,UAAU;AACjB,QAAI,UAAU,MAAO;AACrB,QAAI,SAAS,KAAK,MAAM,MAAO,UAAS,KAAK;AAAA,EAC/C;AACA,SACE,gBAAAH;AAAA,IAAC;AAAA;AAAA,MACE,GAAG;AAAA,MACJ,OAAO;AAAA,MACP,UAAU,CAAC,MAAM;AACf,eAAO,UAAU;AACjB,iBAAS,EAAE,cAAc,KAAK;AAAA,MAChC;AAAA,MACA,QAAQ,CAAC,MAAM;AACb,iBAAS,CAAC;AACV,eAAO;AAAA,MACT;AAAA,MACA,WAAW,CAAC,MAAM;AAChB,oBAAY,CAAC;AACb,YAAI,EAAE,iBAAkB;AACxB,YAAI,EAAE,QAAQ,SAAS;AACrB,YAAE,eAAe;AACjB,iBAAO;AAAA,QACT,WAAW,EAAE,QAAQ,UAAU;AAC7B,iBAAO,UAAU;AACjB,mBAAS,KAAK;AAAA,QAChB;AAAA,MACF;AAAA;AAAA,EACF;AAEJ;AAgBO,SAAS,cAAc,EAAE,YAAY,iBAAiB,YAAY,WAAW,OAAO,UAAU,GAAuB;AAC1H,QAAM,EAAE,MAAM,UAAU,IAAI,cAAc,UAAU;AACpD,QAAM,QAAQ,CAAC,KAAa,WAAmB,CAAC,MAA8C;AAC5F,UAAM,OAAO,EAAE,eAAe,QAAQ,YAAY,KAAK;AACvD,QAAI,CAAC,SAAS,KAAK,KAAK,QAAQ,OAAO,EAAE,CAAC,EAAG;AAC7C,MAAE,eAAe;AACjB,eAAW,WAAW,KAAK,QAAQ,IAAI;AAAA,EACzC;AACA,SACE,qBAAC,SAAI,WAAW,iDAAiD,aAAa,EAAE,IAAI,mBAAgB,IAClG;AAAA,yBAAC,WAAM,WAAU,kCACf;AAAA,sBAAAA,KAAC,WAAM,WAAU,eACf,+BAAC,QACC;AAAA,wBAAAA,KAAC,QAAG,WAAU,yFAAyF,0BAAe;AAAA,QACrH,KAAK,OAAO,IAAI,CAAC,GAAG,OAAO;AAC1B,gBAAM,QAAQ,iBAAiB,MAAM,EAAE;AACvC,gBAAM,WAAW,WAAW,SAAS,YAAY,UAAU,aAAa,EAAE;AAC1E,iBACE,gBAAAA,KAAC,QAAc,kBAAgB,EAAE,IAAI,WAAW,yDAAyD,WAAW,kBAAkB,EAAE,IACtI,+BAAC,SAAI,WAAU,2BACb;AAAA,4BAAAA;AAAA,cAAC;AAAA;AAAA,gBACC,MAAK;AAAA,gBACL,cAAY,GAAG,EAAE,IAAI;AAAA,gBACrB,OAAO,qBAAqB,KAAK;AAAA,gBACjC,UAAU;AAAA,gBACV,eAAe,MAAM,WAAW,aAAa,SAAS,EAAE,EAAE,EAAE;AAAA,gBAC5D,UAAU,CAAC,MAAM,WAAW,aAAa,EAAE,IAAI,EAAE,OAAO,EAAE,cAAc,MAAM,CAAC;AAAA,gBAC/E,QAAQ,MAAM,WAAW,WAAW;AAAA,gBACpC,WAAU;AAAA;AAAA,YACZ;AAAA,YACA,gBAAAA;AAAA,cAAC;AAAA;AAAA,gBACC,OAAO,EAAE;AAAA,gBACT,cAAW;AAAA,gBACX,SAAS,MAAM,WAAW,OAAO,EAAE,MAAM,UAAU,UAAU,EAAE,GAAG,CAAC;AAAA,gBACnE,UAAU,CAAC,SAAS,KAAK,WAAW,aAAa,EAAE,IAAI,EAAE,KAAK,CAAC;AAAA,gBAC/D,WAAW,GAAG,eAAe,mEAAmE,EAAE,SAAS,uCAAuC,EAAE;AAAA;AAAA,YACtJ;AAAA,YACC,CAAC,YACA,iCACE;AAAA,8BAAAA;AAAA,gBAAC;AAAA;AAAA,kBACC,MAAK;AAAA,kBACL,WAAW;AAAA,kBACX,OAAO,EAAE,SAAS,gBAAgB;AAAA,kBAClC,cAAY,EAAE,SAAS,QAAQ,EAAE,IAAI,KAAK,QAAQ,EAAE,IAAI;AAAA,kBACxD,gBAAc,CAAC,EAAE;AAAA,kBACjB,eAAY;AAAA,kBACZ,SAAS,MAAM,WAAW,aAAa,EAAE,EAAE;AAAA,kBAE1C,YAAE,SAAS,WAAM;AAAA;AAAA,cACpB;AAAA,cACA,gBAAAA,KAAC,YAAO,MAAK,UAAS,WAAW,sBAAsB,OAAM,iBAAgB,cAAY,UAAU,EAAE,IAAI,IAAI,eAAY,iBAAgB,SAAS,MAAM,WAAW,aAAa,EAAE,EAAE,GAAG,kBAEvL;AAAA,eACF;AAAA,aAEJ,KArCO,EAAE,EAsCX;AAAA,QAEJ,CAAC;AAAA,QACA,CAAC,YACA,gBAAAA,KAAC,QAAG,WAAU,mCACZ,0BAAAA,KAAC,YAAO,MAAK,UAAS,WAAW,sBAAsB,OAAM,cAAa,cAAW,cAAa,eAAY,cAAa,SAAS,MAAM,WAAW,UAAU,GAAG,eAElK,GACF;AAAA,SAEJ,GACF;AAAA,MACA,gBAAAA,KAAC,WACE,eAAK,WAAW,IAAI,CAAC,UAAU,MAAM;AACpC,cAAM,cAAc,WAAW,SAAS,cAAc,UAAU,UAAU;AAC1E,eACE,qBAAC,QAAW,uBAAqB,GAAG,WAAW,cAAc,kBAAkB,QAC7E;AAAA,0BAAAA,KAAC,QAAG,WAAU,6DACZ,0BAAAA;AAAA,YAAC;AAAA;AAAA,cACC,OAAO;AAAA,cACP,cAAY,YAAY,IAAI,CAAC;AAAA,cAC7B,SAAS,MAAM,WAAW,OAAO,EAAE,MAAM,YAAY,OAAO,EAAE,CAAC;AAAA,cAC/D,SAAS,MAAM,GAAG,EAAE;AAAA,cACpB,UAAU,CAAC,UAAU,KAAK,WAAW,eAAe,GAAG,KAAK;AAAA,cAC5D,WAAW,GAAG,cAAc;AAAA;AAAA,UAC9B,GACF;AAAA,UACC,KAAK,OAAO,IAAI,CAAC,MAAM;AACtB,kBAAM,QAAQ,EAAE,OAAO,CAAC;AACxB,kBAAM,WAAW,WAAW,SAAS,WAAW,UAAU,aAAa,EAAE,MAAM,UAAU,UAAU;AACnG,mBACE,gBAAAA,KAAC,QAAc,WAAW,uCAAuC,WAAW,kBAAkB,EAAE,IAC9F,0BAAAA;AAAA,cAAC;AAAA;AAAA,gBACC,OAAO,UAAU,QAAQ,UAAU,SAAY,KAAK,OAAO,KAAK;AAAA,gBAChE,WAAU;AAAA,gBACV,cAAY,GAAG,EAAE,IAAI,KAAK,QAAQ;AAAA,gBAClC,OAAO,UAAU,OAAO,SAAY,kBAAkB,OAAO,KAAK,MAAM,MAAM;AAAA,gBAC9E,aAAW,GAAG,EAAE,EAAE,IAAI,CAAC;AAAA,gBACvB,SAAS,MAAM,WAAW,OAAO,EAAE,MAAM,SAAS,UAAU,EAAE,IAAI,OAAO,EAAE,CAAC;AAAA,gBAC5E,SAAS,MAAM,GAAG,KAAK,OAAO,QAAQ,CAAC,CAAC;AAAA,gBACxC,UAAU,CAAC,SAAS,WAAW,SAAS,EAAE,IAAI,GAAG,IAAI,EAAE;AAAA,gBACvD,WAAW;AAAA;AAAA,YACb,KAXO,EAAE,EAYX;AAAA,UAEJ,CAAC;AAAA,UACA,CAAC,YACA,gBAAAA,KAAC,QAAG,WAAU,+BACZ,0BAAAA,KAAC,YAAO,MAAK,UAAS,WAAW,sBAAsB,OAAM,mBAAkB,cAAY,UAAU,QAAQ,IAAI,eAAY,mBAAkB,SAAS,MAAM,WAAW,eAAe,CAAC,GAAG,kBAE5L,GACF;AAAA,aAnCK,CAqCT;AAAA,MAEJ,CAAC,GACH;AAAA,OACF;AAAA,IACC,CAAC,YACA,gBAAAA,KAAC,SAAI,WAAU,OACb,0BAAAA,KAAC,YAAO,MAAK,UAAS,WAAW,GAAG,gBAAgB,sBAAsB,eAAY,gBAAe,SAAS,MAAM,WAAW,YAAY,GAAG,4BAE9I,GACF;AAAA,KAEJ;AAEJ;;;AC5LA,SAAgB,aAAa;AAC7B;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,wBAAAI;AAAA,EACA,oBAAAC;AAAA,EACA;AAAA,EACA;AAAA,OAIK;AAkBH,SA2DI,YAAAC,WA1DF,OAAAC,MADF,QAAAC,aAAA;AAJJ,IAAM,MAAM,CAAC,MAAc,EAAE,OAAO,CAAC,EAAE,YAAY,IAAI,EAAE,MAAM,CAAC;AAEhE,SAAS,MAAM,EAAE,OAAO,SAAS,SAAS,GAAmE;AAC3G,SACE,gBAAAA,MAAC,SAAI,WAAU,2BACb;AAAA,oBAAAD,KAAC,WAAM,SAAkB,WAAW,GAAG,eAAe,kBACnD,iBACH;AAAA,IACA,gBAAAA,KAAC,SAAI,WAAU,kBAAkB,UAAS;AAAA,KAC5C;AAEJ;AAEA,SAAS,OAAO,EAAE,OAAO,SAAS,UAAU,KAAK,GAA4F;AAC3I,SACE,gBAAAC,MAAC,WAAM,WAAU,kEACf;AAAA,oBAAAD,KAAC,WAAM,MAAK,YAAW,WAAU,8BAA6B,SAAkB,eAAa,MAAM,UAAU,CAAC,MAAM,SAAS,EAAE,cAAc,OAAO,GAAG;AAAA,IACtJ;AAAA,KACH;AAEJ;AAEA,SAAS,OAAyB,EAAE,IAAI,OAAO,SAAS,UAAU,MAAM,OAAO,GAAsI;AACnN,SACE,gBAAAA,KAAC,YAAO,IAAQ,WAAW,iBAAiB,OAAc,eAAa,MAAM,UAAU,CAAC,MAAM,SAAS,EAAE,cAAc,KAAU,GAC9H,kBAAQ,IAAI,CAAC,MACZ,gBAAAA,KAAC,YAAe,OAAO,GACpB,mBAAS,CAAC,KAAK,IAAI,CAAC,KADV,CAEb,CACD,GACH;AAEJ;AAEA,SAAS,YAAY,EAAE,YAAY,MAAM,OAAO,QAAQ,WAAW,GAA4G;AAC7K,QAAM,MAAM,CAAC,UAA8B,WAAW,QAAQ,MAAM,KAAK;AACzE,QAAM,YAAY,CAAC,UAAsC,IAAI,EAAE,QAAQ,EAAE,GAAG,MAAM,QAAQ,GAAG,MAAM,EAAE,CAAC;AACtG,QAAM,QAAQ,CAAC,QACb,gBAAAA;AAAA,IAAC;AAAA;AAAA,MACC,IAAI,GAAG,MAAM,IAAI,IAAI,IAAI,GAAG;AAAA,MAC5B,OAAO,MAAM,GAAG,MAAM,OAAO,KAAK,OAAO,MAAM,GAAG,CAAC;AAAA,MACnD,aAAY;AAAA,MACZ,WAAU;AAAA,MACV,eAAa,GAAG,IAAI,QAAQ,GAAG;AAAA,MAC/B,WAAW;AAAA,MACX,UAAU,CAAC,SAAS,IAAI,EAAE,CAAC,GAAG,GAAG,KAAK,KAAK,MAAM,KAAK,OAAO,OAAO,IAAI,EAAE,CAAC,EAAE;AAAA;AAAA,EAC/E;AAEF,QAAM,OAAO,SAAS,MAAM,kBAAkB;AAC9C,SACE,gBAAAC,MAAC,SAAI,WAAW,mBAAmB,gBAAc,QAAQ,IAAI,IAC3D;AAAA,oBAAAA,MAAC,SAAI,WAAU,qCACb;AAAA,sBAAAA,MAAC,QAAG,WAAU,yCACX;AAAA;AAAA,QACD,gBAAAA,MAAC,UAAK,WAAU,0CAAyC;AAAA;AAAA,UAAE,SAAS,MAAO,aAAa,SAAS,WAAY,aAAa,WAAW;AAAA,UAAO;AAAA,WAAC;AAAA,SAC/I;AAAA,MACA,gBAAAD,KAAC,UAAO,OAAM,QAAO,MAAM,GAAG,IAAI,aAAa,SAAS,MAAM,MAAM,UAAU,CAAC,SAAS,IAAI,EAAE,KAAK,CAAC,GAAG;AAAA,OACzG;AAAA,IACA,gBAAAA,KAAC,SAAM,OAAM,SAAQ,SAAS,GAAG,MAAM,IAAI,IAAI,UAC7C,0BAAAA,KAAC,oBAAiB,IAAI,GAAG,MAAM,IAAI,IAAI,UAAU,OAAO,MAAM,OAAO,eAAa,GAAG,IAAI,cAAc,WAAW,iBAAiB,UAAU,CAAC,UAAU,KAAK,IAAI,EAAE,MAAM,CAAC,GAAG,GAC/K;AAAA,IACA,gBAAAA,KAAC,UAAO,OAAM,cAAa,MAAM,GAAG,IAAI,kBAAkB,SAAS,MAAM,WAAW,UAAU,CAAC,cAAc,IAAI,EAAE,UAAU,CAAC,GAAG;AAAA,IAChI,SAAS,OACR,gBAAAC,MAAAF,WAAA,EACE;AAAA,sBAAAC,KAAC,SAAM,OAAM,aACX,0BAAAC,MAAC,SAAI,WAAU,cACZ;AAAA,cAAM,KAAK;AAAA,QACX,MAAM,KAAK;AAAA,SACd,GACF;AAAA,MACA,gBAAAD,KAAC,SAAM,OAAM,UAAS,SAAS,GAAG,MAAM,aACtC,0BAAAC,MAAC,SAAI,WAAU,cACb;AAAA,wBAAAD,KAAC,UAAO,IAAI,GAAG,MAAM,aAAa,MAAK,sBAAqB,OAAO,MAAM,OAAO,SAAS,UAAU,SAAS,qBAAqB,UAAU,CAAC,UAAU,UAAU,EAAE,MAAM,CAAC,GAAG;AAAA,QAC5K,gBAAAA;AAAA,UAAC;AAAA;AAAA,YACC,OAAO,MAAM,OAAO,aAAa,SAAY,KAAK,OAAO,MAAM,OAAO,QAAQ;AAAA,YAC9E,aAAY;AAAA,YACZ,cAAW;AAAA,YACX,OAAM;AAAA,YACN,WAAU;AAAA,YACV,eAAY;AAAA,YACZ,WAAW,GAAG,eAAe;AAAA,YAC7B,UAAU,CAAC,SAAS;AAClB,oBAAM,SAAS,EAAE,GAAG,MAAM,OAAO;AACjC,kBAAI,KAAK,KAAK,MAAM,GAAI,QAAO,OAAO;AAAA,kBACjC,QAAO,WAAW,OAAO,IAAI;AAClC,qBAAO,IAAI,EAAE,OAAO,CAAC,EAAE;AAAA,YACzB;AAAA;AAAA,QACF;AAAA,SACF,GACF;AAAA,MACC,MAAM,OAAO,UAAU,cACtB,gBAAAA,KAAC,SAAM,OAAM,YAAW,SAAS,GAAG,MAAM,eACxC,0BAAAA,KAAC,oBAAiB,IAAI,GAAG,MAAM,eAAe,OAAO,MAAM,OAAO,YAAY,OAAO,eAAY,yBAAwB,WAAW,iBAAiB,UAAU,CAAC,aAAa,KAAK,UAAU,EAAE,UAAU,SAAS,YAAY,EAAE,CAAC,GAAG,GACrO;AAAA,OAEJ;AAAA,KAEJ;AAEJ;AAMO,SAAS,eAAe,EAAE,YAAY,UAAU,UAAU,GAAwB;AACvF,QAAM,EAAE,MAAM,eAAe,IAAI,cAAc,UAAU;AACzD,QAAM,SAAS,MAAM;AACrB,QAAM,OAAO,CAAC,YAAmC,CAAC,YAAY,SAAS,SAAS,OAAO;AACvF,QAAM,YAAY,iBAAiB,KAAK,IAAI;AAC5C,QAAM,QAAQ,KAAK,OAAO,IAAI,CAAC,MAAM,gBAAgB,MAAM,CAAC,CAAC;AAC7D,QAAM,UAAU,aAAa,MAAM,SAAS,KAAK;AACjD,QAAM,WAAW,aAAa,MAAM,KAAK,CAAC,MAAM,MAAM,UAAU,MAAM,MAAM;AAC5E,QAAM,cAAc,iBAAiB,KAAK,OAAO,UAAU,CAAC,MAAM,EAAE,OAAO,eAAe,EAAE,IAAI;AAEhG,SACE,gBAAAC,MAAC,SAAI,WAAW,qBAAqB,aAAa,EAAE,IAAI,wBAAqB,IAC1E;AAAA,SAAK,MAAM,KACV,gBAAAD,KAAC,SAAI,WAAW,mBAAmB,gBAAa,QAC9C,0BAAAA,KAAC,SAAI,WAAU,sDAAqD,MAAK,cAAa,cAAW,cAC9F,sBAAY,IAAI,CAAC,SAChB,gBAAAA,KAAC,YAAkB,MAAK,UAAS,MAAK,SAAQ,gBAAc,KAAK,SAAS,MAAM,mBAAiB,MAAM,WAAW,kBAAkB,KAAK,SAAS,IAAI,GAAG,SAAS,MAAM,WAAW,QAAQ,IAAI,GAC5L,4BAAkB,IAAI,KADZ,IAEb,CACD,GACH,GACF;AAAA,IAGD,KAAK,QAAQ,KACZ,gBAAAC,MAAC,SAAI,WAAW,mBAAmB,gBAAa,UAC9C;AAAA,sBAAAD,KAAC,SAAM,OAAM,SAAQ,SAAS,GAAG,MAAM,UACrC,0BAAAA,KAAC,oBAAiB,IAAI,GAAG,MAAM,UAAU,OAAO,KAAK,OAAO,eAAY,SAAQ,WAAW,iBAAiB,UAAU,CAAC,UAAU,KAAK,WAAW,SAAS,KAAK,GAAG,GACpK;AAAA,MACA,gBAAAA,KAAC,SAAM,OAAM,YAAW,SAAS,GAAG,MAAM,aACxC,0BAAAA,KAAC,oBAAiB,IAAI,GAAG,MAAM,aAAa,OAAO,KAAK,UAAU,eAAY,YAAW,WAAW,iBAAiB,UAAU,CAAC,aAAa,KAAK,WAAW,YAAY,QAAQ,GAAG,GACtL;AAAA,OACF;AAAA,IAGD,KAAK,SAAS,KACb,gBAAAC,MAAC,SAAI,WAAW,mBAAmB,gBAAa,WAC7C;AAAA,mBACC,gBAAAD,KAAC,SAAM,OAAM,YAAW,SAAS,GAAG,MAAM,aACxC,0BAAAA,KAAC,UAAO,IAAI,GAAG,MAAM,aAAa,MAAK,YAAW,OAAO,KAAK,UAAU,SAAS,iBAAiB,QAAQ,EAAE,MAAM,QAAQ,SAAS,WAAW,SAAS,OAAO,GAAG,UAAU,CAAC,aAAa,WAAW,OAAO,EAAE,SAAS,CAAC,GAAG,GAC5N;AAAA,MAED,WACC,gBAAAA,KAAC,SAAM,OAAM,QACX,0BAAAA,KAAC,SAAI,WAAU,0CACX,WAAC,YAAY,YAAY,EAAY,IAAI,CAAC,MAC1C,gBAAAA,KAAC,YAAe,MAAK,UAAS,gBAAc,KAAK,gBAAgB,GAAG,eAAa,eAAe,CAAC,IAAI,WAAW,kBAAkB,KAAK,gBAAgB,CAAC,GAAG,SAAS,MAAM,WAAW,OAAO,EAAE,aAAa,EAAE,CAAC,GAC3M,cAAI,CAAC,KADK,CAEb,CACD,GACH,GACF;AAAA,MAED,YACC,gBAAAA,KAAC,SAAM,OAAM,SAAQ,SAAS,GAAG,MAAM,UACrC,0BAAAA,KAAC,UAAO,IAAI,GAAG,MAAM,UAAU,MAAK,SAAQ,OAAO,KAAK,OAAO,SAAS,cAAc,UAAU,CAAC,UAAU,WAAW,OAAO,EAAE,MAAM,CAAC,GAAG,GAC3I;AAAA,MAED,KAAK,SAAS,WACb,gBAAAA,KAAC,SAAM,OAAM,QAAO,SAAS,GAAG,MAAM,SACpC,0BAAAA;AAAA,QAAC;AAAA;AAAA,UACC,IAAI,GAAG,MAAM;AAAA,UACb,MAAK;AAAA,UACL,KAAK;AAAA,UACL,KAAK;AAAA,UACL,MAAM;AAAA,UACN,OAAO,KAAK;AAAA,UACZ,eAAY;AAAA,UACZ,WAAU;AAAA,UACV,eAAe,MAAM,WAAW,aAAa,aAAa;AAAA,UAC1D,aAAa,MAAM,WAAW,WAAW;AAAA,UACzC,UAAU,CAAC,MAAM,WAAW,OAAO,EAAE,aAAa,OAAO,EAAE,cAAc,KAAK,EAAE,CAAC;AAAA;AAAA,MACnF,GACF;AAAA,MAEF,gBAAAC,MAAC,SAAI,WAAU,kCACZ;AAAA,oBAAY,gBAAAD,KAAC,UAAO,OAAM,UAAS,MAAK,UAAS,SAAS,KAAK,QAAQ,UAAU,CAAC,WAAW,WAAW,OAAO,EAAE,OAAO,CAAC,GAAG;AAAA,QAC7H,gBAAAA,KAAC,UAAO,OAAM,eAAc,MAAK,cAAa,SAAS,KAAK,YAAY,UAAU,CAAC,eAAe,WAAW,OAAO,EAAE,WAAW,CAAC,GAAG;AAAA,SACvI;AAAA,OACF;AAAA,IAGD,KAAK,QAAQ,KACZ,gBAAAC,MAAC,SAAI,WAAW,mBAAmB,gBAAa,UAC9C;AAAA,sBAAAA,MAAC,SAAI,WAAU,qCACb;AAAA,wBAAAD,KAAC,QAAG,WAAU,yCAAwC,oBAAM;AAAA,QAC5D,gBAAAA,KAAC,UAAO,OAAM,QAAO,MAAK,eAAc,SAAS,KAAK,OAAO,MAAM,UAAU,CAAC,MAAM,WAAW,UAAU,EAAE,MAAM,EAAE,CAAC,GAAG;AAAA,SACzH;AAAA,MACC,KAAK,OAAO,QACX,gBAAAA,KAAC,SAAI,WAAU,0CACZ,iCAAuB,IAAI,CAAC,MAC3B,gBAAAA,KAAC,YAAe,MAAK,UAAS,gBAAc,KAAK,OAAO,aAAa,GAAG,eAAa,UAAU,CAAC,IAAI,WAAW,kBAAkB,KAAK,OAAO,aAAa,CAAC,GAAG,SAAS,MAAM,WAAW,UAAU,EAAE,UAAU,EAAE,CAAC,GAC9M,cAAI,CAAC,KADK,CAEb,CACD,GACH;AAAA,OAEJ;AAAA,IAGD,KAAK,MAAM,KAAK,aACf,gBAAAC,MAAAF,WAAA,EACE;AAAA,sBAAAC,KAAC,eAAY,YAAwB,MAAK,KAAI,OAAO,KAAK,OAAO,QAAgB,YAAY,KAAK,gBAAgB,cAAc;AAAA,MAChI,gBAAAA,KAAC,eAAY,YAAwB,MAAK,KAAI,OAAO,KAAK,OAAO,QAAgB,YAAY,KAAK,gBAAgB,cAAc;AAAA,OAClI;AAAA,IAGD,KAAK,QAAQ,KAAK,kBACjB,gBAAAC,MAAC,SAAI,WAAW,mBAAmB,gBAAa,UAAS,kBAAgB,eAAe,IACtF;AAAA,sBAAAD,KAAC,QAAG,WAAU,yCAAwC,oBAAM;AAAA,MAC5D,gBAAAA,KAAC,SAAM,OAAM,QAAO,SAAS,GAAG,MAAM,gBACpC,0BAAAA,KAAC,oBAAiB,IAAI,GAAG,MAAM,gBAAgB,OAAO,eAAe,MAAM,eAAY,eAAc,WAAW,iBAAiB,UAAU,CAAC,SAAS,KAAK,WAAW,aAAa,eAAe,IAAI,EAAE,KAAK,CAAC,GAAG,GAClN;AAAA,MACA,gBAAAA,KAAC,SAAM,OAAM,UAAS,SAAS,GAAG,MAAM,iBACtC,0BAAAC,MAAC,SAAI,WAAU,2BACb;AAAA,wBAAAD;AAAA,UAAC;AAAA;AAAA,YACC,IAAI,GAAG,MAAM;AAAA,YACb,MAAK;AAAA,YACL,OAAOE,sBAAqBC,kBAAiB,MAAM,WAAW,CAAC;AAAA,YAC/D,eAAY;AAAA,YACZ,WAAU;AAAA,YACV,eAAe,MAAM,WAAW,aAAa,SAAS,eAAe,EAAE,EAAE;AAAA,YACzE,QAAQ,MAAM,WAAW,WAAW;AAAA,YACpC,UAAU,CAAC,MAAM,WAAW,aAAa,eAAe,IAAI,EAAE,OAAO,EAAE,cAAc,MAAM,CAAC;AAAA;AAAA,QAC9F;AAAA,QACC,eAAe,SACd,gBAAAH,KAAC,YAAO,MAAK,UAAS,WAAW,kBAAkB,eAAY,eAAc,SAAS,MAAM,WAAW,aAAa,eAAe,IAAI,EAAE,OAAO,KAAK,CAAC,GAAG,qBAEzJ;AAAA,SAEJ,GACF;AAAA,MACC,aACC,gBAAAA,KAAC,SAAM,OAAM,WAAU,SAAS,GAAG,MAAM,gBACvC,0BAAAC;AAAA,QAAC;AAAA;AAAA,UACC,IAAI,GAAG,MAAM;AAAA,UACb,WAAW;AAAA,UACX,OAAO,eAAe,QAAQ;AAAA,UAC9B,eAAY;AAAA,UACZ,UAAU,CAAC,MAAM,WAAW,aAAa,eAAe,IAAI,EAAE,MAAO,EAAE,cAAc,SAAS,KAAa,CAAC;AAAA,UAE5G;AAAA,4BAAAD,KAAC,YAAO,OAAM,IAAG,wBAAU;AAAA,YAC1B,mBAAmB,IAAI,CAAC,MACvB,gBAAAA,KAAC,YAAe,OAAO,GACpB,4BAAkB,CAAC,KADT,CAEb,CACD;AAAA;AAAA;AAAA,MACH,GACF;AAAA,MAEF,gBAAAC,MAAC,SAAI,WAAU,qCACb;AAAA,wBAAAD,KAAC,UAAO,OAAM,UAAS,MAAK,iBAAgB,SAAS,CAAC,CAAC,eAAe,QAAQ,UAAU,CAAC,WAAW,WAAW,aAAa,eAAe,IAAI,EAAE,OAAO,CAAC,GAAG;AAAA,QAC5J,gBAAAA,KAAC,UAAK,WAAU,UAAS;AAAA,QACzB,gBAAAA,KAAC,YAAO,MAAK,UAAS,WAAW,kBAAkB,UAAU,eAAe,GAAG,cAAW,uBAAsB,eAAY,aAAY,SAAS,MAAM,WAAW,WAAW,eAAe,IAAI,cAAc,CAAC,GAAG,oBAElN;AAAA,QACA,gBAAAA,KAAC,YAAO,MAAK,UAAS,WAAW,kBAAkB,UAAU,eAAe,KAAK,OAAO,SAAS,GAAG,cAAW,qBAAoB,eAAY,eAAc,SAAS,MAAM,WAAW,WAAW,eAAe,IAAI,cAAc,CAAC,GAAG,oBAEvO;AAAA,QACA,gBAAAA,KAAC,YAAO,MAAK,UAAS,WAAW,GAAG,gBAAgB,qBAAqB,eAAY,iBAAgB,SAAS,MAAM,WAAW,aAAa,eAAe,EAAE,GAAG,oBAEhK;AAAA,SACF;AAAA,OACF;AAAA,KAEJ;AAEJ;;;AC7SA,SAAS,0BAAAI,+BAAoD;AA2BrD,SACE,OAAAC,MADF,QAAAC,aAAA;AALD,SAAS,YAAY,EAAE,YAAY,gBAAgB,MAAM,eAAe,MAAM,cAAc,MAAM,SAAS,KAAK,aAAa,UAAU,GAAqB;AACjK,QAAM,QAAQ,cAAc,UAAU;AACtC,SACE,gBAAAA,MAAC,SAAI,WAAW,uBAAuB,aAAa,EAAE,IAAI,qBAAkB,IACzE;AAAA,mBACC,gBAAAA,MAAC,SAAI,WAAU,2BAA0B,sBAAmB,IAC1D;AAAA,sBAAAD,KAAC,YAAO,MAAK,UAAS,WAAW,kBAAkB,UAAU,CAAC,MAAM,SAAS,OAAO,MAAM,YAAY,QAAQ,MAAM,SAAS,KAAK,QAAQ,eAAY,QAAO,SAAS,MAAM,WAAW,KAAK,GAAG,kBAE/L;AAAA,MACA,gBAAAA,KAAC,YAAO,MAAK,UAAS,WAAW,kBAAkB,UAAU,CAAC,MAAM,SAAS,OAAO,MAAM,YAAY,QAAQ,MAAM,SAAS,KAAK,QAAQ,eAAY,QAAO,SAAS,MAAM,WAAW,KAAK,GAAG,kBAE/L;AAAA,MACA,gBAAAA,KAAC,UAAK,WAAU,+CAA8C,wBAAqB,IAAG,aAAU,UAC7F,UAAAE,wBAAuB,YAAY,MAAM,SAAS,GACrD;AAAA,OACF;AAAA,IAED,MAAM,OAAO,SAAS,KACrB,gBAAAF,KAAC,OAAE,MAAK,SAAQ,WAAU,gGAA+F,qBAAkB,IACxI,gBAAM,OAAO,IAAI,CAAC,MAAM,EAAE,OAAO,EAAE,KAAK,GAAG,GAC9C;AAAA,IAEF,gBAAAC,MAAC,SAAI,WAAU,2CACb;AAAA,sBAAAD,KAAC,SAAI,WAAU,oEACb,0BAAAA,KAAC,eAAY,YAAwB,QAAiB,GAAG,aAAa,GACxE;AAAA,MACC,iBAAiB,gBAAAA,KAAC,kBAAe,YAAwB,WAAU,+EAA8E;AAAA,OACpJ;AAAA,IACC,gBAAgB,gBAAAA,KAAC,iBAAc,YAAwB;AAAA,KAC1D;AAEJ;","names":["useEffect","useMemo","useRef","useRef","useEffect","useMemo","useEffect","useRef","useState","jsx","useState","useRef","useEffect","chartColorInputValue","chartSeriesColor","Fragment","jsx","jsxs","chartColorInputValue","chartSeriesColor","describeChartSelection","jsx","jsxs","describeChartSelection"]}
|
|
1
|
+
{"version":3,"sources":["../../src/chart/useChartEditor.ts","../../src/chart/styles.ts","../../src/chart/ChartCanvas.tsx","../../src/chart/ChartDataGrid.tsx","../../src/chart/ChartInspector.tsx","../../src/chart/ChartEditor.tsx"],"sourcesContent":["import { useEffect, useMemo, useRef, useSyncExternalStore } from 'react';\nimport {\n ChartController,\n createChartCommands,\n type ChartActionResult,\n type ChartCommandOptions,\n type ChartControllerOptions,\n type ChartSelection,\n type ChartSpecPatch,\n type ChartState,\n type ChartType,\n} from '@pixerate/editor/chart';\n\n/** A `ChartController` created once for the component's lifetime. */\nexport function useChartController(options: ChartControllerOptions = {}): ChartController {\n const ref = useRef<ChartController | null>(null);\n if (!ref.current) ref.current = new ChartController(options);\n return ref.current;\n}\n\n/** The controller's state (re-renders on every change). */\nexport function useChartState(controller: ChartController): ChartState {\n return useSyncExternalStore(controller.subscribe, controller.getState, controller.getState);\n}\n\nexport interface UseChartEditorResult {\n controller: ChartController;\n state: ChartState;\n spec: ChartState['spec'];\n selection: ChartSelection | null;\n update: (patch: ChartSpecPatch) => ChartActionResult;\n setType: (type: ChartType) => ChartActionResult;\n setValue: (seriesId: string, index: number, value: unknown) => ChartActionResult;\n select: (selection: ChartSelection | null) => void;\n undo: () => void;\n redo: () => void;\n}\n\n/**\n * Subscribes to a chart controller and exposes its state with bound actions. Pass options\n * instead of a controller to create one for the component's lifetime.\n */\nexport function useChartEditor(controllerOrOptions: ChartController | ChartControllerOptions = {}): UseChartEditorResult {\n const own = useRef<ChartController | null>(null);\n let controller: ChartController;\n if (controllerOrOptions instanceof ChartController) controller = controllerOrOptions;\n else {\n if (!own.current) own.current = new ChartController(controllerOrOptions);\n controller = own.current;\n }\n const state = useChartState(controller);\n const actions = useMemo(\n () => ({\n update: (patch: ChartSpecPatch) => controller.update(patch),\n setType: (type: ChartType) => controller.setType(type),\n setValue: (seriesId: string, index: number, value: unknown) => controller.setValue(seriesId, index, value),\n select: (selection: ChartSelection | null) => controller.select(selection),\n undo: () => void controller.undo(),\n redo: () => void controller.redo(),\n }),\n [controller],\n );\n return { controller, state, spec: state.spec, selection: state.selection, ...actions };\n}\n\n/** Anything with `register(specs) → unregister` (a `CommandRegistry`). */\nexport interface ChartCommandTarget {\n register(specs: any): () => void;\n}\n\n/**\n * Registers the controller's palette / agent commands (`chart.describe`, `chart.update`,\n * `chart.setValues`, …) in `registry` while mounted.\n */\nexport function useChartCommands(registry: ChartCommandTarget | null | undefined, controller: ChartController, options: ChartCommandOptions = {}): void {\n const { prefix, group, scope } = options;\n useEffect(() => {\n if (!registry) return;\n return registry.register(createChartCommands(controller, { prefix, group, scope }));\n }, [registry, controller, prefix, group, scope]);\n}\n","// Class names shared by the chart components (the same as the Svelte package's).\nexport const chartInputClass =\n 'h-7 w-full min-w-0 rounded-md border border-input bg-background px-2 text-xs text-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-primary disabled:cursor-not-allowed disabled:opacity-50';\nexport const chartButtonClass =\n 'inline-flex h-7 items-center justify-center gap-1 rounded-md border border-input bg-background px-2 text-xs text-foreground hover:bg-muted focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-primary disabled:pointer-events-none disabled:opacity-50';\nexport const chartIconButtonClass =\n 'inline-flex h-6 w-6 shrink-0 items-center justify-center rounded text-xs text-muted-foreground hover:bg-muted hover:text-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-primary disabled:pointer-events-none disabled:opacity-40';\nexport const chartSegmentClass = (active: boolean) =>\n `inline-flex h-7 flex-1 items-center justify-center rounded px-2 text-xs focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-primary ${\n active ? 'bg-background text-foreground shadow-sm' : 'text-muted-foreground hover:text-foreground'\n }`;\nexport const chartLabelClass = 'text-[11px] font-medium text-muted-foreground';\nexport const chartSectionClass = 'space-y-2 border-b border-border pb-3 last:border-b-0';\nexport const chartCellClass =\n 'h-7 w-full min-w-[4.5rem] bg-transparent px-2 text-right text-xs tabular-nums text-foreground focus-visible:bg-background focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-inset focus-visible:ring-primary';\n","import React, { useEffect, useMemo, useRef, useState } from 'react';\nimport {\n CSS_VARIABLE_CHART_THEME,\n chartClientToScene,\n chartTextBaseline,\n chartTextTransform,\n describeChartSelection,\n handleChartKey,\n layoutChart,\n startChartPointDrag,\n type ChartController,\n type ChartMark,\n type ChartPointDrag,\n type ChartTextMeasure,\n type ChartTheme,\n} from '@pixerate/editor/chart';\nimport { useChartState } from './useChartEditor';\n\nexport interface ChartCanvasProps {\n controller: ChartController;\n /** Scene width; with `responsive` this is only the fallback before the container is measured (default 640). */\n width?: number;\n /** Scene height in pixels (default 400). */\n height?: number;\n /** Follow the container's width (default `true`). */\n responsive?: boolean;\n /** Colours and type (default: shadcn-style CSS variables). */\n theme?: Partial<ChartTheme>;\n /** Click to select, drag bars and points, keyboard editing (default `true`). */\n editable?: boolean;\n /** Text width for layout (default: an estimate). */\n measureText?: ChartTextMeasure;\n emptyMessage?: string;\n className?: string;\n}\n\n/** SVG attributes for one mark (colours go in `style` so CSS variables work). */\nfunction renderMark(mark: ChartMark, fontFamily: string, interactive: boolean): React.ReactNode {\n const common = {\n 'data-role': mark.role,\n 'data-chart-key': mark.target ? mark.key : undefined,\n 'data-selected': mark.selected ? '' : undefined,\n opacity: mark.opacity,\n pointerEvents: mark.role === 'selection' || (!mark.target && mark.role !== 'background') ? ('none' as const) : undefined,\n cursor: interactive && mark.target && mark.role !== 'background' ? 'pointer' : undefined,\n };\n switch (mark.kind) {\n case 'rect':\n return <rect key={mark.key} {...common} x={mark.x} y={mark.y} width={mark.width} height={mark.height} rx={mark.radius} style={{ fill: mark.fill, stroke: mark.stroke, strokeWidth: mark.strokeWidth }} />;\n case 'path':\n return (\n <path\n key={mark.key}\n {...common}\n d={mark.d}\n strokeLinejoin=\"round\"\n strokeLinecap=\"round\"\n strokeDasharray={mark.dash}\n style={{ fill: mark.fill ?? 'none', stroke: mark.stroke, strokeWidth: mark.strokeWidth }}\n />\n );\n case 'circle':\n return <circle key={mark.key} {...common} cx={mark.cx} cy={mark.cy} r={mark.r} style={{ fill: mark.fill, stroke: mark.stroke, strokeWidth: mark.strokeWidth }} />;\n case 'line':\n return <line key={mark.key} {...common} x1={mark.x1} y1={mark.y1} x2={mark.x2} y2={mark.y2} strokeDasharray={mark.dash} style={{ stroke: mark.stroke, strokeWidth: mark.strokeWidth }} />;\n case 'text':\n return (\n <text\n key={mark.key}\n {...common}\n x={mark.x}\n y={mark.y}\n textAnchor={mark.anchor}\n dominantBaseline={chartTextBaseline(mark.baseline)}\n transform={chartTextTransform(mark)}\n style={{ fill: mark.fill, fontSize: mark.size, fontWeight: mark.weight, fontFamily, userSelect: 'none' }}\n >\n {mark.text}\n </text>\n );\n }\n}\n\n/**\n * Draws a chart controller's spec as SVG. Click a mark to select it, drag a bar or point to\n * change its value (one undo step), and with the chart focused use ← → ↑ ↓, Delete and\n * Escape (see `handleChartKey`).\n */\nexport function ChartCanvas({ controller, width = 640, height = 400, responsive = true, theme, editable = true, measureText, emptyMessage, className }: ChartCanvasProps) {\n const state = useChartState(controller);\n const wrapper = useRef<HTMLDivElement>(null);\n const svg = useRef<SVGSVGElement>(null);\n const drag = useRef<ChartPointDrag | null>(null);\n const [measured, setMeasured] = useState<number | null>(null);\n // Frozen while a point is dragged so the value axis does not rescale under the pointer.\n const [valueDomain, setValueDomain] = useState<ChartPointDrag['valueDomain'] | null>(null);\n\n useEffect(() => {\n const el = wrapper.current;\n if (!responsive || !el || typeof ResizeObserver === 'undefined') return;\n const observer = new ResizeObserver(([entry]) => {\n const w = Math.round(entry.contentRect.width);\n if (w > 0) setMeasured(w);\n });\n observer.observe(el);\n return () => observer.disconnect();\n }, [responsive]);\n\n const sceneWidth = (responsive && measured) || width;\n const fullTheme = useMemo(() => ({ ...CSS_VARIABLE_CHART_THEME, ...theme }), [theme]);\n const scene = useMemo(\n () => layoutChart(state.spec, { width: sceneWidth, height, theme: fullTheme, selection: editable ? state.selection : null, measureText, emptyMessage, valueDomain }),\n [state.spec, state.selection, sceneWidth, height, fullTheme, editable, measureText, emptyMessage, valueDomain],\n );\n const byKey = useMemo(() => new Map(scene.marks.map((m) => [m.key, m])), [scene]);\n\n useEffect(() => () => drag.current?.end(), []);\n\n const scenePoint = (e: React.PointerEvent) => chartClientToScene(scene, svg.current!.getBoundingClientRect(), e.clientX, e.clientY);\n\n const onPointerDown = (e: React.PointerEvent<SVGSVGElement>) => {\n if (!editable || e.button !== 0) return;\n const key = (e.target as Element).closest?.('[data-chart-key]')?.getAttribute('data-chart-key');\n const target = key ? byKey.get(key)?.target : undefined;\n controller.select(target ?? null);\n drag.current = startChartPointDrag(controller, scene, target, scenePoint(e));\n if (drag.current) {\n setValueDomain(drag.current.valueDomain);\n svg.current?.setPointerCapture?.(e.pointerId);\n }\n };\n const onPointerMove = (e: React.PointerEvent<SVGSVGElement>) => {\n if (drag.current) drag.current.move(scenePoint(e));\n };\n const endDrag = () => {\n drag.current?.end();\n drag.current = null;\n setValueDomain(null);\n };\n const onKeyDown = (e: React.KeyboardEvent<SVGSVGElement>) => {\n if (editable && handleChartKey(controller, scene, e)) e.preventDefault();\n };\n\n const label = state.spec.title || 'Chart';\n return (\n <div ref={wrapper} className={`w-full ${className ?? ''}`} data-chart-canvas=\"\">\n <svg\n ref={svg}\n width={sceneWidth}\n height={height}\n viewBox={`0 0 ${scene.width} ${scene.height}`}\n role=\"img\"\n aria-label={editable ? `${label}. ${describeChartSelection(controller, state.selection)}` : label}\n tabIndex={editable ? 0 : undefined}\n className=\"block max-w-full touch-none select-none rounded-md focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary\"\n onPointerDown={onPointerDown}\n onPointerMove={onPointerMove}\n onPointerUp={endDrag}\n onPointerCancel={endDrag}\n onKeyDown={onKeyDown}\n >\n {scene.marks.map((m) => renderMark(m, scene.theme.fontFamily, editable))}\n </svg>\n </div>\n );\n}\n","import React, { useEffect, useRef, useState } from 'react';\nimport { chartColorInputValue, chartSeriesColor, formatChartNumber, type ChartController } from '@pixerate/editor/chart';\nimport { useChartState } from './useChartEditor';\nimport { chartButtonClass, chartCellClass, chartIconButtonClass, chartInputClass } from './styles';\n\ntype CommitInputProps = {\n value: string;\n /** Called with the typed text. Return `false` to show the stored value again (a refused edit). */\n onCommit: (value: string) => boolean | void;\n} & Omit<React.InputHTMLAttributes<HTMLInputElement>, 'value' | 'onChange' | 'defaultValue'>;\n\n/** A text box that commits on blur or Enter and resets on Escape. Follows `value` unless the user is typing. */\nexport function ChartCommitInput({ value, onCommit, onKeyDown, onBlur, ...rest }: CommitInputProps) {\n const [draft, setDraft] = useState(value);\n const typing = useRef(false);\n useEffect(() => {\n if (!typing.current) setDraft(value);\n }, [value]);\n const commit = () => {\n if (!typing.current) return;\n typing.current = false;\n if (draft === value) return;\n if (onCommit(draft) === false) setDraft(value);\n };\n return (\n <input\n {...rest}\n value={draft}\n onChange={(e) => {\n typing.current = true;\n setDraft(e.currentTarget.value);\n }}\n onBlur={(e) => {\n onBlur?.(e);\n commit();\n }}\n onKeyDown={(e) => {\n onKeyDown?.(e);\n if (e.defaultPrevented) return;\n if (e.key === 'Enter') {\n e.preventDefault();\n commit();\n } else if (e.key === 'Escape') {\n typing.current = false;\n setDraft(value);\n }\n }}\n />\n );\n}\n\nexport interface ChartDataGridProps {\n controller: ChartController;\n /** Header of the category column (default \"Category\"). */\n categoryHeader?: string;\n /** Hide the add / delete buttons. */\n readOnly?: boolean;\n className?: string;\n}\n\n/**\n * The chart's data as an editable grid: categories down the side, one column per series\n * (name, colour, show / hide, delete). Cells take numbers as people type them (`1,200`,\n * `12%`, blank for a gap); pasting TSV or CSV fills and grows the grid from the cell.\n */\nexport function ChartDataGrid({ controller, categoryHeader = 'Category', readOnly = false, className }: ChartDataGridProps) {\n const { spec, selection } = useChartState(controller);\n const paste = (row: number, column: number) => (e: React.ClipboardEvent<HTMLInputElement>) => {\n const text = e.clipboardData?.getData('text/plain') ?? '';\n if (!/[\\t\\n]/.test(text.replace(/\\n$/, ''))) return;\n e.preventDefault();\n controller.pasteCells(row, column, text);\n };\n return (\n <div className={`overflow-auto rounded-md border border-border ${className ?? ''}`} data-chart-grid=\"\">\n <table className=\"w-full border-collapse text-xs\">\n <thead className=\"bg-muted/50\">\n <tr>\n <th className=\"border-b border-r border-border px-2 py-1 text-left font-medium text-muted-foreground\">{categoryHeader}</th>\n {spec.series.map((s, si) => {\n const color = chartSeriesColor(spec, si);\n const selected = selection?.kind === 'series' && selection.seriesId === s.id;\n return (\n <th key={s.id} data-series-id={s.id} className={`border-b border-r border-border px-1 py-1 font-medium ${selected ? 'bg-primary/10' : ''}`}>\n <div className=\"flex items-center gap-1\">\n <input\n type=\"color\"\n aria-label={`${s.name} colour`}\n value={chartColorInputValue(color)}\n disabled={readOnly}\n onPointerDown={() => controller.beginGesture(`color:${s.id}`)}\n onChange={(e) => controller.updateSeries(s.id, { color: e.currentTarget.value })}\n onBlur={() => controller.endGesture()}\n className=\"h-5 w-5 shrink-0 cursor-pointer rounded border-0 bg-transparent p-0\"\n />\n <ChartCommitInput\n value={s.name}\n aria-label=\"Series name\"\n onFocus={() => controller.select({ kind: 'series', seriesId: s.id })}\n onCommit={(name) => void controller.updateSeries(s.id, { name })}\n className={`${chartInputClass} h-6 min-w-[5rem] border-transparent bg-transparent font-medium ${s.hidden ? 'text-muted-foreground line-through' : ''}`}\n />\n {!readOnly && (\n <>\n <button\n type=\"button\"\n className={chartIconButtonClass}\n title={s.hidden ? 'Show series' : 'Hide series'}\n aria-label={s.hidden ? `Show ${s.name}` : `Hide ${s.name}`}\n aria-pressed={!s.hidden}\n data-action=\"toggle-series\"\n onClick={() => controller.toggleSeries(s.id)}\n >\n {s.hidden ? '○' : '●'}\n </button>\n <button type=\"button\" className={chartIconButtonClass} title=\"Delete series\" aria-label={`Delete ${s.name}`} data-action=\"remove-series\" onClick={() => controller.removeSeries(s.id)}>\n ×\n </button>\n </>\n )}\n </div>\n </th>\n );\n })}\n {!readOnly && (\n <th className=\"w-8 border-b border-border px-1\">\n <button type=\"button\" className={chartIconButtonClass} title=\"Add series\" aria-label=\"Add series\" data-action=\"add-series\" onClick={() => controller.addSeries()}>\n +\n </button>\n </th>\n )}\n </tr>\n </thead>\n <tbody>\n {spec.categories.map((category, i) => {\n const rowSelected = selection?.kind === 'category' && selection.index === i;\n return (\n <tr key={i} data-category-index={i} className={rowSelected ? 'bg-primary/10' : undefined}>\n <th className=\"border-b border-r border-border p-0 text-left font-normal\">\n <ChartCommitInput\n value={category}\n aria-label={`Category ${i + 1}`}\n onFocus={() => controller.select({ kind: 'category', index: i })}\n onPaste={paste(i, -1)}\n onCommit={(label) => void controller.renameCategory(i, label)}\n className={`${chartCellClass} text-left`}\n />\n </th>\n {spec.series.map((s) => {\n const value = s.values[i];\n const selected = selection?.kind === 'point' && selection.seriesId === s.id && selection.index === i;\n return (\n <td key={s.id} className={`border-b border-r border-border p-0 ${selected ? 'bg-primary/10' : ''}`}>\n <ChartCommitInput\n value={value === null || value === undefined ? '' : String(value)}\n inputMode=\"decimal\"\n aria-label={`${s.name}, ${category}`}\n title={value === null ? undefined : formatChartNumber(value, spec.yAxis.format)}\n data-cell={`${s.id}:${i}`}\n onFocus={() => controller.select({ kind: 'point', seriesId: s.id, index: i })}\n onPaste={paste(i, spec.series.indexOf(s))}\n onCommit={(text) => controller.setValue(s.id, i, text).ok}\n className={chartCellClass}\n />\n </td>\n );\n })}\n {!readOnly && (\n <td className=\"border-b border-border px-1\">\n <button type=\"button\" className={chartIconButtonClass} title=\"Delete category\" aria-label={`Delete ${category}`} data-action=\"remove-category\" onClick={() => controller.removeCategory(i)}>\n ×\n </button>\n </td>\n )}\n </tr>\n );\n })}\n </tbody>\n </table>\n {!readOnly && (\n <div className=\"p-1\">\n <button type=\"button\" className={`${chartButtonClass} h-6 border-dashed`} data-action=\"add-category\" onClick={() => controller.addCategory()}>\n + Add category\n </button>\n </div>\n )}\n </div>\n );\n}\n","import React, { useId } from 'react';\nimport {\n CHART_CURVES,\n CHART_LEGEND_POSITIONS,\n CHART_NUMBER_STYLES,\n CHART_SERIES_TYPES,\n CHART_STACKINGS,\n CHART_TYPE_LABELS,\n CHART_TYPES,\n chartColorInputValue,\n chartSeriesColor,\n chartSeriesType,\n isCartesianChart,\n type ChartAxis,\n type ChartController,\n type ChartNumberFormat,\n} from '@pixerate/editor/chart';\nimport { useChartState } from './useChartEditor';\nimport { ChartCommitInput } from './ChartDataGrid';\nimport { chartButtonClass, chartInputClass, chartLabelClass, chartSectionClass, chartSegmentClass } from './styles';\n\nexport interface ChartInspectorProps {\n controller: ChartController;\n /** Which sections to show (default: all that apply to the chart). */\n sections?: readonly ChartInspectorSection[];\n className?: string;\n}\n\nexport type ChartInspectorSection = 'type' | 'titles' | 'options' | 'legend' | 'axes' | 'series';\n\nconst cap = (s: string) => s.charAt(0).toUpperCase() + s.slice(1);\n\nfunction Field({ label, htmlFor, children }: { label: string; htmlFor?: string; children: React.ReactNode }) {\n return (\n <div className=\"flex items-center gap-2\">\n <label htmlFor={htmlFor} className={`${chartLabelClass} w-20 shrink-0`}>\n {label}\n </label>\n <div className=\"min-w-0 flex-1\">{children}</div>\n </div>\n );\n}\n\nfunction Toggle({ label, checked, onChange, name }: { label: string; checked: boolean; onChange: (checked: boolean) => void; name: string }) {\n return (\n <label className=\"flex cursor-pointer items-center gap-2 text-xs text-foreground\">\n <input type=\"checkbox\" className=\"h-3.5 w-3.5 accent-primary\" checked={checked} data-option={name} onChange={(e) => onChange(e.currentTarget.checked)} />\n {label}\n </label>\n );\n}\n\nfunction Select<T extends string>({ id, value, options, onChange, name, labels }: { id?: string; value: T; options: readonly T[]; onChange: (value: T) => void; name: string; labels?: Partial<Record<T, string>> }) {\n return (\n <select id={id} className={chartInputClass} value={value} data-option={name} onChange={(e) => onChange(e.currentTarget.value as T)}>\n {options.map((o) => (\n <option key={o} value={o}>\n {labels?.[o] ?? cap(o)}\n </option>\n ))}\n </select>\n );\n}\n\nfunction AxisSection({ controller, axis, value, idBase, horizontal }: { controller: ChartController; axis: 'x' | 'y'; value: ChartAxis; idBase: string; horizontal: boolean }) {\n const set = (patch: Partial<ChartAxis>) => controller.setAxis(axis, patch);\n const setFormat = (patch: Partial<ChartNumberFormat>) => set({ format: { ...value.format, ...patch } });\n const bound = (key: 'min' | 'max') => (\n <ChartCommitInput\n id={`${idBase}-${axis}-${key}`}\n value={value[key] === null ? '' : String(value[key])}\n placeholder=\"Auto\"\n inputMode=\"decimal\"\n data-option={`${axis}Axis.${key}`}\n className={chartInputClass}\n onCommit={(text) => set({ [key]: text.trim() === '' ? null : Number(text) }).ok}\n />\n );\n const name = axis === 'x' ? 'Category axis' : 'Value axis';\n return (\n <div className={chartSectionClass} data-section={`axis-${axis}`}>\n <div className=\"flex items-center justify-between\">\n <h4 className=\"text-xs font-semibold text-foreground\">\n {name}\n <span className=\"ml-1 font-normal text-muted-foreground\">({axis === 'x' ? (horizontal ? 'left' : 'bottom') : horizontal ? 'bottom' : 'left'})</span>\n </h4>\n <Toggle label=\"Show\" name={`${axis}Axis.show`} checked={value.show} onChange={(show) => set({ show })} />\n </div>\n <Field label=\"Title\" htmlFor={`${idBase}-${axis}-title`}>\n <ChartCommitInput id={`${idBase}-${axis}-title`} value={value.title} data-option={`${axis}Axis.title`} className={chartInputClass} onCommit={(title) => void set({ title })} />\n </Field>\n <Toggle label=\"Grid lines\" name={`${axis}Axis.gridlines`} checked={value.gridlines} onChange={(gridlines) => set({ gridlines })} />\n {axis === 'y' && (\n <>\n <Field label=\"Min / max\">\n <div className=\"flex gap-1\">\n {bound('min')}\n {bound('max')}\n </div>\n </Field>\n <Field label=\"Format\" htmlFor={`${idBase}-y-format`}>\n <div className=\"flex gap-1\">\n <Select id={`${idBase}-y-format`} name=\"yAxis.format.style\" value={value.format.style ?? 'number'} options={CHART_NUMBER_STYLES} onChange={(style) => setFormat({ style })} />\n <ChartCommitInput\n value={value.format.decimals === undefined ? '' : String(value.format.decimals)}\n placeholder=\"Auto\"\n aria-label=\"Decimals\"\n title=\"Decimals\"\n inputMode=\"numeric\"\n data-option=\"yAxis.format.decimals\"\n className={`${chartInputClass} w-14 shrink-0`}\n onCommit={(text) => {\n const format = { ...value.format };\n if (text.trim() === '') delete format.decimals;\n else format.decimals = Number(text);\n return set({ format }).ok;\n }}\n />\n </div>\n </Field>\n {value.format.style === 'currency' && (\n <Field label=\"Currency\" htmlFor={`${idBase}-y-currency`}>\n <ChartCommitInput id={`${idBase}-y-currency`} value={value.format.currency ?? 'USD'} data-option=\"yAxis.format.currency\" className={chartInputClass} onCommit={(currency) => void setFormat({ currency: currency.toUpperCase() })} />\n </Field>\n )}\n </>\n )}\n </div>\n );\n}\n\n/**\n * Settings for a chart controller: type, titles, stacking and line options, legend, both\n * axes and the selected series. Every change is one undo step.\n */\nexport function ChartInspector({ controller, sections, className }: ChartInspectorProps) {\n const { spec, selectedSeries } = useChartState(controller);\n const idBase = useId();\n const show = (section: ChartInspectorSection) => !sections || sections.includes(section);\n const cartesian = isCartesianChart(spec.type);\n const types = spec.series.map((s) => chartSeriesType(spec, s));\n const hasBars = cartesian && types.includes('bar');\n const hasLines = cartesian && types.some((t) => t === 'line' || t === 'area');\n const seriesIndex = selectedSeries ? spec.series.findIndex((s) => s.id === selectedSeries.id) : -1;\n\n return (\n <div className={`space-y-3 text-xs ${className ?? ''}`} data-chart-inspector=\"\">\n {show('type') && (\n <div className={chartSectionClass} data-section=\"type\">\n <div className=\"grid grid-cols-3 gap-0.5 rounded-md bg-muted p-0.5\" role=\"radiogroup\" aria-label=\"Chart type\">\n {CHART_TYPES.map((type) => (\n <button key={type} type=\"button\" role=\"radio\" aria-checked={spec.type === type} data-chart-type={type} className={chartSegmentClass(spec.type === type)} onClick={() => controller.setType(type)}>\n {CHART_TYPE_LABELS[type]}\n </button>\n ))}\n </div>\n </div>\n )}\n\n {show('titles') && (\n <div className={chartSectionClass} data-section=\"titles\">\n <Field label=\"Title\" htmlFor={`${idBase}-title`}>\n <ChartCommitInput id={`${idBase}-title`} value={spec.title} data-option=\"title\" className={chartInputClass} onCommit={(title) => void controller.setTitle(title)} />\n </Field>\n <Field label=\"Subtitle\" htmlFor={`${idBase}-subtitle`}>\n <ChartCommitInput id={`${idBase}-subtitle`} value={spec.subtitle} data-option=\"subtitle\" className={chartInputClass} onCommit={(subtitle) => void controller.setSubtitle(subtitle)} />\n </Field>\n </div>\n )}\n\n {show('options') && (\n <div className={chartSectionClass} data-section=\"options\">\n {cartesian && (\n <Field label=\"Stacking\" htmlFor={`${idBase}-stacking`}>\n <Select id={`${idBase}-stacking`} name=\"stacking\" value={spec.stacking} options={CHART_STACKINGS} labels={{ none: 'None', stacked: 'Stacked', percent: '100%' }} onChange={(stacking) => controller.update({ stacking })} />\n </Field>\n )}\n {hasBars && (\n <Field label=\"Bars\">\n <div className=\"flex gap-0.5 rounded-md bg-muted p-0.5\">\n {(['vertical', 'horizontal'] as const).map((o) => (\n <button key={o} type=\"button\" aria-pressed={spec.orientation === o} data-option={`orientation.${o}`} className={chartSegmentClass(spec.orientation === o)} onClick={() => controller.update({ orientation: o })}>\n {cap(o)}\n </button>\n ))}\n </div>\n </Field>\n )}\n {hasLines && (\n <Field label=\"Lines\" htmlFor={`${idBase}-curve`}>\n <Select id={`${idBase}-curve`} name=\"curve\" value={spec.curve} options={CHART_CURVES} onChange={(curve) => controller.update({ curve })} />\n </Field>\n )}\n {spec.type === 'donut' && (\n <Field label=\"Hole\" htmlFor={`${idBase}-hole`}>\n <input\n id={`${idBase}-hole`}\n type=\"range\"\n min={0}\n max={0.9}\n step={0.05}\n value={spec.innerRadius}\n data-option=\"innerRadius\"\n className=\"w-full accent-primary\"\n onPointerDown={() => controller.beginGesture('innerRadius')}\n onPointerUp={() => controller.endGesture()}\n onChange={(e) => controller.update({ innerRadius: Number(e.currentTarget.value) })}\n />\n </Field>\n )}\n <div className=\"flex flex-wrap gap-x-4 gap-y-1\">\n {hasLines && <Toggle label=\"Points\" name=\"points\" checked={spec.points} onChange={(points) => controller.update({ points })} />}\n <Toggle label=\"Data labels\" name=\"dataLabels\" checked={spec.dataLabels} onChange={(dataLabels) => controller.update({ dataLabels })} />\n </div>\n </div>\n )}\n\n {show('legend') && (\n <div className={chartSectionClass} data-section=\"legend\">\n <div className=\"flex items-center justify-between\">\n <h4 className=\"text-xs font-semibold text-foreground\">Legend</h4>\n <Toggle label=\"Show\" name=\"legend.show\" checked={spec.legend.show} onChange={(v) => controller.setLegend({ show: v })} />\n </div>\n {spec.legend.show && (\n <div className=\"flex gap-0.5 rounded-md bg-muted p-0.5\">\n {CHART_LEGEND_POSITIONS.map((p) => (\n <button key={p} type=\"button\" aria-pressed={spec.legend.position === p} data-option={`legend.${p}`} className={chartSegmentClass(spec.legend.position === p)} onClick={() => controller.setLegend({ position: p })}>\n {cap(p)}\n </button>\n ))}\n </div>\n )}\n </div>\n )}\n\n {show('axes') && cartesian && (\n <>\n <AxisSection controller={controller} axis=\"x\" value={spec.xAxis} idBase={idBase} horizontal={spec.orientation === 'horizontal'} />\n <AxisSection controller={controller} axis=\"y\" value={spec.yAxis} idBase={idBase} horizontal={spec.orientation === 'horizontal'} />\n </>\n )}\n\n {show('series') && selectedSeries && (\n <div className={chartSectionClass} data-section=\"series\" data-series-id={selectedSeries.id}>\n <h4 className=\"text-xs font-semibold text-foreground\">Series</h4>\n <Field label=\"Name\" htmlFor={`${idBase}-series-name`}>\n <ChartCommitInput id={`${idBase}-series-name`} value={selectedSeries.name} data-option=\"series.name\" className={chartInputClass} onCommit={(name) => void controller.updateSeries(selectedSeries.id, { name })} />\n </Field>\n <Field label=\"Colour\" htmlFor={`${idBase}-series-color`}>\n <div className=\"flex items-center gap-1\">\n <input\n id={`${idBase}-series-color`}\n type=\"color\"\n value={chartColorInputValue(chartSeriesColor(spec, seriesIndex))}\n data-option=\"series.color\"\n className=\"h-7 w-9 shrink-0 cursor-pointer rounded border border-input bg-background p-0.5\"\n onPointerDown={() => controller.beginGesture(`color:${selectedSeries.id}`)}\n onBlur={() => controller.endGesture()}\n onChange={(e) => controller.updateSeries(selectedSeries.id, { color: e.currentTarget.value })}\n />\n {selectedSeries.color && (\n <button type=\"button\" className={chartButtonClass} data-action=\"reset-color\" onClick={() => controller.updateSeries(selectedSeries.id, { color: null })}>\n Palette\n </button>\n )}\n </div>\n </Field>\n {cartesian && (\n <Field label=\"Draw as\" htmlFor={`${idBase}-series-type`}>\n <select\n id={`${idBase}-series-type`}\n className={chartInputClass}\n value={selectedSeries.type ?? ''}\n data-option=\"series.type\"\n onChange={(e) => controller.updateSeries(selectedSeries.id, { type: (e.currentTarget.value || null) as any })}\n >\n <option value=\"\">Chart type</option>\n {CHART_SERIES_TYPES.map((t) => (\n <option key={t} value={t}>\n {CHART_TYPE_LABELS[t]}\n </option>\n ))}\n </select>\n </Field>\n )}\n <div className=\"flex flex-wrap items-center gap-1\">\n <Toggle label=\"Hidden\" name=\"series.hidden\" checked={!!selectedSeries.hidden} onChange={(hidden) => controller.updateSeries(selectedSeries.id, { hidden })} />\n <span className=\"flex-1\" />\n <button type=\"button\" className={chartButtonClass} disabled={seriesIndex <= 0} aria-label=\"Move series earlier\" data-action=\"series-up\" onClick={() => controller.moveSeries(selectedSeries.id, seriesIndex - 1)}>\n ↑\n </button>\n <button type=\"button\" className={chartButtonClass} disabled={seriesIndex >= spec.series.length - 1} aria-label=\"Move series later\" data-action=\"series-down\" onClick={() => controller.moveSeries(selectedSeries.id, seriesIndex + 1)}>\n ↓\n </button>\n <button type=\"button\" className={`${chartButtonClass} text-destructive`} data-action=\"series-delete\" onClick={() => controller.removeSeries(selectedSeries.id)}>\n Delete\n </button>\n </div>\n </div>\n )}\n </div>\n );\n}\n","import React from 'react';\nimport { describeChartSelection, type ChartController } from '@pixerate/editor/chart';\nimport { ChartCanvas, type ChartCanvasProps } from './ChartCanvas';\nimport { ChartDataGrid } from './ChartDataGrid';\nimport { ChartInspector } from './ChartInspector';\nimport { useChartState } from './useChartEditor';\nimport { chartButtonClass } from './styles';\n\nexport interface ChartEditorProps {\n controller: ChartController;\n /** The settings sidebar (default `true`). */\n showInspector?: boolean;\n /** The data grid under the chart (default `true`). */\n showDataGrid?: boolean;\n /** Undo / redo and the selection readout (default `true`). */\n showToolbar?: boolean;\n /** Chart height in pixels (default 380). */\n height?: number;\n canvasProps?: Omit<ChartCanvasProps, 'controller' | 'height'>;\n className?: string;\n}\n\n/** Toolbar, chart, settings sidebar and data grid for a `ChartController`. */\nexport function ChartEditor({ controller, showInspector = true, showDataGrid = true, showToolbar = true, height = 380, canvasProps, className }: ChartEditorProps) {\n const state = useChartState(controller);\n return (\n <div className={`flex flex-col gap-2 ${className ?? ''}`} data-chart-editor=\"\">\n {showToolbar && (\n <div className=\"flex items-center gap-1\" data-chart-toolbar=\"\">\n <button type=\"button\" className={chartButtonClass} disabled={!state.canUndo} title={state.undoLabel ? `Undo ${state.undoLabel}` : 'Undo'} data-action=\"undo\" onClick={() => controller.undo()}>\n Undo\n </button>\n <button type=\"button\" className={chartButtonClass} disabled={!state.canRedo} title={state.redoLabel ? `Redo ${state.redoLabel}` : 'Redo'} data-action=\"redo\" onClick={() => controller.redo()}>\n Redo\n </button>\n <span className=\"ml-2 truncate text-xs text-muted-foreground\" data-chart-selection=\"\" aria-live=\"polite\">\n {describeChartSelection(controller, state.selection)}\n </span>\n </div>\n )}\n {state.issues.length > 0 && (\n <p role=\"alert\" className=\"rounded-md border border-destructive/40 bg-destructive/10 px-2 py-1 text-xs text-destructive\" data-chart-issues=\"\">\n {state.issues.map((i) => i.message).join(' ')}\n </p>\n )}\n <div className=\"flex min-h-0 flex-col gap-2 md:flex-row\">\n <div className=\"min-w-0 flex-1 rounded-md border border-border bg-background p-1\">\n <ChartCanvas controller={controller} height={height} {...canvasProps} />\n </div>\n {showInspector && <ChartInspector controller={controller} className=\"w-full shrink-0 overflow-y-auto rounded-md border border-border p-3 md:w-64\" />}\n </div>\n {showDataGrid && <ChartDataGrid controller={controller} />}\n </div>\n );\n}\n"],"mappings":"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","names":["useEffect","useMemo","useRef","useRef","useEffect","useMemo","useEffect","useRef","useState","jsx","useState","useRef","useEffect","chartColorInputValue","chartSeriesColor","Fragment","jsx","jsxs","chartColorInputValue","chartSeriesColor","describeChartSelection","jsx","jsxs","describeChartSelection"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pixerate/editor-react",
|
|
3
|
-
"version": "0.35.
|
|
3
|
+
"version": "0.35.1",
|
|
4
4
|
"description": "React bindings and prompt/rich-text components for @pixerate/editor",
|
|
5
5
|
"author": "Pixerate",
|
|
6
6
|
"license": "MIT",
|
|
@@ -115,7 +115,7 @@
|
|
|
115
115
|
},
|
|
116
116
|
"peerDependencies": {
|
|
117
117
|
"@dagrejs/dagre": "^1.1.8",
|
|
118
|
-
"@pixerate/editor": ">=0.46.
|
|
118
|
+
"@pixerate/editor": ">=0.46.1 <1.0.0-0",
|
|
119
119
|
"@tiptap/core": "^2.11.5",
|
|
120
120
|
"@tiptap/pm": "^2.11.5",
|
|
121
121
|
"@tiptap/react": "^2.11.5",
|
|
@@ -135,14 +135,14 @@
|
|
|
135
135
|
"@tiptap/core": "^2.11.5",
|
|
136
136
|
"@tiptap/pm": "^2.11.5",
|
|
137
137
|
"@tiptap/react": "^2.11.5",
|
|
138
|
-
"@types/react": "^19.
|
|
139
|
-
"@types/react-dom": "^19.
|
|
140
|
-
"react": "^19.
|
|
141
|
-
"react-dom": "^19.
|
|
138
|
+
"@types/react": "^19.3.0",
|
|
139
|
+
"@types/react-dom": "^19.3.0",
|
|
140
|
+
"react": "^19.3.0",
|
|
141
|
+
"react-dom": "^19.3.0",
|
|
142
142
|
"tsup": "^8.4.0",
|
|
143
143
|
"typescript": "^5.7.3",
|
|
144
144
|
"vitest": "^4.1.11",
|
|
145
|
-
"@pixerate/editor": "0.46.
|
|
145
|
+
"@pixerate/editor": "0.46.1"
|
|
146
146
|
},
|
|
147
147
|
"scripts": {
|
|
148
148
|
"build": "tsup",
|