@pixerate/editor-react 0.30.0 → 0.31.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/vector/index.cjs
CHANGED
|
@@ -373,6 +373,27 @@ function VectorCanvas({
|
|
|
373
373
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("circle", { cx: w.x, cy: w.y, r: import_vector3.VECTOR_OVERLAY_THEME.cornerWidgetRadius + (w.hovered ? 1 : 0), fill: import_vector3.VECTOR_OVERLAY_THEME.handleFill, stroke: accentColor }),
|
|
374
374
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("circle", { cx: w.x, cy: w.y, r: 1.5, fill: accentColor })
|
|
375
375
|
] }, `corner:${w.ref.nodeId}:${w.ref.subpath}:${w.ref.index}`)),
|
|
376
|
+
overlay.blend.spines.map((sp) => /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("g", { "data-vector-blend-spine": sp.id, "data-replaced": sp.replaced || void 0, children: [
|
|
377
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: sp.d, fill: "none", stroke: accentColor, strokeDasharray: "4 3" }),
|
|
378
|
+
sp.keys.map((k, i) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("circle", { cx: k.x, cy: k.y, r: import_vector3.VECTOR_OVERLAY_THEME.handleRadius, fill: import_vector3.VECTOR_OVERLAY_THEME.handleFill, stroke: accentColor }, i))
|
|
379
|
+
] }, `blend:${sp.id}`)),
|
|
380
|
+
overlay.blend.start && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("g", { "data-vector-blend-start": "", children: [
|
|
381
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: overlay.blend.start.d, fill: "none", stroke: accentColor, strokeWidth: 2 }),
|
|
382
|
+
overlay.blend.start.anchor && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("circle", { cx: overlay.blend.start.anchor.x, cy: overlay.blend.start.anchor.y, r: import_vector3.VECTOR_OVERLAY_THEME.handleRadius + 1, fill: accentColor })
|
|
383
|
+
] }),
|
|
384
|
+
overlay.blend.anchors.map((a, i) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
385
|
+
"rect",
|
|
386
|
+
{
|
|
387
|
+
"data-vector-blend-anchor": i,
|
|
388
|
+
x: a.x - as / 2,
|
|
389
|
+
y: a.y - as / 2,
|
|
390
|
+
width: as,
|
|
391
|
+
height: as,
|
|
392
|
+
fill: a.hovered ? accentColor : import_vector3.VECTOR_OVERLAY_THEME.handleFill,
|
|
393
|
+
stroke: accentColor
|
|
394
|
+
},
|
|
395
|
+
`blend-anchor:${i}`
|
|
396
|
+
)),
|
|
376
397
|
overlay.widthSpot && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("g", { "data-vector-width-spot": "", children: [
|
|
377
398
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("line", { x1: overlay.widthSpot.left.x, y1: overlay.widthSpot.left.y, x2: overlay.widthSpot.right.x, y2: overlay.widthSpot.right.y, stroke: accentColor, strokeDasharray: "3 2" }),
|
|
378
399
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: (0, import_vector3.vectorDiamondPath)(overlay.widthSpot.x, overlay.widthSpot.y), fill: "none", stroke: accentColor })
|
|
@@ -483,7 +504,16 @@ var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
|
483
504
|
var VECTOR_SNAP_TITLE = "Snap to objects";
|
|
484
505
|
var modKeyLabel = () => typeof navigator !== "undefined" && /Mac|iPhone|iPad/.test(navigator.platform ?? "") ? "\u2318" : "Ctrl";
|
|
485
506
|
var buttonClass = "inline-flex h-8 min-w-8 items-center justify-center rounded-md border border-border bg-background px-2 text-xs font-medium text-foreground hover:bg-muted disabled:cursor-not-allowed disabled:opacity-40 aria-pressed:bg-primary aria-pressed:text-primary-foreground";
|
|
486
|
-
function VectorToolbar({
|
|
507
|
+
function VectorToolbar({
|
|
508
|
+
controller,
|
|
509
|
+
tools = import_vector4.VECTOR_TOOLS,
|
|
510
|
+
showHistory = true,
|
|
511
|
+
showArrange = true,
|
|
512
|
+
showSnap = true,
|
|
513
|
+
showPathEdit = true,
|
|
514
|
+
showBlend = true,
|
|
515
|
+
className
|
|
516
|
+
}) {
|
|
487
517
|
const state = useVectorEditorState(controller);
|
|
488
518
|
const count = state.selection.length;
|
|
489
519
|
const points = state.tool === "direct" ? state.selectedAnchors.length : 0;
|
|
@@ -599,6 +629,7 @@ function VectorToolbar({ controller, tools = import_vector4.VECTOR_TOOLS, showHi
|
|
|
599
629
|
}
|
|
600
630
|
)
|
|
601
631
|
] }),
|
|
632
|
+
showBlend && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(VectorBlendControls, { controller }),
|
|
602
633
|
showArrange && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
|
|
603
634
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "ml-1 flex items-center gap-1", role: "group", "aria-label": "Combine", children: [
|
|
604
635
|
act("\u222A", "Union", () => controller.booleanOp("union"), count < 2),
|
|
@@ -635,6 +666,69 @@ function VectorToolbar({ controller, tools = import_vector4.VECTOR_TOOLS, showHi
|
|
|
635
666
|
] })
|
|
636
667
|
] });
|
|
637
668
|
}
|
|
669
|
+
function VectorBlendControls({ controller }) {
|
|
670
|
+
const state = useVectorEditorState(controller);
|
|
671
|
+
const blend = (0, import_vector4.getVectorBlendControls)(state);
|
|
672
|
+
const o = blend.options;
|
|
673
|
+
const selected = blend.ids.length > 0;
|
|
674
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "ml-1 flex items-center gap-1", role: "group", "aria-label": "Blend", "data-vector-blend-controls": "", children: [
|
|
675
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("button", { type: "button", "data-vector-blend-action": "make", className: buttonClass, title: "Make Blend", "aria-label": "Make Blend", disabled: !blend.canBlend, onClick: () => controller.blend(), children: "\u29D3" }),
|
|
676
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
677
|
+
"select",
|
|
678
|
+
{
|
|
679
|
+
"aria-label": "Blend spacing",
|
|
680
|
+
className: "h-7 rounded border border-border bg-background px-1 text-xs",
|
|
681
|
+
value: o.spacing,
|
|
682
|
+
onChange: (e) => (0, import_vector4.applyVectorBlendOptions)(controller, { spacing: e.target.value }),
|
|
683
|
+
children: import_vector4.VECTOR_BLEND_SPACINGS.map((sp) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("option", { value: sp, children: import_vector4.VECTOR_BLEND_SPACING_LABELS[sp] }, sp))
|
|
684
|
+
}
|
|
685
|
+
),
|
|
686
|
+
o.spacing !== "smoothColor" && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
687
|
+
"input",
|
|
688
|
+
{
|
|
689
|
+
type: "number",
|
|
690
|
+
min: o.spacing === "steps" ? 1 : 0.5,
|
|
691
|
+
step: 1,
|
|
692
|
+
"aria-label": o.spacing === "steps" ? "Blend steps" : "Blend distance",
|
|
693
|
+
className: "h-7 w-16 rounded border border-border bg-background px-1.5 text-xs",
|
|
694
|
+
value: o.spacing === "steps" ? o.steps : o.distance,
|
|
695
|
+
onChange: (e) => {
|
|
696
|
+
const n = parseFloat(e.target.value);
|
|
697
|
+
if (!Number.isFinite(n) || n <= 0) return;
|
|
698
|
+
(0, import_vector4.applyVectorBlendOptions)(controller, o.spacing === "steps" ? { steps: n } : { distance: n });
|
|
699
|
+
}
|
|
700
|
+
}
|
|
701
|
+
),
|
|
702
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
703
|
+
"button",
|
|
704
|
+
{
|
|
705
|
+
type: "button",
|
|
706
|
+
"data-vector-blend-action": "orient",
|
|
707
|
+
className: buttonClass,
|
|
708
|
+
"aria-pressed": o.orientToSpine,
|
|
709
|
+
title: "Orient steps to the spine",
|
|
710
|
+
"aria-label": "Orient to spine",
|
|
711
|
+
onClick: () => (0, import_vector4.applyVectorBlendOptions)(controller, { orientToSpine: !o.orientToSpine }),
|
|
712
|
+
children: "\u293F"
|
|
713
|
+
}
|
|
714
|
+
),
|
|
715
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
716
|
+
"button",
|
|
717
|
+
{
|
|
718
|
+
type: "button",
|
|
719
|
+
"data-vector-blend-action": "spine",
|
|
720
|
+
className: buttonClass,
|
|
721
|
+
title: "Replace Spine (select a blend and a path)",
|
|
722
|
+
"aria-label": "Replace Spine",
|
|
723
|
+
disabled: !blend.canReplaceSpine,
|
|
724
|
+
onClick: () => controller.replaceBlendSpine(),
|
|
725
|
+
children: "\u2307"
|
|
726
|
+
}
|
|
727
|
+
),
|
|
728
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("button", { type: "button", "data-vector-blend-action": "expand", className: buttonClass, title: "Expand Blend", "aria-label": "Expand Blend", disabled: !selected, onClick: () => controller.expandBlend(), children: "\u29C9" }),
|
|
729
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("button", { type: "button", "data-vector-blend-action": "release", className: buttonClass, title: "Release Blend", "aria-label": "Release Blend", disabled: !selected, onClick: () => controller.releaseBlend(), children: "\u29C4" })
|
|
730
|
+
] });
|
|
731
|
+
}
|
|
638
732
|
var selectClass = "h-7 min-w-0 flex-1 rounded border border-border bg-background px-1 text-xs";
|
|
639
733
|
var numberClass = "h-7 w-16 rounded border border-border bg-background px-1.5 text-xs";
|
|
640
734
|
function VectorStylePanel({ controller, className }) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/vector/index.ts","../../src/vector/useVectorEditor.ts","../../src/vector/VectorCanvas.tsx","../../src/vector/VectorWidthPointEditor.tsx","../../src/vector/VectorToolbar.tsx","../../src/vector/VectorEditor.tsx"],"sourcesContent":["export * from './useVectorEditor';\nexport * from './VectorCanvas';\nexport * from './VectorWidthPointEditor';\nexport * from './VectorToolbar';\nexport * from './VectorEditor';\n","import { useEffect, useMemo, useRef, useSyncExternalStore } from 'react';\nimport {\n VectorEditorController,\n createVectorCommands,\n type VectorCommandOptions,\n type VectorEditorOptions,\n type VectorEditorState,\n type VectorTool,\n} from '@pixerate/editor/vector';\n\n/** A `VectorEditorController` created once for the component's lifetime (destroyed on unmount). */\nexport function useVectorEditorController(options: VectorEditorOptions = {}): VectorEditorController {\n const ref = useRef<VectorEditorController | null>(null);\n if (!ref.current) ref.current = new VectorEditorController(options);\n const controller = ref.current;\n useEffect(() => () => controller.destroy(), [controller]);\n return controller;\n}\n\n/** The controller's state (re-renders on every change). */\nexport function useVectorEditorState(controller: VectorEditorController): VectorEditorState {\n return useSyncExternalStore(controller.subscribe, controller.getState, controller.getState);\n}\n\nexport interface UseVectorEditorResult {\n controller: VectorEditorController;\n state: VectorEditorState;\n setTool: (tool: VectorTool) => void;\n undo: () => void;\n redo: () => void;\n deleteSelection: () => void;\n toSvg: () => string;\n}\n\n/**\n * Subscribes to a vector editor controller and exposes its state with bound actions. Pass\n * options instead of a controller to create one for the component's lifetime.\n */\nexport function useVectorEditor(controllerOrOptions: VectorEditorController | VectorEditorOptions = {}): UseVectorEditorResult {\n const own = useRef<VectorEditorController | null>(null);\n let controller: VectorEditorController;\n if (controllerOrOptions instanceof VectorEditorController) controller = controllerOrOptions;\n else {\n if (!own.current) own.current = new VectorEditorController(controllerOrOptions);\n controller = own.current;\n }\n const state = useVectorEditorState(controller);\n const actions = useMemo(\n () => ({\n setTool: (tool: VectorTool) => controller.setTool(tool),\n undo: () => void controller.undo(),\n redo: () => void controller.redo(),\n deleteSelection: () => void controller.deleteSelection(),\n toSvg: () => controller.toSvg(),\n }),\n [controller],\n );\n return { controller, state, ...actions };\n}\n\n/** Anything with `register(specs) → unregister` (a `CommandRegistry`). */\nexport interface VectorCommandTarget {\n register(specs: any): () => void;\n}\n\n/**\n * Registers the controller's palette / agent commands (`vector.addShape`, `vector.boolean`, …)\n * in `registry` while mounted, so `createCommandToolProvider` exposes them to agents.\n */\nexport function useVectorCommands(\n registry: VectorCommandTarget | null | undefined,\n controller: VectorEditorController,\n options: VectorCommandOptions = {},\n): void {\n const { prefix, group, scope } = options;\n useEffect(() => {\n if (!registry) return;\n return registry.register(createVectorCommands(controller, { prefix, group, scope }));\n }, [registry, controller, prefix, group, scope]);\n}\n","import React, { useEffect, useId, useRef } from 'react';\nimport {\n VECTOR_OVERLAY_THEME as THEME,\n getVectorOverlayRenderData,\n getVectorSceneRenderData,\n isVectorTextTarget,\n toVectorKeyInput,\n toVectorPointerInput,\n vectorDiamondPath,\n type VectorEditorController,\n type VectorRenderNode,\n type VectorRenderPath,\n type SvgGradientDef,\n} from '@pixerate/editor/vector';\nimport { useVectorEditorState } from './useVectorEditor';\nimport { VectorWidthPointEditor } from './VectorWidthPointEditor';\n\nexport interface VectorCanvasProps {\n controller: VectorEditorController;\n /** Fit the artboard into the canvas when it first gets a size (default `true`). */\n fitOnMount?: boolean;\n /** Draw a checkerboard behind a transparent artboard (default `true`). */\n checkerboard?: boolean;\n /** Overlay accent colour (default sky blue). */\n accentColor?: string;\n /** Smart guide colour (default magenta). */\n guideColor?: string;\n className?: string;\n style?: React.CSSProperties;\n /** Accessible label (default \"Vector canvas\"). */\n 'aria-label'?: string;\n}\n\n/** Renders `<linearGradient>` / `<radialGradient>` descriptors. */\nexport function VectorGradientDefs({ defs }: { defs: readonly SvgGradientDef[] }) {\n if (!defs.length) return null;\n return (\n <defs>\n {defs.map((def) => {\n const stops = def.stops.map((s, i) => <stop key={i} offset={s.offset} stopColor={s.stopColor} stopOpacity={s.stopOpacity} />);\n return def.type === 'radial' ? (\n <radialGradient key={def.id} id={def.id} {...(def.attrs as any)}>\n {stops}\n </radialGradient>\n ) : (\n <linearGradient key={def.id} id={def.id} {...(def.attrs as any)}>\n {stops}\n </linearGradient>\n );\n })}\n </defs>\n );\n}\n\n/** Renders scene nodes (paths and groups) from `getVectorSceneRenderData`. */\nexport function VectorSceneNodes({ nodes }: { nodes: readonly VectorRenderNode[] }) {\n return (\n <>\n {nodes.map((node) =>\n node.kind === 'group' ? (\n <g key={node.id} data-vector-id={node.id} transform={node.transform} opacity={node.opacity < 1 ? node.opacity : undefined}>\n <VectorSceneNodes nodes={node.children} />\n </g>\n ) : node.strokeParts ? (\n <VectorPartedPath key={node.id} node={node} />\n ) : (\n <path\n key={node.id}\n data-vector-id={node.id}\n transform={node.transform}\n d={node.d}\n fill={node.fill}\n fillRule={node.fillRule}\n stroke={node.stroke}\n strokeWidth={node.stroke === 'none' ? undefined : node.strokeWidth}\n strokeLinecap={node.strokeLinecap as any}\n strokeLinejoin={node.strokeLinejoin as any}\n strokeDasharray={node.strokeDasharray}\n opacity={node.opacity < 1 ? node.opacity : undefined}\n />\n ),\n )}\n </>\n );\n}\n\n/** A path whose stroke is aligned inside / outside (double width, clipped or masked by the shape) or has arrowheads. */\nfunction VectorPartedPath({ node }: { node: VectorRenderPath }) {\n const sp = node.strokeParts!;\n const clip = sp.clip;\n const b = clip?.bounds;\n return (\n <g data-vector-id={node.id} data-vector-stroke-align={sp.align} transform={node.transform} opacity={node.opacity < 1 ? node.opacity : undefined}>\n {clip && b && (\n <defs>\n {clip.kind === 'clip' ? (\n <clipPath id={clip.id}>\n <path d={node.d} clipRule={node.fillRule} />\n </clipPath>\n ) : (\n <mask id={clip.id} maskUnits=\"userSpaceOnUse\" x={b.x} y={b.y} width={b.width} height={b.height}>\n <rect x={b.x} y={b.y} width={b.width} height={b.height} fill=\"#fff\" />\n <path d={node.d} fill=\"#000\" fillRule={node.fillRule} />\n </mask>\n )}\n </defs>\n )}\n <path data-vector-part=\"fill\" d={node.d} fill={node.fill} fillRule={node.fillRule} stroke=\"none\" />\n {sp.outline !== undefined ? (\n // A variable-width stroke: its outline, filled.\n <path\n data-vector-part=\"stroke-outline\"\n d={sp.outline}\n fill={node.stroke}\n clipPath={clip?.kind === 'clip' ? `url(#${clip.id})` : undefined}\n mask={clip?.kind === 'mask' ? `url(#${clip.id})` : undefined}\n />\n ) : (\n <path\n data-vector-part=\"stroke\"\n d={sp.d}\n fill=\"none\"\n stroke={node.stroke}\n strokeWidth={sp.width}\n strokeLinecap={node.strokeLinecap as any}\n strokeLinejoin={node.strokeLinejoin as any}\n strokeDasharray={node.strokeDasharray}\n clipPath={clip?.kind === 'clip' ? `url(#${clip.id})` : undefined}\n mask={clip?.kind === 'mask' ? `url(#${clip.id})` : undefined}\n />\n )}\n {sp.heads.map((head, i) => (\n <path key={i} data-vector-part=\"head\" d={head} fill={node.stroke} />\n ))}\n </g>\n );\n}\n\n/**\n * An SVG canvas for a `VectorEditorController`: draws the document and the editing overlay\n * and forwards pointer, wheel, keyboard and clipboard events. Focus it to use shortcuts.\n */\nexport function VectorCanvas({\n controller,\n fitOnMount = true,\n checkerboard = true,\n accentColor = THEME.accent,\n guideColor = THEME.guide,\n className,\n style,\n 'aria-label': ariaLabel = 'Vector canvas',\n}: VectorCanvasProps) {\n const state = useVectorEditorState(controller);\n const svgRef = useRef<SVGSVGElement | null>(null);\n const fitted = useRef(!fitOnMount);\n const uid = useId().replace(/:/g, '');\n const scene = getVectorSceneRenderData(state, { idPrefix: `ve${uid}-` });\n const overlay = getVectorOverlayRenderData(state);\n\n useEffect(() => {\n const el = svgRef.current;\n if (!el || fitted.current) return;\n const fit = () => {\n const rect = el.getBoundingClientRect();\n if (fitted.current || rect.width <= 0 || rect.height <= 0) return;\n fitted.current = true;\n controller.zoomToFit({ width: rect.width, height: rect.height });\n };\n fit();\n if (fitted.current || typeof ResizeObserver === 'undefined') return;\n const observer = new ResizeObserver(fit);\n observer.observe(el);\n return () => observer.disconnect();\n }, [controller]);\n\n // Wheel needs a non-passive listener to stop page scroll / browser zoom.\n useEffect(() => {\n const el = svgRef.current;\n if (!el) return;\n const onWheel = (e: WheelEvent) => {\n e.preventDefault();\n controller.wheel(local(e), { x: e.deltaX, y: e.deltaY }, toVectorPointerInput(e));\n };\n el.addEventListener('wheel', onWheel, { passive: false });\n return () => el.removeEventListener('wheel', onWheel);\n }, [controller]);\n\n const local = (e: { clientX: number; clientY: number }) => {\n const rect = svgRef.current?.getBoundingClientRect();\n return { x: e.clientX - (rect?.left ?? 0), y: e.clientY - (rect?.top ?? 0) };\n };\n\n const clipboard = (kind: 'copy' | 'cut' | 'paste') => (event: React.ClipboardEvent) => {\n const native = (event && 'nativeEvent' in event ? event.nativeEvent : event) as ClipboardEvent;\n const data = native?.clipboardData;\n if (kind === 'paste') {\n const text = data?.getData('text/plain') ?? '';\n const pasted = text ? controller.paste(text) : controller.paste();\n if (pasted.length) event.preventDefault?.();\n return;\n }\n const text = kind === 'cut' ? controller.cut() : controller.copy();\n if (text && data) {\n data.setData('text/plain', text);\n event.preventDefault?.();\n }\n };\n\n const hs = THEME.transformHandleSize;\n const as = THEME.anchorSize;\n const box = overlay.selectionBox;\n const edit = state.widthPointEdit;\n const editAt = edit && { x: edit.point.x * state.viewport.zoom + state.viewport.x, y: edit.point.y * state.viewport.zoom + state.viewport.y };\n\n return (\n <svg\n ref={svgRef}\n role=\"application\"\n aria-label={ariaLabel}\n tabIndex={0}\n data-tool={state.tool}\n className={className}\n style={{ display: 'block', width: '100%', height: '100%', outline: 'none', touchAction: 'none', userSelect: 'none', cursor: state.cursor, ...style }}\n onPointerDown={(e) => {\n svgRef.current?.focus({ preventScroll: true });\n (e.currentTarget as Element).setPointerCapture?.(e.pointerId);\n controller.pointerDown(local(e), toVectorPointerInput(e));\n }}\n onPointerMove={(e) => controller.pointerMove(local(e), toVectorPointerInput(e))}\n onPointerUp={(e) => {\n (e.currentTarget as Element).releasePointerCapture?.(e.pointerId);\n controller.pointerUp(local(e), toVectorPointerInput(e));\n }}\n onPointerCancel={() => controller.cancelDrag()}\n onPointerLeave={() => controller.pointerLeave()}\n onDoubleClick={(e) => controller.doubleClick(local(e))}\n onKeyDown={(e) => {\n if (isVectorTextTarget(e.target)) return;\n if (controller.keyDown(toVectorKeyInput(e))) e.preventDefault();\n }}\n onKeyUp={(e) => controller.keyUp(toVectorKeyInput(e))}\n onCopy={clipboard('copy')}\n onCut={clipboard('cut')}\n onPaste={clipboard('paste')}\n >\n {checkerboard && (\n <defs>\n <pattern id={`ve${uid}-checker`} width={16} height={16} patternUnits=\"userSpaceOnUse\">\n <rect width={16} height={16} fill=\"#ffffff\" />\n <rect width={8} height={8} fill=\"#e5e7eb\" />\n <rect x={8} y={8} width={8} height={8} fill=\"#e5e7eb\" />\n </pattern>\n </defs>\n )}\n <VectorGradientDefs defs={scene.defs} />\n <rect\n data-vector-artboard=\"\"\n x={overlay.artboard.x}\n y={overlay.artboard.y}\n width={overlay.artboard.width}\n height={overlay.artboard.height}\n fill={scene.background ?? (checkerboard ? `url(#ve${uid}-checker)` : '#ffffff')}\n stroke=\"rgba(0,0,0,0.12)\"\n />\n <g data-vector-scene=\"\" transform={scene.transform}>\n <VectorSceneNodes nodes={scene.nodes} />\n </g>\n <g data-vector-overlay=\"\" pointerEvents=\"none\" fill=\"none\">\n {overlay.outlines.map((o) => (\n <path key={o.id} d={o.d} stroke={accentColor} strokeWidth={o.selected ? 1 : 1.5} opacity={o.selected ? 1 : 0.7} />\n ))}\n {overlay.penPreview && <path d={overlay.penPreview} stroke={accentColor} strokeDasharray=\"4 3\" />}\n {box && (\n <g data-vector-selection=\"\" transform={box.transform || undefined}>\n <rect x={box.x} y={box.y} width={box.width} height={box.height} stroke={accentColor} />\n <line x1={box.x + box.width / 2} y1={box.y} x2={box.x + box.width / 2} y2={box.y - 24} stroke={accentColor} />\n {box.handles.map((h) =>\n h.handle === 'rotate' ? (\n <circle key={h.handle} data-handle={h.handle} cx={h.x} cy={h.y} r={hs / 2 + 1} fill={THEME.handleFill} stroke={accentColor} />\n ) : (\n <rect key={h.handle} data-handle={h.handle} x={h.x - hs / 2} y={h.y - hs / 2} width={hs} height={hs} fill={THEME.handleFill} stroke={accentColor} />\n ),\n )}\n </g>\n )}\n {overlay.handles.map((h) => (\n <g key={`${h.ref.nodeId}:${h.ref.subpath}:${h.ref.index}:${h.ref.handle}`} data-vector-handle={h.ref.handle}>\n <line x1={h.anchorX} y1={h.anchorY} x2={h.x} y2={h.y} stroke={accentColor} />\n <circle cx={h.x} cy={h.y} r={THEME.handleRadius + (h.hovered ? 1 : 0)} fill={THEME.handleFill} stroke={accentColor} />\n </g>\n ))}\n {overlay.anchors.map((a) => {\n const size = as + (a.hovered ? 2 : 0);\n const fill = a.selected ? accentColor : THEME.handleFill;\n const key = `${a.ref.nodeId}:${a.ref.subpath}:${a.ref.index}`;\n return a.type === 'corner' ? (\n <rect key={key} data-vector-anchor={a.ref.index} x={a.x - size / 2} y={a.y - size / 2} width={size} height={size} fill={fill} stroke={accentColor} />\n ) : (\n <circle key={key} data-vector-anchor={a.ref.index} cx={a.x} cy={a.y} r={size / 2} fill={fill} stroke={accentColor} />\n );\n })}\n {overlay.cornerWidgets.map((w) => (\n <g key={`corner:${w.ref.nodeId}:${w.ref.subpath}:${w.ref.index}`} data-vector-corner-widget={w.ref.index} data-corner-kind={w.kind}>\n <circle cx={w.x} cy={w.y} r={THEME.cornerWidgetRadius + (w.hovered ? 1 : 0)} fill={THEME.handleFill} stroke={accentColor} />\n <circle cx={w.x} cy={w.y} r={1.5} fill={accentColor} />\n </g>\n ))}\n {overlay.widthSpot && (\n <g data-vector-width-spot=\"\">\n <line x1={overlay.widthSpot.left.x} y1={overlay.widthSpot.left.y} x2={overlay.widthSpot.right.x} y2={overlay.widthSpot.right.y} stroke={accentColor} strokeDasharray=\"3 2\" />\n <path d={vectorDiamondPath(overlay.widthSpot.x, overlay.widthSpot.y)} fill=\"none\" stroke={accentColor} />\n </g>\n )}\n {overlay.widthPoints.map((w) => (\n <g key={`width:${w.ref.nodeId}:${w.ref.subpath}:${w.ref.index}`} data-vector-width-point={w.ref.index} data-selected={w.selected || undefined}>\n <line x1={w.left.x} y1={w.left.y} x2={w.right.x} y2={w.right.y} stroke={accentColor} />\n <path d={vectorDiamondPath(w.x, w.y)} fill={w.selected || w.active ? accentColor : THEME.handleFill} stroke={accentColor} strokeWidth={w.hovered === 'center' ? 2 : 1} />\n {(['left', 'right'] as const).map((side) => (\n <circle key={side} data-vector-width-side={side} cx={w[side].x} cy={w[side].y} r={THEME.handleRadius + (w.hovered === side ? 1 : 0)} fill={THEME.handleFill} stroke={accentColor} />\n ))}\n </g>\n ))}\n {state.tool === 'pen' && overlay.anchors.some((a) => a.closes && a.hovered) && (\n <circle cx={overlay.anchors.find((a) => a.closes)!.x} cy={overlay.anchors.find((a) => a.closes)!.y} r={as} stroke={accentColor} />\n )}\n {overlay.builder && (\n <g data-vector-builder={overlay.builder.mode}>\n {overlay.builder.faces.map((d, i) => (\n <path\n key={`f${i}`}\n data-vector-builder-face=\"\"\n d={d}\n fill={overlay.builder!.mode === 'erase' ? THEME.builderEraseFill : THEME.builderFill}\n fillRule=\"nonzero\"\n stroke={overlay.builder!.mode === 'erase' ? THEME.builderErase : accentColor}\n strokeWidth={1}\n />\n ))}\n {overlay.builder.hatches.map((d, i) =>\n d ? (\n <path\n key={`h${i}`}\n data-vector-builder-hatch=\"\"\n d={d}\n fill=\"none\"\n stroke={overlay.builder!.mode === 'erase' ? THEME.builderErase : accentColor}\n strokeOpacity={THEME.builderHatchOpacity}\n strokeWidth={1}\n />\n ) : null\n )}\n {overlay.builder.lines.map((d, i) => (\n <path key={`l${i}`} data-vector-builder-line=\"\" d={d} fill=\"none\" stroke={THEME.builderErase} strokeWidth={3} strokeLinecap=\"round\" />\n ))}\n {overlay.builder.trail && <path data-vector-builder-trail=\"\" d={overlay.builder.trail} fill=\"none\" stroke={overlay.builder.mode === 'erase' ? THEME.builderErase : accentColor} strokeWidth={1} />}\n </g>\n )}\n {overlay.toolStroke && (\n <path\n data-vector-tool-stroke={overlay.toolStroke.tool}\n d={overlay.toolStroke.d}\n stroke={overlay.toolStroke.tool === 'eraser' ? THEME.eraserFill : accentColor}\n strokeWidth={overlay.toolStroke.tool === 'eraser' ? overlay.toolStroke.width : 1}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeDasharray={overlay.toolStroke.tool === 'knife' ? '5 3' : undefined}\n />\n )}\n {overlay.pencilString && (\n <line\n data-vector-pencil-string=\"\"\n x1={overlay.pencilString.x1}\n y1={overlay.pencilString.y1}\n x2={overlay.pencilString.x2}\n y2={overlay.pencilString.y2}\n stroke={accentColor}\n strokeDasharray=\"2 2\"\n />\n )}\n {overlay.cutPoint && <circle data-vector-cut-point=\"\" cx={overlay.cutPoint.x} cy={overlay.cutPoint.y} r={THEME.handleRadius + 1} fill={THEME.handleFill} stroke={accentColor} />}\n {overlay.marquee && (\n <rect\n data-vector-marquee=\"\"\n x={overlay.marquee.x}\n y={overlay.marquee.y}\n width={overlay.marquee.width}\n height={overlay.marquee.height}\n fill={THEME.marqueeFill}\n stroke={accentColor}\n strokeDasharray=\"3 2\"\n />\n )}\n {overlay.guides.lines.length > 0 && (\n <g data-vector-guides=\"\" stroke={guideColor}>\n {overlay.guides.lines.map((l, i) => (\n <line key={i} data-vector-guide={l.kind} x1={l.x1} y1={l.y1} x2={l.x2} y2={l.y2} strokeDasharray={l.kind === 'construction' ? '4 3' : undefined} />\n ))}\n </g>\n )}\n {overlay.guides.labels.map((l, i) => (\n <text\n key={i}\n data-vector-guide-label={l.kind}\n x={l.x + 6}\n y={l.y - 6}\n fontSize={10}\n fill={guideColor}\n stroke=\"#ffffff\"\n strokeWidth={3}\n paintOrder=\"stroke\"\n style={{ fontFamily: 'system-ui, sans-serif' }}\n >\n {l.text}\n </text>\n ))}\n {overlay.status && (\n <text data-vector-status=\"\" x={8} y=\"100%\" dy={-8} fontSize={11} fill={accentColor} style={{ fontFamily: 'system-ui, sans-serif' }}>\n {overlay.status}\n </text>\n )}\n </g>\n {edit && editAt && (\n // Width Point Edit (double-click with the width tool), beside the point.\n <foreignObject data-vector-width-point-edit=\"\" x={editAt.x + 12} y={editAt.y + 12} width={180} height={140} style={{ overflow: 'visible' }}>\n <VectorWidthPointEditor key={`${edit.nodeId}:${edit.index}:${edit.t}`} controller={controller} edit={edit} accentColor={accentColor} />\n </foreignObject>\n )}\n </svg>\n );\n}\n","import React, { useRef, useState } from 'react';\nimport { VECTOR_OVERLAY_THEME as THEME, type VectorEditorController, type VectorWidthPointEdit } from '@pixerate/editor/vector';\n\nexport interface VectorWidthPointEditorProps {\n controller: VectorEditorController;\n /** The point being edited (`state.widthPointEdit`). */\n edit: VectorWidthPointEdit;\n /** Accent colour of the Apply button (default sky blue). */\n accentColor?: string;\n className?: string;\n style?: React.CSSProperties;\n}\n\nconst round = (v: number, digits: number) => String(Math.round(v * 10 ** digits) / 10 ** digits);\n\nconst fieldStyle: React.CSSProperties = { display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 6 };\nconst inputStyle: React.CSSProperties = { width: 72, font: 'inherit', padding: '1px 4px' };\n\n/**\n * Width Point Edit: the position (percent along the path) and the left / right side widths\n * (document units) of the width point a width-tool double-click opened. Apply (or Enter) sets\n * them with `commitWidthPointEdit`; Cancel or Escape closes it. `<VectorCanvas>` shows it next\n * to the point; use it on its own to place it elsewhere.\n */\nexport function VectorWidthPointEditor({ controller, edit, accentColor = THEME.accent, className, style }: VectorWidthPointEditorProps) {\n const [position, setPosition] = useState(() => round(edit.t * 100, 2));\n const [left, setLeft] = useState(() => round(edit.left, 3));\n const [right, setRight] = useState(() => round(edit.right, 3));\n const formRef = useRef<HTMLFormElement | null>(null);\n // Hand the keyboard back to the canvas around it.\n const refocus = () => (formRef.current?.closest('svg') as SVGSVGElement | null)?.focus?.({ preventScroll: true });\n const close = () => {\n refocus();\n controller.closeWidthPointEdit();\n };\n const num = (v: string) => (v.trim() !== '' && Number.isFinite(Number(v)) ? Number(v) : undefined);\n const apply = () => {\n const t = num(position);\n refocus();\n controller.commitWidthPointEdit({ t: t === undefined ? undefined : Math.min(Math.max(t, 0), 100) / 100, left: num(left), right: num(right) });\n };\n const stop = (e: React.SyntheticEvent) => e.stopPropagation();\n return (\n <form\n ref={formRef}\n data-vector-width-point-editor=\"\"\n aria-label=\"Width point\"\n className={className}\n style={{\n display: 'grid',\n gap: 4,\n padding: 8,\n background: '#ffffff',\n border: '1px solid rgba(0,0,0,0.15)',\n borderRadius: 6,\n boxShadow: '0 2px 8px rgba(0,0,0,0.15)',\n font: '12px system-ui, sans-serif',\n color: '#18181b',\n ...style,\n }}\n // Keep the canvas from treating clicks, keys and clipboard use in here as editing gestures.\n onPointerDown={stop}\n onPointerMove={stop}\n onPointerUp={stop}\n onDoubleClick={stop}\n onCopy={stop}\n onCut={stop}\n onPaste={stop}\n onKeyDown={(e) => {\n e.stopPropagation();\n if (e.key === 'Escape') {\n e.preventDefault();\n close();\n }\n }}\n onSubmit={(e) => {\n e.preventDefault();\n apply();\n }}\n >\n <label style={fieldStyle}>\n Position %\n <input aria-label=\"Width point position\" type=\"number\" min={0} max={100} step=\"any\" value={position} onChange={(e) => setPosition(e.target.value)} style={inputStyle} autoFocus />\n </label>\n <label style={fieldStyle}>\n Left\n <input aria-label=\"Width point left side\" type=\"number\" min={0} step=\"any\" value={left} onChange={(e) => setLeft(e.target.value)} style={inputStyle} />\n </label>\n <label style={fieldStyle}>\n Right\n <input aria-label=\"Width point right side\" type=\"number\" min={0} step=\"any\" value={right} onChange={(e) => setRight(e.target.value)} style={inputStyle} />\n </label>\n <div style={{ display: 'flex', justifyContent: 'flex-end', gap: 4, marginTop: 2 }}>\n <button type=\"button\" onClick={close}>\n Cancel\n </button>\n <button type=\"submit\" style={{ background: accentColor, color: '#ffffff', border: 'none', borderRadius: 4, padding: '2px 8px' }}>\n {edit.index === null ? 'Add' : 'Apply'}\n </button>\n </div>\n </form>\n );\n}\n","import React from 'react';\nimport {\n VECTOR_TOOLS,\n VECTOR_TOOL_GLYPHS,\n VECTOR_TOOL_SHORTCUTS,\n VECTOR_EDIT_TOGGLES,\n VECTOR_PATH_ACTIONS,\n VECTOR_PATHFINDER_ACTIONS,\n VECTOR_FILL_GAP,\n VECTOR_ARROWHEADS,\n VECTOR_ARROWHEAD_LABELS,\n VECTOR_CORNER_KINDS,\n VECTOR_CORNER_KIND_LABELS,\n VECTOR_STROKE_ALIGN_LABELS,\n VECTOR_WIDTH_PRESETS,\n getVectorSelectionStyle,\n widthProfilePreset,\n widthProfilePresetId,\n vectorPaintToHex,\n vectorToolLabel,\n type VectorArrowhead,\n type VectorCornerKind,\n type VectorEditorController,\n type VectorStrokeAlign,\n type VectorTool,\n type VectorWidthPreset,\n} from '@pixerate/editor/vector';\nimport { useVectorEditorState } from './useVectorEditor';\n\nconst VECTOR_SNAP_TITLE = 'Snap to objects';\nconst modKeyLabel = () => (typeof navigator !== 'undefined' && /Mac|iPhone|iPad/.test(navigator.platform ?? '') ? '⌘' : 'Ctrl');\n\nconst buttonClass =\n 'inline-flex h-8 min-w-8 items-center justify-center rounded-md border border-border bg-background px-2 text-xs font-medium text-foreground hover:bg-muted disabled:cursor-not-allowed disabled:opacity-40 aria-pressed:bg-primary aria-pressed:text-primary-foreground';\n\nexport interface VectorToolbarProps {\n controller: VectorEditorController;\n /** Tools to show (default: all). */\n tools?: readonly VectorTool[];\n /** Undo / redo buttons (default `true`). */\n showHistory?: boolean;\n /** Boolean, Pathfinder, group, arrange and align buttons (default `true`). */\n showArrange?: boolean;\n /** The snapping toggle (default `true`). */\n showSnap?: boolean;\n /**\n * Path editing: Join, Average, Cut at Points, Remove Redundant Points, Smooth, the Keep\n * Shape / Curvature / Shapes toggles, and the pencil smoothing and eraser size inputs while\n * those tools are active (default `true`).\n */\n showPathEdit?: boolean;\n className?: string;\n}\n\n/** Tool picker plus undo, snapping, boolean operations, grouping, stacking and alignment. */\nexport function VectorToolbar({ controller, tools = VECTOR_TOOLS, showHistory = true, showArrange = true, showSnap = true, showPathEdit = true, className }: VectorToolbarProps) {\n const state = useVectorEditorState(controller);\n const count = state.selection.length;\n const points = state.tool === 'direct' ? state.selectedAnchors.length : 0;\n const editing = state.editing;\n const groupSelected = state.selection.some((id) => controller.getNode(id)?.type === 'group');\n const act = (label: string, title: string, run: () => unknown, disabled = false) => (\n <button key={label} type=\"button\" className={buttonClass} title={title} aria-label={title} disabled={disabled} onClick={() => void run()}>\n {label}\n </button>\n );\n return (\n <div role=\"toolbar\" aria-label=\"Vector tools\" className={`flex flex-wrap items-center gap-1 ${className ?? ''}`}>\n <div className=\"flex items-center gap-1\" role=\"group\" aria-label=\"Tools\">\n {tools.map((tool) => (\n <button\n key={tool}\n type=\"button\"\n data-vector-tool={tool}\n className={buttonClass}\n aria-pressed={state.tool === tool}\n title={`${vectorToolLabel(tool)} (${VECTOR_TOOL_SHORTCUTS[tool]})`}\n aria-label={vectorToolLabel(tool)}\n onClick={() => controller.setTool(tool)}\n >\n {VECTOR_TOOL_GLYPHS[tool]}\n </button>\n ))}\n </div>\n {showHistory && (\n <div className=\"ml-1 flex items-center gap-1\" role=\"group\" aria-label=\"History\">\n {act('↶', state.canUndo ? `Undo ${state.undoLabel}` : 'Undo', () => controller.undo(), !state.canUndo)}\n {act('↷', state.canRedo ? `Redo ${state.redoLabel}` : 'Redo', () => controller.redo(), !state.canRedo)}\n </div>\n )}\n {showSnap && (\n <div className=\"ml-1 flex items-center gap-1\" role=\"group\" aria-label=\"Snapping\">\n <button\n type=\"button\"\n data-vector-snap=\"\"\n className={buttonClass}\n aria-pressed={state.snap.objects}\n title={`${VECTOR_SNAP_TITLE} (hold ${modKeyLabel()} to bypass)`}\n aria-label={VECTOR_SNAP_TITLE}\n onClick={() => controller.toggleSnapping()}\n >\n Snap\n </button>\n </div>\n )}\n {showPathEdit && (\n <div className=\"ml-1 flex items-center gap-1\" role=\"group\" aria-label=\"Path editing\">\n {VECTOR_PATH_ACTIONS.map((a) => (\n <button\n key={a.id}\n type=\"button\"\n data-vector-path-action={a.id}\n className={buttonClass}\n title={a.shortcut ? `${a.title} (${modKeyLabel()}+${a.shortcut})` : a.title}\n aria-label={a.title}\n disabled={!a.enabled(count, points)}\n onClick={() => void a.run(controller)}\n >\n {a.label}\n </button>\n ))}\n {VECTOR_EDIT_TOGGLES.map((t) => (\n <button\n key={t.key}\n type=\"button\"\n data-vector-edit={t.key}\n className={buttonClass}\n aria-pressed={editing[t.key]}\n title={t.title}\n aria-label={t.title}\n onClick={() => controller.setEditing({ [t.key]: !editing[t.key] })}\n >\n {t.label}\n </button>\n ))}\n {state.tool === 'pencil' && (\n <label className=\"flex items-center gap-1 text-xs text-foreground\">\n Smoothing\n <input\n type=\"range\"\n min={0}\n max={1}\n step={0.05}\n aria-label=\"Pencil smoothing\"\n className=\"h-4 w-20 accent-primary\"\n value={editing.pencilSmoothing}\n onChange={(e) => controller.setEditing({ pencilSmoothing: parseFloat(e.target.value) })}\n />\n </label>\n )}\n {state.tool === 'eraser' && (\n <label className=\"flex items-center gap-1 text-xs text-foreground\">\n Size\n <input\n type=\"number\"\n min={0.5}\n step={1}\n aria-label=\"Eraser size\"\n className=\"h-7 w-16 rounded border border-border bg-background px-1.5 text-xs\"\n value={editing.eraserSize}\n onChange={(e) => {\n const n = parseFloat(e.target.value);\n if (Number.isFinite(n) && n > 0) controller.setEditing({ eraserSize: n });\n }}\n />\n </label>\n )}\n {state.tool === 'paintBucket' && (\n <button\n type=\"button\"\n data-vector-fill-gap=\"\"\n className={buttonClass}\n aria-pressed={editing.fillGap > 0}\n title=\"Close small gaps between path ends when filling\"\n aria-label=\"Close gaps\"\n onClick={() => controller.setEditing({ fillGap: editing.fillGap > 0 ? 0 : VECTOR_FILL_GAP })}\n >\n Gaps\n </button>\n )}\n </div>\n )}\n {showArrange && (\n <>\n <div className=\"ml-1 flex items-center gap-1\" role=\"group\" aria-label=\"Combine\">\n {act('∪', 'Union', () => controller.booleanOp('union'), count < 2)}\n {act('−', 'Subtract', () => controller.booleanOp('subtract'), count < 2)}\n {act('∩', 'Intersect', () => controller.booleanOp('intersect'), count < 2)}\n {act('⊻', 'Exclude', () => controller.booleanOp('exclude'), count < 2)}\n {act('G', 'Group', () => controller.group(), count < 1)}\n {act('U', 'Ungroup', () => controller.ungroup(), !groupSelected)}\n </div>\n <div className=\"ml-1 flex items-center gap-1\" role=\"group\" aria-label=\"Pathfinder\">\n {VECTOR_PATHFINDER_ACTIONS.map((a) => (\n <button\n key={a.id}\n type=\"button\"\n data-vector-pathfinder={a.id}\n className={buttonClass}\n title={a.title}\n aria-label={a.title}\n disabled={count < a.min}\n onClick={() => void controller.pathfinder(a.id)}\n >\n {a.label}\n </button>\n ))}\n </div>\n <div className=\"ml-1 flex items-center gap-1\" role=\"group\" aria-label=\"Arrange\">\n {act('⇈', 'Bring to Front', () => controller.arrange('front'), count < 1)}\n {act('⇊', 'Send to Back', () => controller.arrange('back'), count < 1)}\n {act('⇤', 'Align Left', () => controller.align('left'), count < 1)}\n {act('↔', 'Align Center', () => controller.align('center'), count < 1)}\n {act('⇥', 'Align Right', () => controller.align('right'), count < 1)}\n {act('⤒', 'Align Top', () => controller.align('top'), count < 1)}\n {act('↕', 'Align Middle', () => controller.align('middle'), count < 1)}\n {act('⤓', 'Align Bottom', () => controller.align('bottom'), count < 1)}\n </div>\n </>\n )}\n </div>\n );\n}\n\nexport interface VectorStylePanelProps {\n controller: VectorEditorController;\n className?: string;\n}\n\nconst selectClass = 'h-7 min-w-0 flex-1 rounded border border-border bg-background px-1 text-xs';\nconst numberClass = 'h-7 w-16 rounded border border-border bg-background px-1.5 text-xs';\n\n/**\n * Fill, stroke, stroke width, alignment and width profile, arrowheads, live corner radius and opacity of the\n * selection (corners of the selected points with the direct tool); with nothing selected it\n * edits the defaults for new shapes.\n */\nexport function VectorStylePanel({ controller, className }: VectorStylePanelProps) {\n const state = useVectorEditorState(controller);\n const style = getVectorSelectionStyle(state);\n const d = state.defaults;\n const source = style ?? {\n fill: d.fill ?? null,\n stroke: d.stroke ?? null,\n strokeWidth: d.strokeWidth ?? 1,\n opacity: 1,\n strokeAlign: d.strokeAlign ?? 'center',\n startArrow: d.startArrow ?? null,\n endArrow: d.endArrow ?? null,\n arrowAlign: d.arrowAlign ?? 'extend',\n startArrowScale: d.startArrowScale ?? 1,\n endArrowScale: d.endArrowScale ?? 1,\n widthProfile: widthProfilePresetId(d.strokeWidthProfile),\n cornerRadius: d.cornerRadius,\n cornerKind: d.cornerKind ?? 'round',\n corners: 1,\n hasOpenPath: true,\n };\n const setCorners = (patch: { radius?: number; kind?: VectorCornerKind }) => {\n if (!style) controller.setDefaults({ ...(patch.radius !== undefined ? { cornerRadius: patch.radius } : {}), ...(patch.kind ? { cornerKind: patch.kind } : {}) });\n else if (patch.radius !== undefined) controller.setCornerRadius(patch.radius);\n else if (patch.kind) controller.setCornerKind(patch.kind);\n };\n const setProfile = (id: VectorWidthPreset) => {\n if (style) controller.setWidthProfile(id);\n else controller.setDefaults({ strokeWidthProfile: widthProfilePreset(id)?.length ? widthProfilePreset(id) : null });\n };\n const mixed = (key: keyof NonNullable<typeof style>['mixed']) => (style?.mixed[key] ? <span className=\"text-[11px] text-muted-foreground\">Mixed</span> : null);\n const arrowRow = (end: 'start' | 'end', label: string) => {\n const key = end === 'start' ? 'startArrow' : 'endArrow';\n const scaleKey = end === 'start' ? 'startArrowScale' : 'endArrowScale';\n return (\n <div className=\"flex items-center gap-2\" data-vector-style={key}>\n <span className=\"w-16 text-xs text-foreground\">{label}</span>\n <select aria-label={`${label} arrowhead`} className={selectClass} value={source[key] ?? ''} onChange={(e) => apply({ [key]: (e.target.value || null) as VectorArrowhead | null })}>\n <option value=\"\">None</option>\n {VECTOR_ARROWHEADS.map((h) => (\n <option key={h} value={h}>\n {VECTOR_ARROWHEAD_LABELS[h]}\n </option>\n ))}\n </select>\n <input\n type=\"number\"\n min={0.1}\n step={0.25}\n aria-label={`${label} arrowhead scale`}\n title=\"Scale (× stroke width)\"\n className={numberClass}\n value={source[scaleKey]}\n onChange={(e) => {\n const n = parseFloat(e.target.value);\n if (Number.isFinite(n) && n > 0) apply({ [scaleKey]: n });\n }}\n />\n </div>\n );\n };\n const apply = (patch: Record<string, unknown>) => {\n if (style) controller.setStyle(patch);\n else controller.setDefaults(patch);\n };\n const paintRow = (key: 'fill' | 'stroke', label: string) => {\n const paint = source[key];\n const hex = vectorPaintToHex(paint);\n const on = paint !== null && paint !== 'none';\n return (\n <div className=\"flex items-center gap-2\" data-vector-style={key}>\n <label className=\"flex w-16 items-center gap-1.5 text-xs text-foreground\">\n <input type=\"checkbox\" checked={on} aria-label={`${label} on`} onChange={(e) => apply({ [key]: e.target.checked ? (hex ?? '#000000') : null })} />\n {label}\n </label>\n <input\n type=\"color\"\n aria-label={`${label} colour`}\n className=\"h-7 w-10 cursor-pointer rounded border border-border bg-background disabled:opacity-40\"\n disabled={!on}\n value={hex ?? '#000000'}\n onChange={(e) => apply({ [key]: e.target.value })}\n />\n {on && !hex && <span className=\"truncate text-[11px] text-muted-foreground\">{typeof paint === 'string' ? paint : 'Gradient'}</span>}\n {style?.mixed[key] && <span className=\"text-[11px] text-muted-foreground\">Mixed</span>}\n </div>\n );\n };\n return (\n <div className={`space-y-2 ${className ?? ''}`} aria-label={style ? 'Selection style' : 'New shape style'}>\n <p className=\"text-[11px] font-medium uppercase tracking-wide text-muted-foreground\">{style ? 'Selection' : 'New shapes'}</p>\n {paintRow('fill', 'Fill')}\n {paintRow('stroke', 'Stroke')}\n <label className=\"flex items-center gap-2 text-xs text-foreground\">\n <span className=\"w-16\">Width</span>\n <input\n type=\"number\"\n min={0}\n step={0.5}\n aria-label=\"Stroke width\"\n className=\"h-7 w-20 rounded border border-border bg-background px-1.5 text-xs\"\n value={source.strokeWidth}\n onChange={(e) => {\n const n = parseFloat(e.target.value);\n if (Number.isFinite(n) && n >= 0) apply({ strokeWidth: n });\n }}\n />\n </label>\n <label className=\"flex items-center gap-2 text-xs text-foreground\" data-vector-style=\"strokeAlign\">\n <span className=\"w-16\">Align</span>\n <select aria-label=\"Stroke alignment\" className={selectClass} value={source.strokeAlign} onChange={(e) => apply({ strokeAlign: e.target.value as VectorStrokeAlign })}>\n {(Object.keys(VECTOR_STROKE_ALIGN_LABELS) as VectorStrokeAlign[]).map((a) => (\n <option key={a} value={a}>\n {VECTOR_STROKE_ALIGN_LABELS[a]}\n </option>\n ))}\n </select>\n {mixed('strokeAlign')}\n </label>\n <div className=\"flex items-center gap-2 text-xs text-foreground\" data-vector-style=\"widthProfile\">\n <span className=\"w-16\">Profile</span>\n <select\n aria-label=\"Width profile\"\n className={selectClass}\n value={source.widthProfile}\n onChange={(e) => {\n if (e.target.value !== 'custom') setProfile(e.target.value as VectorWidthPreset);\n }}\n >\n {VECTOR_WIDTH_PRESETS.map((p) => (\n <option key={p.id} value={p.id}>\n {p.label}\n </option>\n ))}\n {source.widthProfile === 'custom' && (\n <option value=\"custom\" disabled>\n Custom\n </option>\n )}\n </select>\n <button\n type=\"button\"\n className={buttonClass}\n title=\"Reset to uniform width\"\n aria-label=\"Reset to uniform width\"\n disabled={source.widthProfile === 'uniform' && !style?.mixed.widthProfile}\n onClick={() => setProfile('uniform')}\n >\n ═\n </button>\n {mixed('widthProfile')}\n </div>\n {source.hasOpenPath && (\n <>\n {arrowRow('start', 'Start')}\n {arrowRow('end', 'End')}\n {(source.startArrow || source.endArrow) && (\n <label className=\"flex items-center gap-2 text-xs text-foreground\" data-vector-style=\"arrowAlign\">\n <span className=\"w-16\">Heads</span>\n <select aria-label=\"Arrowhead alignment\" className={selectClass} value={source.arrowAlign} onChange={(e) => apply({ arrowAlign: e.target.value })}>\n <option value=\"extend\">Tip past end</option>\n <option value=\"tip\">Tip at end</option>\n </select>\n </label>\n )}\n </>\n )}\n {source.corners > 0 && (\n <div className=\"flex items-center gap-2\" data-vector-style=\"corners\">\n <span className=\"w-16 text-xs text-foreground\">Corners</span>\n <input\n type=\"number\"\n min={0}\n step={1}\n aria-label=\"Corner radius\"\n className={numberClass}\n value={Math.round(source.cornerRadius * 100) / 100}\n onChange={(e) => {\n const n = parseFloat(e.target.value);\n if (Number.isFinite(n) && n >= 0) setCorners({ radius: n });\n }}\n />\n <select aria-label=\"Corner kind\" className={selectClass} value={source.cornerKind} onChange={(e) => setCorners({ kind: e.target.value as VectorCornerKind })}>\n {VECTOR_CORNER_KINDS.map((k) => (\n <option key={k} value={k}>\n {VECTOR_CORNER_KIND_LABELS[k]}\n </option>\n ))}\n </select>\n {mixed('cornerRadius')}\n </div>\n )}\n {style && (\n <label className=\"flex items-center gap-2 text-xs text-foreground\">\n <span className=\"w-16\">Opacity</span>\n <input\n type=\"range\"\n min={0}\n max={1}\n step={0.05}\n aria-label=\"Opacity\"\n className=\"h-4 flex-1 accent-primary\"\n value={source.opacity}\n onChange={(e) => apply({ opacity: parseFloat(e.target.value) })}\n />\n </label>\n )}\n </div>\n );\n}\n","import React from 'react';\nimport type { VectorEditorController, VectorTool } from '@pixerate/editor/vector';\nimport { VectorCanvas, type VectorCanvasProps } from './VectorCanvas';\nimport { VectorStylePanel, VectorToolbar } from './VectorToolbar';\n\nexport interface VectorEditorProps {\n controller: VectorEditorController;\n /** Tools in the toolbar (default: all). */\n tools?: readonly VectorTool[];\n /** The style sidebar (default `true`). */\n showStylePanel?: boolean;\n /** Canvas height (default 520px). */\n height?: number | string;\n canvasProps?: Omit<VectorCanvasProps, 'controller'>;\n className?: string;\n}\n\n/** Toolbar, canvas and style panel for a `VectorEditorController`. */\nexport function VectorEditor({ controller, tools, showStylePanel = true, height = 520, canvasProps, className }: VectorEditorProps) {\n return (\n <div className={`flex flex-col gap-2 ${className ?? ''}`} data-vector-editor=\"\">\n <VectorToolbar controller={controller} tools={tools} />\n <div className=\"flex min-h-0 flex-col gap-2 md:flex-row\">\n <div className=\"relative min-h-[320px] flex-1 overflow-hidden rounded-md border border-border bg-muted/40\" style={{ height }}>\n <VectorCanvas controller={controller} {...canvasProps} />\n </div>\n {showStylePanel && <VectorStylePanel controller={controller} className=\"w-full shrink-0 rounded-md border border-border p-3 md:w-56\" />}\n </div>\n </div>\n );\n}\n"],"mappings":"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","names":["import_react","import_vector","import_react","import_vector","THEME","import_jsx_runtime","THEME","text","import_vector","import_jsx_runtime","import_jsx_runtime"]}
|
|
1
|
+
{"version":3,"sources":["../../src/vector/index.ts","../../src/vector/useVectorEditor.ts","../../src/vector/VectorCanvas.tsx","../../src/vector/VectorWidthPointEditor.tsx","../../src/vector/VectorToolbar.tsx","../../src/vector/VectorEditor.tsx"],"sourcesContent":["export * from './useVectorEditor';\nexport * from './VectorCanvas';\nexport * from './VectorWidthPointEditor';\nexport * from './VectorToolbar';\nexport * from './VectorEditor';\n","import { useEffect, useMemo, useRef, useSyncExternalStore } from 'react';\nimport {\n VectorEditorController,\n createVectorCommands,\n type VectorCommandOptions,\n type VectorEditorOptions,\n type VectorEditorState,\n type VectorTool,\n} from '@pixerate/editor/vector';\n\n/** A `VectorEditorController` created once for the component's lifetime (destroyed on unmount). */\nexport function useVectorEditorController(options: VectorEditorOptions = {}): VectorEditorController {\n const ref = useRef<VectorEditorController | null>(null);\n if (!ref.current) ref.current = new VectorEditorController(options);\n const controller = ref.current;\n useEffect(() => () => controller.destroy(), [controller]);\n return controller;\n}\n\n/** The controller's state (re-renders on every change). */\nexport function useVectorEditorState(controller: VectorEditorController): VectorEditorState {\n return useSyncExternalStore(controller.subscribe, controller.getState, controller.getState);\n}\n\nexport interface UseVectorEditorResult {\n controller: VectorEditorController;\n state: VectorEditorState;\n setTool: (tool: VectorTool) => void;\n undo: () => void;\n redo: () => void;\n deleteSelection: () => void;\n toSvg: () => string;\n}\n\n/**\n * Subscribes to a vector editor controller and exposes its state with bound actions. Pass\n * options instead of a controller to create one for the component's lifetime.\n */\nexport function useVectorEditor(controllerOrOptions: VectorEditorController | VectorEditorOptions = {}): UseVectorEditorResult {\n const own = useRef<VectorEditorController | null>(null);\n let controller: VectorEditorController;\n if (controllerOrOptions instanceof VectorEditorController) controller = controllerOrOptions;\n else {\n if (!own.current) own.current = new VectorEditorController(controllerOrOptions);\n controller = own.current;\n }\n const state = useVectorEditorState(controller);\n const actions = useMemo(\n () => ({\n setTool: (tool: VectorTool) => controller.setTool(tool),\n undo: () => void controller.undo(),\n redo: () => void controller.redo(),\n deleteSelection: () => void controller.deleteSelection(),\n toSvg: () => controller.toSvg(),\n }),\n [controller],\n );\n return { controller, state, ...actions };\n}\n\n/** Anything with `register(specs) → unregister` (a `CommandRegistry`). */\nexport interface VectorCommandTarget {\n register(specs: any): () => void;\n}\n\n/**\n * Registers the controller's palette / agent commands (`vector.addShape`, `vector.boolean`, …)\n * in `registry` while mounted, so `createCommandToolProvider` exposes them to agents.\n */\nexport function useVectorCommands(\n registry: VectorCommandTarget | null | undefined,\n controller: VectorEditorController,\n options: VectorCommandOptions = {},\n): void {\n const { prefix, group, scope } = options;\n useEffect(() => {\n if (!registry) return;\n return registry.register(createVectorCommands(controller, { prefix, group, scope }));\n }, [registry, controller, prefix, group, scope]);\n}\n","import React, { useEffect, useId, useRef } from 'react';\nimport {\n VECTOR_OVERLAY_THEME as THEME,\n getVectorOverlayRenderData,\n getVectorSceneRenderData,\n isVectorTextTarget,\n toVectorKeyInput,\n toVectorPointerInput,\n vectorDiamondPath,\n type VectorEditorController,\n type VectorRenderNode,\n type VectorRenderPath,\n type SvgGradientDef,\n} from '@pixerate/editor/vector';\nimport { useVectorEditorState } from './useVectorEditor';\nimport { VectorWidthPointEditor } from './VectorWidthPointEditor';\n\nexport interface VectorCanvasProps {\n controller: VectorEditorController;\n /** Fit the artboard into the canvas when it first gets a size (default `true`). */\n fitOnMount?: boolean;\n /** Draw a checkerboard behind a transparent artboard (default `true`). */\n checkerboard?: boolean;\n /** Overlay accent colour (default sky blue). */\n accentColor?: string;\n /** Smart guide colour (default magenta). */\n guideColor?: string;\n className?: string;\n style?: React.CSSProperties;\n /** Accessible label (default \"Vector canvas\"). */\n 'aria-label'?: string;\n}\n\n/** Renders `<linearGradient>` / `<radialGradient>` descriptors. */\nexport function VectorGradientDefs({ defs }: { defs: readonly SvgGradientDef[] }) {\n if (!defs.length) return null;\n return (\n <defs>\n {defs.map((def) => {\n const stops = def.stops.map((s, i) => <stop key={i} offset={s.offset} stopColor={s.stopColor} stopOpacity={s.stopOpacity} />);\n return def.type === 'radial' ? (\n <radialGradient key={def.id} id={def.id} {...(def.attrs as any)}>\n {stops}\n </radialGradient>\n ) : (\n <linearGradient key={def.id} id={def.id} {...(def.attrs as any)}>\n {stops}\n </linearGradient>\n );\n })}\n </defs>\n );\n}\n\n/** Renders scene nodes (paths and groups) from `getVectorSceneRenderData`. */\nexport function VectorSceneNodes({ nodes }: { nodes: readonly VectorRenderNode[] }) {\n return (\n <>\n {nodes.map((node) =>\n node.kind === 'group' ? (\n <g key={node.id} data-vector-id={node.id} transform={node.transform} opacity={node.opacity < 1 ? node.opacity : undefined}>\n <VectorSceneNodes nodes={node.children} />\n </g>\n ) : node.strokeParts ? (\n <VectorPartedPath key={node.id} node={node} />\n ) : (\n <path\n key={node.id}\n data-vector-id={node.id}\n transform={node.transform}\n d={node.d}\n fill={node.fill}\n fillRule={node.fillRule}\n stroke={node.stroke}\n strokeWidth={node.stroke === 'none' ? undefined : node.strokeWidth}\n strokeLinecap={node.strokeLinecap as any}\n strokeLinejoin={node.strokeLinejoin as any}\n strokeDasharray={node.strokeDasharray}\n opacity={node.opacity < 1 ? node.opacity : undefined}\n />\n ),\n )}\n </>\n );\n}\n\n/** A path whose stroke is aligned inside / outside (double width, clipped or masked by the shape) or has arrowheads. */\nfunction VectorPartedPath({ node }: { node: VectorRenderPath }) {\n const sp = node.strokeParts!;\n const clip = sp.clip;\n const b = clip?.bounds;\n return (\n <g data-vector-id={node.id} data-vector-stroke-align={sp.align} transform={node.transform} opacity={node.opacity < 1 ? node.opacity : undefined}>\n {clip && b && (\n <defs>\n {clip.kind === 'clip' ? (\n <clipPath id={clip.id}>\n <path d={node.d} clipRule={node.fillRule} />\n </clipPath>\n ) : (\n <mask id={clip.id} maskUnits=\"userSpaceOnUse\" x={b.x} y={b.y} width={b.width} height={b.height}>\n <rect x={b.x} y={b.y} width={b.width} height={b.height} fill=\"#fff\" />\n <path d={node.d} fill=\"#000\" fillRule={node.fillRule} />\n </mask>\n )}\n </defs>\n )}\n <path data-vector-part=\"fill\" d={node.d} fill={node.fill} fillRule={node.fillRule} stroke=\"none\" />\n {sp.outline !== undefined ? (\n // A variable-width stroke: its outline, filled.\n <path\n data-vector-part=\"stroke-outline\"\n d={sp.outline}\n fill={node.stroke}\n clipPath={clip?.kind === 'clip' ? `url(#${clip.id})` : undefined}\n mask={clip?.kind === 'mask' ? `url(#${clip.id})` : undefined}\n />\n ) : (\n <path\n data-vector-part=\"stroke\"\n d={sp.d}\n fill=\"none\"\n stroke={node.stroke}\n strokeWidth={sp.width}\n strokeLinecap={node.strokeLinecap as any}\n strokeLinejoin={node.strokeLinejoin as any}\n strokeDasharray={node.strokeDasharray}\n clipPath={clip?.kind === 'clip' ? `url(#${clip.id})` : undefined}\n mask={clip?.kind === 'mask' ? `url(#${clip.id})` : undefined}\n />\n )}\n {sp.heads.map((head, i) => (\n <path key={i} data-vector-part=\"head\" d={head} fill={node.stroke} />\n ))}\n </g>\n );\n}\n\n/**\n * An SVG canvas for a `VectorEditorController`: draws the document and the editing overlay\n * and forwards pointer, wheel, keyboard and clipboard events. Focus it to use shortcuts.\n */\nexport function VectorCanvas({\n controller,\n fitOnMount = true,\n checkerboard = true,\n accentColor = THEME.accent,\n guideColor = THEME.guide,\n className,\n style,\n 'aria-label': ariaLabel = 'Vector canvas',\n}: VectorCanvasProps) {\n const state = useVectorEditorState(controller);\n const svgRef = useRef<SVGSVGElement | null>(null);\n const fitted = useRef(!fitOnMount);\n const uid = useId().replace(/:/g, '');\n const scene = getVectorSceneRenderData(state, { idPrefix: `ve${uid}-` });\n const overlay = getVectorOverlayRenderData(state);\n\n useEffect(() => {\n const el = svgRef.current;\n if (!el || fitted.current) return;\n const fit = () => {\n const rect = el.getBoundingClientRect();\n if (fitted.current || rect.width <= 0 || rect.height <= 0) return;\n fitted.current = true;\n controller.zoomToFit({ width: rect.width, height: rect.height });\n };\n fit();\n if (fitted.current || typeof ResizeObserver === 'undefined') return;\n const observer = new ResizeObserver(fit);\n observer.observe(el);\n return () => observer.disconnect();\n }, [controller]);\n\n // Wheel needs a non-passive listener to stop page scroll / browser zoom.\n useEffect(() => {\n const el = svgRef.current;\n if (!el) return;\n const onWheel = (e: WheelEvent) => {\n e.preventDefault();\n controller.wheel(local(e), { x: e.deltaX, y: e.deltaY }, toVectorPointerInput(e));\n };\n el.addEventListener('wheel', onWheel, { passive: false });\n return () => el.removeEventListener('wheel', onWheel);\n }, [controller]);\n\n const local = (e: { clientX: number; clientY: number }) => {\n const rect = svgRef.current?.getBoundingClientRect();\n return { x: e.clientX - (rect?.left ?? 0), y: e.clientY - (rect?.top ?? 0) };\n };\n\n const clipboard = (kind: 'copy' | 'cut' | 'paste') => (event: React.ClipboardEvent) => {\n const native = (event && 'nativeEvent' in event ? event.nativeEvent : event) as ClipboardEvent;\n const data = native?.clipboardData;\n if (kind === 'paste') {\n const text = data?.getData('text/plain') ?? '';\n const pasted = text ? controller.paste(text) : controller.paste();\n if (pasted.length) event.preventDefault?.();\n return;\n }\n const text = kind === 'cut' ? controller.cut() : controller.copy();\n if (text && data) {\n data.setData('text/plain', text);\n event.preventDefault?.();\n }\n };\n\n const hs = THEME.transformHandleSize;\n const as = THEME.anchorSize;\n const box = overlay.selectionBox;\n const edit = state.widthPointEdit;\n const editAt = edit && { x: edit.point.x * state.viewport.zoom + state.viewport.x, y: edit.point.y * state.viewport.zoom + state.viewport.y };\n\n return (\n <svg\n ref={svgRef}\n role=\"application\"\n aria-label={ariaLabel}\n tabIndex={0}\n data-tool={state.tool}\n className={className}\n style={{ display: 'block', width: '100%', height: '100%', outline: 'none', touchAction: 'none', userSelect: 'none', cursor: state.cursor, ...style }}\n onPointerDown={(e) => {\n svgRef.current?.focus({ preventScroll: true });\n (e.currentTarget as Element).setPointerCapture?.(e.pointerId);\n controller.pointerDown(local(e), toVectorPointerInput(e));\n }}\n onPointerMove={(e) => controller.pointerMove(local(e), toVectorPointerInput(e))}\n onPointerUp={(e) => {\n (e.currentTarget as Element).releasePointerCapture?.(e.pointerId);\n controller.pointerUp(local(e), toVectorPointerInput(e));\n }}\n onPointerCancel={() => controller.cancelDrag()}\n onPointerLeave={() => controller.pointerLeave()}\n onDoubleClick={(e) => controller.doubleClick(local(e))}\n onKeyDown={(e) => {\n if (isVectorTextTarget(e.target)) return;\n if (controller.keyDown(toVectorKeyInput(e))) e.preventDefault();\n }}\n onKeyUp={(e) => controller.keyUp(toVectorKeyInput(e))}\n onCopy={clipboard('copy')}\n onCut={clipboard('cut')}\n onPaste={clipboard('paste')}\n >\n {checkerboard && (\n <defs>\n <pattern id={`ve${uid}-checker`} width={16} height={16} patternUnits=\"userSpaceOnUse\">\n <rect width={16} height={16} fill=\"#ffffff\" />\n <rect width={8} height={8} fill=\"#e5e7eb\" />\n <rect x={8} y={8} width={8} height={8} fill=\"#e5e7eb\" />\n </pattern>\n </defs>\n )}\n <VectorGradientDefs defs={scene.defs} />\n <rect\n data-vector-artboard=\"\"\n x={overlay.artboard.x}\n y={overlay.artboard.y}\n width={overlay.artboard.width}\n height={overlay.artboard.height}\n fill={scene.background ?? (checkerboard ? `url(#ve${uid}-checker)` : '#ffffff')}\n stroke=\"rgba(0,0,0,0.12)\"\n />\n <g data-vector-scene=\"\" transform={scene.transform}>\n <VectorSceneNodes nodes={scene.nodes} />\n </g>\n <g data-vector-overlay=\"\" pointerEvents=\"none\" fill=\"none\">\n {overlay.outlines.map((o) => (\n <path key={o.id} d={o.d} stroke={accentColor} strokeWidth={o.selected ? 1 : 1.5} opacity={o.selected ? 1 : 0.7} />\n ))}\n {overlay.penPreview && <path d={overlay.penPreview} stroke={accentColor} strokeDasharray=\"4 3\" />}\n {box && (\n <g data-vector-selection=\"\" transform={box.transform || undefined}>\n <rect x={box.x} y={box.y} width={box.width} height={box.height} stroke={accentColor} />\n <line x1={box.x + box.width / 2} y1={box.y} x2={box.x + box.width / 2} y2={box.y - 24} stroke={accentColor} />\n {box.handles.map((h) =>\n h.handle === 'rotate' ? (\n <circle key={h.handle} data-handle={h.handle} cx={h.x} cy={h.y} r={hs / 2 + 1} fill={THEME.handleFill} stroke={accentColor} />\n ) : (\n <rect key={h.handle} data-handle={h.handle} x={h.x - hs / 2} y={h.y - hs / 2} width={hs} height={hs} fill={THEME.handleFill} stroke={accentColor} />\n ),\n )}\n </g>\n )}\n {overlay.handles.map((h) => (\n <g key={`${h.ref.nodeId}:${h.ref.subpath}:${h.ref.index}:${h.ref.handle}`} data-vector-handle={h.ref.handle}>\n <line x1={h.anchorX} y1={h.anchorY} x2={h.x} y2={h.y} stroke={accentColor} />\n <circle cx={h.x} cy={h.y} r={THEME.handleRadius + (h.hovered ? 1 : 0)} fill={THEME.handleFill} stroke={accentColor} />\n </g>\n ))}\n {overlay.anchors.map((a) => {\n const size = as + (a.hovered ? 2 : 0);\n const fill = a.selected ? accentColor : THEME.handleFill;\n const key = `${a.ref.nodeId}:${a.ref.subpath}:${a.ref.index}`;\n return a.type === 'corner' ? (\n <rect key={key} data-vector-anchor={a.ref.index} x={a.x - size / 2} y={a.y - size / 2} width={size} height={size} fill={fill} stroke={accentColor} />\n ) : (\n <circle key={key} data-vector-anchor={a.ref.index} cx={a.x} cy={a.y} r={size / 2} fill={fill} stroke={accentColor} />\n );\n })}\n {overlay.cornerWidgets.map((w) => (\n <g key={`corner:${w.ref.nodeId}:${w.ref.subpath}:${w.ref.index}`} data-vector-corner-widget={w.ref.index} data-corner-kind={w.kind}>\n <circle cx={w.x} cy={w.y} r={THEME.cornerWidgetRadius + (w.hovered ? 1 : 0)} fill={THEME.handleFill} stroke={accentColor} />\n <circle cx={w.x} cy={w.y} r={1.5} fill={accentColor} />\n </g>\n ))}\n {overlay.blend.spines.map((sp) => (\n <g key={`blend:${sp.id}`} data-vector-blend-spine={sp.id} data-replaced={sp.replaced || undefined}>\n <path d={sp.d} fill=\"none\" stroke={accentColor} strokeDasharray=\"4 3\" />\n {sp.keys.map((k, i) => (\n <circle key={i} cx={k.x} cy={k.y} r={THEME.handleRadius} fill={THEME.handleFill} stroke={accentColor} />\n ))}\n </g>\n ))}\n {overlay.blend.start && (\n <g data-vector-blend-start=\"\">\n <path d={overlay.blend.start.d} fill=\"none\" stroke={accentColor} strokeWidth={2} />\n {overlay.blend.start.anchor && <circle cx={overlay.blend.start.anchor.x} cy={overlay.blend.start.anchor.y} r={THEME.handleRadius + 1} fill={accentColor} />}\n </g>\n )}\n {overlay.blend.anchors.map((a, i) => (\n <rect\n key={`blend-anchor:${i}`}\n data-vector-blend-anchor={i}\n x={a.x - as / 2}\n y={a.y - as / 2}\n width={as}\n height={as}\n fill={a.hovered ? accentColor : THEME.handleFill}\n stroke={accentColor}\n />\n ))}\n {overlay.widthSpot && (\n <g data-vector-width-spot=\"\">\n <line x1={overlay.widthSpot.left.x} y1={overlay.widthSpot.left.y} x2={overlay.widthSpot.right.x} y2={overlay.widthSpot.right.y} stroke={accentColor} strokeDasharray=\"3 2\" />\n <path d={vectorDiamondPath(overlay.widthSpot.x, overlay.widthSpot.y)} fill=\"none\" stroke={accentColor} />\n </g>\n )}\n {overlay.widthPoints.map((w) => (\n <g key={`width:${w.ref.nodeId}:${w.ref.subpath}:${w.ref.index}`} data-vector-width-point={w.ref.index} data-selected={w.selected || undefined}>\n <line x1={w.left.x} y1={w.left.y} x2={w.right.x} y2={w.right.y} stroke={accentColor} />\n <path d={vectorDiamondPath(w.x, w.y)} fill={w.selected || w.active ? accentColor : THEME.handleFill} stroke={accentColor} strokeWidth={w.hovered === 'center' ? 2 : 1} />\n {(['left', 'right'] as const).map((side) => (\n <circle key={side} data-vector-width-side={side} cx={w[side].x} cy={w[side].y} r={THEME.handleRadius + (w.hovered === side ? 1 : 0)} fill={THEME.handleFill} stroke={accentColor} />\n ))}\n </g>\n ))}\n {state.tool === 'pen' && overlay.anchors.some((a) => a.closes && a.hovered) && (\n <circle cx={overlay.anchors.find((a) => a.closes)!.x} cy={overlay.anchors.find((a) => a.closes)!.y} r={as} stroke={accentColor} />\n )}\n {overlay.builder && (\n <g data-vector-builder={overlay.builder.mode}>\n {overlay.builder.faces.map((d, i) => (\n <path\n key={`f${i}`}\n data-vector-builder-face=\"\"\n d={d}\n fill={overlay.builder!.mode === 'erase' ? THEME.builderEraseFill : THEME.builderFill}\n fillRule=\"nonzero\"\n stroke={overlay.builder!.mode === 'erase' ? THEME.builderErase : accentColor}\n strokeWidth={1}\n />\n ))}\n {overlay.builder.hatches.map((d, i) =>\n d ? (\n <path\n key={`h${i}`}\n data-vector-builder-hatch=\"\"\n d={d}\n fill=\"none\"\n stroke={overlay.builder!.mode === 'erase' ? THEME.builderErase : accentColor}\n strokeOpacity={THEME.builderHatchOpacity}\n strokeWidth={1}\n />\n ) : null\n )}\n {overlay.builder.lines.map((d, i) => (\n <path key={`l${i}`} data-vector-builder-line=\"\" d={d} fill=\"none\" stroke={THEME.builderErase} strokeWidth={3} strokeLinecap=\"round\" />\n ))}\n {overlay.builder.trail && <path data-vector-builder-trail=\"\" d={overlay.builder.trail} fill=\"none\" stroke={overlay.builder.mode === 'erase' ? THEME.builderErase : accentColor} strokeWidth={1} />}\n </g>\n )}\n {overlay.toolStroke && (\n <path\n data-vector-tool-stroke={overlay.toolStroke.tool}\n d={overlay.toolStroke.d}\n stroke={overlay.toolStroke.tool === 'eraser' ? THEME.eraserFill : accentColor}\n strokeWidth={overlay.toolStroke.tool === 'eraser' ? overlay.toolStroke.width : 1}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeDasharray={overlay.toolStroke.tool === 'knife' ? '5 3' : undefined}\n />\n )}\n {overlay.pencilString && (\n <line\n data-vector-pencil-string=\"\"\n x1={overlay.pencilString.x1}\n y1={overlay.pencilString.y1}\n x2={overlay.pencilString.x2}\n y2={overlay.pencilString.y2}\n stroke={accentColor}\n strokeDasharray=\"2 2\"\n />\n )}\n {overlay.cutPoint && <circle data-vector-cut-point=\"\" cx={overlay.cutPoint.x} cy={overlay.cutPoint.y} r={THEME.handleRadius + 1} fill={THEME.handleFill} stroke={accentColor} />}\n {overlay.marquee && (\n <rect\n data-vector-marquee=\"\"\n x={overlay.marquee.x}\n y={overlay.marquee.y}\n width={overlay.marquee.width}\n height={overlay.marquee.height}\n fill={THEME.marqueeFill}\n stroke={accentColor}\n strokeDasharray=\"3 2\"\n />\n )}\n {overlay.guides.lines.length > 0 && (\n <g data-vector-guides=\"\" stroke={guideColor}>\n {overlay.guides.lines.map((l, i) => (\n <line key={i} data-vector-guide={l.kind} x1={l.x1} y1={l.y1} x2={l.x2} y2={l.y2} strokeDasharray={l.kind === 'construction' ? '4 3' : undefined} />\n ))}\n </g>\n )}\n {overlay.guides.labels.map((l, i) => (\n <text\n key={i}\n data-vector-guide-label={l.kind}\n x={l.x + 6}\n y={l.y - 6}\n fontSize={10}\n fill={guideColor}\n stroke=\"#ffffff\"\n strokeWidth={3}\n paintOrder=\"stroke\"\n style={{ fontFamily: 'system-ui, sans-serif' }}\n >\n {l.text}\n </text>\n ))}\n {overlay.status && (\n <text data-vector-status=\"\" x={8} y=\"100%\" dy={-8} fontSize={11} fill={accentColor} style={{ fontFamily: 'system-ui, sans-serif' }}>\n {overlay.status}\n </text>\n )}\n </g>\n {edit && editAt && (\n // Width Point Edit (double-click with the width tool), beside the point.\n <foreignObject data-vector-width-point-edit=\"\" x={editAt.x + 12} y={editAt.y + 12} width={180} height={140} style={{ overflow: 'visible' }}>\n <VectorWidthPointEditor key={`${edit.nodeId}:${edit.index}:${edit.t}`} controller={controller} edit={edit} accentColor={accentColor} />\n </foreignObject>\n )}\n </svg>\n );\n}\n","import React, { useRef, useState } from 'react';\nimport { VECTOR_OVERLAY_THEME as THEME, type VectorEditorController, type VectorWidthPointEdit } from '@pixerate/editor/vector';\n\nexport interface VectorWidthPointEditorProps {\n controller: VectorEditorController;\n /** The point being edited (`state.widthPointEdit`). */\n edit: VectorWidthPointEdit;\n /** Accent colour of the Apply button (default sky blue). */\n accentColor?: string;\n className?: string;\n style?: React.CSSProperties;\n}\n\nconst round = (v: number, digits: number) => String(Math.round(v * 10 ** digits) / 10 ** digits);\n\nconst fieldStyle: React.CSSProperties = { display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 6 };\nconst inputStyle: React.CSSProperties = { width: 72, font: 'inherit', padding: '1px 4px' };\n\n/**\n * Width Point Edit: the position (percent along the path) and the left / right side widths\n * (document units) of the width point a width-tool double-click opened. Apply (or Enter) sets\n * them with `commitWidthPointEdit`; Cancel or Escape closes it. `<VectorCanvas>` shows it next\n * to the point; use it on its own to place it elsewhere.\n */\nexport function VectorWidthPointEditor({ controller, edit, accentColor = THEME.accent, className, style }: VectorWidthPointEditorProps) {\n const [position, setPosition] = useState(() => round(edit.t * 100, 2));\n const [left, setLeft] = useState(() => round(edit.left, 3));\n const [right, setRight] = useState(() => round(edit.right, 3));\n const formRef = useRef<HTMLFormElement | null>(null);\n // Hand the keyboard back to the canvas around it.\n const refocus = () => (formRef.current?.closest('svg') as SVGSVGElement | null)?.focus?.({ preventScroll: true });\n const close = () => {\n refocus();\n controller.closeWidthPointEdit();\n };\n const num = (v: string) => (v.trim() !== '' && Number.isFinite(Number(v)) ? Number(v) : undefined);\n const apply = () => {\n const t = num(position);\n refocus();\n controller.commitWidthPointEdit({ t: t === undefined ? undefined : Math.min(Math.max(t, 0), 100) / 100, left: num(left), right: num(right) });\n };\n const stop = (e: React.SyntheticEvent) => e.stopPropagation();\n return (\n <form\n ref={formRef}\n data-vector-width-point-editor=\"\"\n aria-label=\"Width point\"\n className={className}\n style={{\n display: 'grid',\n gap: 4,\n padding: 8,\n background: '#ffffff',\n border: '1px solid rgba(0,0,0,0.15)',\n borderRadius: 6,\n boxShadow: '0 2px 8px rgba(0,0,0,0.15)',\n font: '12px system-ui, sans-serif',\n color: '#18181b',\n ...style,\n }}\n // Keep the canvas from treating clicks, keys and clipboard use in here as editing gestures.\n onPointerDown={stop}\n onPointerMove={stop}\n onPointerUp={stop}\n onDoubleClick={stop}\n onCopy={stop}\n onCut={stop}\n onPaste={stop}\n onKeyDown={(e) => {\n e.stopPropagation();\n if (e.key === 'Escape') {\n e.preventDefault();\n close();\n }\n }}\n onSubmit={(e) => {\n e.preventDefault();\n apply();\n }}\n >\n <label style={fieldStyle}>\n Position %\n <input aria-label=\"Width point position\" type=\"number\" min={0} max={100} step=\"any\" value={position} onChange={(e) => setPosition(e.target.value)} style={inputStyle} autoFocus />\n </label>\n <label style={fieldStyle}>\n Left\n <input aria-label=\"Width point left side\" type=\"number\" min={0} step=\"any\" value={left} onChange={(e) => setLeft(e.target.value)} style={inputStyle} />\n </label>\n <label style={fieldStyle}>\n Right\n <input aria-label=\"Width point right side\" type=\"number\" min={0} step=\"any\" value={right} onChange={(e) => setRight(e.target.value)} style={inputStyle} />\n </label>\n <div style={{ display: 'flex', justifyContent: 'flex-end', gap: 4, marginTop: 2 }}>\n <button type=\"button\" onClick={close}>\n Cancel\n </button>\n <button type=\"submit\" style={{ background: accentColor, color: '#ffffff', border: 'none', borderRadius: 4, padding: '2px 8px' }}>\n {edit.index === null ? 'Add' : 'Apply'}\n </button>\n </div>\n </form>\n );\n}\n","import React from 'react';\nimport {\n VECTOR_TOOLS,\n VECTOR_TOOL_GLYPHS,\n VECTOR_TOOL_SHORTCUTS,\n VECTOR_EDIT_TOGGLES,\n VECTOR_PATH_ACTIONS,\n VECTOR_PATHFINDER_ACTIONS,\n VECTOR_FILL_GAP,\n VECTOR_ARROWHEADS,\n VECTOR_ARROWHEAD_LABELS,\n VECTOR_CORNER_KINDS,\n VECTOR_CORNER_KIND_LABELS,\n VECTOR_STROKE_ALIGN_LABELS,\n VECTOR_WIDTH_PRESETS,\n VECTOR_BLEND_SPACINGS,\n VECTOR_BLEND_SPACING_LABELS,\n applyVectorBlendOptions,\n getVectorBlendControls,\n getVectorSelectionStyle,\n widthProfilePreset,\n widthProfilePresetId,\n vectorPaintToHex,\n vectorToolLabel,\n type VectorArrowhead,\n type VectorBlendSpacing,\n type VectorCornerKind,\n type VectorEditorController,\n type VectorStrokeAlign,\n type VectorTool,\n type VectorWidthPreset,\n} from '@pixerate/editor/vector';\nimport { useVectorEditorState } from './useVectorEditor';\n\nconst VECTOR_SNAP_TITLE = 'Snap to objects';\nconst modKeyLabel = () => (typeof navigator !== 'undefined' && /Mac|iPhone|iPad/.test(navigator.platform ?? '') ? '⌘' : 'Ctrl');\n\nconst buttonClass =\n 'inline-flex h-8 min-w-8 items-center justify-center rounded-md border border-border bg-background px-2 text-xs font-medium text-foreground hover:bg-muted disabled:cursor-not-allowed disabled:opacity-40 aria-pressed:bg-primary aria-pressed:text-primary-foreground';\n\nexport interface VectorToolbarProps {\n controller: VectorEditorController;\n /** Tools to show (default: all). */\n tools?: readonly VectorTool[];\n /** Undo / redo buttons (default `true`). */\n showHistory?: boolean;\n /** Boolean, Pathfinder, group, arrange and align buttons (default `true`). */\n showArrange?: boolean;\n /** The snapping toggle (default `true`). */\n showSnap?: boolean;\n /**\n * Path editing: Join, Average, Cut at Points, Remove Redundant Points, Smooth, the Keep\n * Shape / Curvature / Shapes toggles, and the pencil smoothing and eraser size inputs while\n * those tools are active (default `true`).\n */\n showPathEdit?: boolean;\n /**\n * Blend: Make Blend, spacing (steps, distance or smooth colour), steps / distance, orient to\n * spine, Replace Spine, Expand and Release (default `true`).\n */\n showBlend?: boolean;\n className?: string;\n}\n\n/** Tool picker plus undo, snapping, boolean operations, grouping, stacking and alignment. */\nexport function VectorToolbar({\n controller,\n tools = VECTOR_TOOLS,\n showHistory = true,\n showArrange = true,\n showSnap = true,\n showPathEdit = true,\n showBlend = true,\n className,\n}: VectorToolbarProps) {\n const state = useVectorEditorState(controller);\n const count = state.selection.length;\n const points = state.tool === 'direct' ? state.selectedAnchors.length : 0;\n const editing = state.editing;\n const groupSelected = state.selection.some((id) => controller.getNode(id)?.type === 'group');\n const act = (label: string, title: string, run: () => unknown, disabled = false) => (\n <button key={label} type=\"button\" className={buttonClass} title={title} aria-label={title} disabled={disabled} onClick={() => void run()}>\n {label}\n </button>\n );\n return (\n <div role=\"toolbar\" aria-label=\"Vector tools\" className={`flex flex-wrap items-center gap-1 ${className ?? ''}`}>\n <div className=\"flex items-center gap-1\" role=\"group\" aria-label=\"Tools\">\n {tools.map((tool) => (\n <button\n key={tool}\n type=\"button\"\n data-vector-tool={tool}\n className={buttonClass}\n aria-pressed={state.tool === tool}\n title={`${vectorToolLabel(tool)} (${VECTOR_TOOL_SHORTCUTS[tool]})`}\n aria-label={vectorToolLabel(tool)}\n onClick={() => controller.setTool(tool)}\n >\n {VECTOR_TOOL_GLYPHS[tool]}\n </button>\n ))}\n </div>\n {showHistory && (\n <div className=\"ml-1 flex items-center gap-1\" role=\"group\" aria-label=\"History\">\n {act('↶', state.canUndo ? `Undo ${state.undoLabel}` : 'Undo', () => controller.undo(), !state.canUndo)}\n {act('↷', state.canRedo ? `Redo ${state.redoLabel}` : 'Redo', () => controller.redo(), !state.canRedo)}\n </div>\n )}\n {showSnap && (\n <div className=\"ml-1 flex items-center gap-1\" role=\"group\" aria-label=\"Snapping\">\n <button\n type=\"button\"\n data-vector-snap=\"\"\n className={buttonClass}\n aria-pressed={state.snap.objects}\n title={`${VECTOR_SNAP_TITLE} (hold ${modKeyLabel()} to bypass)`}\n aria-label={VECTOR_SNAP_TITLE}\n onClick={() => controller.toggleSnapping()}\n >\n Snap\n </button>\n </div>\n )}\n {showPathEdit && (\n <div className=\"ml-1 flex items-center gap-1\" role=\"group\" aria-label=\"Path editing\">\n {VECTOR_PATH_ACTIONS.map((a) => (\n <button\n key={a.id}\n type=\"button\"\n data-vector-path-action={a.id}\n className={buttonClass}\n title={a.shortcut ? `${a.title} (${modKeyLabel()}+${a.shortcut})` : a.title}\n aria-label={a.title}\n disabled={!a.enabled(count, points)}\n onClick={() => void a.run(controller)}\n >\n {a.label}\n </button>\n ))}\n {VECTOR_EDIT_TOGGLES.map((t) => (\n <button\n key={t.key}\n type=\"button\"\n data-vector-edit={t.key}\n className={buttonClass}\n aria-pressed={editing[t.key]}\n title={t.title}\n aria-label={t.title}\n onClick={() => controller.setEditing({ [t.key]: !editing[t.key] })}\n >\n {t.label}\n </button>\n ))}\n {state.tool === 'pencil' && (\n <label className=\"flex items-center gap-1 text-xs text-foreground\">\n Smoothing\n <input\n type=\"range\"\n min={0}\n max={1}\n step={0.05}\n aria-label=\"Pencil smoothing\"\n className=\"h-4 w-20 accent-primary\"\n value={editing.pencilSmoothing}\n onChange={(e) => controller.setEditing({ pencilSmoothing: parseFloat(e.target.value) })}\n />\n </label>\n )}\n {state.tool === 'eraser' && (\n <label className=\"flex items-center gap-1 text-xs text-foreground\">\n Size\n <input\n type=\"number\"\n min={0.5}\n step={1}\n aria-label=\"Eraser size\"\n className=\"h-7 w-16 rounded border border-border bg-background px-1.5 text-xs\"\n value={editing.eraserSize}\n onChange={(e) => {\n const n = parseFloat(e.target.value);\n if (Number.isFinite(n) && n > 0) controller.setEditing({ eraserSize: n });\n }}\n />\n </label>\n )}\n {state.tool === 'paintBucket' && (\n <button\n type=\"button\"\n data-vector-fill-gap=\"\"\n className={buttonClass}\n aria-pressed={editing.fillGap > 0}\n title=\"Close small gaps between path ends when filling\"\n aria-label=\"Close gaps\"\n onClick={() => controller.setEditing({ fillGap: editing.fillGap > 0 ? 0 : VECTOR_FILL_GAP })}\n >\n Gaps\n </button>\n )}\n </div>\n )}\n {showBlend && <VectorBlendControls controller={controller} />}\n {showArrange && (\n <>\n <div className=\"ml-1 flex items-center gap-1\" role=\"group\" aria-label=\"Combine\">\n {act('∪', 'Union', () => controller.booleanOp('union'), count < 2)}\n {act('−', 'Subtract', () => controller.booleanOp('subtract'), count < 2)}\n {act('∩', 'Intersect', () => controller.booleanOp('intersect'), count < 2)}\n {act('⊻', 'Exclude', () => controller.booleanOp('exclude'), count < 2)}\n {act('G', 'Group', () => controller.group(), count < 1)}\n {act('U', 'Ungroup', () => controller.ungroup(), !groupSelected)}\n </div>\n <div className=\"ml-1 flex items-center gap-1\" role=\"group\" aria-label=\"Pathfinder\">\n {VECTOR_PATHFINDER_ACTIONS.map((a) => (\n <button\n key={a.id}\n type=\"button\"\n data-vector-pathfinder={a.id}\n className={buttonClass}\n title={a.title}\n aria-label={a.title}\n disabled={count < a.min}\n onClick={() => void controller.pathfinder(a.id)}\n >\n {a.label}\n </button>\n ))}\n </div>\n <div className=\"ml-1 flex items-center gap-1\" role=\"group\" aria-label=\"Arrange\">\n {act('⇈', 'Bring to Front', () => controller.arrange('front'), count < 1)}\n {act('⇊', 'Send to Back', () => controller.arrange('back'), count < 1)}\n {act('⇤', 'Align Left', () => controller.align('left'), count < 1)}\n {act('↔', 'Align Center', () => controller.align('center'), count < 1)}\n {act('⇥', 'Align Right', () => controller.align('right'), count < 1)}\n {act('⤒', 'Align Top', () => controller.align('top'), count < 1)}\n {act('↕', 'Align Middle', () => controller.align('middle'), count < 1)}\n {act('⤓', 'Align Bottom', () => controller.align('bottom'), count < 1)}\n </div>\n </>\n )}\n </div>\n );\n}\n\n/** Blend buttons and options: they edit the selected blends and the options new blends get. */\nfunction VectorBlendControls({ controller }: { controller: VectorEditorController }) {\n const state = useVectorEditorState(controller);\n const blend = getVectorBlendControls(state);\n const o = blend.options;\n const selected = blend.ids.length > 0;\n return (\n <div className=\"ml-1 flex items-center gap-1\" role=\"group\" aria-label=\"Blend\" data-vector-blend-controls=\"\">\n <button type=\"button\" data-vector-blend-action=\"make\" className={buttonClass} title=\"Make Blend\" aria-label=\"Make Blend\" disabled={!blend.canBlend} onClick={() => controller.blend()}>\n ⧓\n </button>\n <select\n aria-label=\"Blend spacing\"\n className=\"h-7 rounded border border-border bg-background px-1 text-xs\"\n value={o.spacing}\n onChange={(e) => applyVectorBlendOptions(controller, { spacing: e.target.value as VectorBlendSpacing })}\n >\n {VECTOR_BLEND_SPACINGS.map((sp) => (\n <option key={sp} value={sp}>\n {VECTOR_BLEND_SPACING_LABELS[sp]}\n </option>\n ))}\n </select>\n {o.spacing !== 'smoothColor' && (\n <input\n type=\"number\"\n min={o.spacing === 'steps' ? 1 : 0.5}\n step={1}\n aria-label={o.spacing === 'steps' ? 'Blend steps' : 'Blend distance'}\n className=\"h-7 w-16 rounded border border-border bg-background px-1.5 text-xs\"\n value={o.spacing === 'steps' ? o.steps : o.distance}\n onChange={(e) => {\n const n = parseFloat(e.target.value);\n if (!Number.isFinite(n) || n <= 0) return;\n applyVectorBlendOptions(controller, o.spacing === 'steps' ? { steps: n } : { distance: n });\n }}\n />\n )}\n <button\n type=\"button\"\n data-vector-blend-action=\"orient\"\n className={buttonClass}\n aria-pressed={o.orientToSpine}\n title=\"Orient steps to the spine\"\n aria-label=\"Orient to spine\"\n onClick={() => applyVectorBlendOptions(controller, { orientToSpine: !o.orientToSpine })}\n >\n ⤿\n </button>\n <button\n type=\"button\"\n data-vector-blend-action=\"spine\"\n className={buttonClass}\n title=\"Replace Spine (select a blend and a path)\"\n aria-label=\"Replace Spine\"\n disabled={!blend.canReplaceSpine}\n onClick={() => controller.replaceBlendSpine()}\n >\n ⌇\n </button>\n <button type=\"button\" data-vector-blend-action=\"expand\" className={buttonClass} title=\"Expand Blend\" aria-label=\"Expand Blend\" disabled={!selected} onClick={() => controller.expandBlend()}>\n ⧉\n </button>\n <button type=\"button\" data-vector-blend-action=\"release\" className={buttonClass} title=\"Release Blend\" aria-label=\"Release Blend\" disabled={!selected} onClick={() => controller.releaseBlend()}>\n ⧄\n </button>\n </div>\n );\n}\n\nexport interface VectorStylePanelProps {\n controller: VectorEditorController;\n className?: string;\n}\n\nconst selectClass = 'h-7 min-w-0 flex-1 rounded border border-border bg-background px-1 text-xs';\nconst numberClass = 'h-7 w-16 rounded border border-border bg-background px-1.5 text-xs';\n\n/**\n * Fill, stroke, stroke width, alignment and width profile, arrowheads, live corner radius and opacity of the\n * selection (corners of the selected points with the direct tool); with nothing selected it\n * edits the defaults for new shapes.\n */\nexport function VectorStylePanel({ controller, className }: VectorStylePanelProps) {\n const state = useVectorEditorState(controller);\n const style = getVectorSelectionStyle(state);\n const d = state.defaults;\n const source = style ?? {\n fill: d.fill ?? null,\n stroke: d.stroke ?? null,\n strokeWidth: d.strokeWidth ?? 1,\n opacity: 1,\n strokeAlign: d.strokeAlign ?? 'center',\n startArrow: d.startArrow ?? null,\n endArrow: d.endArrow ?? null,\n arrowAlign: d.arrowAlign ?? 'extend',\n startArrowScale: d.startArrowScale ?? 1,\n endArrowScale: d.endArrowScale ?? 1,\n widthProfile: widthProfilePresetId(d.strokeWidthProfile),\n cornerRadius: d.cornerRadius,\n cornerKind: d.cornerKind ?? 'round',\n corners: 1,\n hasOpenPath: true,\n };\n const setCorners = (patch: { radius?: number; kind?: VectorCornerKind }) => {\n if (!style) controller.setDefaults({ ...(patch.radius !== undefined ? { cornerRadius: patch.radius } : {}), ...(patch.kind ? { cornerKind: patch.kind } : {}) });\n else if (patch.radius !== undefined) controller.setCornerRadius(patch.radius);\n else if (patch.kind) controller.setCornerKind(patch.kind);\n };\n const setProfile = (id: VectorWidthPreset) => {\n if (style) controller.setWidthProfile(id);\n else controller.setDefaults({ strokeWidthProfile: widthProfilePreset(id)?.length ? widthProfilePreset(id) : null });\n };\n const mixed = (key: keyof NonNullable<typeof style>['mixed']) => (style?.mixed[key] ? <span className=\"text-[11px] text-muted-foreground\">Mixed</span> : null);\n const arrowRow = (end: 'start' | 'end', label: string) => {\n const key = end === 'start' ? 'startArrow' : 'endArrow';\n const scaleKey = end === 'start' ? 'startArrowScale' : 'endArrowScale';\n return (\n <div className=\"flex items-center gap-2\" data-vector-style={key}>\n <span className=\"w-16 text-xs text-foreground\">{label}</span>\n <select aria-label={`${label} arrowhead`} className={selectClass} value={source[key] ?? ''} onChange={(e) => apply({ [key]: (e.target.value || null) as VectorArrowhead | null })}>\n <option value=\"\">None</option>\n {VECTOR_ARROWHEADS.map((h) => (\n <option key={h} value={h}>\n {VECTOR_ARROWHEAD_LABELS[h]}\n </option>\n ))}\n </select>\n <input\n type=\"number\"\n min={0.1}\n step={0.25}\n aria-label={`${label} arrowhead scale`}\n title=\"Scale (× stroke width)\"\n className={numberClass}\n value={source[scaleKey]}\n onChange={(e) => {\n const n = parseFloat(e.target.value);\n if (Number.isFinite(n) && n > 0) apply({ [scaleKey]: n });\n }}\n />\n </div>\n );\n };\n const apply = (patch: Record<string, unknown>) => {\n if (style) controller.setStyle(patch);\n else controller.setDefaults(patch);\n };\n const paintRow = (key: 'fill' | 'stroke', label: string) => {\n const paint = source[key];\n const hex = vectorPaintToHex(paint);\n const on = paint !== null && paint !== 'none';\n return (\n <div className=\"flex items-center gap-2\" data-vector-style={key}>\n <label className=\"flex w-16 items-center gap-1.5 text-xs text-foreground\">\n <input type=\"checkbox\" checked={on} aria-label={`${label} on`} onChange={(e) => apply({ [key]: e.target.checked ? (hex ?? '#000000') : null })} />\n {label}\n </label>\n <input\n type=\"color\"\n aria-label={`${label} colour`}\n className=\"h-7 w-10 cursor-pointer rounded border border-border bg-background disabled:opacity-40\"\n disabled={!on}\n value={hex ?? '#000000'}\n onChange={(e) => apply({ [key]: e.target.value })}\n />\n {on && !hex && <span className=\"truncate text-[11px] text-muted-foreground\">{typeof paint === 'string' ? paint : 'Gradient'}</span>}\n {style?.mixed[key] && <span className=\"text-[11px] text-muted-foreground\">Mixed</span>}\n </div>\n );\n };\n return (\n <div className={`space-y-2 ${className ?? ''}`} aria-label={style ? 'Selection style' : 'New shape style'}>\n <p className=\"text-[11px] font-medium uppercase tracking-wide text-muted-foreground\">{style ? 'Selection' : 'New shapes'}</p>\n {paintRow('fill', 'Fill')}\n {paintRow('stroke', 'Stroke')}\n <label className=\"flex items-center gap-2 text-xs text-foreground\">\n <span className=\"w-16\">Width</span>\n <input\n type=\"number\"\n min={0}\n step={0.5}\n aria-label=\"Stroke width\"\n className=\"h-7 w-20 rounded border border-border bg-background px-1.5 text-xs\"\n value={source.strokeWidth}\n onChange={(e) => {\n const n = parseFloat(e.target.value);\n if (Number.isFinite(n) && n >= 0) apply({ strokeWidth: n });\n }}\n />\n </label>\n <label className=\"flex items-center gap-2 text-xs text-foreground\" data-vector-style=\"strokeAlign\">\n <span className=\"w-16\">Align</span>\n <select aria-label=\"Stroke alignment\" className={selectClass} value={source.strokeAlign} onChange={(e) => apply({ strokeAlign: e.target.value as VectorStrokeAlign })}>\n {(Object.keys(VECTOR_STROKE_ALIGN_LABELS) as VectorStrokeAlign[]).map((a) => (\n <option key={a} value={a}>\n {VECTOR_STROKE_ALIGN_LABELS[a]}\n </option>\n ))}\n </select>\n {mixed('strokeAlign')}\n </label>\n <div className=\"flex items-center gap-2 text-xs text-foreground\" data-vector-style=\"widthProfile\">\n <span className=\"w-16\">Profile</span>\n <select\n aria-label=\"Width profile\"\n className={selectClass}\n value={source.widthProfile}\n onChange={(e) => {\n if (e.target.value !== 'custom') setProfile(e.target.value as VectorWidthPreset);\n }}\n >\n {VECTOR_WIDTH_PRESETS.map((p) => (\n <option key={p.id} value={p.id}>\n {p.label}\n </option>\n ))}\n {source.widthProfile === 'custom' && (\n <option value=\"custom\" disabled>\n Custom\n </option>\n )}\n </select>\n <button\n type=\"button\"\n className={buttonClass}\n title=\"Reset to uniform width\"\n aria-label=\"Reset to uniform width\"\n disabled={source.widthProfile === 'uniform' && !style?.mixed.widthProfile}\n onClick={() => setProfile('uniform')}\n >\n ═\n </button>\n {mixed('widthProfile')}\n </div>\n {source.hasOpenPath && (\n <>\n {arrowRow('start', 'Start')}\n {arrowRow('end', 'End')}\n {(source.startArrow || source.endArrow) && (\n <label className=\"flex items-center gap-2 text-xs text-foreground\" data-vector-style=\"arrowAlign\">\n <span className=\"w-16\">Heads</span>\n <select aria-label=\"Arrowhead alignment\" className={selectClass} value={source.arrowAlign} onChange={(e) => apply({ arrowAlign: e.target.value })}>\n <option value=\"extend\">Tip past end</option>\n <option value=\"tip\">Tip at end</option>\n </select>\n </label>\n )}\n </>\n )}\n {source.corners > 0 && (\n <div className=\"flex items-center gap-2\" data-vector-style=\"corners\">\n <span className=\"w-16 text-xs text-foreground\">Corners</span>\n <input\n type=\"number\"\n min={0}\n step={1}\n aria-label=\"Corner radius\"\n className={numberClass}\n value={Math.round(source.cornerRadius * 100) / 100}\n onChange={(e) => {\n const n = parseFloat(e.target.value);\n if (Number.isFinite(n) && n >= 0) setCorners({ radius: n });\n }}\n />\n <select aria-label=\"Corner kind\" className={selectClass} value={source.cornerKind} onChange={(e) => setCorners({ kind: e.target.value as VectorCornerKind })}>\n {VECTOR_CORNER_KINDS.map((k) => (\n <option key={k} value={k}>\n {VECTOR_CORNER_KIND_LABELS[k]}\n </option>\n ))}\n </select>\n {mixed('cornerRadius')}\n </div>\n )}\n {style && (\n <label className=\"flex items-center gap-2 text-xs text-foreground\">\n <span className=\"w-16\">Opacity</span>\n <input\n type=\"range\"\n min={0}\n max={1}\n step={0.05}\n aria-label=\"Opacity\"\n className=\"h-4 flex-1 accent-primary\"\n value={source.opacity}\n onChange={(e) => apply({ opacity: parseFloat(e.target.value) })}\n />\n </label>\n )}\n </div>\n );\n}\n","import React from 'react';\nimport type { VectorEditorController, VectorTool } from '@pixerate/editor/vector';\nimport { VectorCanvas, type VectorCanvasProps } from './VectorCanvas';\nimport { VectorStylePanel, VectorToolbar } from './VectorToolbar';\n\nexport interface VectorEditorProps {\n controller: VectorEditorController;\n /** Tools in the toolbar (default: all). */\n tools?: readonly VectorTool[];\n /** The style sidebar (default `true`). */\n showStylePanel?: boolean;\n /** Canvas height (default 520px). */\n height?: number | string;\n canvasProps?: Omit<VectorCanvasProps, 'controller'>;\n className?: string;\n}\n\n/** Toolbar, canvas and style panel for a `VectorEditorController`. */\nexport function VectorEditor({ controller, tools, showStylePanel = true, height = 520, canvasProps, className }: VectorEditorProps) {\n return (\n <div className={`flex flex-col gap-2 ${className ?? ''}`} data-vector-editor=\"\">\n <VectorToolbar controller={controller} tools={tools} />\n <div className=\"flex min-h-0 flex-col gap-2 md:flex-row\">\n <div className=\"relative min-h-[320px] flex-1 overflow-hidden rounded-md border border-border bg-muted/40\" style={{ height }}>\n <VectorCanvas controller={controller} {...canvasProps} />\n </div>\n {showStylePanel && <VectorStylePanel controller={controller} className=\"w-full shrink-0 rounded-md border border-border p-3 md:w-56\" />}\n </div>\n </div>\n );\n}\n"],"mappings":"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","names":["import_react","import_vector","import_react","import_vector","THEME","import_jsx_runtime","THEME","text","import_vector","import_jsx_runtime","import_jsx_runtime"]}
|
package/dist/vector/index.d.cts
CHANGED
|
@@ -91,10 +91,15 @@ interface VectorToolbarProps {
|
|
|
91
91
|
* those tools are active (default `true`).
|
|
92
92
|
*/
|
|
93
93
|
showPathEdit?: boolean;
|
|
94
|
+
/**
|
|
95
|
+
* Blend: Make Blend, spacing (steps, distance or smooth colour), steps / distance, orient to
|
|
96
|
+
* spine, Replace Spine, Expand and Release (default `true`).
|
|
97
|
+
*/
|
|
98
|
+
showBlend?: boolean;
|
|
94
99
|
className?: string;
|
|
95
100
|
}
|
|
96
101
|
/** Tool picker plus undo, snapping, boolean operations, grouping, stacking and alignment. */
|
|
97
|
-
declare function VectorToolbar({ controller, tools, showHistory, showArrange, showSnap, showPathEdit, className }: VectorToolbarProps): React__default.JSX.Element;
|
|
102
|
+
declare function VectorToolbar({ controller, tools, showHistory, showArrange, showSnap, showPathEdit, showBlend, className, }: VectorToolbarProps): React__default.JSX.Element;
|
|
98
103
|
interface VectorStylePanelProps {
|
|
99
104
|
controller: VectorEditorController;
|
|
100
105
|
className?: string;
|
package/dist/vector/index.d.ts
CHANGED
|
@@ -91,10 +91,15 @@ interface VectorToolbarProps {
|
|
|
91
91
|
* those tools are active (default `true`).
|
|
92
92
|
*/
|
|
93
93
|
showPathEdit?: boolean;
|
|
94
|
+
/**
|
|
95
|
+
* Blend: Make Blend, spacing (steps, distance or smooth colour), steps / distance, orient to
|
|
96
|
+
* spine, Replace Spine, Expand and Release (default `true`).
|
|
97
|
+
*/
|
|
98
|
+
showBlend?: boolean;
|
|
94
99
|
className?: string;
|
|
95
100
|
}
|
|
96
101
|
/** Tool picker plus undo, snapping, boolean operations, grouping, stacking and alignment. */
|
|
97
|
-
declare function VectorToolbar({ controller, tools, showHistory, showArrange, showSnap, showPathEdit, className }: VectorToolbarProps): React__default.JSX.Element;
|
|
102
|
+
declare function VectorToolbar({ controller, tools, showHistory, showArrange, showSnap, showPathEdit, showBlend, className, }: VectorToolbarProps): React__default.JSX.Element;
|
|
98
103
|
interface VectorStylePanelProps {
|
|
99
104
|
controller: VectorEditorController;
|
|
100
105
|
className?: string;
|
package/dist/vector/index.js
CHANGED
|
@@ -348,6 +348,27 @@ function VectorCanvas({
|
|
|
348
348
|
/* @__PURE__ */ jsx2("circle", { cx: w.x, cy: w.y, r: THEME2.cornerWidgetRadius + (w.hovered ? 1 : 0), fill: THEME2.handleFill, stroke: accentColor }),
|
|
349
349
|
/* @__PURE__ */ jsx2("circle", { cx: w.x, cy: w.y, r: 1.5, fill: accentColor })
|
|
350
350
|
] }, `corner:${w.ref.nodeId}:${w.ref.subpath}:${w.ref.index}`)),
|
|
351
|
+
overlay.blend.spines.map((sp) => /* @__PURE__ */ jsxs2("g", { "data-vector-blend-spine": sp.id, "data-replaced": sp.replaced || void 0, children: [
|
|
352
|
+
/* @__PURE__ */ jsx2("path", { d: sp.d, fill: "none", stroke: accentColor, strokeDasharray: "4 3" }),
|
|
353
|
+
sp.keys.map((k, i) => /* @__PURE__ */ jsx2("circle", { cx: k.x, cy: k.y, r: THEME2.handleRadius, fill: THEME2.handleFill, stroke: accentColor }, i))
|
|
354
|
+
] }, `blend:${sp.id}`)),
|
|
355
|
+
overlay.blend.start && /* @__PURE__ */ jsxs2("g", { "data-vector-blend-start": "", children: [
|
|
356
|
+
/* @__PURE__ */ jsx2("path", { d: overlay.blend.start.d, fill: "none", stroke: accentColor, strokeWidth: 2 }),
|
|
357
|
+
overlay.blend.start.anchor && /* @__PURE__ */ jsx2("circle", { cx: overlay.blend.start.anchor.x, cy: overlay.blend.start.anchor.y, r: THEME2.handleRadius + 1, fill: accentColor })
|
|
358
|
+
] }),
|
|
359
|
+
overlay.blend.anchors.map((a, i) => /* @__PURE__ */ jsx2(
|
|
360
|
+
"rect",
|
|
361
|
+
{
|
|
362
|
+
"data-vector-blend-anchor": i,
|
|
363
|
+
x: a.x - as / 2,
|
|
364
|
+
y: a.y - as / 2,
|
|
365
|
+
width: as,
|
|
366
|
+
height: as,
|
|
367
|
+
fill: a.hovered ? accentColor : THEME2.handleFill,
|
|
368
|
+
stroke: accentColor
|
|
369
|
+
},
|
|
370
|
+
`blend-anchor:${i}`
|
|
371
|
+
)),
|
|
351
372
|
overlay.widthSpot && /* @__PURE__ */ jsxs2("g", { "data-vector-width-spot": "", children: [
|
|
352
373
|
/* @__PURE__ */ jsx2("line", { x1: overlay.widthSpot.left.x, y1: overlay.widthSpot.left.y, x2: overlay.widthSpot.right.x, y2: overlay.widthSpot.right.y, stroke: accentColor, strokeDasharray: "3 2" }),
|
|
353
374
|
/* @__PURE__ */ jsx2("path", { d: vectorDiamondPath(overlay.widthSpot.x, overlay.widthSpot.y), fill: "none", stroke: accentColor })
|
|
@@ -467,6 +488,10 @@ import {
|
|
|
467
488
|
VECTOR_CORNER_KIND_LABELS,
|
|
468
489
|
VECTOR_STROKE_ALIGN_LABELS,
|
|
469
490
|
VECTOR_WIDTH_PRESETS,
|
|
491
|
+
VECTOR_BLEND_SPACINGS,
|
|
492
|
+
VECTOR_BLEND_SPACING_LABELS,
|
|
493
|
+
applyVectorBlendOptions,
|
|
494
|
+
getVectorBlendControls,
|
|
470
495
|
getVectorSelectionStyle,
|
|
471
496
|
widthProfilePreset,
|
|
472
497
|
widthProfilePresetId,
|
|
@@ -477,7 +502,16 @@ import { Fragment as Fragment2, jsx as jsx3, jsxs as jsxs3 } from "react/jsx-run
|
|
|
477
502
|
var VECTOR_SNAP_TITLE = "Snap to objects";
|
|
478
503
|
var modKeyLabel = () => typeof navigator !== "undefined" && /Mac|iPhone|iPad/.test(navigator.platform ?? "") ? "\u2318" : "Ctrl";
|
|
479
504
|
var buttonClass = "inline-flex h-8 min-w-8 items-center justify-center rounded-md border border-border bg-background px-2 text-xs font-medium text-foreground hover:bg-muted disabled:cursor-not-allowed disabled:opacity-40 aria-pressed:bg-primary aria-pressed:text-primary-foreground";
|
|
480
|
-
function VectorToolbar({
|
|
505
|
+
function VectorToolbar({
|
|
506
|
+
controller,
|
|
507
|
+
tools = VECTOR_TOOLS,
|
|
508
|
+
showHistory = true,
|
|
509
|
+
showArrange = true,
|
|
510
|
+
showSnap = true,
|
|
511
|
+
showPathEdit = true,
|
|
512
|
+
showBlend = true,
|
|
513
|
+
className
|
|
514
|
+
}) {
|
|
481
515
|
const state = useVectorEditorState(controller);
|
|
482
516
|
const count = state.selection.length;
|
|
483
517
|
const points = state.tool === "direct" ? state.selectedAnchors.length : 0;
|
|
@@ -593,6 +627,7 @@ function VectorToolbar({ controller, tools = VECTOR_TOOLS, showHistory = true, s
|
|
|
593
627
|
}
|
|
594
628
|
)
|
|
595
629
|
] }),
|
|
630
|
+
showBlend && /* @__PURE__ */ jsx3(VectorBlendControls, { controller }),
|
|
596
631
|
showArrange && /* @__PURE__ */ jsxs3(Fragment2, { children: [
|
|
597
632
|
/* @__PURE__ */ jsxs3("div", { className: "ml-1 flex items-center gap-1", role: "group", "aria-label": "Combine", children: [
|
|
598
633
|
act("\u222A", "Union", () => controller.booleanOp("union"), count < 2),
|
|
@@ -629,6 +664,69 @@ function VectorToolbar({ controller, tools = VECTOR_TOOLS, showHistory = true, s
|
|
|
629
664
|
] })
|
|
630
665
|
] });
|
|
631
666
|
}
|
|
667
|
+
function VectorBlendControls({ controller }) {
|
|
668
|
+
const state = useVectorEditorState(controller);
|
|
669
|
+
const blend = getVectorBlendControls(state);
|
|
670
|
+
const o = blend.options;
|
|
671
|
+
const selected = blend.ids.length > 0;
|
|
672
|
+
return /* @__PURE__ */ jsxs3("div", { className: "ml-1 flex items-center gap-1", role: "group", "aria-label": "Blend", "data-vector-blend-controls": "", children: [
|
|
673
|
+
/* @__PURE__ */ jsx3("button", { type: "button", "data-vector-blend-action": "make", className: buttonClass, title: "Make Blend", "aria-label": "Make Blend", disabled: !blend.canBlend, onClick: () => controller.blend(), children: "\u29D3" }),
|
|
674
|
+
/* @__PURE__ */ jsx3(
|
|
675
|
+
"select",
|
|
676
|
+
{
|
|
677
|
+
"aria-label": "Blend spacing",
|
|
678
|
+
className: "h-7 rounded border border-border bg-background px-1 text-xs",
|
|
679
|
+
value: o.spacing,
|
|
680
|
+
onChange: (e) => applyVectorBlendOptions(controller, { spacing: e.target.value }),
|
|
681
|
+
children: VECTOR_BLEND_SPACINGS.map((sp) => /* @__PURE__ */ jsx3("option", { value: sp, children: VECTOR_BLEND_SPACING_LABELS[sp] }, sp))
|
|
682
|
+
}
|
|
683
|
+
),
|
|
684
|
+
o.spacing !== "smoothColor" && /* @__PURE__ */ jsx3(
|
|
685
|
+
"input",
|
|
686
|
+
{
|
|
687
|
+
type: "number",
|
|
688
|
+
min: o.spacing === "steps" ? 1 : 0.5,
|
|
689
|
+
step: 1,
|
|
690
|
+
"aria-label": o.spacing === "steps" ? "Blend steps" : "Blend distance",
|
|
691
|
+
className: "h-7 w-16 rounded border border-border bg-background px-1.5 text-xs",
|
|
692
|
+
value: o.spacing === "steps" ? o.steps : o.distance,
|
|
693
|
+
onChange: (e) => {
|
|
694
|
+
const n = parseFloat(e.target.value);
|
|
695
|
+
if (!Number.isFinite(n) || n <= 0) return;
|
|
696
|
+
applyVectorBlendOptions(controller, o.spacing === "steps" ? { steps: n } : { distance: n });
|
|
697
|
+
}
|
|
698
|
+
}
|
|
699
|
+
),
|
|
700
|
+
/* @__PURE__ */ jsx3(
|
|
701
|
+
"button",
|
|
702
|
+
{
|
|
703
|
+
type: "button",
|
|
704
|
+
"data-vector-blend-action": "orient",
|
|
705
|
+
className: buttonClass,
|
|
706
|
+
"aria-pressed": o.orientToSpine,
|
|
707
|
+
title: "Orient steps to the spine",
|
|
708
|
+
"aria-label": "Orient to spine",
|
|
709
|
+
onClick: () => applyVectorBlendOptions(controller, { orientToSpine: !o.orientToSpine }),
|
|
710
|
+
children: "\u293F"
|
|
711
|
+
}
|
|
712
|
+
),
|
|
713
|
+
/* @__PURE__ */ jsx3(
|
|
714
|
+
"button",
|
|
715
|
+
{
|
|
716
|
+
type: "button",
|
|
717
|
+
"data-vector-blend-action": "spine",
|
|
718
|
+
className: buttonClass,
|
|
719
|
+
title: "Replace Spine (select a blend and a path)",
|
|
720
|
+
"aria-label": "Replace Spine",
|
|
721
|
+
disabled: !blend.canReplaceSpine,
|
|
722
|
+
onClick: () => controller.replaceBlendSpine(),
|
|
723
|
+
children: "\u2307"
|
|
724
|
+
}
|
|
725
|
+
),
|
|
726
|
+
/* @__PURE__ */ jsx3("button", { type: "button", "data-vector-blend-action": "expand", className: buttonClass, title: "Expand Blend", "aria-label": "Expand Blend", disabled: !selected, onClick: () => controller.expandBlend(), children: "\u29C9" }),
|
|
727
|
+
/* @__PURE__ */ jsx3("button", { type: "button", "data-vector-blend-action": "release", className: buttonClass, title: "Release Blend", "aria-label": "Release Blend", disabled: !selected, onClick: () => controller.releaseBlend(), children: "\u29C4" })
|
|
728
|
+
] });
|
|
729
|
+
}
|
|
632
730
|
var selectClass = "h-7 min-w-0 flex-1 rounded border border-border bg-background px-1 text-xs";
|
|
633
731
|
var numberClass = "h-7 w-16 rounded border border-border bg-background px-1.5 text-xs";
|
|
634
732
|
function VectorStylePanel({ controller, className }) {
|
package/dist/vector/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/vector/useVectorEditor.ts","../../src/vector/VectorCanvas.tsx","../../src/vector/VectorWidthPointEditor.tsx","../../src/vector/VectorToolbar.tsx","../../src/vector/VectorEditor.tsx"],"sourcesContent":["import { useEffect, useMemo, useRef, useSyncExternalStore } from 'react';\nimport {\n VectorEditorController,\n createVectorCommands,\n type VectorCommandOptions,\n type VectorEditorOptions,\n type VectorEditorState,\n type VectorTool,\n} from '@pixerate/editor/vector';\n\n/** A `VectorEditorController` created once for the component's lifetime (destroyed on unmount). */\nexport function useVectorEditorController(options: VectorEditorOptions = {}): VectorEditorController {\n const ref = useRef<VectorEditorController | null>(null);\n if (!ref.current) ref.current = new VectorEditorController(options);\n const controller = ref.current;\n useEffect(() => () => controller.destroy(), [controller]);\n return controller;\n}\n\n/** The controller's state (re-renders on every change). */\nexport function useVectorEditorState(controller: VectorEditorController): VectorEditorState {\n return useSyncExternalStore(controller.subscribe, controller.getState, controller.getState);\n}\n\nexport interface UseVectorEditorResult {\n controller: VectorEditorController;\n state: VectorEditorState;\n setTool: (tool: VectorTool) => void;\n undo: () => void;\n redo: () => void;\n deleteSelection: () => void;\n toSvg: () => string;\n}\n\n/**\n * Subscribes to a vector editor controller and exposes its state with bound actions. Pass\n * options instead of a controller to create one for the component's lifetime.\n */\nexport function useVectorEditor(controllerOrOptions: VectorEditorController | VectorEditorOptions = {}): UseVectorEditorResult {\n const own = useRef<VectorEditorController | null>(null);\n let controller: VectorEditorController;\n if (controllerOrOptions instanceof VectorEditorController) controller = controllerOrOptions;\n else {\n if (!own.current) own.current = new VectorEditorController(controllerOrOptions);\n controller = own.current;\n }\n const state = useVectorEditorState(controller);\n const actions = useMemo(\n () => ({\n setTool: (tool: VectorTool) => controller.setTool(tool),\n undo: () => void controller.undo(),\n redo: () => void controller.redo(),\n deleteSelection: () => void controller.deleteSelection(),\n toSvg: () => controller.toSvg(),\n }),\n [controller],\n );\n return { controller, state, ...actions };\n}\n\n/** Anything with `register(specs) → unregister` (a `CommandRegistry`). */\nexport interface VectorCommandTarget {\n register(specs: any): () => void;\n}\n\n/**\n * Registers the controller's palette / agent commands (`vector.addShape`, `vector.boolean`, …)\n * in `registry` while mounted, so `createCommandToolProvider` exposes them to agents.\n */\nexport function useVectorCommands(\n registry: VectorCommandTarget | null | undefined,\n controller: VectorEditorController,\n options: VectorCommandOptions = {},\n): void {\n const { prefix, group, scope } = options;\n useEffect(() => {\n if (!registry) return;\n return registry.register(createVectorCommands(controller, { prefix, group, scope }));\n }, [registry, controller, prefix, group, scope]);\n}\n","import React, { useEffect, useId, useRef } from 'react';\nimport {\n VECTOR_OVERLAY_THEME as THEME,\n getVectorOverlayRenderData,\n getVectorSceneRenderData,\n isVectorTextTarget,\n toVectorKeyInput,\n toVectorPointerInput,\n vectorDiamondPath,\n type VectorEditorController,\n type VectorRenderNode,\n type VectorRenderPath,\n type SvgGradientDef,\n} from '@pixerate/editor/vector';\nimport { useVectorEditorState } from './useVectorEditor';\nimport { VectorWidthPointEditor } from './VectorWidthPointEditor';\n\nexport interface VectorCanvasProps {\n controller: VectorEditorController;\n /** Fit the artboard into the canvas when it first gets a size (default `true`). */\n fitOnMount?: boolean;\n /** Draw a checkerboard behind a transparent artboard (default `true`). */\n checkerboard?: boolean;\n /** Overlay accent colour (default sky blue). */\n accentColor?: string;\n /** Smart guide colour (default magenta). */\n guideColor?: string;\n className?: string;\n style?: React.CSSProperties;\n /** Accessible label (default \"Vector canvas\"). */\n 'aria-label'?: string;\n}\n\n/** Renders `<linearGradient>` / `<radialGradient>` descriptors. */\nexport function VectorGradientDefs({ defs }: { defs: readonly SvgGradientDef[] }) {\n if (!defs.length) return null;\n return (\n <defs>\n {defs.map((def) => {\n const stops = def.stops.map((s, i) => <stop key={i} offset={s.offset} stopColor={s.stopColor} stopOpacity={s.stopOpacity} />);\n return def.type === 'radial' ? (\n <radialGradient key={def.id} id={def.id} {...(def.attrs as any)}>\n {stops}\n </radialGradient>\n ) : (\n <linearGradient key={def.id} id={def.id} {...(def.attrs as any)}>\n {stops}\n </linearGradient>\n );\n })}\n </defs>\n );\n}\n\n/** Renders scene nodes (paths and groups) from `getVectorSceneRenderData`. */\nexport function VectorSceneNodes({ nodes }: { nodes: readonly VectorRenderNode[] }) {\n return (\n <>\n {nodes.map((node) =>\n node.kind === 'group' ? (\n <g key={node.id} data-vector-id={node.id} transform={node.transform} opacity={node.opacity < 1 ? node.opacity : undefined}>\n <VectorSceneNodes nodes={node.children} />\n </g>\n ) : node.strokeParts ? (\n <VectorPartedPath key={node.id} node={node} />\n ) : (\n <path\n key={node.id}\n data-vector-id={node.id}\n transform={node.transform}\n d={node.d}\n fill={node.fill}\n fillRule={node.fillRule}\n stroke={node.stroke}\n strokeWidth={node.stroke === 'none' ? undefined : node.strokeWidth}\n strokeLinecap={node.strokeLinecap as any}\n strokeLinejoin={node.strokeLinejoin as any}\n strokeDasharray={node.strokeDasharray}\n opacity={node.opacity < 1 ? node.opacity : undefined}\n />\n ),\n )}\n </>\n );\n}\n\n/** A path whose stroke is aligned inside / outside (double width, clipped or masked by the shape) or has arrowheads. */\nfunction VectorPartedPath({ node }: { node: VectorRenderPath }) {\n const sp = node.strokeParts!;\n const clip = sp.clip;\n const b = clip?.bounds;\n return (\n <g data-vector-id={node.id} data-vector-stroke-align={sp.align} transform={node.transform} opacity={node.opacity < 1 ? node.opacity : undefined}>\n {clip && b && (\n <defs>\n {clip.kind === 'clip' ? (\n <clipPath id={clip.id}>\n <path d={node.d} clipRule={node.fillRule} />\n </clipPath>\n ) : (\n <mask id={clip.id} maskUnits=\"userSpaceOnUse\" x={b.x} y={b.y} width={b.width} height={b.height}>\n <rect x={b.x} y={b.y} width={b.width} height={b.height} fill=\"#fff\" />\n <path d={node.d} fill=\"#000\" fillRule={node.fillRule} />\n </mask>\n )}\n </defs>\n )}\n <path data-vector-part=\"fill\" d={node.d} fill={node.fill} fillRule={node.fillRule} stroke=\"none\" />\n {sp.outline !== undefined ? (\n // A variable-width stroke: its outline, filled.\n <path\n data-vector-part=\"stroke-outline\"\n d={sp.outline}\n fill={node.stroke}\n clipPath={clip?.kind === 'clip' ? `url(#${clip.id})` : undefined}\n mask={clip?.kind === 'mask' ? `url(#${clip.id})` : undefined}\n />\n ) : (\n <path\n data-vector-part=\"stroke\"\n d={sp.d}\n fill=\"none\"\n stroke={node.stroke}\n strokeWidth={sp.width}\n strokeLinecap={node.strokeLinecap as any}\n strokeLinejoin={node.strokeLinejoin as any}\n strokeDasharray={node.strokeDasharray}\n clipPath={clip?.kind === 'clip' ? `url(#${clip.id})` : undefined}\n mask={clip?.kind === 'mask' ? `url(#${clip.id})` : undefined}\n />\n )}\n {sp.heads.map((head, i) => (\n <path key={i} data-vector-part=\"head\" d={head} fill={node.stroke} />\n ))}\n </g>\n );\n}\n\n/**\n * An SVG canvas for a `VectorEditorController`: draws the document and the editing overlay\n * and forwards pointer, wheel, keyboard and clipboard events. Focus it to use shortcuts.\n */\nexport function VectorCanvas({\n controller,\n fitOnMount = true,\n checkerboard = true,\n accentColor = THEME.accent,\n guideColor = THEME.guide,\n className,\n style,\n 'aria-label': ariaLabel = 'Vector canvas',\n}: VectorCanvasProps) {\n const state = useVectorEditorState(controller);\n const svgRef = useRef<SVGSVGElement | null>(null);\n const fitted = useRef(!fitOnMount);\n const uid = useId().replace(/:/g, '');\n const scene = getVectorSceneRenderData(state, { idPrefix: `ve${uid}-` });\n const overlay = getVectorOverlayRenderData(state);\n\n useEffect(() => {\n const el = svgRef.current;\n if (!el || fitted.current) return;\n const fit = () => {\n const rect = el.getBoundingClientRect();\n if (fitted.current || rect.width <= 0 || rect.height <= 0) return;\n fitted.current = true;\n controller.zoomToFit({ width: rect.width, height: rect.height });\n };\n fit();\n if (fitted.current || typeof ResizeObserver === 'undefined') return;\n const observer = new ResizeObserver(fit);\n observer.observe(el);\n return () => observer.disconnect();\n }, [controller]);\n\n // Wheel needs a non-passive listener to stop page scroll / browser zoom.\n useEffect(() => {\n const el = svgRef.current;\n if (!el) return;\n const onWheel = (e: WheelEvent) => {\n e.preventDefault();\n controller.wheel(local(e), { x: e.deltaX, y: e.deltaY }, toVectorPointerInput(e));\n };\n el.addEventListener('wheel', onWheel, { passive: false });\n return () => el.removeEventListener('wheel', onWheel);\n }, [controller]);\n\n const local = (e: { clientX: number; clientY: number }) => {\n const rect = svgRef.current?.getBoundingClientRect();\n return { x: e.clientX - (rect?.left ?? 0), y: e.clientY - (rect?.top ?? 0) };\n };\n\n const clipboard = (kind: 'copy' | 'cut' | 'paste') => (event: React.ClipboardEvent) => {\n const native = (event && 'nativeEvent' in event ? event.nativeEvent : event) as ClipboardEvent;\n const data = native?.clipboardData;\n if (kind === 'paste') {\n const text = data?.getData('text/plain') ?? '';\n const pasted = text ? controller.paste(text) : controller.paste();\n if (pasted.length) event.preventDefault?.();\n return;\n }\n const text = kind === 'cut' ? controller.cut() : controller.copy();\n if (text && data) {\n data.setData('text/plain', text);\n event.preventDefault?.();\n }\n };\n\n const hs = THEME.transformHandleSize;\n const as = THEME.anchorSize;\n const box = overlay.selectionBox;\n const edit = state.widthPointEdit;\n const editAt = edit && { x: edit.point.x * state.viewport.zoom + state.viewport.x, y: edit.point.y * state.viewport.zoom + state.viewport.y };\n\n return (\n <svg\n ref={svgRef}\n role=\"application\"\n aria-label={ariaLabel}\n tabIndex={0}\n data-tool={state.tool}\n className={className}\n style={{ display: 'block', width: '100%', height: '100%', outline: 'none', touchAction: 'none', userSelect: 'none', cursor: state.cursor, ...style }}\n onPointerDown={(e) => {\n svgRef.current?.focus({ preventScroll: true });\n (e.currentTarget as Element).setPointerCapture?.(e.pointerId);\n controller.pointerDown(local(e), toVectorPointerInput(e));\n }}\n onPointerMove={(e) => controller.pointerMove(local(e), toVectorPointerInput(e))}\n onPointerUp={(e) => {\n (e.currentTarget as Element).releasePointerCapture?.(e.pointerId);\n controller.pointerUp(local(e), toVectorPointerInput(e));\n }}\n onPointerCancel={() => controller.cancelDrag()}\n onPointerLeave={() => controller.pointerLeave()}\n onDoubleClick={(e) => controller.doubleClick(local(e))}\n onKeyDown={(e) => {\n if (isVectorTextTarget(e.target)) return;\n if (controller.keyDown(toVectorKeyInput(e))) e.preventDefault();\n }}\n onKeyUp={(e) => controller.keyUp(toVectorKeyInput(e))}\n onCopy={clipboard('copy')}\n onCut={clipboard('cut')}\n onPaste={clipboard('paste')}\n >\n {checkerboard && (\n <defs>\n <pattern id={`ve${uid}-checker`} width={16} height={16} patternUnits=\"userSpaceOnUse\">\n <rect width={16} height={16} fill=\"#ffffff\" />\n <rect width={8} height={8} fill=\"#e5e7eb\" />\n <rect x={8} y={8} width={8} height={8} fill=\"#e5e7eb\" />\n </pattern>\n </defs>\n )}\n <VectorGradientDefs defs={scene.defs} />\n <rect\n data-vector-artboard=\"\"\n x={overlay.artboard.x}\n y={overlay.artboard.y}\n width={overlay.artboard.width}\n height={overlay.artboard.height}\n fill={scene.background ?? (checkerboard ? `url(#ve${uid}-checker)` : '#ffffff')}\n stroke=\"rgba(0,0,0,0.12)\"\n />\n <g data-vector-scene=\"\" transform={scene.transform}>\n <VectorSceneNodes nodes={scene.nodes} />\n </g>\n <g data-vector-overlay=\"\" pointerEvents=\"none\" fill=\"none\">\n {overlay.outlines.map((o) => (\n <path key={o.id} d={o.d} stroke={accentColor} strokeWidth={o.selected ? 1 : 1.5} opacity={o.selected ? 1 : 0.7} />\n ))}\n {overlay.penPreview && <path d={overlay.penPreview} stroke={accentColor} strokeDasharray=\"4 3\" />}\n {box && (\n <g data-vector-selection=\"\" transform={box.transform || undefined}>\n <rect x={box.x} y={box.y} width={box.width} height={box.height} stroke={accentColor} />\n <line x1={box.x + box.width / 2} y1={box.y} x2={box.x + box.width / 2} y2={box.y - 24} stroke={accentColor} />\n {box.handles.map((h) =>\n h.handle === 'rotate' ? (\n <circle key={h.handle} data-handle={h.handle} cx={h.x} cy={h.y} r={hs / 2 + 1} fill={THEME.handleFill} stroke={accentColor} />\n ) : (\n <rect key={h.handle} data-handle={h.handle} x={h.x - hs / 2} y={h.y - hs / 2} width={hs} height={hs} fill={THEME.handleFill} stroke={accentColor} />\n ),\n )}\n </g>\n )}\n {overlay.handles.map((h) => (\n <g key={`${h.ref.nodeId}:${h.ref.subpath}:${h.ref.index}:${h.ref.handle}`} data-vector-handle={h.ref.handle}>\n <line x1={h.anchorX} y1={h.anchorY} x2={h.x} y2={h.y} stroke={accentColor} />\n <circle cx={h.x} cy={h.y} r={THEME.handleRadius + (h.hovered ? 1 : 0)} fill={THEME.handleFill} stroke={accentColor} />\n </g>\n ))}\n {overlay.anchors.map((a) => {\n const size = as + (a.hovered ? 2 : 0);\n const fill = a.selected ? accentColor : THEME.handleFill;\n const key = `${a.ref.nodeId}:${a.ref.subpath}:${a.ref.index}`;\n return a.type === 'corner' ? (\n <rect key={key} data-vector-anchor={a.ref.index} x={a.x - size / 2} y={a.y - size / 2} width={size} height={size} fill={fill} stroke={accentColor} />\n ) : (\n <circle key={key} data-vector-anchor={a.ref.index} cx={a.x} cy={a.y} r={size / 2} fill={fill} stroke={accentColor} />\n );\n })}\n {overlay.cornerWidgets.map((w) => (\n <g key={`corner:${w.ref.nodeId}:${w.ref.subpath}:${w.ref.index}`} data-vector-corner-widget={w.ref.index} data-corner-kind={w.kind}>\n <circle cx={w.x} cy={w.y} r={THEME.cornerWidgetRadius + (w.hovered ? 1 : 0)} fill={THEME.handleFill} stroke={accentColor} />\n <circle cx={w.x} cy={w.y} r={1.5} fill={accentColor} />\n </g>\n ))}\n {overlay.widthSpot && (\n <g data-vector-width-spot=\"\">\n <line x1={overlay.widthSpot.left.x} y1={overlay.widthSpot.left.y} x2={overlay.widthSpot.right.x} y2={overlay.widthSpot.right.y} stroke={accentColor} strokeDasharray=\"3 2\" />\n <path d={vectorDiamondPath(overlay.widthSpot.x, overlay.widthSpot.y)} fill=\"none\" stroke={accentColor} />\n </g>\n )}\n {overlay.widthPoints.map((w) => (\n <g key={`width:${w.ref.nodeId}:${w.ref.subpath}:${w.ref.index}`} data-vector-width-point={w.ref.index} data-selected={w.selected || undefined}>\n <line x1={w.left.x} y1={w.left.y} x2={w.right.x} y2={w.right.y} stroke={accentColor} />\n <path d={vectorDiamondPath(w.x, w.y)} fill={w.selected || w.active ? accentColor : THEME.handleFill} stroke={accentColor} strokeWidth={w.hovered === 'center' ? 2 : 1} />\n {(['left', 'right'] as const).map((side) => (\n <circle key={side} data-vector-width-side={side} cx={w[side].x} cy={w[side].y} r={THEME.handleRadius + (w.hovered === side ? 1 : 0)} fill={THEME.handleFill} stroke={accentColor} />\n ))}\n </g>\n ))}\n {state.tool === 'pen' && overlay.anchors.some((a) => a.closes && a.hovered) && (\n <circle cx={overlay.anchors.find((a) => a.closes)!.x} cy={overlay.anchors.find((a) => a.closes)!.y} r={as} stroke={accentColor} />\n )}\n {overlay.builder && (\n <g data-vector-builder={overlay.builder.mode}>\n {overlay.builder.faces.map((d, i) => (\n <path\n key={`f${i}`}\n data-vector-builder-face=\"\"\n d={d}\n fill={overlay.builder!.mode === 'erase' ? THEME.builderEraseFill : THEME.builderFill}\n fillRule=\"nonzero\"\n stroke={overlay.builder!.mode === 'erase' ? THEME.builderErase : accentColor}\n strokeWidth={1}\n />\n ))}\n {overlay.builder.hatches.map((d, i) =>\n d ? (\n <path\n key={`h${i}`}\n data-vector-builder-hatch=\"\"\n d={d}\n fill=\"none\"\n stroke={overlay.builder!.mode === 'erase' ? THEME.builderErase : accentColor}\n strokeOpacity={THEME.builderHatchOpacity}\n strokeWidth={1}\n />\n ) : null\n )}\n {overlay.builder.lines.map((d, i) => (\n <path key={`l${i}`} data-vector-builder-line=\"\" d={d} fill=\"none\" stroke={THEME.builderErase} strokeWidth={3} strokeLinecap=\"round\" />\n ))}\n {overlay.builder.trail && <path data-vector-builder-trail=\"\" d={overlay.builder.trail} fill=\"none\" stroke={overlay.builder.mode === 'erase' ? THEME.builderErase : accentColor} strokeWidth={1} />}\n </g>\n )}\n {overlay.toolStroke && (\n <path\n data-vector-tool-stroke={overlay.toolStroke.tool}\n d={overlay.toolStroke.d}\n stroke={overlay.toolStroke.tool === 'eraser' ? THEME.eraserFill : accentColor}\n strokeWidth={overlay.toolStroke.tool === 'eraser' ? overlay.toolStroke.width : 1}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeDasharray={overlay.toolStroke.tool === 'knife' ? '5 3' : undefined}\n />\n )}\n {overlay.pencilString && (\n <line\n data-vector-pencil-string=\"\"\n x1={overlay.pencilString.x1}\n y1={overlay.pencilString.y1}\n x2={overlay.pencilString.x2}\n y2={overlay.pencilString.y2}\n stroke={accentColor}\n strokeDasharray=\"2 2\"\n />\n )}\n {overlay.cutPoint && <circle data-vector-cut-point=\"\" cx={overlay.cutPoint.x} cy={overlay.cutPoint.y} r={THEME.handleRadius + 1} fill={THEME.handleFill} stroke={accentColor} />}\n {overlay.marquee && (\n <rect\n data-vector-marquee=\"\"\n x={overlay.marquee.x}\n y={overlay.marquee.y}\n width={overlay.marquee.width}\n height={overlay.marquee.height}\n fill={THEME.marqueeFill}\n stroke={accentColor}\n strokeDasharray=\"3 2\"\n />\n )}\n {overlay.guides.lines.length > 0 && (\n <g data-vector-guides=\"\" stroke={guideColor}>\n {overlay.guides.lines.map((l, i) => (\n <line key={i} data-vector-guide={l.kind} x1={l.x1} y1={l.y1} x2={l.x2} y2={l.y2} strokeDasharray={l.kind === 'construction' ? '4 3' : undefined} />\n ))}\n </g>\n )}\n {overlay.guides.labels.map((l, i) => (\n <text\n key={i}\n data-vector-guide-label={l.kind}\n x={l.x + 6}\n y={l.y - 6}\n fontSize={10}\n fill={guideColor}\n stroke=\"#ffffff\"\n strokeWidth={3}\n paintOrder=\"stroke\"\n style={{ fontFamily: 'system-ui, sans-serif' }}\n >\n {l.text}\n </text>\n ))}\n {overlay.status && (\n <text data-vector-status=\"\" x={8} y=\"100%\" dy={-8} fontSize={11} fill={accentColor} style={{ fontFamily: 'system-ui, sans-serif' }}>\n {overlay.status}\n </text>\n )}\n </g>\n {edit && editAt && (\n // Width Point Edit (double-click with the width tool), beside the point.\n <foreignObject data-vector-width-point-edit=\"\" x={editAt.x + 12} y={editAt.y + 12} width={180} height={140} style={{ overflow: 'visible' }}>\n <VectorWidthPointEditor key={`${edit.nodeId}:${edit.index}:${edit.t}`} controller={controller} edit={edit} accentColor={accentColor} />\n </foreignObject>\n )}\n </svg>\n );\n}\n","import React, { useRef, useState } from 'react';\nimport { VECTOR_OVERLAY_THEME as THEME, type VectorEditorController, type VectorWidthPointEdit } from '@pixerate/editor/vector';\n\nexport interface VectorWidthPointEditorProps {\n controller: VectorEditorController;\n /** The point being edited (`state.widthPointEdit`). */\n edit: VectorWidthPointEdit;\n /** Accent colour of the Apply button (default sky blue). */\n accentColor?: string;\n className?: string;\n style?: React.CSSProperties;\n}\n\nconst round = (v: number, digits: number) => String(Math.round(v * 10 ** digits) / 10 ** digits);\n\nconst fieldStyle: React.CSSProperties = { display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 6 };\nconst inputStyle: React.CSSProperties = { width: 72, font: 'inherit', padding: '1px 4px' };\n\n/**\n * Width Point Edit: the position (percent along the path) and the left / right side widths\n * (document units) of the width point a width-tool double-click opened. Apply (or Enter) sets\n * them with `commitWidthPointEdit`; Cancel or Escape closes it. `<VectorCanvas>` shows it next\n * to the point; use it on its own to place it elsewhere.\n */\nexport function VectorWidthPointEditor({ controller, edit, accentColor = THEME.accent, className, style }: VectorWidthPointEditorProps) {\n const [position, setPosition] = useState(() => round(edit.t * 100, 2));\n const [left, setLeft] = useState(() => round(edit.left, 3));\n const [right, setRight] = useState(() => round(edit.right, 3));\n const formRef = useRef<HTMLFormElement | null>(null);\n // Hand the keyboard back to the canvas around it.\n const refocus = () => (formRef.current?.closest('svg') as SVGSVGElement | null)?.focus?.({ preventScroll: true });\n const close = () => {\n refocus();\n controller.closeWidthPointEdit();\n };\n const num = (v: string) => (v.trim() !== '' && Number.isFinite(Number(v)) ? Number(v) : undefined);\n const apply = () => {\n const t = num(position);\n refocus();\n controller.commitWidthPointEdit({ t: t === undefined ? undefined : Math.min(Math.max(t, 0), 100) / 100, left: num(left), right: num(right) });\n };\n const stop = (e: React.SyntheticEvent) => e.stopPropagation();\n return (\n <form\n ref={formRef}\n data-vector-width-point-editor=\"\"\n aria-label=\"Width point\"\n className={className}\n style={{\n display: 'grid',\n gap: 4,\n padding: 8,\n background: '#ffffff',\n border: '1px solid rgba(0,0,0,0.15)',\n borderRadius: 6,\n boxShadow: '0 2px 8px rgba(0,0,0,0.15)',\n font: '12px system-ui, sans-serif',\n color: '#18181b',\n ...style,\n }}\n // Keep the canvas from treating clicks, keys and clipboard use in here as editing gestures.\n onPointerDown={stop}\n onPointerMove={stop}\n onPointerUp={stop}\n onDoubleClick={stop}\n onCopy={stop}\n onCut={stop}\n onPaste={stop}\n onKeyDown={(e) => {\n e.stopPropagation();\n if (e.key === 'Escape') {\n e.preventDefault();\n close();\n }\n }}\n onSubmit={(e) => {\n e.preventDefault();\n apply();\n }}\n >\n <label style={fieldStyle}>\n Position %\n <input aria-label=\"Width point position\" type=\"number\" min={0} max={100} step=\"any\" value={position} onChange={(e) => setPosition(e.target.value)} style={inputStyle} autoFocus />\n </label>\n <label style={fieldStyle}>\n Left\n <input aria-label=\"Width point left side\" type=\"number\" min={0} step=\"any\" value={left} onChange={(e) => setLeft(e.target.value)} style={inputStyle} />\n </label>\n <label style={fieldStyle}>\n Right\n <input aria-label=\"Width point right side\" type=\"number\" min={0} step=\"any\" value={right} onChange={(e) => setRight(e.target.value)} style={inputStyle} />\n </label>\n <div style={{ display: 'flex', justifyContent: 'flex-end', gap: 4, marginTop: 2 }}>\n <button type=\"button\" onClick={close}>\n Cancel\n </button>\n <button type=\"submit\" style={{ background: accentColor, color: '#ffffff', border: 'none', borderRadius: 4, padding: '2px 8px' }}>\n {edit.index === null ? 'Add' : 'Apply'}\n </button>\n </div>\n </form>\n );\n}\n","import React from 'react';\nimport {\n VECTOR_TOOLS,\n VECTOR_TOOL_GLYPHS,\n VECTOR_TOOL_SHORTCUTS,\n VECTOR_EDIT_TOGGLES,\n VECTOR_PATH_ACTIONS,\n VECTOR_PATHFINDER_ACTIONS,\n VECTOR_FILL_GAP,\n VECTOR_ARROWHEADS,\n VECTOR_ARROWHEAD_LABELS,\n VECTOR_CORNER_KINDS,\n VECTOR_CORNER_KIND_LABELS,\n VECTOR_STROKE_ALIGN_LABELS,\n VECTOR_WIDTH_PRESETS,\n getVectorSelectionStyle,\n widthProfilePreset,\n widthProfilePresetId,\n vectorPaintToHex,\n vectorToolLabel,\n type VectorArrowhead,\n type VectorCornerKind,\n type VectorEditorController,\n type VectorStrokeAlign,\n type VectorTool,\n type VectorWidthPreset,\n} from '@pixerate/editor/vector';\nimport { useVectorEditorState } from './useVectorEditor';\n\nconst VECTOR_SNAP_TITLE = 'Snap to objects';\nconst modKeyLabel = () => (typeof navigator !== 'undefined' && /Mac|iPhone|iPad/.test(navigator.platform ?? '') ? '⌘' : 'Ctrl');\n\nconst buttonClass =\n 'inline-flex h-8 min-w-8 items-center justify-center rounded-md border border-border bg-background px-2 text-xs font-medium text-foreground hover:bg-muted disabled:cursor-not-allowed disabled:opacity-40 aria-pressed:bg-primary aria-pressed:text-primary-foreground';\n\nexport interface VectorToolbarProps {\n controller: VectorEditorController;\n /** Tools to show (default: all). */\n tools?: readonly VectorTool[];\n /** Undo / redo buttons (default `true`). */\n showHistory?: boolean;\n /** Boolean, Pathfinder, group, arrange and align buttons (default `true`). */\n showArrange?: boolean;\n /** The snapping toggle (default `true`). */\n showSnap?: boolean;\n /**\n * Path editing: Join, Average, Cut at Points, Remove Redundant Points, Smooth, the Keep\n * Shape / Curvature / Shapes toggles, and the pencil smoothing and eraser size inputs while\n * those tools are active (default `true`).\n */\n showPathEdit?: boolean;\n className?: string;\n}\n\n/** Tool picker plus undo, snapping, boolean operations, grouping, stacking and alignment. */\nexport function VectorToolbar({ controller, tools = VECTOR_TOOLS, showHistory = true, showArrange = true, showSnap = true, showPathEdit = true, className }: VectorToolbarProps) {\n const state = useVectorEditorState(controller);\n const count = state.selection.length;\n const points = state.tool === 'direct' ? state.selectedAnchors.length : 0;\n const editing = state.editing;\n const groupSelected = state.selection.some((id) => controller.getNode(id)?.type === 'group');\n const act = (label: string, title: string, run: () => unknown, disabled = false) => (\n <button key={label} type=\"button\" className={buttonClass} title={title} aria-label={title} disabled={disabled} onClick={() => void run()}>\n {label}\n </button>\n );\n return (\n <div role=\"toolbar\" aria-label=\"Vector tools\" className={`flex flex-wrap items-center gap-1 ${className ?? ''}`}>\n <div className=\"flex items-center gap-1\" role=\"group\" aria-label=\"Tools\">\n {tools.map((tool) => (\n <button\n key={tool}\n type=\"button\"\n data-vector-tool={tool}\n className={buttonClass}\n aria-pressed={state.tool === tool}\n title={`${vectorToolLabel(tool)} (${VECTOR_TOOL_SHORTCUTS[tool]})`}\n aria-label={vectorToolLabel(tool)}\n onClick={() => controller.setTool(tool)}\n >\n {VECTOR_TOOL_GLYPHS[tool]}\n </button>\n ))}\n </div>\n {showHistory && (\n <div className=\"ml-1 flex items-center gap-1\" role=\"group\" aria-label=\"History\">\n {act('↶', state.canUndo ? `Undo ${state.undoLabel}` : 'Undo', () => controller.undo(), !state.canUndo)}\n {act('↷', state.canRedo ? `Redo ${state.redoLabel}` : 'Redo', () => controller.redo(), !state.canRedo)}\n </div>\n )}\n {showSnap && (\n <div className=\"ml-1 flex items-center gap-1\" role=\"group\" aria-label=\"Snapping\">\n <button\n type=\"button\"\n data-vector-snap=\"\"\n className={buttonClass}\n aria-pressed={state.snap.objects}\n title={`${VECTOR_SNAP_TITLE} (hold ${modKeyLabel()} to bypass)`}\n aria-label={VECTOR_SNAP_TITLE}\n onClick={() => controller.toggleSnapping()}\n >\n Snap\n </button>\n </div>\n )}\n {showPathEdit && (\n <div className=\"ml-1 flex items-center gap-1\" role=\"group\" aria-label=\"Path editing\">\n {VECTOR_PATH_ACTIONS.map((a) => (\n <button\n key={a.id}\n type=\"button\"\n data-vector-path-action={a.id}\n className={buttonClass}\n title={a.shortcut ? `${a.title} (${modKeyLabel()}+${a.shortcut})` : a.title}\n aria-label={a.title}\n disabled={!a.enabled(count, points)}\n onClick={() => void a.run(controller)}\n >\n {a.label}\n </button>\n ))}\n {VECTOR_EDIT_TOGGLES.map((t) => (\n <button\n key={t.key}\n type=\"button\"\n data-vector-edit={t.key}\n className={buttonClass}\n aria-pressed={editing[t.key]}\n title={t.title}\n aria-label={t.title}\n onClick={() => controller.setEditing({ [t.key]: !editing[t.key] })}\n >\n {t.label}\n </button>\n ))}\n {state.tool === 'pencil' && (\n <label className=\"flex items-center gap-1 text-xs text-foreground\">\n Smoothing\n <input\n type=\"range\"\n min={0}\n max={1}\n step={0.05}\n aria-label=\"Pencil smoothing\"\n className=\"h-4 w-20 accent-primary\"\n value={editing.pencilSmoothing}\n onChange={(e) => controller.setEditing({ pencilSmoothing: parseFloat(e.target.value) })}\n />\n </label>\n )}\n {state.tool === 'eraser' && (\n <label className=\"flex items-center gap-1 text-xs text-foreground\">\n Size\n <input\n type=\"number\"\n min={0.5}\n step={1}\n aria-label=\"Eraser size\"\n className=\"h-7 w-16 rounded border border-border bg-background px-1.5 text-xs\"\n value={editing.eraserSize}\n onChange={(e) => {\n const n = parseFloat(e.target.value);\n if (Number.isFinite(n) && n > 0) controller.setEditing({ eraserSize: n });\n }}\n />\n </label>\n )}\n {state.tool === 'paintBucket' && (\n <button\n type=\"button\"\n data-vector-fill-gap=\"\"\n className={buttonClass}\n aria-pressed={editing.fillGap > 0}\n title=\"Close small gaps between path ends when filling\"\n aria-label=\"Close gaps\"\n onClick={() => controller.setEditing({ fillGap: editing.fillGap > 0 ? 0 : VECTOR_FILL_GAP })}\n >\n Gaps\n </button>\n )}\n </div>\n )}\n {showArrange && (\n <>\n <div className=\"ml-1 flex items-center gap-1\" role=\"group\" aria-label=\"Combine\">\n {act('∪', 'Union', () => controller.booleanOp('union'), count < 2)}\n {act('−', 'Subtract', () => controller.booleanOp('subtract'), count < 2)}\n {act('∩', 'Intersect', () => controller.booleanOp('intersect'), count < 2)}\n {act('⊻', 'Exclude', () => controller.booleanOp('exclude'), count < 2)}\n {act('G', 'Group', () => controller.group(), count < 1)}\n {act('U', 'Ungroup', () => controller.ungroup(), !groupSelected)}\n </div>\n <div className=\"ml-1 flex items-center gap-1\" role=\"group\" aria-label=\"Pathfinder\">\n {VECTOR_PATHFINDER_ACTIONS.map((a) => (\n <button\n key={a.id}\n type=\"button\"\n data-vector-pathfinder={a.id}\n className={buttonClass}\n title={a.title}\n aria-label={a.title}\n disabled={count < a.min}\n onClick={() => void controller.pathfinder(a.id)}\n >\n {a.label}\n </button>\n ))}\n </div>\n <div className=\"ml-1 flex items-center gap-1\" role=\"group\" aria-label=\"Arrange\">\n {act('⇈', 'Bring to Front', () => controller.arrange('front'), count < 1)}\n {act('⇊', 'Send to Back', () => controller.arrange('back'), count < 1)}\n {act('⇤', 'Align Left', () => controller.align('left'), count < 1)}\n {act('↔', 'Align Center', () => controller.align('center'), count < 1)}\n {act('⇥', 'Align Right', () => controller.align('right'), count < 1)}\n {act('⤒', 'Align Top', () => controller.align('top'), count < 1)}\n {act('↕', 'Align Middle', () => controller.align('middle'), count < 1)}\n {act('⤓', 'Align Bottom', () => controller.align('bottom'), count < 1)}\n </div>\n </>\n )}\n </div>\n );\n}\n\nexport interface VectorStylePanelProps {\n controller: VectorEditorController;\n className?: string;\n}\n\nconst selectClass = 'h-7 min-w-0 flex-1 rounded border border-border bg-background px-1 text-xs';\nconst numberClass = 'h-7 w-16 rounded border border-border bg-background px-1.5 text-xs';\n\n/**\n * Fill, stroke, stroke width, alignment and width profile, arrowheads, live corner radius and opacity of the\n * selection (corners of the selected points with the direct tool); with nothing selected it\n * edits the defaults for new shapes.\n */\nexport function VectorStylePanel({ controller, className }: VectorStylePanelProps) {\n const state = useVectorEditorState(controller);\n const style = getVectorSelectionStyle(state);\n const d = state.defaults;\n const source = style ?? {\n fill: d.fill ?? null,\n stroke: d.stroke ?? null,\n strokeWidth: d.strokeWidth ?? 1,\n opacity: 1,\n strokeAlign: d.strokeAlign ?? 'center',\n startArrow: d.startArrow ?? null,\n endArrow: d.endArrow ?? null,\n arrowAlign: d.arrowAlign ?? 'extend',\n startArrowScale: d.startArrowScale ?? 1,\n endArrowScale: d.endArrowScale ?? 1,\n widthProfile: widthProfilePresetId(d.strokeWidthProfile),\n cornerRadius: d.cornerRadius,\n cornerKind: d.cornerKind ?? 'round',\n corners: 1,\n hasOpenPath: true,\n };\n const setCorners = (patch: { radius?: number; kind?: VectorCornerKind }) => {\n if (!style) controller.setDefaults({ ...(patch.radius !== undefined ? { cornerRadius: patch.radius } : {}), ...(patch.kind ? { cornerKind: patch.kind } : {}) });\n else if (patch.radius !== undefined) controller.setCornerRadius(patch.radius);\n else if (patch.kind) controller.setCornerKind(patch.kind);\n };\n const setProfile = (id: VectorWidthPreset) => {\n if (style) controller.setWidthProfile(id);\n else controller.setDefaults({ strokeWidthProfile: widthProfilePreset(id)?.length ? widthProfilePreset(id) : null });\n };\n const mixed = (key: keyof NonNullable<typeof style>['mixed']) => (style?.mixed[key] ? <span className=\"text-[11px] text-muted-foreground\">Mixed</span> : null);\n const arrowRow = (end: 'start' | 'end', label: string) => {\n const key = end === 'start' ? 'startArrow' : 'endArrow';\n const scaleKey = end === 'start' ? 'startArrowScale' : 'endArrowScale';\n return (\n <div className=\"flex items-center gap-2\" data-vector-style={key}>\n <span className=\"w-16 text-xs text-foreground\">{label}</span>\n <select aria-label={`${label} arrowhead`} className={selectClass} value={source[key] ?? ''} onChange={(e) => apply({ [key]: (e.target.value || null) as VectorArrowhead | null })}>\n <option value=\"\">None</option>\n {VECTOR_ARROWHEADS.map((h) => (\n <option key={h} value={h}>\n {VECTOR_ARROWHEAD_LABELS[h]}\n </option>\n ))}\n </select>\n <input\n type=\"number\"\n min={0.1}\n step={0.25}\n aria-label={`${label} arrowhead scale`}\n title=\"Scale (× stroke width)\"\n className={numberClass}\n value={source[scaleKey]}\n onChange={(e) => {\n const n = parseFloat(e.target.value);\n if (Number.isFinite(n) && n > 0) apply({ [scaleKey]: n });\n }}\n />\n </div>\n );\n };\n const apply = (patch: Record<string, unknown>) => {\n if (style) controller.setStyle(patch);\n else controller.setDefaults(patch);\n };\n const paintRow = (key: 'fill' | 'stroke', label: string) => {\n const paint = source[key];\n const hex = vectorPaintToHex(paint);\n const on = paint !== null && paint !== 'none';\n return (\n <div className=\"flex items-center gap-2\" data-vector-style={key}>\n <label className=\"flex w-16 items-center gap-1.5 text-xs text-foreground\">\n <input type=\"checkbox\" checked={on} aria-label={`${label} on`} onChange={(e) => apply({ [key]: e.target.checked ? (hex ?? '#000000') : null })} />\n {label}\n </label>\n <input\n type=\"color\"\n aria-label={`${label} colour`}\n className=\"h-7 w-10 cursor-pointer rounded border border-border bg-background disabled:opacity-40\"\n disabled={!on}\n value={hex ?? '#000000'}\n onChange={(e) => apply({ [key]: e.target.value })}\n />\n {on && !hex && <span className=\"truncate text-[11px] text-muted-foreground\">{typeof paint === 'string' ? paint : 'Gradient'}</span>}\n {style?.mixed[key] && <span className=\"text-[11px] text-muted-foreground\">Mixed</span>}\n </div>\n );\n };\n return (\n <div className={`space-y-2 ${className ?? ''}`} aria-label={style ? 'Selection style' : 'New shape style'}>\n <p className=\"text-[11px] font-medium uppercase tracking-wide text-muted-foreground\">{style ? 'Selection' : 'New shapes'}</p>\n {paintRow('fill', 'Fill')}\n {paintRow('stroke', 'Stroke')}\n <label className=\"flex items-center gap-2 text-xs text-foreground\">\n <span className=\"w-16\">Width</span>\n <input\n type=\"number\"\n min={0}\n step={0.5}\n aria-label=\"Stroke width\"\n className=\"h-7 w-20 rounded border border-border bg-background px-1.5 text-xs\"\n value={source.strokeWidth}\n onChange={(e) => {\n const n = parseFloat(e.target.value);\n if (Number.isFinite(n) && n >= 0) apply({ strokeWidth: n });\n }}\n />\n </label>\n <label className=\"flex items-center gap-2 text-xs text-foreground\" data-vector-style=\"strokeAlign\">\n <span className=\"w-16\">Align</span>\n <select aria-label=\"Stroke alignment\" className={selectClass} value={source.strokeAlign} onChange={(e) => apply({ strokeAlign: e.target.value as VectorStrokeAlign })}>\n {(Object.keys(VECTOR_STROKE_ALIGN_LABELS) as VectorStrokeAlign[]).map((a) => (\n <option key={a} value={a}>\n {VECTOR_STROKE_ALIGN_LABELS[a]}\n </option>\n ))}\n </select>\n {mixed('strokeAlign')}\n </label>\n <div className=\"flex items-center gap-2 text-xs text-foreground\" data-vector-style=\"widthProfile\">\n <span className=\"w-16\">Profile</span>\n <select\n aria-label=\"Width profile\"\n className={selectClass}\n value={source.widthProfile}\n onChange={(e) => {\n if (e.target.value !== 'custom') setProfile(e.target.value as VectorWidthPreset);\n }}\n >\n {VECTOR_WIDTH_PRESETS.map((p) => (\n <option key={p.id} value={p.id}>\n {p.label}\n </option>\n ))}\n {source.widthProfile === 'custom' && (\n <option value=\"custom\" disabled>\n Custom\n </option>\n )}\n </select>\n <button\n type=\"button\"\n className={buttonClass}\n title=\"Reset to uniform width\"\n aria-label=\"Reset to uniform width\"\n disabled={source.widthProfile === 'uniform' && !style?.mixed.widthProfile}\n onClick={() => setProfile('uniform')}\n >\n ═\n </button>\n {mixed('widthProfile')}\n </div>\n {source.hasOpenPath && (\n <>\n {arrowRow('start', 'Start')}\n {arrowRow('end', 'End')}\n {(source.startArrow || source.endArrow) && (\n <label className=\"flex items-center gap-2 text-xs text-foreground\" data-vector-style=\"arrowAlign\">\n <span className=\"w-16\">Heads</span>\n <select aria-label=\"Arrowhead alignment\" className={selectClass} value={source.arrowAlign} onChange={(e) => apply({ arrowAlign: e.target.value })}>\n <option value=\"extend\">Tip past end</option>\n <option value=\"tip\">Tip at end</option>\n </select>\n </label>\n )}\n </>\n )}\n {source.corners > 0 && (\n <div className=\"flex items-center gap-2\" data-vector-style=\"corners\">\n <span className=\"w-16 text-xs text-foreground\">Corners</span>\n <input\n type=\"number\"\n min={0}\n step={1}\n aria-label=\"Corner radius\"\n className={numberClass}\n value={Math.round(source.cornerRadius * 100) / 100}\n onChange={(e) => {\n const n = parseFloat(e.target.value);\n if (Number.isFinite(n) && n >= 0) setCorners({ radius: n });\n }}\n />\n <select aria-label=\"Corner kind\" className={selectClass} value={source.cornerKind} onChange={(e) => setCorners({ kind: e.target.value as VectorCornerKind })}>\n {VECTOR_CORNER_KINDS.map((k) => (\n <option key={k} value={k}>\n {VECTOR_CORNER_KIND_LABELS[k]}\n </option>\n ))}\n </select>\n {mixed('cornerRadius')}\n </div>\n )}\n {style && (\n <label className=\"flex items-center gap-2 text-xs text-foreground\">\n <span className=\"w-16\">Opacity</span>\n <input\n type=\"range\"\n min={0}\n max={1}\n step={0.05}\n aria-label=\"Opacity\"\n className=\"h-4 flex-1 accent-primary\"\n value={source.opacity}\n onChange={(e) => apply({ opacity: parseFloat(e.target.value) })}\n />\n </label>\n )}\n </div>\n );\n}\n","import React from 'react';\nimport type { VectorEditorController, VectorTool } from '@pixerate/editor/vector';\nimport { VectorCanvas, type VectorCanvasProps } from './VectorCanvas';\nimport { VectorStylePanel, VectorToolbar } from './VectorToolbar';\n\nexport interface VectorEditorProps {\n controller: VectorEditorController;\n /** Tools in the toolbar (default: all). */\n tools?: readonly VectorTool[];\n /** The style sidebar (default `true`). */\n showStylePanel?: boolean;\n /** Canvas height (default 520px). */\n height?: number | string;\n canvasProps?: Omit<VectorCanvasProps, 'controller'>;\n className?: string;\n}\n\n/** Toolbar, canvas and style panel for a `VectorEditorController`. */\nexport function VectorEditor({ controller, tools, showStylePanel = true, height = 520, canvasProps, className }: VectorEditorProps) {\n return (\n <div className={`flex flex-col gap-2 ${className ?? ''}`} data-vector-editor=\"\">\n <VectorToolbar controller={controller} tools={tools} />\n <div className=\"flex min-h-0 flex-col gap-2 md:flex-row\">\n <div className=\"relative min-h-[320px] flex-1 overflow-hidden rounded-md border border-border bg-muted/40\" style={{ height }}>\n <VectorCanvas controller={controller} {...canvasProps} />\n </div>\n {showStylePanel && <VectorStylePanel controller={controller} className=\"w-full shrink-0 rounded-md border border-border p-3 md:w-56\" />}\n </div>\n </div>\n );\n}\n"],"mappings":"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","names":["useEffect","useRef","THEME","useRef","jsx","jsxs","THEME","useRef","useEffect","text","Fragment","jsx","jsxs","jsx","jsxs"]}
|
|
1
|
+
{"version":3,"sources":["../../src/vector/useVectorEditor.ts","../../src/vector/VectorCanvas.tsx","../../src/vector/VectorWidthPointEditor.tsx","../../src/vector/VectorToolbar.tsx","../../src/vector/VectorEditor.tsx"],"sourcesContent":["import { useEffect, useMemo, useRef, useSyncExternalStore } from 'react';\nimport {\n VectorEditorController,\n createVectorCommands,\n type VectorCommandOptions,\n type VectorEditorOptions,\n type VectorEditorState,\n type VectorTool,\n} from '@pixerate/editor/vector';\n\n/** A `VectorEditorController` created once for the component's lifetime (destroyed on unmount). */\nexport function useVectorEditorController(options: VectorEditorOptions = {}): VectorEditorController {\n const ref = useRef<VectorEditorController | null>(null);\n if (!ref.current) ref.current = new VectorEditorController(options);\n const controller = ref.current;\n useEffect(() => () => controller.destroy(), [controller]);\n return controller;\n}\n\n/** The controller's state (re-renders on every change). */\nexport function useVectorEditorState(controller: VectorEditorController): VectorEditorState {\n return useSyncExternalStore(controller.subscribe, controller.getState, controller.getState);\n}\n\nexport interface UseVectorEditorResult {\n controller: VectorEditorController;\n state: VectorEditorState;\n setTool: (tool: VectorTool) => void;\n undo: () => void;\n redo: () => void;\n deleteSelection: () => void;\n toSvg: () => string;\n}\n\n/**\n * Subscribes to a vector editor controller and exposes its state with bound actions. Pass\n * options instead of a controller to create one for the component's lifetime.\n */\nexport function useVectorEditor(controllerOrOptions: VectorEditorController | VectorEditorOptions = {}): UseVectorEditorResult {\n const own = useRef<VectorEditorController | null>(null);\n let controller: VectorEditorController;\n if (controllerOrOptions instanceof VectorEditorController) controller = controllerOrOptions;\n else {\n if (!own.current) own.current = new VectorEditorController(controllerOrOptions);\n controller = own.current;\n }\n const state = useVectorEditorState(controller);\n const actions = useMemo(\n () => ({\n setTool: (tool: VectorTool) => controller.setTool(tool),\n undo: () => void controller.undo(),\n redo: () => void controller.redo(),\n deleteSelection: () => void controller.deleteSelection(),\n toSvg: () => controller.toSvg(),\n }),\n [controller],\n );\n return { controller, state, ...actions };\n}\n\n/** Anything with `register(specs) → unregister` (a `CommandRegistry`). */\nexport interface VectorCommandTarget {\n register(specs: any): () => void;\n}\n\n/**\n * Registers the controller's palette / agent commands (`vector.addShape`, `vector.boolean`, …)\n * in `registry` while mounted, so `createCommandToolProvider` exposes them to agents.\n */\nexport function useVectorCommands(\n registry: VectorCommandTarget | null | undefined,\n controller: VectorEditorController,\n options: VectorCommandOptions = {},\n): void {\n const { prefix, group, scope } = options;\n useEffect(() => {\n if (!registry) return;\n return registry.register(createVectorCommands(controller, { prefix, group, scope }));\n }, [registry, controller, prefix, group, scope]);\n}\n","import React, { useEffect, useId, useRef } from 'react';\nimport {\n VECTOR_OVERLAY_THEME as THEME,\n getVectorOverlayRenderData,\n getVectorSceneRenderData,\n isVectorTextTarget,\n toVectorKeyInput,\n toVectorPointerInput,\n vectorDiamondPath,\n type VectorEditorController,\n type VectorRenderNode,\n type VectorRenderPath,\n type SvgGradientDef,\n} from '@pixerate/editor/vector';\nimport { useVectorEditorState } from './useVectorEditor';\nimport { VectorWidthPointEditor } from './VectorWidthPointEditor';\n\nexport interface VectorCanvasProps {\n controller: VectorEditorController;\n /** Fit the artboard into the canvas when it first gets a size (default `true`). */\n fitOnMount?: boolean;\n /** Draw a checkerboard behind a transparent artboard (default `true`). */\n checkerboard?: boolean;\n /** Overlay accent colour (default sky blue). */\n accentColor?: string;\n /** Smart guide colour (default magenta). */\n guideColor?: string;\n className?: string;\n style?: React.CSSProperties;\n /** Accessible label (default \"Vector canvas\"). */\n 'aria-label'?: string;\n}\n\n/** Renders `<linearGradient>` / `<radialGradient>` descriptors. */\nexport function VectorGradientDefs({ defs }: { defs: readonly SvgGradientDef[] }) {\n if (!defs.length) return null;\n return (\n <defs>\n {defs.map((def) => {\n const stops = def.stops.map((s, i) => <stop key={i} offset={s.offset} stopColor={s.stopColor} stopOpacity={s.stopOpacity} />);\n return def.type === 'radial' ? (\n <radialGradient key={def.id} id={def.id} {...(def.attrs as any)}>\n {stops}\n </radialGradient>\n ) : (\n <linearGradient key={def.id} id={def.id} {...(def.attrs as any)}>\n {stops}\n </linearGradient>\n );\n })}\n </defs>\n );\n}\n\n/** Renders scene nodes (paths and groups) from `getVectorSceneRenderData`. */\nexport function VectorSceneNodes({ nodes }: { nodes: readonly VectorRenderNode[] }) {\n return (\n <>\n {nodes.map((node) =>\n node.kind === 'group' ? (\n <g key={node.id} data-vector-id={node.id} transform={node.transform} opacity={node.opacity < 1 ? node.opacity : undefined}>\n <VectorSceneNodes nodes={node.children} />\n </g>\n ) : node.strokeParts ? (\n <VectorPartedPath key={node.id} node={node} />\n ) : (\n <path\n key={node.id}\n data-vector-id={node.id}\n transform={node.transform}\n d={node.d}\n fill={node.fill}\n fillRule={node.fillRule}\n stroke={node.stroke}\n strokeWidth={node.stroke === 'none' ? undefined : node.strokeWidth}\n strokeLinecap={node.strokeLinecap as any}\n strokeLinejoin={node.strokeLinejoin as any}\n strokeDasharray={node.strokeDasharray}\n opacity={node.opacity < 1 ? node.opacity : undefined}\n />\n ),\n )}\n </>\n );\n}\n\n/** A path whose stroke is aligned inside / outside (double width, clipped or masked by the shape) or has arrowheads. */\nfunction VectorPartedPath({ node }: { node: VectorRenderPath }) {\n const sp = node.strokeParts!;\n const clip = sp.clip;\n const b = clip?.bounds;\n return (\n <g data-vector-id={node.id} data-vector-stroke-align={sp.align} transform={node.transform} opacity={node.opacity < 1 ? node.opacity : undefined}>\n {clip && b && (\n <defs>\n {clip.kind === 'clip' ? (\n <clipPath id={clip.id}>\n <path d={node.d} clipRule={node.fillRule} />\n </clipPath>\n ) : (\n <mask id={clip.id} maskUnits=\"userSpaceOnUse\" x={b.x} y={b.y} width={b.width} height={b.height}>\n <rect x={b.x} y={b.y} width={b.width} height={b.height} fill=\"#fff\" />\n <path d={node.d} fill=\"#000\" fillRule={node.fillRule} />\n </mask>\n )}\n </defs>\n )}\n <path data-vector-part=\"fill\" d={node.d} fill={node.fill} fillRule={node.fillRule} stroke=\"none\" />\n {sp.outline !== undefined ? (\n // A variable-width stroke: its outline, filled.\n <path\n data-vector-part=\"stroke-outline\"\n d={sp.outline}\n fill={node.stroke}\n clipPath={clip?.kind === 'clip' ? `url(#${clip.id})` : undefined}\n mask={clip?.kind === 'mask' ? `url(#${clip.id})` : undefined}\n />\n ) : (\n <path\n data-vector-part=\"stroke\"\n d={sp.d}\n fill=\"none\"\n stroke={node.stroke}\n strokeWidth={sp.width}\n strokeLinecap={node.strokeLinecap as any}\n strokeLinejoin={node.strokeLinejoin as any}\n strokeDasharray={node.strokeDasharray}\n clipPath={clip?.kind === 'clip' ? `url(#${clip.id})` : undefined}\n mask={clip?.kind === 'mask' ? `url(#${clip.id})` : undefined}\n />\n )}\n {sp.heads.map((head, i) => (\n <path key={i} data-vector-part=\"head\" d={head} fill={node.stroke} />\n ))}\n </g>\n );\n}\n\n/**\n * An SVG canvas for a `VectorEditorController`: draws the document and the editing overlay\n * and forwards pointer, wheel, keyboard and clipboard events. Focus it to use shortcuts.\n */\nexport function VectorCanvas({\n controller,\n fitOnMount = true,\n checkerboard = true,\n accentColor = THEME.accent,\n guideColor = THEME.guide,\n className,\n style,\n 'aria-label': ariaLabel = 'Vector canvas',\n}: VectorCanvasProps) {\n const state = useVectorEditorState(controller);\n const svgRef = useRef<SVGSVGElement | null>(null);\n const fitted = useRef(!fitOnMount);\n const uid = useId().replace(/:/g, '');\n const scene = getVectorSceneRenderData(state, { idPrefix: `ve${uid}-` });\n const overlay = getVectorOverlayRenderData(state);\n\n useEffect(() => {\n const el = svgRef.current;\n if (!el || fitted.current) return;\n const fit = () => {\n const rect = el.getBoundingClientRect();\n if (fitted.current || rect.width <= 0 || rect.height <= 0) return;\n fitted.current = true;\n controller.zoomToFit({ width: rect.width, height: rect.height });\n };\n fit();\n if (fitted.current || typeof ResizeObserver === 'undefined') return;\n const observer = new ResizeObserver(fit);\n observer.observe(el);\n return () => observer.disconnect();\n }, [controller]);\n\n // Wheel needs a non-passive listener to stop page scroll / browser zoom.\n useEffect(() => {\n const el = svgRef.current;\n if (!el) return;\n const onWheel = (e: WheelEvent) => {\n e.preventDefault();\n controller.wheel(local(e), { x: e.deltaX, y: e.deltaY }, toVectorPointerInput(e));\n };\n el.addEventListener('wheel', onWheel, { passive: false });\n return () => el.removeEventListener('wheel', onWheel);\n }, [controller]);\n\n const local = (e: { clientX: number; clientY: number }) => {\n const rect = svgRef.current?.getBoundingClientRect();\n return { x: e.clientX - (rect?.left ?? 0), y: e.clientY - (rect?.top ?? 0) };\n };\n\n const clipboard = (kind: 'copy' | 'cut' | 'paste') => (event: React.ClipboardEvent) => {\n const native = (event && 'nativeEvent' in event ? event.nativeEvent : event) as ClipboardEvent;\n const data = native?.clipboardData;\n if (kind === 'paste') {\n const text = data?.getData('text/plain') ?? '';\n const pasted = text ? controller.paste(text) : controller.paste();\n if (pasted.length) event.preventDefault?.();\n return;\n }\n const text = kind === 'cut' ? controller.cut() : controller.copy();\n if (text && data) {\n data.setData('text/plain', text);\n event.preventDefault?.();\n }\n };\n\n const hs = THEME.transformHandleSize;\n const as = THEME.anchorSize;\n const box = overlay.selectionBox;\n const edit = state.widthPointEdit;\n const editAt = edit && { x: edit.point.x * state.viewport.zoom + state.viewport.x, y: edit.point.y * state.viewport.zoom + state.viewport.y };\n\n return (\n <svg\n ref={svgRef}\n role=\"application\"\n aria-label={ariaLabel}\n tabIndex={0}\n data-tool={state.tool}\n className={className}\n style={{ display: 'block', width: '100%', height: '100%', outline: 'none', touchAction: 'none', userSelect: 'none', cursor: state.cursor, ...style }}\n onPointerDown={(e) => {\n svgRef.current?.focus({ preventScroll: true });\n (e.currentTarget as Element).setPointerCapture?.(e.pointerId);\n controller.pointerDown(local(e), toVectorPointerInput(e));\n }}\n onPointerMove={(e) => controller.pointerMove(local(e), toVectorPointerInput(e))}\n onPointerUp={(e) => {\n (e.currentTarget as Element).releasePointerCapture?.(e.pointerId);\n controller.pointerUp(local(e), toVectorPointerInput(e));\n }}\n onPointerCancel={() => controller.cancelDrag()}\n onPointerLeave={() => controller.pointerLeave()}\n onDoubleClick={(e) => controller.doubleClick(local(e))}\n onKeyDown={(e) => {\n if (isVectorTextTarget(e.target)) return;\n if (controller.keyDown(toVectorKeyInput(e))) e.preventDefault();\n }}\n onKeyUp={(e) => controller.keyUp(toVectorKeyInput(e))}\n onCopy={clipboard('copy')}\n onCut={clipboard('cut')}\n onPaste={clipboard('paste')}\n >\n {checkerboard && (\n <defs>\n <pattern id={`ve${uid}-checker`} width={16} height={16} patternUnits=\"userSpaceOnUse\">\n <rect width={16} height={16} fill=\"#ffffff\" />\n <rect width={8} height={8} fill=\"#e5e7eb\" />\n <rect x={8} y={8} width={8} height={8} fill=\"#e5e7eb\" />\n </pattern>\n </defs>\n )}\n <VectorGradientDefs defs={scene.defs} />\n <rect\n data-vector-artboard=\"\"\n x={overlay.artboard.x}\n y={overlay.artboard.y}\n width={overlay.artboard.width}\n height={overlay.artboard.height}\n fill={scene.background ?? (checkerboard ? `url(#ve${uid}-checker)` : '#ffffff')}\n stroke=\"rgba(0,0,0,0.12)\"\n />\n <g data-vector-scene=\"\" transform={scene.transform}>\n <VectorSceneNodes nodes={scene.nodes} />\n </g>\n <g data-vector-overlay=\"\" pointerEvents=\"none\" fill=\"none\">\n {overlay.outlines.map((o) => (\n <path key={o.id} d={o.d} stroke={accentColor} strokeWidth={o.selected ? 1 : 1.5} opacity={o.selected ? 1 : 0.7} />\n ))}\n {overlay.penPreview && <path d={overlay.penPreview} stroke={accentColor} strokeDasharray=\"4 3\" />}\n {box && (\n <g data-vector-selection=\"\" transform={box.transform || undefined}>\n <rect x={box.x} y={box.y} width={box.width} height={box.height} stroke={accentColor} />\n <line x1={box.x + box.width / 2} y1={box.y} x2={box.x + box.width / 2} y2={box.y - 24} stroke={accentColor} />\n {box.handles.map((h) =>\n h.handle === 'rotate' ? (\n <circle key={h.handle} data-handle={h.handle} cx={h.x} cy={h.y} r={hs / 2 + 1} fill={THEME.handleFill} stroke={accentColor} />\n ) : (\n <rect key={h.handle} data-handle={h.handle} x={h.x - hs / 2} y={h.y - hs / 2} width={hs} height={hs} fill={THEME.handleFill} stroke={accentColor} />\n ),\n )}\n </g>\n )}\n {overlay.handles.map((h) => (\n <g key={`${h.ref.nodeId}:${h.ref.subpath}:${h.ref.index}:${h.ref.handle}`} data-vector-handle={h.ref.handle}>\n <line x1={h.anchorX} y1={h.anchorY} x2={h.x} y2={h.y} stroke={accentColor} />\n <circle cx={h.x} cy={h.y} r={THEME.handleRadius + (h.hovered ? 1 : 0)} fill={THEME.handleFill} stroke={accentColor} />\n </g>\n ))}\n {overlay.anchors.map((a) => {\n const size = as + (a.hovered ? 2 : 0);\n const fill = a.selected ? accentColor : THEME.handleFill;\n const key = `${a.ref.nodeId}:${a.ref.subpath}:${a.ref.index}`;\n return a.type === 'corner' ? (\n <rect key={key} data-vector-anchor={a.ref.index} x={a.x - size / 2} y={a.y - size / 2} width={size} height={size} fill={fill} stroke={accentColor} />\n ) : (\n <circle key={key} data-vector-anchor={a.ref.index} cx={a.x} cy={a.y} r={size / 2} fill={fill} stroke={accentColor} />\n );\n })}\n {overlay.cornerWidgets.map((w) => (\n <g key={`corner:${w.ref.nodeId}:${w.ref.subpath}:${w.ref.index}`} data-vector-corner-widget={w.ref.index} data-corner-kind={w.kind}>\n <circle cx={w.x} cy={w.y} r={THEME.cornerWidgetRadius + (w.hovered ? 1 : 0)} fill={THEME.handleFill} stroke={accentColor} />\n <circle cx={w.x} cy={w.y} r={1.5} fill={accentColor} />\n </g>\n ))}\n {overlay.blend.spines.map((sp) => (\n <g key={`blend:${sp.id}`} data-vector-blend-spine={sp.id} data-replaced={sp.replaced || undefined}>\n <path d={sp.d} fill=\"none\" stroke={accentColor} strokeDasharray=\"4 3\" />\n {sp.keys.map((k, i) => (\n <circle key={i} cx={k.x} cy={k.y} r={THEME.handleRadius} fill={THEME.handleFill} stroke={accentColor} />\n ))}\n </g>\n ))}\n {overlay.blend.start && (\n <g data-vector-blend-start=\"\">\n <path d={overlay.blend.start.d} fill=\"none\" stroke={accentColor} strokeWidth={2} />\n {overlay.blend.start.anchor && <circle cx={overlay.blend.start.anchor.x} cy={overlay.blend.start.anchor.y} r={THEME.handleRadius + 1} fill={accentColor} />}\n </g>\n )}\n {overlay.blend.anchors.map((a, i) => (\n <rect\n key={`blend-anchor:${i}`}\n data-vector-blend-anchor={i}\n x={a.x - as / 2}\n y={a.y - as / 2}\n width={as}\n height={as}\n fill={a.hovered ? accentColor : THEME.handleFill}\n stroke={accentColor}\n />\n ))}\n {overlay.widthSpot && (\n <g data-vector-width-spot=\"\">\n <line x1={overlay.widthSpot.left.x} y1={overlay.widthSpot.left.y} x2={overlay.widthSpot.right.x} y2={overlay.widthSpot.right.y} stroke={accentColor} strokeDasharray=\"3 2\" />\n <path d={vectorDiamondPath(overlay.widthSpot.x, overlay.widthSpot.y)} fill=\"none\" stroke={accentColor} />\n </g>\n )}\n {overlay.widthPoints.map((w) => (\n <g key={`width:${w.ref.nodeId}:${w.ref.subpath}:${w.ref.index}`} data-vector-width-point={w.ref.index} data-selected={w.selected || undefined}>\n <line x1={w.left.x} y1={w.left.y} x2={w.right.x} y2={w.right.y} stroke={accentColor} />\n <path d={vectorDiamondPath(w.x, w.y)} fill={w.selected || w.active ? accentColor : THEME.handleFill} stroke={accentColor} strokeWidth={w.hovered === 'center' ? 2 : 1} />\n {(['left', 'right'] as const).map((side) => (\n <circle key={side} data-vector-width-side={side} cx={w[side].x} cy={w[side].y} r={THEME.handleRadius + (w.hovered === side ? 1 : 0)} fill={THEME.handleFill} stroke={accentColor} />\n ))}\n </g>\n ))}\n {state.tool === 'pen' && overlay.anchors.some((a) => a.closes && a.hovered) && (\n <circle cx={overlay.anchors.find((a) => a.closes)!.x} cy={overlay.anchors.find((a) => a.closes)!.y} r={as} stroke={accentColor} />\n )}\n {overlay.builder && (\n <g data-vector-builder={overlay.builder.mode}>\n {overlay.builder.faces.map((d, i) => (\n <path\n key={`f${i}`}\n data-vector-builder-face=\"\"\n d={d}\n fill={overlay.builder!.mode === 'erase' ? THEME.builderEraseFill : THEME.builderFill}\n fillRule=\"nonzero\"\n stroke={overlay.builder!.mode === 'erase' ? THEME.builderErase : accentColor}\n strokeWidth={1}\n />\n ))}\n {overlay.builder.hatches.map((d, i) =>\n d ? (\n <path\n key={`h${i}`}\n data-vector-builder-hatch=\"\"\n d={d}\n fill=\"none\"\n stroke={overlay.builder!.mode === 'erase' ? THEME.builderErase : accentColor}\n strokeOpacity={THEME.builderHatchOpacity}\n strokeWidth={1}\n />\n ) : null\n )}\n {overlay.builder.lines.map((d, i) => (\n <path key={`l${i}`} data-vector-builder-line=\"\" d={d} fill=\"none\" stroke={THEME.builderErase} strokeWidth={3} strokeLinecap=\"round\" />\n ))}\n {overlay.builder.trail && <path data-vector-builder-trail=\"\" d={overlay.builder.trail} fill=\"none\" stroke={overlay.builder.mode === 'erase' ? THEME.builderErase : accentColor} strokeWidth={1} />}\n </g>\n )}\n {overlay.toolStroke && (\n <path\n data-vector-tool-stroke={overlay.toolStroke.tool}\n d={overlay.toolStroke.d}\n stroke={overlay.toolStroke.tool === 'eraser' ? THEME.eraserFill : accentColor}\n strokeWidth={overlay.toolStroke.tool === 'eraser' ? overlay.toolStroke.width : 1}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeDasharray={overlay.toolStroke.tool === 'knife' ? '5 3' : undefined}\n />\n )}\n {overlay.pencilString && (\n <line\n data-vector-pencil-string=\"\"\n x1={overlay.pencilString.x1}\n y1={overlay.pencilString.y1}\n x2={overlay.pencilString.x2}\n y2={overlay.pencilString.y2}\n stroke={accentColor}\n strokeDasharray=\"2 2\"\n />\n )}\n {overlay.cutPoint && <circle data-vector-cut-point=\"\" cx={overlay.cutPoint.x} cy={overlay.cutPoint.y} r={THEME.handleRadius + 1} fill={THEME.handleFill} stroke={accentColor} />}\n {overlay.marquee && (\n <rect\n data-vector-marquee=\"\"\n x={overlay.marquee.x}\n y={overlay.marquee.y}\n width={overlay.marquee.width}\n height={overlay.marquee.height}\n fill={THEME.marqueeFill}\n stroke={accentColor}\n strokeDasharray=\"3 2\"\n />\n )}\n {overlay.guides.lines.length > 0 && (\n <g data-vector-guides=\"\" stroke={guideColor}>\n {overlay.guides.lines.map((l, i) => (\n <line key={i} data-vector-guide={l.kind} x1={l.x1} y1={l.y1} x2={l.x2} y2={l.y2} strokeDasharray={l.kind === 'construction' ? '4 3' : undefined} />\n ))}\n </g>\n )}\n {overlay.guides.labels.map((l, i) => (\n <text\n key={i}\n data-vector-guide-label={l.kind}\n x={l.x + 6}\n y={l.y - 6}\n fontSize={10}\n fill={guideColor}\n stroke=\"#ffffff\"\n strokeWidth={3}\n paintOrder=\"stroke\"\n style={{ fontFamily: 'system-ui, sans-serif' }}\n >\n {l.text}\n </text>\n ))}\n {overlay.status && (\n <text data-vector-status=\"\" x={8} y=\"100%\" dy={-8} fontSize={11} fill={accentColor} style={{ fontFamily: 'system-ui, sans-serif' }}>\n {overlay.status}\n </text>\n )}\n </g>\n {edit && editAt && (\n // Width Point Edit (double-click with the width tool), beside the point.\n <foreignObject data-vector-width-point-edit=\"\" x={editAt.x + 12} y={editAt.y + 12} width={180} height={140} style={{ overflow: 'visible' }}>\n <VectorWidthPointEditor key={`${edit.nodeId}:${edit.index}:${edit.t}`} controller={controller} edit={edit} accentColor={accentColor} />\n </foreignObject>\n )}\n </svg>\n );\n}\n","import React, { useRef, useState } from 'react';\nimport { VECTOR_OVERLAY_THEME as THEME, type VectorEditorController, type VectorWidthPointEdit } from '@pixerate/editor/vector';\n\nexport interface VectorWidthPointEditorProps {\n controller: VectorEditorController;\n /** The point being edited (`state.widthPointEdit`). */\n edit: VectorWidthPointEdit;\n /** Accent colour of the Apply button (default sky blue). */\n accentColor?: string;\n className?: string;\n style?: React.CSSProperties;\n}\n\nconst round = (v: number, digits: number) => String(Math.round(v * 10 ** digits) / 10 ** digits);\n\nconst fieldStyle: React.CSSProperties = { display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 6 };\nconst inputStyle: React.CSSProperties = { width: 72, font: 'inherit', padding: '1px 4px' };\n\n/**\n * Width Point Edit: the position (percent along the path) and the left / right side widths\n * (document units) of the width point a width-tool double-click opened. Apply (or Enter) sets\n * them with `commitWidthPointEdit`; Cancel or Escape closes it. `<VectorCanvas>` shows it next\n * to the point; use it on its own to place it elsewhere.\n */\nexport function VectorWidthPointEditor({ controller, edit, accentColor = THEME.accent, className, style }: VectorWidthPointEditorProps) {\n const [position, setPosition] = useState(() => round(edit.t * 100, 2));\n const [left, setLeft] = useState(() => round(edit.left, 3));\n const [right, setRight] = useState(() => round(edit.right, 3));\n const formRef = useRef<HTMLFormElement | null>(null);\n // Hand the keyboard back to the canvas around it.\n const refocus = () => (formRef.current?.closest('svg') as SVGSVGElement | null)?.focus?.({ preventScroll: true });\n const close = () => {\n refocus();\n controller.closeWidthPointEdit();\n };\n const num = (v: string) => (v.trim() !== '' && Number.isFinite(Number(v)) ? Number(v) : undefined);\n const apply = () => {\n const t = num(position);\n refocus();\n controller.commitWidthPointEdit({ t: t === undefined ? undefined : Math.min(Math.max(t, 0), 100) / 100, left: num(left), right: num(right) });\n };\n const stop = (e: React.SyntheticEvent) => e.stopPropagation();\n return (\n <form\n ref={formRef}\n data-vector-width-point-editor=\"\"\n aria-label=\"Width point\"\n className={className}\n style={{\n display: 'grid',\n gap: 4,\n padding: 8,\n background: '#ffffff',\n border: '1px solid rgba(0,0,0,0.15)',\n borderRadius: 6,\n boxShadow: '0 2px 8px rgba(0,0,0,0.15)',\n font: '12px system-ui, sans-serif',\n color: '#18181b',\n ...style,\n }}\n // Keep the canvas from treating clicks, keys and clipboard use in here as editing gestures.\n onPointerDown={stop}\n onPointerMove={stop}\n onPointerUp={stop}\n onDoubleClick={stop}\n onCopy={stop}\n onCut={stop}\n onPaste={stop}\n onKeyDown={(e) => {\n e.stopPropagation();\n if (e.key === 'Escape') {\n e.preventDefault();\n close();\n }\n }}\n onSubmit={(e) => {\n e.preventDefault();\n apply();\n }}\n >\n <label style={fieldStyle}>\n Position %\n <input aria-label=\"Width point position\" type=\"number\" min={0} max={100} step=\"any\" value={position} onChange={(e) => setPosition(e.target.value)} style={inputStyle} autoFocus />\n </label>\n <label style={fieldStyle}>\n Left\n <input aria-label=\"Width point left side\" type=\"number\" min={0} step=\"any\" value={left} onChange={(e) => setLeft(e.target.value)} style={inputStyle} />\n </label>\n <label style={fieldStyle}>\n Right\n <input aria-label=\"Width point right side\" type=\"number\" min={0} step=\"any\" value={right} onChange={(e) => setRight(e.target.value)} style={inputStyle} />\n </label>\n <div style={{ display: 'flex', justifyContent: 'flex-end', gap: 4, marginTop: 2 }}>\n <button type=\"button\" onClick={close}>\n Cancel\n </button>\n <button type=\"submit\" style={{ background: accentColor, color: '#ffffff', border: 'none', borderRadius: 4, padding: '2px 8px' }}>\n {edit.index === null ? 'Add' : 'Apply'}\n </button>\n </div>\n </form>\n );\n}\n","import React from 'react';\nimport {\n VECTOR_TOOLS,\n VECTOR_TOOL_GLYPHS,\n VECTOR_TOOL_SHORTCUTS,\n VECTOR_EDIT_TOGGLES,\n VECTOR_PATH_ACTIONS,\n VECTOR_PATHFINDER_ACTIONS,\n VECTOR_FILL_GAP,\n VECTOR_ARROWHEADS,\n VECTOR_ARROWHEAD_LABELS,\n VECTOR_CORNER_KINDS,\n VECTOR_CORNER_KIND_LABELS,\n VECTOR_STROKE_ALIGN_LABELS,\n VECTOR_WIDTH_PRESETS,\n VECTOR_BLEND_SPACINGS,\n VECTOR_BLEND_SPACING_LABELS,\n applyVectorBlendOptions,\n getVectorBlendControls,\n getVectorSelectionStyle,\n widthProfilePreset,\n widthProfilePresetId,\n vectorPaintToHex,\n vectorToolLabel,\n type VectorArrowhead,\n type VectorBlendSpacing,\n type VectorCornerKind,\n type VectorEditorController,\n type VectorStrokeAlign,\n type VectorTool,\n type VectorWidthPreset,\n} from '@pixerate/editor/vector';\nimport { useVectorEditorState } from './useVectorEditor';\n\nconst VECTOR_SNAP_TITLE = 'Snap to objects';\nconst modKeyLabel = () => (typeof navigator !== 'undefined' && /Mac|iPhone|iPad/.test(navigator.platform ?? '') ? '⌘' : 'Ctrl');\n\nconst buttonClass =\n 'inline-flex h-8 min-w-8 items-center justify-center rounded-md border border-border bg-background px-2 text-xs font-medium text-foreground hover:bg-muted disabled:cursor-not-allowed disabled:opacity-40 aria-pressed:bg-primary aria-pressed:text-primary-foreground';\n\nexport interface VectorToolbarProps {\n controller: VectorEditorController;\n /** Tools to show (default: all). */\n tools?: readonly VectorTool[];\n /** Undo / redo buttons (default `true`). */\n showHistory?: boolean;\n /** Boolean, Pathfinder, group, arrange and align buttons (default `true`). */\n showArrange?: boolean;\n /** The snapping toggle (default `true`). */\n showSnap?: boolean;\n /**\n * Path editing: Join, Average, Cut at Points, Remove Redundant Points, Smooth, the Keep\n * Shape / Curvature / Shapes toggles, and the pencil smoothing and eraser size inputs while\n * those tools are active (default `true`).\n */\n showPathEdit?: boolean;\n /**\n * Blend: Make Blend, spacing (steps, distance or smooth colour), steps / distance, orient to\n * spine, Replace Spine, Expand and Release (default `true`).\n */\n showBlend?: boolean;\n className?: string;\n}\n\n/** Tool picker plus undo, snapping, boolean operations, grouping, stacking and alignment. */\nexport function VectorToolbar({\n controller,\n tools = VECTOR_TOOLS,\n showHistory = true,\n showArrange = true,\n showSnap = true,\n showPathEdit = true,\n showBlend = true,\n className,\n}: VectorToolbarProps) {\n const state = useVectorEditorState(controller);\n const count = state.selection.length;\n const points = state.tool === 'direct' ? state.selectedAnchors.length : 0;\n const editing = state.editing;\n const groupSelected = state.selection.some((id) => controller.getNode(id)?.type === 'group');\n const act = (label: string, title: string, run: () => unknown, disabled = false) => (\n <button key={label} type=\"button\" className={buttonClass} title={title} aria-label={title} disabled={disabled} onClick={() => void run()}>\n {label}\n </button>\n );\n return (\n <div role=\"toolbar\" aria-label=\"Vector tools\" className={`flex flex-wrap items-center gap-1 ${className ?? ''}`}>\n <div className=\"flex items-center gap-1\" role=\"group\" aria-label=\"Tools\">\n {tools.map((tool) => (\n <button\n key={tool}\n type=\"button\"\n data-vector-tool={tool}\n className={buttonClass}\n aria-pressed={state.tool === tool}\n title={`${vectorToolLabel(tool)} (${VECTOR_TOOL_SHORTCUTS[tool]})`}\n aria-label={vectorToolLabel(tool)}\n onClick={() => controller.setTool(tool)}\n >\n {VECTOR_TOOL_GLYPHS[tool]}\n </button>\n ))}\n </div>\n {showHistory && (\n <div className=\"ml-1 flex items-center gap-1\" role=\"group\" aria-label=\"History\">\n {act('↶', state.canUndo ? `Undo ${state.undoLabel}` : 'Undo', () => controller.undo(), !state.canUndo)}\n {act('↷', state.canRedo ? `Redo ${state.redoLabel}` : 'Redo', () => controller.redo(), !state.canRedo)}\n </div>\n )}\n {showSnap && (\n <div className=\"ml-1 flex items-center gap-1\" role=\"group\" aria-label=\"Snapping\">\n <button\n type=\"button\"\n data-vector-snap=\"\"\n className={buttonClass}\n aria-pressed={state.snap.objects}\n title={`${VECTOR_SNAP_TITLE} (hold ${modKeyLabel()} to bypass)`}\n aria-label={VECTOR_SNAP_TITLE}\n onClick={() => controller.toggleSnapping()}\n >\n Snap\n </button>\n </div>\n )}\n {showPathEdit && (\n <div className=\"ml-1 flex items-center gap-1\" role=\"group\" aria-label=\"Path editing\">\n {VECTOR_PATH_ACTIONS.map((a) => (\n <button\n key={a.id}\n type=\"button\"\n data-vector-path-action={a.id}\n className={buttonClass}\n title={a.shortcut ? `${a.title} (${modKeyLabel()}+${a.shortcut})` : a.title}\n aria-label={a.title}\n disabled={!a.enabled(count, points)}\n onClick={() => void a.run(controller)}\n >\n {a.label}\n </button>\n ))}\n {VECTOR_EDIT_TOGGLES.map((t) => (\n <button\n key={t.key}\n type=\"button\"\n data-vector-edit={t.key}\n className={buttonClass}\n aria-pressed={editing[t.key]}\n title={t.title}\n aria-label={t.title}\n onClick={() => controller.setEditing({ [t.key]: !editing[t.key] })}\n >\n {t.label}\n </button>\n ))}\n {state.tool === 'pencil' && (\n <label className=\"flex items-center gap-1 text-xs text-foreground\">\n Smoothing\n <input\n type=\"range\"\n min={0}\n max={1}\n step={0.05}\n aria-label=\"Pencil smoothing\"\n className=\"h-4 w-20 accent-primary\"\n value={editing.pencilSmoothing}\n onChange={(e) => controller.setEditing({ pencilSmoothing: parseFloat(e.target.value) })}\n />\n </label>\n )}\n {state.tool === 'eraser' && (\n <label className=\"flex items-center gap-1 text-xs text-foreground\">\n Size\n <input\n type=\"number\"\n min={0.5}\n step={1}\n aria-label=\"Eraser size\"\n className=\"h-7 w-16 rounded border border-border bg-background px-1.5 text-xs\"\n value={editing.eraserSize}\n onChange={(e) => {\n const n = parseFloat(e.target.value);\n if (Number.isFinite(n) && n > 0) controller.setEditing({ eraserSize: n });\n }}\n />\n </label>\n )}\n {state.tool === 'paintBucket' && (\n <button\n type=\"button\"\n data-vector-fill-gap=\"\"\n className={buttonClass}\n aria-pressed={editing.fillGap > 0}\n title=\"Close small gaps between path ends when filling\"\n aria-label=\"Close gaps\"\n onClick={() => controller.setEditing({ fillGap: editing.fillGap > 0 ? 0 : VECTOR_FILL_GAP })}\n >\n Gaps\n </button>\n )}\n </div>\n )}\n {showBlend && <VectorBlendControls controller={controller} />}\n {showArrange && (\n <>\n <div className=\"ml-1 flex items-center gap-1\" role=\"group\" aria-label=\"Combine\">\n {act('∪', 'Union', () => controller.booleanOp('union'), count < 2)}\n {act('−', 'Subtract', () => controller.booleanOp('subtract'), count < 2)}\n {act('∩', 'Intersect', () => controller.booleanOp('intersect'), count < 2)}\n {act('⊻', 'Exclude', () => controller.booleanOp('exclude'), count < 2)}\n {act('G', 'Group', () => controller.group(), count < 1)}\n {act('U', 'Ungroup', () => controller.ungroup(), !groupSelected)}\n </div>\n <div className=\"ml-1 flex items-center gap-1\" role=\"group\" aria-label=\"Pathfinder\">\n {VECTOR_PATHFINDER_ACTIONS.map((a) => (\n <button\n key={a.id}\n type=\"button\"\n data-vector-pathfinder={a.id}\n className={buttonClass}\n title={a.title}\n aria-label={a.title}\n disabled={count < a.min}\n onClick={() => void controller.pathfinder(a.id)}\n >\n {a.label}\n </button>\n ))}\n </div>\n <div className=\"ml-1 flex items-center gap-1\" role=\"group\" aria-label=\"Arrange\">\n {act('⇈', 'Bring to Front', () => controller.arrange('front'), count < 1)}\n {act('⇊', 'Send to Back', () => controller.arrange('back'), count < 1)}\n {act('⇤', 'Align Left', () => controller.align('left'), count < 1)}\n {act('↔', 'Align Center', () => controller.align('center'), count < 1)}\n {act('⇥', 'Align Right', () => controller.align('right'), count < 1)}\n {act('⤒', 'Align Top', () => controller.align('top'), count < 1)}\n {act('↕', 'Align Middle', () => controller.align('middle'), count < 1)}\n {act('⤓', 'Align Bottom', () => controller.align('bottom'), count < 1)}\n </div>\n </>\n )}\n </div>\n );\n}\n\n/** Blend buttons and options: they edit the selected blends and the options new blends get. */\nfunction VectorBlendControls({ controller }: { controller: VectorEditorController }) {\n const state = useVectorEditorState(controller);\n const blend = getVectorBlendControls(state);\n const o = blend.options;\n const selected = blend.ids.length > 0;\n return (\n <div className=\"ml-1 flex items-center gap-1\" role=\"group\" aria-label=\"Blend\" data-vector-blend-controls=\"\">\n <button type=\"button\" data-vector-blend-action=\"make\" className={buttonClass} title=\"Make Blend\" aria-label=\"Make Blend\" disabled={!blend.canBlend} onClick={() => controller.blend()}>\n ⧓\n </button>\n <select\n aria-label=\"Blend spacing\"\n className=\"h-7 rounded border border-border bg-background px-1 text-xs\"\n value={o.spacing}\n onChange={(e) => applyVectorBlendOptions(controller, { spacing: e.target.value as VectorBlendSpacing })}\n >\n {VECTOR_BLEND_SPACINGS.map((sp) => (\n <option key={sp} value={sp}>\n {VECTOR_BLEND_SPACING_LABELS[sp]}\n </option>\n ))}\n </select>\n {o.spacing !== 'smoothColor' && (\n <input\n type=\"number\"\n min={o.spacing === 'steps' ? 1 : 0.5}\n step={1}\n aria-label={o.spacing === 'steps' ? 'Blend steps' : 'Blend distance'}\n className=\"h-7 w-16 rounded border border-border bg-background px-1.5 text-xs\"\n value={o.spacing === 'steps' ? o.steps : o.distance}\n onChange={(e) => {\n const n = parseFloat(e.target.value);\n if (!Number.isFinite(n) || n <= 0) return;\n applyVectorBlendOptions(controller, o.spacing === 'steps' ? { steps: n } : { distance: n });\n }}\n />\n )}\n <button\n type=\"button\"\n data-vector-blend-action=\"orient\"\n className={buttonClass}\n aria-pressed={o.orientToSpine}\n title=\"Orient steps to the spine\"\n aria-label=\"Orient to spine\"\n onClick={() => applyVectorBlendOptions(controller, { orientToSpine: !o.orientToSpine })}\n >\n ⤿\n </button>\n <button\n type=\"button\"\n data-vector-blend-action=\"spine\"\n className={buttonClass}\n title=\"Replace Spine (select a blend and a path)\"\n aria-label=\"Replace Spine\"\n disabled={!blend.canReplaceSpine}\n onClick={() => controller.replaceBlendSpine()}\n >\n ⌇\n </button>\n <button type=\"button\" data-vector-blend-action=\"expand\" className={buttonClass} title=\"Expand Blend\" aria-label=\"Expand Blend\" disabled={!selected} onClick={() => controller.expandBlend()}>\n ⧉\n </button>\n <button type=\"button\" data-vector-blend-action=\"release\" className={buttonClass} title=\"Release Blend\" aria-label=\"Release Blend\" disabled={!selected} onClick={() => controller.releaseBlend()}>\n ⧄\n </button>\n </div>\n );\n}\n\nexport interface VectorStylePanelProps {\n controller: VectorEditorController;\n className?: string;\n}\n\nconst selectClass = 'h-7 min-w-0 flex-1 rounded border border-border bg-background px-1 text-xs';\nconst numberClass = 'h-7 w-16 rounded border border-border bg-background px-1.5 text-xs';\n\n/**\n * Fill, stroke, stroke width, alignment and width profile, arrowheads, live corner radius and opacity of the\n * selection (corners of the selected points with the direct tool); with nothing selected it\n * edits the defaults for new shapes.\n */\nexport function VectorStylePanel({ controller, className }: VectorStylePanelProps) {\n const state = useVectorEditorState(controller);\n const style = getVectorSelectionStyle(state);\n const d = state.defaults;\n const source = style ?? {\n fill: d.fill ?? null,\n stroke: d.stroke ?? null,\n strokeWidth: d.strokeWidth ?? 1,\n opacity: 1,\n strokeAlign: d.strokeAlign ?? 'center',\n startArrow: d.startArrow ?? null,\n endArrow: d.endArrow ?? null,\n arrowAlign: d.arrowAlign ?? 'extend',\n startArrowScale: d.startArrowScale ?? 1,\n endArrowScale: d.endArrowScale ?? 1,\n widthProfile: widthProfilePresetId(d.strokeWidthProfile),\n cornerRadius: d.cornerRadius,\n cornerKind: d.cornerKind ?? 'round',\n corners: 1,\n hasOpenPath: true,\n };\n const setCorners = (patch: { radius?: number; kind?: VectorCornerKind }) => {\n if (!style) controller.setDefaults({ ...(patch.radius !== undefined ? { cornerRadius: patch.radius } : {}), ...(patch.kind ? { cornerKind: patch.kind } : {}) });\n else if (patch.radius !== undefined) controller.setCornerRadius(patch.radius);\n else if (patch.kind) controller.setCornerKind(patch.kind);\n };\n const setProfile = (id: VectorWidthPreset) => {\n if (style) controller.setWidthProfile(id);\n else controller.setDefaults({ strokeWidthProfile: widthProfilePreset(id)?.length ? widthProfilePreset(id) : null });\n };\n const mixed = (key: keyof NonNullable<typeof style>['mixed']) => (style?.mixed[key] ? <span className=\"text-[11px] text-muted-foreground\">Mixed</span> : null);\n const arrowRow = (end: 'start' | 'end', label: string) => {\n const key = end === 'start' ? 'startArrow' : 'endArrow';\n const scaleKey = end === 'start' ? 'startArrowScale' : 'endArrowScale';\n return (\n <div className=\"flex items-center gap-2\" data-vector-style={key}>\n <span className=\"w-16 text-xs text-foreground\">{label}</span>\n <select aria-label={`${label} arrowhead`} className={selectClass} value={source[key] ?? ''} onChange={(e) => apply({ [key]: (e.target.value || null) as VectorArrowhead | null })}>\n <option value=\"\">None</option>\n {VECTOR_ARROWHEADS.map((h) => (\n <option key={h} value={h}>\n {VECTOR_ARROWHEAD_LABELS[h]}\n </option>\n ))}\n </select>\n <input\n type=\"number\"\n min={0.1}\n step={0.25}\n aria-label={`${label} arrowhead scale`}\n title=\"Scale (× stroke width)\"\n className={numberClass}\n value={source[scaleKey]}\n onChange={(e) => {\n const n = parseFloat(e.target.value);\n if (Number.isFinite(n) && n > 0) apply({ [scaleKey]: n });\n }}\n />\n </div>\n );\n };\n const apply = (patch: Record<string, unknown>) => {\n if (style) controller.setStyle(patch);\n else controller.setDefaults(patch);\n };\n const paintRow = (key: 'fill' | 'stroke', label: string) => {\n const paint = source[key];\n const hex = vectorPaintToHex(paint);\n const on = paint !== null && paint !== 'none';\n return (\n <div className=\"flex items-center gap-2\" data-vector-style={key}>\n <label className=\"flex w-16 items-center gap-1.5 text-xs text-foreground\">\n <input type=\"checkbox\" checked={on} aria-label={`${label} on`} onChange={(e) => apply({ [key]: e.target.checked ? (hex ?? '#000000') : null })} />\n {label}\n </label>\n <input\n type=\"color\"\n aria-label={`${label} colour`}\n className=\"h-7 w-10 cursor-pointer rounded border border-border bg-background disabled:opacity-40\"\n disabled={!on}\n value={hex ?? '#000000'}\n onChange={(e) => apply({ [key]: e.target.value })}\n />\n {on && !hex && <span className=\"truncate text-[11px] text-muted-foreground\">{typeof paint === 'string' ? paint : 'Gradient'}</span>}\n {style?.mixed[key] && <span className=\"text-[11px] text-muted-foreground\">Mixed</span>}\n </div>\n );\n };\n return (\n <div className={`space-y-2 ${className ?? ''}`} aria-label={style ? 'Selection style' : 'New shape style'}>\n <p className=\"text-[11px] font-medium uppercase tracking-wide text-muted-foreground\">{style ? 'Selection' : 'New shapes'}</p>\n {paintRow('fill', 'Fill')}\n {paintRow('stroke', 'Stroke')}\n <label className=\"flex items-center gap-2 text-xs text-foreground\">\n <span className=\"w-16\">Width</span>\n <input\n type=\"number\"\n min={0}\n step={0.5}\n aria-label=\"Stroke width\"\n className=\"h-7 w-20 rounded border border-border bg-background px-1.5 text-xs\"\n value={source.strokeWidth}\n onChange={(e) => {\n const n = parseFloat(e.target.value);\n if (Number.isFinite(n) && n >= 0) apply({ strokeWidth: n });\n }}\n />\n </label>\n <label className=\"flex items-center gap-2 text-xs text-foreground\" data-vector-style=\"strokeAlign\">\n <span className=\"w-16\">Align</span>\n <select aria-label=\"Stroke alignment\" className={selectClass} value={source.strokeAlign} onChange={(e) => apply({ strokeAlign: e.target.value as VectorStrokeAlign })}>\n {(Object.keys(VECTOR_STROKE_ALIGN_LABELS) as VectorStrokeAlign[]).map((a) => (\n <option key={a} value={a}>\n {VECTOR_STROKE_ALIGN_LABELS[a]}\n </option>\n ))}\n </select>\n {mixed('strokeAlign')}\n </label>\n <div className=\"flex items-center gap-2 text-xs text-foreground\" data-vector-style=\"widthProfile\">\n <span className=\"w-16\">Profile</span>\n <select\n aria-label=\"Width profile\"\n className={selectClass}\n value={source.widthProfile}\n onChange={(e) => {\n if (e.target.value !== 'custom') setProfile(e.target.value as VectorWidthPreset);\n }}\n >\n {VECTOR_WIDTH_PRESETS.map((p) => (\n <option key={p.id} value={p.id}>\n {p.label}\n </option>\n ))}\n {source.widthProfile === 'custom' && (\n <option value=\"custom\" disabled>\n Custom\n </option>\n )}\n </select>\n <button\n type=\"button\"\n className={buttonClass}\n title=\"Reset to uniform width\"\n aria-label=\"Reset to uniform width\"\n disabled={source.widthProfile === 'uniform' && !style?.mixed.widthProfile}\n onClick={() => setProfile('uniform')}\n >\n ═\n </button>\n {mixed('widthProfile')}\n </div>\n {source.hasOpenPath && (\n <>\n {arrowRow('start', 'Start')}\n {arrowRow('end', 'End')}\n {(source.startArrow || source.endArrow) && (\n <label className=\"flex items-center gap-2 text-xs text-foreground\" data-vector-style=\"arrowAlign\">\n <span className=\"w-16\">Heads</span>\n <select aria-label=\"Arrowhead alignment\" className={selectClass} value={source.arrowAlign} onChange={(e) => apply({ arrowAlign: e.target.value })}>\n <option value=\"extend\">Tip past end</option>\n <option value=\"tip\">Tip at end</option>\n </select>\n </label>\n )}\n </>\n )}\n {source.corners > 0 && (\n <div className=\"flex items-center gap-2\" data-vector-style=\"corners\">\n <span className=\"w-16 text-xs text-foreground\">Corners</span>\n <input\n type=\"number\"\n min={0}\n step={1}\n aria-label=\"Corner radius\"\n className={numberClass}\n value={Math.round(source.cornerRadius * 100) / 100}\n onChange={(e) => {\n const n = parseFloat(e.target.value);\n if (Number.isFinite(n) && n >= 0) setCorners({ radius: n });\n }}\n />\n <select aria-label=\"Corner kind\" className={selectClass} value={source.cornerKind} onChange={(e) => setCorners({ kind: e.target.value as VectorCornerKind })}>\n {VECTOR_CORNER_KINDS.map((k) => (\n <option key={k} value={k}>\n {VECTOR_CORNER_KIND_LABELS[k]}\n </option>\n ))}\n </select>\n {mixed('cornerRadius')}\n </div>\n )}\n {style && (\n <label className=\"flex items-center gap-2 text-xs text-foreground\">\n <span className=\"w-16\">Opacity</span>\n <input\n type=\"range\"\n min={0}\n max={1}\n step={0.05}\n aria-label=\"Opacity\"\n className=\"h-4 flex-1 accent-primary\"\n value={source.opacity}\n onChange={(e) => apply({ opacity: parseFloat(e.target.value) })}\n />\n </label>\n )}\n </div>\n );\n}\n","import React from 'react';\nimport type { VectorEditorController, VectorTool } from '@pixerate/editor/vector';\nimport { VectorCanvas, type VectorCanvasProps } from './VectorCanvas';\nimport { VectorStylePanel, VectorToolbar } from './VectorToolbar';\n\nexport interface VectorEditorProps {\n controller: VectorEditorController;\n /** Tools in the toolbar (default: all). */\n tools?: readonly VectorTool[];\n /** The style sidebar (default `true`). */\n showStylePanel?: boolean;\n /** Canvas height (default 520px). */\n height?: number | string;\n canvasProps?: Omit<VectorCanvasProps, 'controller'>;\n className?: string;\n}\n\n/** Toolbar, canvas and style panel for a `VectorEditorController`. */\nexport function VectorEditor({ controller, tools, showStylePanel = true, height = 520, canvasProps, className }: VectorEditorProps) {\n return (\n <div className={`flex flex-col gap-2 ${className ?? ''}`} data-vector-editor=\"\">\n <VectorToolbar controller={controller} tools={tools} />\n <div className=\"flex min-h-0 flex-col gap-2 md:flex-row\">\n <div className=\"relative min-h-[320px] flex-1 overflow-hidden rounded-md border border-border bg-muted/40\" style={{ height }}>\n <VectorCanvas controller={controller} {...canvasProps} />\n </div>\n {showStylePanel && <VectorStylePanel controller={controller} className=\"w-full shrink-0 rounded-md border border-border p-3 md:w-56\" />}\n </div>\n </div>\n );\n}\n"],"mappings":"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","names":["useEffect","useRef","THEME","useRef","jsx","jsxs","THEME","useRef","useEffect","text","Fragment","jsx","jsxs","jsx","jsxs"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pixerate/editor-react",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.31.0",
|
|
4
4
|
"description": "React bindings and prompt/rich-text components for @pixerate/editor",
|
|
5
5
|
"author": "Pixerate",
|
|
6
6
|
"license": "MIT",
|
|
@@ -107,7 +107,7 @@
|
|
|
107
107
|
},
|
|
108
108
|
"peerDependencies": {
|
|
109
109
|
"@dagrejs/dagre": "^1.1.8",
|
|
110
|
-
"@pixerate/editor": ">=0.
|
|
110
|
+
"@pixerate/editor": ">=0.41.0 <1.0.0-0",
|
|
111
111
|
"@tiptap/core": "^2.11.5",
|
|
112
112
|
"@tiptap/pm": "^2.11.5",
|
|
113
113
|
"@tiptap/react": "^2.11.5",
|
|
@@ -134,7 +134,7 @@
|
|
|
134
134
|
"tsup": "^8.4.0",
|
|
135
135
|
"typescript": "^5.7.3",
|
|
136
136
|
"vitest": "^4.1.11",
|
|
137
|
-
"@pixerate/editor": "0.
|
|
137
|
+
"@pixerate/editor": "0.41.0"
|
|
138
138
|
},
|
|
139
139
|
"scripts": {
|
|
140
140
|
"build": "tsup",
|