@pixerate/editor-react 0.31.0 → 0.32.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 +277 -106
- package/dist/vector/index.cjs.map +1 -1
- package/dist/vector/index.d.cts +14 -2
- package/dist/vector/index.d.ts +14 -2
- package/dist/vector/index.js +257 -94
- package/dist/vector/index.js.map +1 -1
- package/package.json +3 -3
package/dist/vector/index.cjs
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
2
3
|
var __defProp = Object.defineProperty;
|
|
3
4
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
5
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
5
7
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
8
|
var __export = (target, all) => {
|
|
7
9
|
for (var name in all)
|
|
@@ -15,6 +17,14 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
15
17
|
}
|
|
16
18
|
return to;
|
|
17
19
|
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
18
28
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
29
|
|
|
20
30
|
// src/vector/index.ts
|
|
@@ -22,6 +32,7 @@ var vector_exports = {};
|
|
|
22
32
|
__export(vector_exports, {
|
|
23
33
|
VectorCanvas: () => VectorCanvas,
|
|
24
34
|
VectorEditor: () => VectorEditor,
|
|
35
|
+
VectorEffectsPanel: () => VectorEffectsPanel,
|
|
25
36
|
VectorGradientDefs: () => VectorGradientDefs,
|
|
26
37
|
VectorSceneNodes: () => VectorSceneNodes,
|
|
27
38
|
VectorStylePanel: () => VectorStylePanel,
|
|
@@ -499,14 +510,157 @@ function VectorCanvas({
|
|
|
499
510
|
}
|
|
500
511
|
|
|
501
512
|
// src/vector/VectorToolbar.tsx
|
|
513
|
+
var import_react4 = __toESM(require("react"), 1);
|
|
514
|
+
var import_vector5 = require("@pixerate/editor/vector");
|
|
515
|
+
|
|
516
|
+
// src/vector/VectorEffectsPanel.tsx
|
|
502
517
|
var import_vector4 = require("@pixerate/editor/vector");
|
|
503
518
|
var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
519
|
+
var buttonClass = "inline-flex h-7 min-w-7 items-center justify-center rounded-md border border-border bg-background px-1.5 text-xs font-medium text-foreground hover:bg-muted disabled:cursor-not-allowed disabled:opacity-40";
|
|
520
|
+
var numberClass = "h-7 w-16 rounded border border-border bg-background px-1.5 text-xs";
|
|
521
|
+
var selectClass = "h-7 min-w-0 flex-1 rounded border border-border bg-background px-1 text-xs";
|
|
522
|
+
var labelClass = "w-full truncate text-[11px] text-muted-foreground";
|
|
523
|
+
function VectorEffectsPanel({ controller, className }) {
|
|
524
|
+
const state = useVectorEditorState(controller);
|
|
525
|
+
const panel = (0, import_vector4.getVectorEffectsPanel)(state);
|
|
526
|
+
if (!panel) return null;
|
|
527
|
+
const nodeId = panel.nodeId;
|
|
528
|
+
const end = () => controller.endMergedEdit();
|
|
529
|
+
const set = (e, key, value, merge) => {
|
|
530
|
+
if (nodeId) controller.updateEffect(nodeId, e.id, { params: { [key]: value } }, { merge });
|
|
531
|
+
};
|
|
532
|
+
const number = (e, spec) => {
|
|
533
|
+
const value = Number(e.params[spec.key] ?? 0);
|
|
534
|
+
const label = `${e.label} ${spec.label}`;
|
|
535
|
+
const onChange = (ev) => {
|
|
536
|
+
const n = parseFloat(ev.target.value);
|
|
537
|
+
if (Number.isFinite(n)) set(e, spec.key, n, true);
|
|
538
|
+
};
|
|
539
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("label", { className: "flex flex-wrap items-center gap-x-2 gap-y-0.5 text-xs text-foreground", "data-vector-effect-param": spec.key, children: [
|
|
540
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: labelClass, children: spec.label }),
|
|
541
|
+
spec.slider && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
542
|
+
"input",
|
|
543
|
+
{
|
|
544
|
+
type: "range",
|
|
545
|
+
min: spec.min,
|
|
546
|
+
max: spec.max,
|
|
547
|
+
step: spec.step,
|
|
548
|
+
"aria-label": `${label} slider`,
|
|
549
|
+
className: "h-4 min-w-0 flex-1 accent-primary",
|
|
550
|
+
value,
|
|
551
|
+
onChange,
|
|
552
|
+
onPointerUp: end,
|
|
553
|
+
onKeyUp: end,
|
|
554
|
+
onBlur: end
|
|
555
|
+
}
|
|
556
|
+
),
|
|
557
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
558
|
+
"input",
|
|
559
|
+
{
|
|
560
|
+
type: "number",
|
|
561
|
+
min: spec.min,
|
|
562
|
+
max: spec.max,
|
|
563
|
+
step: spec.step,
|
|
564
|
+
"aria-label": label,
|
|
565
|
+
className: numberClass,
|
|
566
|
+
value: Math.round(value * 1e3) / 1e3,
|
|
567
|
+
onChange,
|
|
568
|
+
onBlur: end
|
|
569
|
+
}
|
|
570
|
+
)
|
|
571
|
+
] }, spec.key);
|
|
572
|
+
};
|
|
573
|
+
const vec2 = (e, spec) => {
|
|
574
|
+
const v = e.params[spec.key] ?? { x: 0, y: 0 };
|
|
575
|
+
const field = (axis) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
576
|
+
"input",
|
|
577
|
+
{
|
|
578
|
+
type: "number",
|
|
579
|
+
step: spec.kind === "vec2" ? spec.step : 1,
|
|
580
|
+
"aria-label": `${e.label} ${spec.label} ${axis}`,
|
|
581
|
+
className: numberClass,
|
|
582
|
+
value: Math.round(v[axis] * 1e3) / 1e3,
|
|
583
|
+
onChange: (ev) => {
|
|
584
|
+
const n = parseFloat(ev.target.value);
|
|
585
|
+
if (Number.isFinite(n)) set(e, spec.key, { ...v, [axis]: n }, true);
|
|
586
|
+
},
|
|
587
|
+
onBlur: end
|
|
588
|
+
}
|
|
589
|
+
);
|
|
590
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "flex flex-wrap items-center gap-x-2 gap-y-0.5 text-xs text-foreground", "data-vector-effect-param": spec.key, children: [
|
|
591
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: labelClass, children: spec.label }),
|
|
592
|
+
field("x"),
|
|
593
|
+
field("y")
|
|
594
|
+
] }, spec.key);
|
|
595
|
+
};
|
|
596
|
+
const param = (e, spec) => {
|
|
597
|
+
if (spec.kind === "number") return number(e, spec);
|
|
598
|
+
if (spec.kind === "vec2") return vec2(e, spec);
|
|
599
|
+
if (spec.kind === "boolean")
|
|
600
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("label", { className: "flex items-center gap-2 text-xs text-foreground", "data-vector-effect-param": spec.key, children: [
|
|
601
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "min-w-0 flex-1 truncate", children: spec.label }),
|
|
602
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("input", { type: "checkbox", "aria-label": `${e.label} ${spec.label}`, checked: !!e.params[spec.key], onChange: (ev) => set(e, spec.key, ev.target.checked, false) })
|
|
603
|
+
] }, spec.key);
|
|
604
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("label", { className: "flex flex-wrap items-center gap-x-2 gap-y-0.5 text-xs text-foreground", "data-vector-effect-param": spec.key, children: [
|
|
605
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: labelClass, children: spec.label }),
|
|
606
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("select", { "aria-label": `${e.label} ${spec.label}`, className: selectClass, value: String(e.params[spec.key] ?? ""), onChange: (ev) => set(e, spec.key, ev.target.value, false), children: spec.options.map((o) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("option", { value: o.value, children: o.label }, o.value)) })
|
|
607
|
+
] }, spec.key);
|
|
608
|
+
};
|
|
609
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: `space-y-2 ${className ?? ""}`, "data-vector-effects": "", "aria-label": "Effects", children: [
|
|
610
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
611
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "w-16 text-[11px] font-medium uppercase tracking-wide text-muted-foreground", children: "Effects" }),
|
|
612
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
|
|
613
|
+
"select",
|
|
614
|
+
{
|
|
615
|
+
"aria-label": "Add effect",
|
|
616
|
+
className: selectClass,
|
|
617
|
+
value: "",
|
|
618
|
+
onChange: (ev) => {
|
|
619
|
+
if (ev.target.value) controller.addEffect(ev.target.value);
|
|
620
|
+
},
|
|
621
|
+
children: [
|
|
622
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("option", { value: "", children: "Add effect\u2026" }),
|
|
623
|
+
import_vector4.VECTOR_EFFECT_MENU.map((m) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("option", { value: m.type, children: m.label }, m.type))
|
|
624
|
+
]
|
|
625
|
+
}
|
|
626
|
+
),
|
|
627
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("button", { type: "button", className: buttonClass, title: "Expand Appearance", "aria-label": "Expand Appearance", disabled: !panel.expandable, onClick: () => controller.expandAppearance(), children: "Expand" })
|
|
628
|
+
] }),
|
|
629
|
+
panel.count > 1 && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "text-[11px] text-muted-foreground", children: "Select one object to edit its effects." }),
|
|
630
|
+
nodeId && panel.effects.map((e, i) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "space-y-1 rounded border border-border p-1.5", "data-vector-effect": e.id, "data-vector-effect-type": e.type, children: [
|
|
631
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "flex items-center gap-1", children: [
|
|
632
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("label", { className: "flex min-w-0 flex-1 items-center gap-1.5 text-xs font-medium text-foreground", children: [
|
|
633
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("input", { type: "checkbox", "aria-label": `${e.label} on`, checked: e.enabled, onChange: (ev) => controller.updateEffect(nodeId, e.id, { enabled: ev.target.checked }) }),
|
|
634
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "truncate", children: e.label })
|
|
635
|
+
] }),
|
|
636
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("button", { type: "button", className: buttonClass, title: "Move up", "aria-label": `Move ${e.label} up`, disabled: i === 0, onClick: () => controller.moveEffect(nodeId, e.id, i - 1), children: "\u2191" }),
|
|
637
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
638
|
+
"button",
|
|
639
|
+
{
|
|
640
|
+
type: "button",
|
|
641
|
+
className: buttonClass,
|
|
642
|
+
title: "Move down",
|
|
643
|
+
"aria-label": `Move ${e.label} down`,
|
|
644
|
+
disabled: i === panel.effects.length - 1,
|
|
645
|
+
onClick: () => controller.moveEffect(nodeId, e.id, i + 1),
|
|
646
|
+
children: "\u2193"
|
|
647
|
+
}
|
|
648
|
+
),
|
|
649
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("button", { type: "button", className: buttonClass, title: "Remove", "aria-label": `Remove ${e.label}`, onClick: () => controller.removeEffect(nodeId, e.id), children: "\xD7" })
|
|
650
|
+
] }),
|
|
651
|
+
e.specs.map((spec) => param(e, spec))
|
|
652
|
+
] }, e.id))
|
|
653
|
+
] });
|
|
654
|
+
}
|
|
655
|
+
|
|
656
|
+
// src/vector/VectorToolbar.tsx
|
|
657
|
+
var import_jsx_runtime4 = require("react/jsx-runtime");
|
|
504
658
|
var VECTOR_SNAP_TITLE = "Snap to objects";
|
|
505
659
|
var modKeyLabel = () => typeof navigator !== "undefined" && /Mac|iPhone|iPad/.test(navigator.platform ?? "") ? "\u2318" : "Ctrl";
|
|
506
|
-
var
|
|
660
|
+
var buttonClass2 = "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";
|
|
507
661
|
function VectorToolbar({
|
|
508
662
|
controller,
|
|
509
|
-
tools =
|
|
663
|
+
tools = import_vector5.VECTOR_TOOLS,
|
|
510
664
|
showHistory = true,
|
|
511
665
|
showArrange = true,
|
|
512
666
|
showSnap = true,
|
|
@@ -519,32 +673,34 @@ function VectorToolbar({
|
|
|
519
673
|
const points = state.tool === "direct" ? state.selectedAnchors.length : 0;
|
|
520
674
|
const editing = state.editing;
|
|
521
675
|
const groupSelected = state.selection.some((id) => controller.getNode(id)?.type === "group");
|
|
522
|
-
const
|
|
523
|
-
|
|
524
|
-
|
|
676
|
+
const [live, setLive] = import_react4.default.useState(false);
|
|
677
|
+
const booleanDisabled = live ? count < 1 : count < 2;
|
|
678
|
+
const act = (label, title, run, disabled = false) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("button", { type: "button", className: buttonClass2, title, "aria-label": title, disabled, onClick: () => void run(), children: label }, label);
|
|
679
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { role: "toolbar", "aria-label": "Vector tools", className: `flex flex-wrap items-center gap-1 ${className ?? ""}`, children: [
|
|
680
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "flex items-center gap-1", role: "group", "aria-label": "Tools", children: tools.map((tool) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
525
681
|
"button",
|
|
526
682
|
{
|
|
527
683
|
type: "button",
|
|
528
684
|
"data-vector-tool": tool,
|
|
529
|
-
className:
|
|
685
|
+
className: buttonClass2,
|
|
530
686
|
"aria-pressed": state.tool === tool,
|
|
531
|
-
title: `${(0,
|
|
532
|
-
"aria-label": (0,
|
|
687
|
+
title: `${(0, import_vector5.vectorToolLabel)(tool)} (${import_vector5.VECTOR_TOOL_SHORTCUTS[tool]})`,
|
|
688
|
+
"aria-label": (0, import_vector5.vectorToolLabel)(tool),
|
|
533
689
|
onClick: () => controller.setTool(tool),
|
|
534
|
-
children:
|
|
690
|
+
children: import_vector5.VECTOR_TOOL_GLYPHS[tool]
|
|
535
691
|
},
|
|
536
692
|
tool
|
|
537
693
|
)) }),
|
|
538
|
-
showHistory && /* @__PURE__ */ (0,
|
|
694
|
+
showHistory && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "ml-1 flex items-center gap-1", role: "group", "aria-label": "History", children: [
|
|
539
695
|
act("\u21B6", state.canUndo ? `Undo ${state.undoLabel}` : "Undo", () => controller.undo(), !state.canUndo),
|
|
540
696
|
act("\u21B7", state.canRedo ? `Redo ${state.redoLabel}` : "Redo", () => controller.redo(), !state.canRedo)
|
|
541
697
|
] }),
|
|
542
|
-
showSnap && /* @__PURE__ */ (0,
|
|
698
|
+
showSnap && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "ml-1 flex items-center gap-1", role: "group", "aria-label": "Snapping", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
543
699
|
"button",
|
|
544
700
|
{
|
|
545
701
|
type: "button",
|
|
546
702
|
"data-vector-snap": "",
|
|
547
|
-
className:
|
|
703
|
+
className: buttonClass2,
|
|
548
704
|
"aria-pressed": state.snap.objects,
|
|
549
705
|
title: `${VECTOR_SNAP_TITLE} (hold ${modKeyLabel()} to bypass)`,
|
|
550
706
|
"aria-label": VECTOR_SNAP_TITLE,
|
|
@@ -552,13 +708,13 @@ function VectorToolbar({
|
|
|
552
708
|
children: "Snap"
|
|
553
709
|
}
|
|
554
710
|
) }),
|
|
555
|
-
showPathEdit && /* @__PURE__ */ (0,
|
|
556
|
-
|
|
711
|
+
showPathEdit && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "ml-1 flex items-center gap-1", role: "group", "aria-label": "Path editing", children: [
|
|
712
|
+
import_vector5.VECTOR_PATH_ACTIONS.map((a) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
557
713
|
"button",
|
|
558
714
|
{
|
|
559
715
|
type: "button",
|
|
560
716
|
"data-vector-path-action": a.id,
|
|
561
|
-
className:
|
|
717
|
+
className: buttonClass2,
|
|
562
718
|
title: a.shortcut ? `${a.title} (${modKeyLabel()}+${a.shortcut})` : a.title,
|
|
563
719
|
"aria-label": a.title,
|
|
564
720
|
disabled: !a.enabled(count, points),
|
|
@@ -567,12 +723,12 @@ function VectorToolbar({
|
|
|
567
723
|
},
|
|
568
724
|
a.id
|
|
569
725
|
)),
|
|
570
|
-
|
|
726
|
+
import_vector5.VECTOR_EDIT_TOGGLES.map((t) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
571
727
|
"button",
|
|
572
728
|
{
|
|
573
729
|
type: "button",
|
|
574
730
|
"data-vector-edit": t.key,
|
|
575
|
-
className:
|
|
731
|
+
className: buttonClass2,
|
|
576
732
|
"aria-pressed": editing[t.key],
|
|
577
733
|
title: t.title,
|
|
578
734
|
"aria-label": t.title,
|
|
@@ -581,9 +737,9 @@ function VectorToolbar({
|
|
|
581
737
|
},
|
|
582
738
|
t.key
|
|
583
739
|
)),
|
|
584
|
-
state.tool === "pencil" && /* @__PURE__ */ (0,
|
|
740
|
+
state.tool === "pencil" && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("label", { className: "flex items-center gap-1 text-xs text-foreground", children: [
|
|
585
741
|
"Smoothing",
|
|
586
|
-
/* @__PURE__ */ (0,
|
|
742
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
587
743
|
"input",
|
|
588
744
|
{
|
|
589
745
|
type: "range",
|
|
@@ -597,9 +753,9 @@ function VectorToolbar({
|
|
|
597
753
|
}
|
|
598
754
|
)
|
|
599
755
|
] }),
|
|
600
|
-
state.tool === "eraser" && /* @__PURE__ */ (0,
|
|
756
|
+
state.tool === "eraser" && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("label", { className: "flex items-center gap-1 text-xs text-foreground", children: [
|
|
601
757
|
"Size",
|
|
602
|
-
/* @__PURE__ */ (0,
|
|
758
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
603
759
|
"input",
|
|
604
760
|
{
|
|
605
761
|
type: "number",
|
|
@@ -615,36 +771,49 @@ function VectorToolbar({
|
|
|
615
771
|
}
|
|
616
772
|
)
|
|
617
773
|
] }),
|
|
618
|
-
state.tool === "paintBucket" && /* @__PURE__ */ (0,
|
|
774
|
+
state.tool === "paintBucket" && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
619
775
|
"button",
|
|
620
776
|
{
|
|
621
777
|
type: "button",
|
|
622
778
|
"data-vector-fill-gap": "",
|
|
623
|
-
className:
|
|
779
|
+
className: buttonClass2,
|
|
624
780
|
"aria-pressed": editing.fillGap > 0,
|
|
625
781
|
title: "Close small gaps between path ends when filling",
|
|
626
782
|
"aria-label": "Close gaps",
|
|
627
|
-
onClick: () => controller.setEditing({ fillGap: editing.fillGap > 0 ? 0 :
|
|
783
|
+
onClick: () => controller.setEditing({ fillGap: editing.fillGap > 0 ? 0 : import_vector5.VECTOR_FILL_GAP }),
|
|
628
784
|
children: "Gaps"
|
|
629
785
|
}
|
|
630
786
|
)
|
|
631
787
|
] }),
|
|
632
|
-
showBlend && /* @__PURE__ */ (0,
|
|
633
|
-
showArrange && /* @__PURE__ */ (0,
|
|
634
|
-
/* @__PURE__ */ (0,
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
788
|
+
showBlend && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(VectorBlendControls, { controller }),
|
|
789
|
+
showArrange && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_jsx_runtime4.Fragment, { children: [
|
|
790
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "ml-1 flex items-center gap-1", role: "group", "aria-label": "Combine", children: [
|
|
791
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
792
|
+
"button",
|
|
793
|
+
{
|
|
794
|
+
type: "button",
|
|
795
|
+
"data-vector-live-boolean": "",
|
|
796
|
+
className: buttonClass2,
|
|
797
|
+
"aria-pressed": live,
|
|
798
|
+
title: "Live booleans: keep the shapes editable",
|
|
799
|
+
"aria-label": "Live booleans",
|
|
800
|
+
onClick: () => setLive(!live),
|
|
801
|
+
children: "Live"
|
|
802
|
+
}
|
|
803
|
+
),
|
|
804
|
+
act("\u222A", "Union", () => controller.booleanOp("union", { live }), booleanDisabled),
|
|
805
|
+
act("\u2212", "Subtract", () => controller.booleanOp("subtract", { live }), booleanDisabled),
|
|
806
|
+
act("\u2229", "Intersect", () => controller.booleanOp("intersect", { live }), booleanDisabled),
|
|
807
|
+
act("\u22BB", "Exclude", () => controller.booleanOp("exclude", { live }), booleanDisabled),
|
|
639
808
|
act("G", "Group", () => controller.group(), count < 1),
|
|
640
809
|
act("U", "Ungroup", () => controller.ungroup(), !groupSelected)
|
|
641
810
|
] }),
|
|
642
|
-
/* @__PURE__ */ (0,
|
|
811
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "ml-1 flex items-center gap-1", role: "group", "aria-label": "Pathfinder", children: import_vector5.VECTOR_PATHFINDER_ACTIONS.map((a) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
643
812
|
"button",
|
|
644
813
|
{
|
|
645
814
|
type: "button",
|
|
646
815
|
"data-vector-pathfinder": a.id,
|
|
647
|
-
className:
|
|
816
|
+
className: buttonClass2,
|
|
648
817
|
title: a.title,
|
|
649
818
|
"aria-label": a.title,
|
|
650
819
|
disabled: count < a.min,
|
|
@@ -653,7 +822,7 @@ function VectorToolbar({
|
|
|
653
822
|
},
|
|
654
823
|
a.id
|
|
655
824
|
)) }),
|
|
656
|
-
/* @__PURE__ */ (0,
|
|
825
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "ml-1 flex items-center gap-1", role: "group", "aria-label": "Arrange", children: [
|
|
657
826
|
act("\u21C8", "Bring to Front", () => controller.arrange("front"), count < 1),
|
|
658
827
|
act("\u21CA", "Send to Back", () => controller.arrange("back"), count < 1),
|
|
659
828
|
act("\u21E4", "Align Left", () => controller.align("left"), count < 1),
|
|
@@ -668,22 +837,22 @@ function VectorToolbar({
|
|
|
668
837
|
}
|
|
669
838
|
function VectorBlendControls({ controller }) {
|
|
670
839
|
const state = useVectorEditorState(controller);
|
|
671
|
-
const blend = (0,
|
|
840
|
+
const blend = (0, import_vector5.getVectorBlendControls)(state);
|
|
672
841
|
const o = blend.options;
|
|
673
842
|
const selected = blend.ids.length > 0;
|
|
674
|
-
return /* @__PURE__ */ (0,
|
|
675
|
-
/* @__PURE__ */ (0,
|
|
676
|
-
/* @__PURE__ */ (0,
|
|
843
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "ml-1 flex items-center gap-1", role: "group", "aria-label": "Blend", "data-vector-blend-controls": "", children: [
|
|
844
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("button", { type: "button", "data-vector-blend-action": "make", className: buttonClass2, title: "Make Blend", "aria-label": "Make Blend", disabled: !blend.canBlend, onClick: () => controller.blend(), children: "\u29D3" }),
|
|
845
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
677
846
|
"select",
|
|
678
847
|
{
|
|
679
848
|
"aria-label": "Blend spacing",
|
|
680
849
|
className: "h-7 rounded border border-border bg-background px-1 text-xs",
|
|
681
850
|
value: o.spacing,
|
|
682
|
-
onChange: (e) => (0,
|
|
683
|
-
children:
|
|
851
|
+
onChange: (e) => (0, import_vector5.applyVectorBlendOptions)(controller, { spacing: e.target.value }),
|
|
852
|
+
children: import_vector5.VECTOR_BLEND_SPACINGS.map((sp) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("option", { value: sp, children: import_vector5.VECTOR_BLEND_SPACING_LABELS[sp] }, sp))
|
|
684
853
|
}
|
|
685
854
|
),
|
|
686
|
-
o.spacing !== "smoothColor" && /* @__PURE__ */ (0,
|
|
855
|
+
o.spacing !== "smoothColor" && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
687
856
|
"input",
|
|
688
857
|
{
|
|
689
858
|
type: "number",
|
|
@@ -695,29 +864,29 @@ function VectorBlendControls({ controller }) {
|
|
|
695
864
|
onChange: (e) => {
|
|
696
865
|
const n = parseFloat(e.target.value);
|
|
697
866
|
if (!Number.isFinite(n) || n <= 0) return;
|
|
698
|
-
(0,
|
|
867
|
+
(0, import_vector5.applyVectorBlendOptions)(controller, o.spacing === "steps" ? { steps: n } : { distance: n });
|
|
699
868
|
}
|
|
700
869
|
}
|
|
701
870
|
),
|
|
702
|
-
/* @__PURE__ */ (0,
|
|
871
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
703
872
|
"button",
|
|
704
873
|
{
|
|
705
874
|
type: "button",
|
|
706
875
|
"data-vector-blend-action": "orient",
|
|
707
|
-
className:
|
|
876
|
+
className: buttonClass2,
|
|
708
877
|
"aria-pressed": o.orientToSpine,
|
|
709
878
|
title: "Orient steps to the spine",
|
|
710
879
|
"aria-label": "Orient to spine",
|
|
711
|
-
onClick: () => (0,
|
|
880
|
+
onClick: () => (0, import_vector5.applyVectorBlendOptions)(controller, { orientToSpine: !o.orientToSpine }),
|
|
712
881
|
children: "\u293F"
|
|
713
882
|
}
|
|
714
883
|
),
|
|
715
|
-
/* @__PURE__ */ (0,
|
|
884
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
716
885
|
"button",
|
|
717
886
|
{
|
|
718
887
|
type: "button",
|
|
719
888
|
"data-vector-blend-action": "spine",
|
|
720
|
-
className:
|
|
889
|
+
className: buttonClass2,
|
|
721
890
|
title: "Replace Spine (select a blend and a path)",
|
|
722
891
|
"aria-label": "Replace Spine",
|
|
723
892
|
disabled: !blend.canReplaceSpine,
|
|
@@ -725,15 +894,15 @@ function VectorBlendControls({ controller }) {
|
|
|
725
894
|
children: "\u2307"
|
|
726
895
|
}
|
|
727
896
|
),
|
|
728
|
-
/* @__PURE__ */ (0,
|
|
729
|
-
/* @__PURE__ */ (0,
|
|
897
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("button", { type: "button", "data-vector-blend-action": "expand", className: buttonClass2, title: "Expand Blend", "aria-label": "Expand Blend", disabled: !selected, onClick: () => controller.expandBlend(), children: "\u29C9" }),
|
|
898
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("button", { type: "button", "data-vector-blend-action": "release", className: buttonClass2, title: "Release Blend", "aria-label": "Release Blend", disabled: !selected, onClick: () => controller.releaseBlend(), children: "\u29C4" })
|
|
730
899
|
] });
|
|
731
900
|
}
|
|
732
|
-
var
|
|
733
|
-
var
|
|
901
|
+
var selectClass2 = "h-7 min-w-0 flex-1 rounded border border-border bg-background px-1 text-xs";
|
|
902
|
+
var numberClass2 = "h-7 w-16 rounded border border-border bg-background px-1.5 text-xs";
|
|
734
903
|
function VectorStylePanel({ controller, className }) {
|
|
735
904
|
const state = useVectorEditorState(controller);
|
|
736
|
-
const style = (0,
|
|
905
|
+
const style = (0, import_vector5.getVectorSelectionStyle)(state);
|
|
737
906
|
const d = state.defaults;
|
|
738
907
|
const source = style ?? {
|
|
739
908
|
fill: d.fill ?? null,
|
|
@@ -746,7 +915,7 @@ function VectorStylePanel({ controller, className }) {
|
|
|
746
915
|
arrowAlign: d.arrowAlign ?? "extend",
|
|
747
916
|
startArrowScale: d.startArrowScale ?? 1,
|
|
748
917
|
endArrowScale: d.endArrowScale ?? 1,
|
|
749
|
-
widthProfile: (0,
|
|
918
|
+
widthProfile: (0, import_vector5.widthProfilePresetId)(d.strokeWidthProfile),
|
|
750
919
|
cornerRadius: d.cornerRadius,
|
|
751
920
|
cornerKind: d.cornerKind ?? "round",
|
|
752
921
|
corners: 1,
|
|
@@ -759,19 +928,19 @@ function VectorStylePanel({ controller, className }) {
|
|
|
759
928
|
};
|
|
760
929
|
const setProfile = (id) => {
|
|
761
930
|
if (style) controller.setWidthProfile(id);
|
|
762
|
-
else controller.setDefaults({ strokeWidthProfile: (0,
|
|
931
|
+
else controller.setDefaults({ strokeWidthProfile: (0, import_vector5.widthProfilePreset)(id)?.length ? (0, import_vector5.widthProfilePreset)(id) : null });
|
|
763
932
|
};
|
|
764
|
-
const mixed = (key) => style?.mixed[key] ? /* @__PURE__ */ (0,
|
|
933
|
+
const mixed = (key) => style?.mixed[key] ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "text-[11px] text-muted-foreground", children: "Mixed" }) : null;
|
|
765
934
|
const arrowRow = (end, label) => {
|
|
766
935
|
const key = end === "start" ? "startArrow" : "endArrow";
|
|
767
936
|
const scaleKey = end === "start" ? "startArrowScale" : "endArrowScale";
|
|
768
|
-
return /* @__PURE__ */ (0,
|
|
769
|
-
/* @__PURE__ */ (0,
|
|
770
|
-
/* @__PURE__ */ (0,
|
|
771
|
-
/* @__PURE__ */ (0,
|
|
772
|
-
|
|
937
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "flex items-center gap-2", "data-vector-style": key, children: [
|
|
938
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "w-16 text-xs text-foreground", children: label }),
|
|
939
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("select", { "aria-label": `${label} arrowhead`, className: selectClass2, value: source[key] ?? "", onChange: (e) => apply({ [key]: e.target.value || null }), children: [
|
|
940
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("option", { value: "", children: "None" }),
|
|
941
|
+
import_vector5.VECTOR_ARROWHEADS.map((h) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("option", { value: h, children: import_vector5.VECTOR_ARROWHEAD_LABELS[h] }, h))
|
|
773
942
|
] }),
|
|
774
|
-
/* @__PURE__ */ (0,
|
|
943
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
775
944
|
"input",
|
|
776
945
|
{
|
|
777
946
|
type: "number",
|
|
@@ -779,7 +948,7 @@ function VectorStylePanel({ controller, className }) {
|
|
|
779
948
|
step: 0.25,
|
|
780
949
|
"aria-label": `${label} arrowhead scale`,
|
|
781
950
|
title: "Scale (\xD7 stroke width)",
|
|
782
|
-
className:
|
|
951
|
+
className: numberClass2,
|
|
783
952
|
value: source[scaleKey],
|
|
784
953
|
onChange: (e) => {
|
|
785
954
|
const n = parseFloat(e.target.value);
|
|
@@ -795,14 +964,14 @@ function VectorStylePanel({ controller, className }) {
|
|
|
795
964
|
};
|
|
796
965
|
const paintRow = (key, label) => {
|
|
797
966
|
const paint = source[key];
|
|
798
|
-
const hex = (0,
|
|
967
|
+
const hex = (0, import_vector5.vectorPaintToHex)(paint);
|
|
799
968
|
const on = paint !== null && paint !== "none";
|
|
800
|
-
return /* @__PURE__ */ (0,
|
|
801
|
-
/* @__PURE__ */ (0,
|
|
802
|
-
/* @__PURE__ */ (0,
|
|
969
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "flex items-center gap-2", "data-vector-style": key, children: [
|
|
970
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("label", { className: "flex w-16 items-center gap-1.5 text-xs text-foreground", children: [
|
|
971
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("input", { type: "checkbox", checked: on, "aria-label": `${label} on`, onChange: (e) => apply({ [key]: e.target.checked ? hex ?? "#000000" : null }) }),
|
|
803
972
|
label
|
|
804
973
|
] }),
|
|
805
|
-
/* @__PURE__ */ (0,
|
|
974
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
806
975
|
"input",
|
|
807
976
|
{
|
|
808
977
|
type: "color",
|
|
@@ -813,17 +982,17 @@ function VectorStylePanel({ controller, className }) {
|
|
|
813
982
|
onChange: (e) => apply({ [key]: e.target.value })
|
|
814
983
|
}
|
|
815
984
|
),
|
|
816
|
-
on && !hex && /* @__PURE__ */ (0,
|
|
817
|
-
style?.mixed[key] && /* @__PURE__ */ (0,
|
|
985
|
+
on && !hex && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "truncate text-[11px] text-muted-foreground", children: typeof paint === "string" ? paint : "Gradient" }),
|
|
986
|
+
style?.mixed[key] && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "text-[11px] text-muted-foreground", children: "Mixed" })
|
|
818
987
|
] });
|
|
819
988
|
};
|
|
820
|
-
return /* @__PURE__ */ (0,
|
|
821
|
-
/* @__PURE__ */ (0,
|
|
989
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: `space-y-2 ${className ?? ""}`, "aria-label": style ? "Selection style" : "New shape style", children: [
|
|
990
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "text-[11px] font-medium uppercase tracking-wide text-muted-foreground", children: style ? "Selection" : "New shapes" }),
|
|
822
991
|
paintRow("fill", "Fill"),
|
|
823
992
|
paintRow("stroke", "Stroke"),
|
|
824
|
-
/* @__PURE__ */ (0,
|
|
825
|
-
/* @__PURE__ */ (0,
|
|
826
|
-
/* @__PURE__ */ (0,
|
|
993
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("label", { className: "flex items-center gap-2 text-xs text-foreground", children: [
|
|
994
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "w-16", children: "Width" }),
|
|
995
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
827
996
|
"input",
|
|
828
997
|
{
|
|
829
998
|
type: "number",
|
|
@@ -839,33 +1008,33 @@ function VectorStylePanel({ controller, className }) {
|
|
|
839
1008
|
}
|
|
840
1009
|
)
|
|
841
1010
|
] }),
|
|
842
|
-
/* @__PURE__ */ (0,
|
|
843
|
-
/* @__PURE__ */ (0,
|
|
844
|
-
/* @__PURE__ */ (0,
|
|
1011
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("label", { className: "flex items-center gap-2 text-xs text-foreground", "data-vector-style": "strokeAlign", children: [
|
|
1012
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "w-16", children: "Align" }),
|
|
1013
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("select", { "aria-label": "Stroke alignment", className: selectClass2, value: source.strokeAlign, onChange: (e) => apply({ strokeAlign: e.target.value }), children: Object.keys(import_vector5.VECTOR_STROKE_ALIGN_LABELS).map((a) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("option", { value: a, children: import_vector5.VECTOR_STROKE_ALIGN_LABELS[a] }, a)) }),
|
|
845
1014
|
mixed("strokeAlign")
|
|
846
1015
|
] }),
|
|
847
|
-
/* @__PURE__ */ (0,
|
|
848
|
-
/* @__PURE__ */ (0,
|
|
849
|
-
/* @__PURE__ */ (0,
|
|
1016
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "flex items-center gap-2 text-xs text-foreground", "data-vector-style": "widthProfile", children: [
|
|
1017
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "w-16", children: "Profile" }),
|
|
1018
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
|
|
850
1019
|
"select",
|
|
851
1020
|
{
|
|
852
1021
|
"aria-label": "Width profile",
|
|
853
|
-
className:
|
|
1022
|
+
className: selectClass2,
|
|
854
1023
|
value: source.widthProfile,
|
|
855
1024
|
onChange: (e) => {
|
|
856
1025
|
if (e.target.value !== "custom") setProfile(e.target.value);
|
|
857
1026
|
},
|
|
858
1027
|
children: [
|
|
859
|
-
|
|
860
|
-
source.widthProfile === "custom" && /* @__PURE__ */ (0,
|
|
1028
|
+
import_vector5.VECTOR_WIDTH_PRESETS.map((p) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("option", { value: p.id, children: p.label }, p.id)),
|
|
1029
|
+
source.widthProfile === "custom" && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("option", { value: "custom", disabled: true, children: "Custom" })
|
|
861
1030
|
]
|
|
862
1031
|
}
|
|
863
1032
|
),
|
|
864
|
-
/* @__PURE__ */ (0,
|
|
1033
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
865
1034
|
"button",
|
|
866
1035
|
{
|
|
867
1036
|
type: "button",
|
|
868
|
-
className:
|
|
1037
|
+
className: buttonClass2,
|
|
869
1038
|
title: "Reset to uniform width",
|
|
870
1039
|
"aria-label": "Reset to uniform width",
|
|
871
1040
|
disabled: source.widthProfile === "uniform" && !style?.mixed.widthProfile,
|
|
@@ -875,27 +1044,27 @@ function VectorStylePanel({ controller, className }) {
|
|
|
875
1044
|
),
|
|
876
1045
|
mixed("widthProfile")
|
|
877
1046
|
] }),
|
|
878
|
-
source.hasOpenPath && /* @__PURE__ */ (0,
|
|
1047
|
+
source.hasOpenPath && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_jsx_runtime4.Fragment, { children: [
|
|
879
1048
|
arrowRow("start", "Start"),
|
|
880
1049
|
arrowRow("end", "End"),
|
|
881
|
-
(source.startArrow || source.endArrow) && /* @__PURE__ */ (0,
|
|
882
|
-
/* @__PURE__ */ (0,
|
|
883
|
-
/* @__PURE__ */ (0,
|
|
884
|
-
/* @__PURE__ */ (0,
|
|
885
|
-
/* @__PURE__ */ (0,
|
|
1050
|
+
(source.startArrow || source.endArrow) && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("label", { className: "flex items-center gap-2 text-xs text-foreground", "data-vector-style": "arrowAlign", children: [
|
|
1051
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "w-16", children: "Heads" }),
|
|
1052
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("select", { "aria-label": "Arrowhead alignment", className: selectClass2, value: source.arrowAlign, onChange: (e) => apply({ arrowAlign: e.target.value }), children: [
|
|
1053
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("option", { value: "extend", children: "Tip past end" }),
|
|
1054
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("option", { value: "tip", children: "Tip at end" })
|
|
886
1055
|
] })
|
|
887
1056
|
] })
|
|
888
1057
|
] }),
|
|
889
|
-
source.corners > 0 && /* @__PURE__ */ (0,
|
|
890
|
-
/* @__PURE__ */ (0,
|
|
891
|
-
/* @__PURE__ */ (0,
|
|
1058
|
+
source.corners > 0 && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "flex items-center gap-2", "data-vector-style": "corners", children: [
|
|
1059
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "w-16 text-xs text-foreground", children: "Corners" }),
|
|
1060
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
892
1061
|
"input",
|
|
893
1062
|
{
|
|
894
1063
|
type: "number",
|
|
895
1064
|
min: 0,
|
|
896
1065
|
step: 1,
|
|
897
1066
|
"aria-label": "Corner radius",
|
|
898
|
-
className:
|
|
1067
|
+
className: numberClass2,
|
|
899
1068
|
value: Math.round(source.cornerRadius * 100) / 100,
|
|
900
1069
|
onChange: (e) => {
|
|
901
1070
|
const n = parseFloat(e.target.value);
|
|
@@ -903,12 +1072,12 @@ function VectorStylePanel({ controller, className }) {
|
|
|
903
1072
|
}
|
|
904
1073
|
}
|
|
905
1074
|
),
|
|
906
|
-
/* @__PURE__ */ (0,
|
|
1075
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("select", { "aria-label": "Corner kind", className: selectClass2, value: source.cornerKind, onChange: (e) => setCorners({ kind: e.target.value }), children: import_vector5.VECTOR_CORNER_KINDS.map((k) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("option", { value: k, children: import_vector5.VECTOR_CORNER_KIND_LABELS[k] }, k)) }),
|
|
907
1076
|
mixed("cornerRadius")
|
|
908
1077
|
] }),
|
|
909
|
-
style && /* @__PURE__ */ (0,
|
|
910
|
-
/* @__PURE__ */ (0,
|
|
911
|
-
/* @__PURE__ */ (0,
|
|
1078
|
+
style && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("label", { className: "flex items-center gap-2 text-xs text-foreground", children: [
|
|
1079
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "w-16", children: "Opacity" }),
|
|
1080
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
912
1081
|
"input",
|
|
913
1082
|
{
|
|
914
1083
|
type: "range",
|
|
@@ -921,18 +1090,19 @@ function VectorStylePanel({ controller, className }) {
|
|
|
921
1090
|
onChange: (e) => apply({ opacity: parseFloat(e.target.value) })
|
|
922
1091
|
}
|
|
923
1092
|
)
|
|
924
|
-
] })
|
|
1093
|
+
] }),
|
|
1094
|
+
style && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(VectorEffectsPanel, { controller })
|
|
925
1095
|
] });
|
|
926
1096
|
}
|
|
927
1097
|
|
|
928
1098
|
// src/vector/VectorEditor.tsx
|
|
929
|
-
var
|
|
1099
|
+
var import_jsx_runtime5 = require("react/jsx-runtime");
|
|
930
1100
|
function VectorEditor({ controller, tools, showStylePanel = true, height = 520, canvasProps, className }) {
|
|
931
|
-
return /* @__PURE__ */ (0,
|
|
932
|
-
/* @__PURE__ */ (0,
|
|
933
|
-
/* @__PURE__ */ (0,
|
|
934
|
-
/* @__PURE__ */ (0,
|
|
935
|
-
showStylePanel && /* @__PURE__ */ (0,
|
|
1101
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: `flex flex-col gap-2 ${className ?? ""}`, "data-vector-editor": "", children: [
|
|
1102
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(VectorToolbar, { controller, tools }),
|
|
1103
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "flex min-h-0 flex-col gap-2 md:flex-row", children: [
|
|
1104
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "relative min-h-[320px] flex-1 overflow-hidden rounded-md border border-border bg-muted/40", style: { height }, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(VectorCanvas, { controller, ...canvasProps }) }),
|
|
1105
|
+
showStylePanel && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(VectorStylePanel, { controller, className: "w-full shrink-0 rounded-md border border-border p-3 md:w-56" })
|
|
936
1106
|
] })
|
|
937
1107
|
] });
|
|
938
1108
|
}
|
|
@@ -940,6 +1110,7 @@ function VectorEditor({ controller, tools, showStylePanel = true, height = 520,
|
|
|
940
1110
|
0 && (module.exports = {
|
|
941
1111
|
VectorCanvas,
|
|
942
1112
|
VectorEditor,
|
|
1113
|
+
VectorEffectsPanel,
|
|
943
1114
|
VectorGradientDefs,
|
|
944
1115
|
VectorSceneNodes,
|
|
945
1116
|
VectorStylePanel,
|