@pixerate/editor-react 0.75.1 → 0.76.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 +224 -174
- package/dist/vector/index.cjs.map +1 -1
- package/dist/vector/index.d.cts +12 -1
- package/dist/vector/index.d.ts +12 -1
- package/dist/vector/index.js +217 -167
- package/dist/vector/index.js.map +1 -1
- package/package.json +3 -3
package/dist/vector/index.cjs
CHANGED
|
@@ -48,6 +48,7 @@ __export(vector_exports, {
|
|
|
48
48
|
VectorShadingPanel: () => VectorShadingPanel,
|
|
49
49
|
VectorStylePanel: () => VectorStylePanel,
|
|
50
50
|
VectorSymbolsPanel: () => VectorSymbolsPanel,
|
|
51
|
+
VectorSymmetryPanel: () => VectorSymmetryPanel,
|
|
51
52
|
VectorTextElement: () => VectorTextElement,
|
|
52
53
|
VectorTextPanel: () => VectorTextPanel,
|
|
53
54
|
VectorToolbar: () => VectorToolbar,
|
|
@@ -683,6 +684,7 @@ function VectorCanvas({
|
|
|
683
684
|
sh.lines.map((d, i) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d, stroke: accentColor, strokeWidth: 1, opacity: 0.7 }, i)),
|
|
684
685
|
sh.points.map((p) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("circle", { "data-vector-shading-point": p.index, "data-selected": p.selected || void 0, cx: p.x, cy: p.y, r: p.selected ? 6 : 4.5, fill: p.color, stroke: p.selected ? accentColor : "#ffffff", strokeWidth: p.selected ? 2 : 1.5 }, p.index))
|
|
685
686
|
] }, `shading:${sh.nodeId}`)),
|
|
687
|
+
overlay.symmetry.map((sy) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("g", { "data-vector-symmetry-axes": sy.nodeId, stroke: accentColor, strokeDasharray: sy.drawing ? void 0 : "6 4", opacity: sy.drawing ? 0.9 : 0.6, children: sy.lines.map((l, i) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("line", { x1: l.x1, y1: l.y1, x2: l.x2, y2: l.y2 }, i)) }, `sym:${sy.nodeId}`)),
|
|
686
688
|
overlay.trackingPoints.map((t, i) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { "data-vector-tracking-point": "", d: `M${t.x - 5} ${t.y}H${t.x + 5}M${t.x} ${t.y - 5}V${t.y + 5}`, stroke: guideColor, strokeWidth: 1.5 }, `track:${i}`)),
|
|
687
689
|
overlay.typedEntry && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("g", { "data-vector-typed-entry": "", transform: `translate(${overlay.typedEntry.x + 14} ${overlay.typedEntry.y + 18})`, children: [
|
|
688
690
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("rect", { x: -3, y: -12, width: overlay.typedEntry.text.length * 7 + 8, height: 17, rx: 3, fill: import_vector3.VECTOR_OVERLAY_THEME.handleFill, stroke: accentColor }),
|
|
@@ -819,7 +821,7 @@ function VectorCanvas({
|
|
|
819
821
|
|
|
820
822
|
// src/vector/VectorToolbar.tsx
|
|
821
823
|
var import_react10 = __toESM(require("react"), 1);
|
|
822
|
-
var
|
|
824
|
+
var import_vector16 = require("@pixerate/editor/vector");
|
|
823
825
|
|
|
824
826
|
// src/vector/VectorEffectsPanel.tsx
|
|
825
827
|
var import_vector4 = require("@pixerate/editor/vector");
|
|
@@ -909,6 +911,15 @@ function VectorEffectsPanel({ controller, className }) {
|
|
|
909
911
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "min-w-0 flex-1 truncate", children: spec.label }),
|
|
910
912
|
/* @__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) })
|
|
911
913
|
] }, spec.key);
|
|
914
|
+
if (spec.kind === "color") {
|
|
915
|
+
const c = e.params[spec.key];
|
|
916
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "flex items-center gap-2 text-xs text-foreground", "data-vector-effect-param": spec.key, children: [
|
|
917
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: labelClass, children: spec.label }),
|
|
918
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("input", { type: "checkbox", "aria-label": `${e.label} ${spec.label} on`, checked: c !== null, onChange: (ev) => set(e, spec.key, ev.target.checked ? "#ffffff" : null, false) }),
|
|
919
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("input", { type: "color", "aria-label": `${e.label} ${spec.label}`, className: "h-6 w-8 cursor-pointer rounded border border-border bg-background disabled:opacity-40", disabled: c === null, value: (0, import_vector4.vectorPaintToHex)(c ?? "#ffffff") ?? "#ffffff", onChange: (ev) => set(e, spec.key, ev.target.value, true), onBlur: end })
|
|
920
|
+
] }, spec.key);
|
|
921
|
+
}
|
|
922
|
+
if (spec.kind !== "select") return null;
|
|
912
923
|
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: [
|
|
913
924
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: labelClass, children: spec.label }),
|
|
914
925
|
/* @__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)) })
|
|
@@ -2024,16 +2035,53 @@ function VectorTracePanel({ controller, className }) {
|
|
|
2024
2035
|
] });
|
|
2025
2036
|
}
|
|
2026
2037
|
|
|
2027
|
-
// src/vector/
|
|
2038
|
+
// src/vector/VectorSymmetryPanel.tsx
|
|
2028
2039
|
var import_vector14 = require("@pixerate/editor/vector");
|
|
2029
2040
|
var import_jsx_runtime14 = require("react/jsx-runtime");
|
|
2041
|
+
var buttonClass12 = "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 aria-pressed:bg-primary aria-pressed:text-primary-foreground";
|
|
2030
2042
|
var selectClass9 = "h-7 min-w-0 flex-1 rounded border border-border bg-background px-1 text-xs";
|
|
2031
|
-
var numberClass8 = "h-7 w-
|
|
2032
|
-
|
|
2043
|
+
var numberClass8 = "h-7 w-12 rounded border border-border bg-background px-1.5 text-xs";
|
|
2044
|
+
function VectorSymmetryPanel({ controller, className }) {
|
|
2045
|
+
const state = useVectorEditorState(controller);
|
|
2046
|
+
const group = state.selection.map((id) => controller.getNode(id)).find(import_vector14.isVectorSymmetryGroup) ?? null;
|
|
2047
|
+
const s = group?.symmetry;
|
|
2048
|
+
const ids = group ? [group.id] : void 0;
|
|
2049
|
+
const drawing = !!group && state.symmetryTarget === group.id;
|
|
2050
|
+
return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: `space-y-2 ${className ?? ""}`, "data-vector-symmetry-panel": "", "aria-label": "Symmetry", children: [
|
|
2051
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex flex-wrap items-center gap-1", children: [
|
|
2052
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "w-16 text-[11px] font-medium uppercase tracking-wide text-muted-foreground", children: "Symmetry" }),
|
|
2053
|
+
!group && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("button", { type: "button", className: buttonClass12, "data-vector-symmetry-action": "make", title: "Make Symmetry: the selection (or nothing yet) mirrored live across a vertical axis", onClick: () => controller.makeSymmetry({ mode: "vertical" }), children: "Mirror" }),
|
|
2054
|
+
!group && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("button", { type: "button", className: buttonClass12, "data-vector-symmetry-action": "radial", title: "Make Symmetry: the selection repeated round its centre", onClick: () => controller.makeSymmetry({ mode: "radial", copies: 6 }), children: "Radial" }),
|
|
2055
|
+
group && s && /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_jsx_runtime14.Fragment, { children: [
|
|
2056
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("select", { "aria-label": "Symmetry mode", className: selectClass9, value: s.mode, onChange: (e) => controller.setSymmetry({ mode: e.target.value }, { ids }), children: import_vector14.VECTOR_SYMMETRY_MODES.map((m) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("option", { value: m, children: import_vector14.VECTOR_SYMMETRY_MODE_LABELS[m] }, m)) }),
|
|
2057
|
+
s.mode === "radial" && /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_jsx_runtime14.Fragment, { children: [
|
|
2058
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("input", { type: "number", min: 2, max: 64, "aria-label": "Symmetry copies", title: "Copies round the circle", className: numberClass8, value: s.copies ?? 6, onChange: (e) => controller.setSymmetry({ copies: Math.max(2, Math.min(64, parseInt(e.target.value, 10) || 2)) }, { ids }) }),
|
|
2059
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("label", { className: "flex items-center gap-1 text-xs text-foreground", title: "Mirror each copy too (kaleidoscope)", children: [
|
|
2060
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("input", { type: "checkbox", "aria-label": "Mirror copies", checked: !!s.mirror, onChange: (e) => controller.setSymmetry({ mirror: e.target.checked }, { ids }) }),
|
|
2061
|
+
"Mirror"
|
|
2062
|
+
] })
|
|
2063
|
+
] })
|
|
2064
|
+
] })
|
|
2065
|
+
] }),
|
|
2066
|
+
group && /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex flex-wrap items-center gap-1", children: [
|
|
2067
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "w-16" }),
|
|
2068
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("button", { type: "button", className: buttonClass12, "aria-pressed": drawing, "data-vector-symmetry-action": "draw", title: "Draw inside: new pen, pencil, shape and text art goes into the group, mirrored as you draw (Escape stops)", onClick: () => drawing ? controller.exitSymmetry() : controller.enterSymmetry(group.id), children: "Draw inside" }),
|
|
2069
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("button", { type: "button", className: buttonClass12, title: "Expand: keep the copies as real objects", onClick: () => controller.releaseSymmetry({ ids, expand: true }), children: "Expand" }),
|
|
2070
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("button", { type: "button", className: buttonClass12, title: "Release: stop repeating (the copies go)", onClick: () => controller.releaseSymmetry({ ids }), children: "Release" })
|
|
2071
|
+
] })
|
|
2072
|
+
] });
|
|
2073
|
+
}
|
|
2074
|
+
|
|
2075
|
+
// src/vector/VectorGradientEditor.tsx
|
|
2076
|
+
var import_vector15 = require("@pixerate/editor/vector");
|
|
2077
|
+
var import_jsx_runtime15 = require("react/jsx-runtime");
|
|
2078
|
+
var selectClass10 = "h-7 min-w-0 flex-1 rounded border border-border bg-background px-1 text-xs";
|
|
2079
|
+
var numberClass9 = "h-7 w-14 rounded border border-border bg-background px-1.5 text-xs";
|
|
2080
|
+
var buttonClass13 = "inline-flex h-7 min-w-7 items-center justify-center rounded border border-border bg-background px-1.5 text-xs text-foreground hover:bg-muted disabled:cursor-not-allowed disabled:opacity-40 aria-pressed:bg-primary aria-pressed:text-primary-foreground";
|
|
2033
2081
|
var percent = (v) => Math.round(v * 1e3) / 10;
|
|
2034
2082
|
function VectorGradientEditor({ controller, className }) {
|
|
2035
2083
|
const state = useVectorEditorState(controller);
|
|
2036
|
-
const ed = (0,
|
|
2084
|
+
const ed = (0, import_vector15.getVectorGradientEditor)(state);
|
|
2037
2085
|
if (!ed) return null;
|
|
2038
2086
|
const g = ed.gradient;
|
|
2039
2087
|
const sel = ed.selected;
|
|
@@ -2041,26 +2089,26 @@ function VectorGradientEditor({ controller, className }) {
|
|
|
2041
2089
|
const setType = (value) => {
|
|
2042
2090
|
if (value === "solid") {
|
|
2043
2091
|
const first = ed.stops[0];
|
|
2044
|
-
controller.setStyle({ [ed.target]: (0,
|
|
2092
|
+
controller.setStyle({ [ed.target]: (0, import_vector15.vectorPaintToHex)(first?.color) ?? first?.color ?? "#000000" }, void 0, { label: "Solid Colour" });
|
|
2045
2093
|
} else controller.setGradient({ type: value });
|
|
2046
2094
|
};
|
|
2047
|
-
return /* @__PURE__ */ (0,
|
|
2048
|
-
/* @__PURE__ */ (0,
|
|
2049
|
-
/* @__PURE__ */ (0,
|
|
2050
|
-
["fill", "stroke"].map((t) => /* @__PURE__ */ (0,
|
|
2051
|
-
ed.mixed && /* @__PURE__ */ (0,
|
|
2095
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: `space-y-1.5 ${className ?? ""}`, "data-vector-gradient-editor": ed.target, "aria-label": "Gradient", children: [
|
|
2096
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "flex items-center gap-1.5", children: [
|
|
2097
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "w-16 text-xs text-foreground", children: "Gradient" }),
|
|
2098
|
+
["fill", "stroke"].map((t) => /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("button", { type: "button", className: buttonClass13, "aria-pressed": ed.target === t, onClick: () => controller.setGradientTarget(t), children: t === "fill" ? "Fill" : "Stroke" }, t)),
|
|
2099
|
+
ed.mixed && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "text-[11px] text-muted-foreground", children: "Mixed" })
|
|
2052
2100
|
] }),
|
|
2053
|
-
/* @__PURE__ */ (0,
|
|
2054
|
-
/* @__PURE__ */ (0,
|
|
2055
|
-
/* @__PURE__ */ (0,
|
|
2056
|
-
/* @__PURE__ */ (0,
|
|
2057
|
-
|
|
2101
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "flex items-center gap-1.5", children: [
|
|
2102
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "w-16 text-xs text-foreground", children: "Type" }),
|
|
2103
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("select", { "aria-label": "Gradient type", className: selectClass10, value: ed.type ?? "solid", onChange: (e) => setType(e.target.value), children: [
|
|
2104
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)("option", { value: "solid", children: "Solid" }),
|
|
2105
|
+
import_vector15.VECTOR_GRADIENT_TYPES.map((t) => /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("option", { value: t, children: import_vector15.VECTOR_GRADIENT_TYPE_LABELS[t] }, t))
|
|
2058
2106
|
] }),
|
|
2059
|
-
/* @__PURE__ */ (0,
|
|
2107
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)("button", { type: "button", className: buttonClass13, "aria-label": "Reverse gradient", title: "Reverse gradient", disabled: !g, onClick: () => controller.reverseGradient(), children: "\u21C4" })
|
|
2060
2108
|
] }),
|
|
2061
|
-
g && /* @__PURE__ */ (0,
|
|
2062
|
-
/* @__PURE__ */ (0,
|
|
2063
|
-
/* @__PURE__ */ (0,
|
|
2109
|
+
g && /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_jsx_runtime15.Fragment, { children: [
|
|
2110
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "relative h-8", "data-vector-gradient-ramp": "", children: [
|
|
2111
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
2064
2112
|
"div",
|
|
2065
2113
|
{
|
|
2066
2114
|
role: "button",
|
|
@@ -2074,7 +2122,7 @@ function VectorGradientEditor({ controller, className }) {
|
|
|
2074
2122
|
}
|
|
2075
2123
|
}
|
|
2076
2124
|
),
|
|
2077
|
-
ed.stops.map((s) => /* @__PURE__ */ (0,
|
|
2125
|
+
ed.stops.map((s) => /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
2078
2126
|
"button",
|
|
2079
2127
|
{
|
|
2080
2128
|
type: "button",
|
|
@@ -2088,21 +2136,21 @@ function VectorGradientEditor({ controller, className }) {
|
|
|
2088
2136
|
s.index
|
|
2089
2137
|
))
|
|
2090
2138
|
] }),
|
|
2091
|
-
sel && /* @__PURE__ */ (0,
|
|
2092
|
-
/* @__PURE__ */ (0,
|
|
2139
|
+
sel && /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "flex flex-wrap items-center gap-1.5", "data-vector-gradient-selected-stop": sel.index, children: [
|
|
2140
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
2093
2141
|
"input",
|
|
2094
2142
|
{
|
|
2095
2143
|
type: "color",
|
|
2096
2144
|
"aria-label": "Stop colour",
|
|
2097
2145
|
className: "h-7 w-9 cursor-pointer rounded border border-border bg-background",
|
|
2098
|
-
value: (0,
|
|
2146
|
+
value: (0, import_vector15.vectorPaintToHex)(sel.color) ?? "#000000",
|
|
2099
2147
|
onChange: (e) => controller.setGradientStop(sel.index, { color: e.target.value }, { merge: `gradient-stop-color-${sel.index}` }),
|
|
2100
2148
|
onBlur: end
|
|
2101
2149
|
}
|
|
2102
2150
|
),
|
|
2103
|
-
/* @__PURE__ */ (0,
|
|
2151
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("label", { className: "flex items-center gap-1 text-[11px] text-muted-foreground", children: [
|
|
2104
2152
|
"Opacity",
|
|
2105
|
-
/* @__PURE__ */ (0,
|
|
2153
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
2106
2154
|
"input",
|
|
2107
2155
|
{
|
|
2108
2156
|
type: "number",
|
|
@@ -2110,7 +2158,7 @@ function VectorGradientEditor({ controller, className }) {
|
|
|
2110
2158
|
max: 100,
|
|
2111
2159
|
step: 5,
|
|
2112
2160
|
"aria-label": "Stop opacity",
|
|
2113
|
-
className:
|
|
2161
|
+
className: numberClass9,
|
|
2114
2162
|
value: percent(sel.opacity ?? 1),
|
|
2115
2163
|
onChange: (e) => {
|
|
2116
2164
|
const n = parseFloat(e.target.value);
|
|
@@ -2119,9 +2167,9 @@ function VectorGradientEditor({ controller, className }) {
|
|
|
2119
2167
|
}
|
|
2120
2168
|
)
|
|
2121
2169
|
] }),
|
|
2122
|
-
/* @__PURE__ */ (0,
|
|
2170
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("label", { className: "flex items-center gap-1 text-[11px] text-muted-foreground", children: [
|
|
2123
2171
|
"At",
|
|
2124
|
-
/* @__PURE__ */ (0,
|
|
2172
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
2125
2173
|
"input",
|
|
2126
2174
|
{
|
|
2127
2175
|
type: "number",
|
|
@@ -2129,7 +2177,7 @@ function VectorGradientEditor({ controller, className }) {
|
|
|
2129
2177
|
max: 100,
|
|
2130
2178
|
step: 1,
|
|
2131
2179
|
"aria-label": "Stop position",
|
|
2132
|
-
className:
|
|
2180
|
+
className: numberClass9,
|
|
2133
2181
|
value: percent(sel.offset),
|
|
2134
2182
|
onChange: (e) => {
|
|
2135
2183
|
const n = parseFloat(e.target.value);
|
|
@@ -2138,9 +2186,9 @@ function VectorGradientEditor({ controller, className }) {
|
|
|
2138
2186
|
}
|
|
2139
2187
|
)
|
|
2140
2188
|
] }),
|
|
2141
|
-
!sel.last && /* @__PURE__ */ (0,
|
|
2189
|
+
!sel.last && /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("label", { className: "flex items-center gap-1 text-[11px] text-muted-foreground", children: [
|
|
2142
2190
|
"Midpoint",
|
|
2143
|
-
/* @__PURE__ */ (0,
|
|
2191
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
2144
2192
|
"input",
|
|
2145
2193
|
{
|
|
2146
2194
|
type: "number",
|
|
@@ -2148,7 +2196,7 @@ function VectorGradientEditor({ controller, className }) {
|
|
|
2148
2196
|
max: 95,
|
|
2149
2197
|
step: 1,
|
|
2150
2198
|
"aria-label": "Stop midpoint",
|
|
2151
|
-
className:
|
|
2199
|
+
className: numberClass9,
|
|
2152
2200
|
value: percent(sel.midpoint ?? 0.5),
|
|
2153
2201
|
onChange: (e) => {
|
|
2154
2202
|
const n = parseFloat(e.target.value);
|
|
@@ -2157,15 +2205,15 @@ function VectorGradientEditor({ controller, className }) {
|
|
|
2157
2205
|
}
|
|
2158
2206
|
)
|
|
2159
2207
|
] }),
|
|
2160
|
-
/* @__PURE__ */ (0,
|
|
2208
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)("button", { type: "button", className: buttonClass13, "aria-label": "Delete stop", title: "Delete stop", disabled: ed.stops.length <= 2, onClick: () => controller.removeGradientStop(sel.index), children: "\u2715" })
|
|
2161
2209
|
] }),
|
|
2162
|
-
/* @__PURE__ */ (0,
|
|
2163
|
-
/* @__PURE__ */ (0,
|
|
2164
|
-
/* @__PURE__ */ (0,
|
|
2210
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("label", { className: "flex items-center gap-1.5 text-xs text-foreground", children: [
|
|
2211
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "w-16", children: "Colours" }),
|
|
2212
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)("select", { "aria-label": "Gradient interpolation", className: selectClass10, value: ed.interpolation, onChange: (e) => controller.setGradient({ interpolation: e.target.value }), children: import_vector15.VECTOR_GRADIENT_INTERPOLATIONS.map((i) => /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("option", { value: i, children: import_vector15.VECTOR_GRADIENT_INTERPOLATION_LABELS[i] }, i)) })
|
|
2165
2213
|
] }),
|
|
2166
|
-
/* @__PURE__ */ (0,
|
|
2167
|
-
/* @__PURE__ */ (0,
|
|
2168
|
-
/* @__PURE__ */ (0,
|
|
2214
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("label", { className: "flex items-center gap-1.5 text-xs text-foreground", children: [
|
|
2215
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "w-16", children: "Smooth" }),
|
|
2216
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
2169
2217
|
"input",
|
|
2170
2218
|
{
|
|
2171
2219
|
type: "range",
|
|
@@ -2181,26 +2229,26 @@ function VectorGradientEditor({ controller, className }) {
|
|
|
2181
2229
|
}
|
|
2182
2230
|
)
|
|
2183
2231
|
] }),
|
|
2184
|
-
/* @__PURE__ */ (0,
|
|
2185
|
-
/* @__PURE__ */ (0,
|
|
2186
|
-
/* @__PURE__ */ (0,
|
|
2232
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("label", { className: "flex items-center gap-1.5 text-xs text-foreground", children: [
|
|
2233
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "w-16", children: "Spread" }),
|
|
2234
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)("select", { "aria-label": "Gradient spread", className: selectClass10, value: ed.spread, onChange: (e) => controller.setGradient({ spread: e.target.value }), children: import_vector15.VECTOR_GRADIENT_SPREADS.map((sp) => /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("option", { value: sp, children: import_vector15.VECTOR_GRADIENT_SPREAD_LABELS[sp] }, sp)) })
|
|
2187
2235
|
] }),
|
|
2188
|
-
ed.target === "stroke" && /* @__PURE__ */ (0,
|
|
2189
|
-
/* @__PURE__ */ (0,
|
|
2190
|
-
/* @__PURE__ */ (0,
|
|
2236
|
+
ed.target === "stroke" && /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("label", { className: "flex items-center gap-1.5 text-xs text-foreground", children: [
|
|
2237
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "w-16", children: "On stroke" }),
|
|
2238
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)("select", { "aria-label": "Gradient on stroke", className: selectClass10, value: ed.strokeMode, onChange: (e) => controller.setGradient({ strokeMode: e.target.value }), children: import_vector15.VECTOR_STROKE_GRADIENT_MODES.map((m) => /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("option", { value: m, children: import_vector15.VECTOR_STROKE_GRADIENT_MODE_LABELS[m] }, m)) })
|
|
2191
2239
|
] })
|
|
2192
2240
|
] })
|
|
2193
2241
|
] });
|
|
2194
2242
|
}
|
|
2195
2243
|
|
|
2196
2244
|
// src/vector/VectorToolbar.tsx
|
|
2197
|
-
var
|
|
2245
|
+
var import_jsx_runtime16 = require("react/jsx-runtime");
|
|
2198
2246
|
var VECTOR_SNAP_TITLE = "Snap to objects";
|
|
2199
2247
|
var modKeyLabel = () => typeof navigator !== "undefined" && /Mac|iPhone|iPad/.test(navigator.platform ?? "") ? "\u2318" : "Ctrl";
|
|
2200
|
-
var
|
|
2248
|
+
var buttonClass14 = "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";
|
|
2201
2249
|
function VectorToolbar({
|
|
2202
2250
|
controller,
|
|
2203
|
-
tools =
|
|
2251
|
+
tools = import_vector16.VECTOR_TOOLS,
|
|
2204
2252
|
showHistory = true,
|
|
2205
2253
|
showArrange = true,
|
|
2206
2254
|
showSnap = true,
|
|
@@ -2214,36 +2262,36 @@ function VectorToolbar({
|
|
|
2214
2262
|
const points = state.tool === "direct" ? state.selectedAnchors.length : 0;
|
|
2215
2263
|
const editing = state.editing;
|
|
2216
2264
|
const groupSelected = state.selection.some((id) => controller.getNode(id)?.type === "group");
|
|
2217
|
-
const maskSelected = state.selection.some((id) => (0,
|
|
2265
|
+
const maskSelected = state.selection.some((id) => (0, import_vector16.isVectorMaskGroup)(controller.getNode(id)));
|
|
2218
2266
|
const [live, setLive] = import_react10.default.useState(false);
|
|
2219
2267
|
const booleanDisabled = live ? count < 1 : count < 2;
|
|
2220
|
-
const act = (label, title, run, disabled = false) => /* @__PURE__ */ (0,
|
|
2221
|
-
return /* @__PURE__ */ (0,
|
|
2222
|
-
/* @__PURE__ */ (0,
|
|
2268
|
+
const act = (label, title, run, disabled = false) => /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("button", { type: "button", className: buttonClass14, title, "aria-label": title, disabled, onClick: () => void run(), children: label }, label);
|
|
2269
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { role: "toolbar", "aria-label": "Vector tools", className: `flex flex-wrap items-center gap-1 ${className ?? ""}`, children: [
|
|
2270
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "flex items-center gap-1", role: "group", "aria-label": "Tools", children: tools.map((tool) => /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
2223
2271
|
"button",
|
|
2224
2272
|
{
|
|
2225
2273
|
type: "button",
|
|
2226
2274
|
"data-vector-tool": tool,
|
|
2227
|
-
className:
|
|
2275
|
+
className: buttonClass14,
|
|
2228
2276
|
"aria-pressed": state.tool === tool,
|
|
2229
|
-
title: `${(0,
|
|
2230
|
-
"aria-label": (0,
|
|
2277
|
+
title: `${(0, import_vector16.vectorToolLabel)(tool)} (${import_vector16.VECTOR_TOOL_SHORTCUTS[tool]})`,
|
|
2278
|
+
"aria-label": (0, import_vector16.vectorToolLabel)(tool),
|
|
2231
2279
|
onClick: () => controller.setTool(tool),
|
|
2232
|
-
children:
|
|
2280
|
+
children: import_vector16.VECTOR_TOOL_GLYPHS[tool]
|
|
2233
2281
|
},
|
|
2234
2282
|
tool
|
|
2235
2283
|
)) }),
|
|
2236
|
-
showHistory && /* @__PURE__ */ (0,
|
|
2284
|
+
showHistory && /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "ml-1 flex items-center gap-1", role: "group", "aria-label": "History", children: [
|
|
2237
2285
|
act("\u21B6", state.canUndo ? `Undo ${state.undoLabel}` : "Undo", () => controller.undo(), !state.canUndo),
|
|
2238
2286
|
act("\u21B7", state.canRedo ? `Redo ${state.redoLabel}` : "Redo", () => controller.redo(), !state.canRedo)
|
|
2239
2287
|
] }),
|
|
2240
|
-
showSnap && /* @__PURE__ */ (0,
|
|
2241
|
-
/* @__PURE__ */ (0,
|
|
2288
|
+
showSnap && /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "ml-1 flex items-center gap-1", role: "group", "aria-label": "Snapping", children: [
|
|
2289
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
2242
2290
|
"button",
|
|
2243
2291
|
{
|
|
2244
2292
|
type: "button",
|
|
2245
2293
|
"data-vector-snap": "",
|
|
2246
|
-
className:
|
|
2294
|
+
className: buttonClass14,
|
|
2247
2295
|
"aria-pressed": state.snap.objects,
|
|
2248
2296
|
title: `${VECTOR_SNAP_TITLE} (hold ${modKeyLabel()} to bypass)`,
|
|
2249
2297
|
"aria-label": VECTOR_SNAP_TITLE,
|
|
@@ -2251,18 +2299,18 @@ function VectorToolbar({
|
|
|
2251
2299
|
children: "Snap"
|
|
2252
2300
|
}
|
|
2253
2301
|
),
|
|
2254
|
-
/* @__PURE__ */ (0,
|
|
2302
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
|
|
2255
2303
|
"select",
|
|
2256
2304
|
{
|
|
2257
2305
|
"data-vector-polar": "",
|
|
2258
2306
|
"aria-label": "Polar tracking increment",
|
|
2259
2307
|
title: "Polar tracking: the angles drawn points snap to from where they leave",
|
|
2260
2308
|
className: "h-8 rounded-md border border-border bg-background px-1 text-xs",
|
|
2261
|
-
value: String((0,
|
|
2262
|
-
onChange: (e) => controller.setSnap({ angles: (0,
|
|
2309
|
+
value: String((0, import_vector16.vectorPolarIncrementOf)(state.snap.angles) ?? ""),
|
|
2310
|
+
onChange: (e) => controller.setSnap({ angles: (0, import_vector16.vectorPolarAngles)(Number(e.target.value)) }),
|
|
2263
2311
|
children: [
|
|
2264
|
-
(0,
|
|
2265
|
-
[90, 45, 30, 15].map((n) => /* @__PURE__ */ (0,
|
|
2312
|
+
(0, import_vector16.vectorPolarIncrementOf)(state.snap.angles) === null && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("option", { value: "", children: "Custom" }),
|
|
2313
|
+
[90, 45, 30, 15].map((n) => /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("option", { value: n, children: [
|
|
2266
2314
|
n,
|
|
2267
2315
|
"\xB0"
|
|
2268
2316
|
] }, n))
|
|
@@ -2270,13 +2318,13 @@ function VectorToolbar({
|
|
|
2270
2318
|
}
|
|
2271
2319
|
)
|
|
2272
2320
|
] }),
|
|
2273
|
-
showPathEdit && /* @__PURE__ */ (0,
|
|
2274
|
-
|
|
2321
|
+
showPathEdit && /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "ml-1 flex items-center gap-1", role: "group", "aria-label": "Path editing", children: [
|
|
2322
|
+
import_vector16.VECTOR_PATH_ACTIONS.map((a) => /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
2275
2323
|
"button",
|
|
2276
2324
|
{
|
|
2277
2325
|
type: "button",
|
|
2278
2326
|
"data-vector-path-action": a.id,
|
|
2279
|
-
className:
|
|
2327
|
+
className: buttonClass14,
|
|
2280
2328
|
title: a.shortcut ? `${a.title} (${modKeyLabel()}+${a.shortcut})` : a.title,
|
|
2281
2329
|
"aria-label": a.title,
|
|
2282
2330
|
disabled: !a.enabled(count, points),
|
|
@@ -2285,12 +2333,12 @@ function VectorToolbar({
|
|
|
2285
2333
|
},
|
|
2286
2334
|
a.id
|
|
2287
2335
|
)),
|
|
2288
|
-
|
|
2336
|
+
import_vector16.VECTOR_EDIT_TOGGLES.map((t) => /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
2289
2337
|
"button",
|
|
2290
2338
|
{
|
|
2291
2339
|
type: "button",
|
|
2292
2340
|
"data-vector-edit": t.key,
|
|
2293
|
-
className:
|
|
2341
|
+
className: buttonClass14,
|
|
2294
2342
|
"aria-pressed": editing[t.key],
|
|
2295
2343
|
title: t.title,
|
|
2296
2344
|
"aria-label": t.title,
|
|
@@ -2299,9 +2347,9 @@ function VectorToolbar({
|
|
|
2299
2347
|
},
|
|
2300
2348
|
t.key
|
|
2301
2349
|
)),
|
|
2302
|
-
state.tool === "pencil" && /* @__PURE__ */ (0,
|
|
2350
|
+
state.tool === "pencil" && /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("label", { className: "flex items-center gap-1 text-xs text-foreground", children: [
|
|
2303
2351
|
"Smoothing",
|
|
2304
|
-
/* @__PURE__ */ (0,
|
|
2352
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
2305
2353
|
"input",
|
|
2306
2354
|
{
|
|
2307
2355
|
type: "range",
|
|
@@ -2315,9 +2363,9 @@ function VectorToolbar({
|
|
|
2315
2363
|
}
|
|
2316
2364
|
)
|
|
2317
2365
|
] }),
|
|
2318
|
-
state.tool === "eraser" && /* @__PURE__ */ (0,
|
|
2366
|
+
state.tool === "eraser" && /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("label", { className: "flex items-center gap-1 text-xs text-foreground", children: [
|
|
2319
2367
|
"Size",
|
|
2320
|
-
/* @__PURE__ */ (0,
|
|
2368
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
2321
2369
|
"input",
|
|
2322
2370
|
{
|
|
2323
2371
|
type: "number",
|
|
@@ -2333,26 +2381,26 @@ function VectorToolbar({
|
|
|
2333
2381
|
}
|
|
2334
2382
|
)
|
|
2335
2383
|
] }),
|
|
2336
|
-
state.tool === "paintBucket" && /* @__PURE__ */ (0,
|
|
2384
|
+
state.tool === "paintBucket" && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
2337
2385
|
"button",
|
|
2338
2386
|
{
|
|
2339
2387
|
type: "button",
|
|
2340
2388
|
"data-vector-fill-gap": "",
|
|
2341
|
-
className:
|
|
2389
|
+
className: buttonClass14,
|
|
2342
2390
|
"aria-pressed": editing.fillGap > 0,
|
|
2343
2391
|
title: "Close small gaps between path ends when filling",
|
|
2344
2392
|
"aria-label": "Close gaps",
|
|
2345
|
-
onClick: () => controller.setEditing({ fillGap: editing.fillGap > 0 ? 0 :
|
|
2393
|
+
onClick: () => controller.setEditing({ fillGap: editing.fillGap > 0 ? 0 : import_vector16.VECTOR_FILL_GAP }),
|
|
2346
2394
|
children: "Gaps"
|
|
2347
2395
|
}
|
|
2348
2396
|
)
|
|
2349
2397
|
] }),
|
|
2350
|
-
showDistort && /* @__PURE__ */ (0,
|
|
2398
|
+
showDistort && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "ml-1 flex items-center gap-1", role: "group", "aria-label": "Distort", children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
2351
2399
|
"button",
|
|
2352
2400
|
{
|
|
2353
2401
|
type: "button",
|
|
2354
2402
|
"data-vector-free-distort": "",
|
|
2355
|
-
className:
|
|
2403
|
+
className: buttonClass14,
|
|
2356
2404
|
"aria-pressed": state.freeDistort,
|
|
2357
2405
|
title: `Free Distort: drag a corner of the selection box to distort in perspective (Shift+Alt+${modKeyLabel()}: symmetric perspective; ${modKeyLabel()}-drag a side to skew)`,
|
|
2358
2406
|
"aria-label": "Free Distort",
|
|
@@ -2360,15 +2408,15 @@ function VectorToolbar({
|
|
|
2360
2408
|
children: "Distort"
|
|
2361
2409
|
}
|
|
2362
2410
|
) }),
|
|
2363
|
-
showBlend && /* @__PURE__ */ (0,
|
|
2364
|
-
showArrange && /* @__PURE__ */ (0,
|
|
2365
|
-
/* @__PURE__ */ (0,
|
|
2366
|
-
/* @__PURE__ */ (0,
|
|
2411
|
+
showBlend && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(VectorBlendControls, { controller }),
|
|
2412
|
+
showArrange && /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_jsx_runtime16.Fragment, { children: [
|
|
2413
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "ml-1 flex items-center gap-1", role: "group", "aria-label": "Combine", children: [
|
|
2414
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
2367
2415
|
"button",
|
|
2368
2416
|
{
|
|
2369
2417
|
type: "button",
|
|
2370
2418
|
"data-vector-live-boolean": "",
|
|
2371
|
-
className:
|
|
2419
|
+
className: buttonClass14,
|
|
2372
2420
|
"aria-pressed": live,
|
|
2373
2421
|
title: "Live booleans: keep the shapes editable",
|
|
2374
2422
|
"aria-label": "Live booleans",
|
|
@@ -2385,12 +2433,12 @@ function VectorToolbar({
|
|
|
2385
2433
|
act("\u25D0", `Make Clipping Mask (${modKeyLabel()}+7)`, () => controller.makeMask("clip"), count < 2),
|
|
2386
2434
|
act("\u25D1", `Release Mask (${modKeyLabel()}+Alt+7)`, () => controller.releaseMask(), !maskSelected)
|
|
2387
2435
|
] }),
|
|
2388
|
-
/* @__PURE__ */ (0,
|
|
2436
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "ml-1 flex items-center gap-1", role: "group", "aria-label": "Pathfinder", children: import_vector16.VECTOR_PATHFINDER_ACTIONS.map((a) => /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
2389
2437
|
"button",
|
|
2390
2438
|
{
|
|
2391
2439
|
type: "button",
|
|
2392
2440
|
"data-vector-pathfinder": a.id,
|
|
2393
|
-
className:
|
|
2441
|
+
className: buttonClass14,
|
|
2394
2442
|
title: a.title,
|
|
2395
2443
|
"aria-label": a.title,
|
|
2396
2444
|
disabled: count < a.min,
|
|
@@ -2399,7 +2447,7 @@ function VectorToolbar({
|
|
|
2399
2447
|
},
|
|
2400
2448
|
a.id
|
|
2401
2449
|
)) }),
|
|
2402
|
-
/* @__PURE__ */ (0,
|
|
2450
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "ml-1 flex items-center gap-1", role: "group", "aria-label": "Arrange", children: [
|
|
2403
2451
|
act("\u21C8", "Bring to Front", () => controller.arrange("front"), count < 1),
|
|
2404
2452
|
act("\u21CA", "Send to Back", () => controller.arrange("back"), count < 1),
|
|
2405
2453
|
act("\u21E4", "Align Left", () => controller.align("left"), count < 1),
|
|
@@ -2414,22 +2462,22 @@ function VectorToolbar({
|
|
|
2414
2462
|
}
|
|
2415
2463
|
function VectorBlendControls({ controller }) {
|
|
2416
2464
|
const state = useVectorEditorState(controller);
|
|
2417
|
-
const blend = (0,
|
|
2465
|
+
const blend = (0, import_vector16.getVectorBlendControls)(state);
|
|
2418
2466
|
const o = blend.options;
|
|
2419
2467
|
const selected = blend.ids.length > 0;
|
|
2420
|
-
return /* @__PURE__ */ (0,
|
|
2421
|
-
/* @__PURE__ */ (0,
|
|
2422
|
-
/* @__PURE__ */ (0,
|
|
2468
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "ml-1 flex items-center gap-1", role: "group", "aria-label": "Blend", "data-vector-blend-controls": "", children: [
|
|
2469
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("button", { type: "button", "data-vector-blend-action": "make", className: buttonClass14, title: "Make Blend", "aria-label": "Make Blend", disabled: !blend.canBlend, onClick: () => controller.blend(), children: "\u29D3" }),
|
|
2470
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
2423
2471
|
"select",
|
|
2424
2472
|
{
|
|
2425
2473
|
"aria-label": "Blend spacing",
|
|
2426
2474
|
className: "h-7 rounded border border-border bg-background px-1 text-xs",
|
|
2427
2475
|
value: o.spacing,
|
|
2428
|
-
onChange: (e) => (0,
|
|
2429
|
-
children:
|
|
2476
|
+
onChange: (e) => (0, import_vector16.applyVectorBlendOptions)(controller, { spacing: e.target.value }),
|
|
2477
|
+
children: import_vector16.VECTOR_BLEND_SPACINGS.map((sp) => /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("option", { value: sp, children: import_vector16.VECTOR_BLEND_SPACING_LABELS[sp] }, sp))
|
|
2430
2478
|
}
|
|
2431
2479
|
),
|
|
2432
|
-
o.spacing !== "smoothColor" && /* @__PURE__ */ (0,
|
|
2480
|
+
o.spacing !== "smoothColor" && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
2433
2481
|
"input",
|
|
2434
2482
|
{
|
|
2435
2483
|
type: "number",
|
|
@@ -2441,29 +2489,29 @@ function VectorBlendControls({ controller }) {
|
|
|
2441
2489
|
onChange: (e) => {
|
|
2442
2490
|
const n = parseFloat(e.target.value);
|
|
2443
2491
|
if (!Number.isFinite(n) || n <= 0) return;
|
|
2444
|
-
(0,
|
|
2492
|
+
(0, import_vector16.applyVectorBlendOptions)(controller, o.spacing === "steps" ? { steps: n } : { distance: n });
|
|
2445
2493
|
}
|
|
2446
2494
|
}
|
|
2447
2495
|
),
|
|
2448
|
-
/* @__PURE__ */ (0,
|
|
2496
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
2449
2497
|
"button",
|
|
2450
2498
|
{
|
|
2451
2499
|
type: "button",
|
|
2452
2500
|
"data-vector-blend-action": "orient",
|
|
2453
|
-
className:
|
|
2501
|
+
className: buttonClass14,
|
|
2454
2502
|
"aria-pressed": o.orientToSpine,
|
|
2455
2503
|
title: "Orient steps to the spine",
|
|
2456
2504
|
"aria-label": "Orient to spine",
|
|
2457
|
-
onClick: () => (0,
|
|
2505
|
+
onClick: () => (0, import_vector16.applyVectorBlendOptions)(controller, { orientToSpine: !o.orientToSpine }),
|
|
2458
2506
|
children: "\u293F"
|
|
2459
2507
|
}
|
|
2460
2508
|
),
|
|
2461
|
-
/* @__PURE__ */ (0,
|
|
2509
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
2462
2510
|
"button",
|
|
2463
2511
|
{
|
|
2464
2512
|
type: "button",
|
|
2465
2513
|
"data-vector-blend-action": "spine",
|
|
2466
|
-
className:
|
|
2514
|
+
className: buttonClass14,
|
|
2467
2515
|
title: "Replace Spine (select a blend and a path)",
|
|
2468
2516
|
"aria-label": "Replace Spine",
|
|
2469
2517
|
disabled: !blend.canReplaceSpine,
|
|
@@ -2471,15 +2519,15 @@ function VectorBlendControls({ controller }) {
|
|
|
2471
2519
|
children: "\u2307"
|
|
2472
2520
|
}
|
|
2473
2521
|
),
|
|
2474
|
-
/* @__PURE__ */ (0,
|
|
2475
|
-
/* @__PURE__ */ (0,
|
|
2522
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("button", { type: "button", "data-vector-blend-action": "expand", className: buttonClass14, title: "Expand Blend", "aria-label": "Expand Blend", disabled: !selected, onClick: () => controller.expandBlend(), children: "\u29C9" }),
|
|
2523
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("button", { type: "button", "data-vector-blend-action": "release", className: buttonClass14, title: "Release Blend", "aria-label": "Release Blend", disabled: !selected, onClick: () => controller.releaseBlend(), children: "\u29C4" })
|
|
2476
2524
|
] });
|
|
2477
2525
|
}
|
|
2478
|
-
var
|
|
2479
|
-
var
|
|
2526
|
+
var selectClass11 = "h-7 min-w-0 flex-1 rounded border border-border bg-background px-1 text-xs";
|
|
2527
|
+
var numberClass10 = "h-7 w-16 rounded border border-border bg-background px-1.5 text-xs";
|
|
2480
2528
|
function VectorStylePanel({ controller, className }) {
|
|
2481
2529
|
const state = useVectorEditorState(controller);
|
|
2482
|
-
const style = (0,
|
|
2530
|
+
const style = (0, import_vector16.getVectorSelectionStyle)(state);
|
|
2483
2531
|
const d = state.defaults;
|
|
2484
2532
|
const source = style ?? {
|
|
2485
2533
|
fill: d.fill ?? null,
|
|
@@ -2492,7 +2540,7 @@ function VectorStylePanel({ controller, className }) {
|
|
|
2492
2540
|
arrowAlign: d.arrowAlign ?? "extend",
|
|
2493
2541
|
startArrowScale: d.startArrowScale ?? 1,
|
|
2494
2542
|
endArrowScale: d.endArrowScale ?? 1,
|
|
2495
|
-
widthProfile: (0,
|
|
2543
|
+
widthProfile: (0, import_vector16.widthProfilePresetId)(d.strokeWidthProfile),
|
|
2496
2544
|
cornerRadius: d.cornerRadius,
|
|
2497
2545
|
cornerKind: d.cornerKind ?? "round",
|
|
2498
2546
|
cornerSmoothing: 0,
|
|
@@ -2506,19 +2554,19 @@ function VectorStylePanel({ controller, className }) {
|
|
|
2506
2554
|
};
|
|
2507
2555
|
const setProfile = (id) => {
|
|
2508
2556
|
if (style) controller.setWidthProfile(id);
|
|
2509
|
-
else controller.setDefaults({ strokeWidthProfile: (0,
|
|
2557
|
+
else controller.setDefaults({ strokeWidthProfile: (0, import_vector16.widthProfilePreset)(id)?.length ? (0, import_vector16.widthProfilePreset)(id) : null });
|
|
2510
2558
|
};
|
|
2511
|
-
const mixed = (key) => style?.mixed[key] ? /* @__PURE__ */ (0,
|
|
2559
|
+
const mixed = (key) => style?.mixed[key] ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "text-[11px] text-muted-foreground", children: "Mixed" }) : null;
|
|
2512
2560
|
const arrowRow = (end, label) => {
|
|
2513
2561
|
const key = end === "start" ? "startArrow" : "endArrow";
|
|
2514
2562
|
const scaleKey = end === "start" ? "startArrowScale" : "endArrowScale";
|
|
2515
|
-
return /* @__PURE__ */ (0,
|
|
2516
|
-
/* @__PURE__ */ (0,
|
|
2517
|
-
/* @__PURE__ */ (0,
|
|
2518
|
-
/* @__PURE__ */ (0,
|
|
2519
|
-
|
|
2563
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "flex items-center gap-2", "data-vector-style": key, children: [
|
|
2564
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "w-16 text-xs text-foreground", children: label }),
|
|
2565
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("select", { "aria-label": `${label} arrowhead`, className: selectClass11, value: source[key] ?? "", onChange: (e) => apply({ [key]: e.target.value || null }), children: [
|
|
2566
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("option", { value: "", children: "None" }),
|
|
2567
|
+
import_vector16.VECTOR_ARROWHEADS.map((h) => /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("option", { value: h, children: import_vector16.VECTOR_ARROWHEAD_LABELS[h] }, h))
|
|
2520
2568
|
] }),
|
|
2521
|
-
/* @__PURE__ */ (0,
|
|
2569
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
2522
2570
|
"input",
|
|
2523
2571
|
{
|
|
2524
2572
|
type: "number",
|
|
@@ -2526,7 +2574,7 @@ function VectorStylePanel({ controller, className }) {
|
|
|
2526
2574
|
step: 0.25,
|
|
2527
2575
|
"aria-label": `${label} arrowhead scale`,
|
|
2528
2576
|
title: "Scale (\xD7 stroke width)",
|
|
2529
|
-
className:
|
|
2577
|
+
className: numberClass10,
|
|
2530
2578
|
value: source[scaleKey],
|
|
2531
2579
|
onChange: (e) => {
|
|
2532
2580
|
const n = parseFloat(e.target.value);
|
|
@@ -2542,14 +2590,14 @@ function VectorStylePanel({ controller, className }) {
|
|
|
2542
2590
|
};
|
|
2543
2591
|
const paintRow = (key, label) => {
|
|
2544
2592
|
const paint = source[key];
|
|
2545
|
-
const hex = (0,
|
|
2593
|
+
const hex = (0, import_vector16.vectorPaintToHex)(paint);
|
|
2546
2594
|
const on = paint !== null && paint !== "none";
|
|
2547
|
-
return /* @__PURE__ */ (0,
|
|
2548
|
-
/* @__PURE__ */ (0,
|
|
2549
|
-
/* @__PURE__ */ (0,
|
|
2595
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "flex items-center gap-2", "data-vector-style": key, children: [
|
|
2596
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("label", { className: "flex w-16 items-center gap-1.5 text-xs text-foreground", children: [
|
|
2597
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("input", { type: "checkbox", checked: on, "aria-label": `${label} on`, onChange: (e) => apply({ [key]: e.target.checked ? hex ?? "#000000" : null }) }),
|
|
2550
2598
|
label
|
|
2551
2599
|
] }),
|
|
2552
|
-
/* @__PURE__ */ (0,
|
|
2600
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
2553
2601
|
"input",
|
|
2554
2602
|
{
|
|
2555
2603
|
type: "color",
|
|
@@ -2560,18 +2608,18 @@ function VectorStylePanel({ controller, className }) {
|
|
|
2560
2608
|
onChange: (e) => apply({ [key]: e.target.value })
|
|
2561
2609
|
}
|
|
2562
2610
|
),
|
|
2563
|
-
on && !hex && /* @__PURE__ */ (0,
|
|
2564
|
-
style?.mixed[key] && /* @__PURE__ */ (0,
|
|
2611
|
+
on && !hex && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "truncate text-[11px] text-muted-foreground", children: typeof paint === "string" ? paint : "Gradient" }),
|
|
2612
|
+
style?.mixed[key] && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "text-[11px] text-muted-foreground", children: "Mixed" })
|
|
2565
2613
|
] });
|
|
2566
2614
|
};
|
|
2567
|
-
return /* @__PURE__ */ (0,
|
|
2568
|
-
/* @__PURE__ */ (0,
|
|
2615
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: `space-y-2 ${className ?? ""}`, "aria-label": style ? "Selection style" : "New shape style", children: [
|
|
2616
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("p", { className: "text-[11px] font-medium uppercase tracking-wide text-muted-foreground", children: style ? "Selection" : "New shapes" }),
|
|
2569
2617
|
paintRow("fill", "Fill"),
|
|
2570
2618
|
paintRow("stroke", "Stroke"),
|
|
2571
|
-
style && /* @__PURE__ */ (0,
|
|
2572
|
-
/* @__PURE__ */ (0,
|
|
2573
|
-
/* @__PURE__ */ (0,
|
|
2574
|
-
/* @__PURE__ */ (0,
|
|
2619
|
+
style && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(VectorGradientEditor, { controller }),
|
|
2620
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("label", { className: "flex items-center gap-2 text-xs text-foreground", children: [
|
|
2621
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "w-16", children: "Width" }),
|
|
2622
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
2575
2623
|
"input",
|
|
2576
2624
|
{
|
|
2577
2625
|
type: "number",
|
|
@@ -2587,33 +2635,33 @@ function VectorStylePanel({ controller, className }) {
|
|
|
2587
2635
|
}
|
|
2588
2636
|
)
|
|
2589
2637
|
] }),
|
|
2590
|
-
/* @__PURE__ */ (0,
|
|
2591
|
-
/* @__PURE__ */ (0,
|
|
2592
|
-
/* @__PURE__ */ (0,
|
|
2638
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("label", { className: "flex items-center gap-2 text-xs text-foreground", "data-vector-style": "strokeAlign", children: [
|
|
2639
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "w-16", children: "Align" }),
|
|
2640
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("select", { "aria-label": "Stroke alignment", className: selectClass11, value: source.strokeAlign, onChange: (e) => apply({ strokeAlign: e.target.value }), children: Object.keys(import_vector16.VECTOR_STROKE_ALIGN_LABELS).map((a) => /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("option", { value: a, children: import_vector16.VECTOR_STROKE_ALIGN_LABELS[a] }, a)) }),
|
|
2593
2641
|
mixed("strokeAlign")
|
|
2594
2642
|
] }),
|
|
2595
|
-
/* @__PURE__ */ (0,
|
|
2596
|
-
/* @__PURE__ */ (0,
|
|
2597
|
-
/* @__PURE__ */ (0,
|
|
2643
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "flex items-center gap-2 text-xs text-foreground", "data-vector-style": "widthProfile", children: [
|
|
2644
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "w-16", children: "Profile" }),
|
|
2645
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
|
|
2598
2646
|
"select",
|
|
2599
2647
|
{
|
|
2600
2648
|
"aria-label": "Width profile",
|
|
2601
|
-
className:
|
|
2649
|
+
className: selectClass11,
|
|
2602
2650
|
value: source.widthProfile,
|
|
2603
2651
|
onChange: (e) => {
|
|
2604
2652
|
if (e.target.value !== "custom") setProfile(e.target.value);
|
|
2605
2653
|
},
|
|
2606
2654
|
children: [
|
|
2607
|
-
|
|
2608
|
-
source.widthProfile === "custom" && /* @__PURE__ */ (0,
|
|
2655
|
+
import_vector16.VECTOR_WIDTH_PRESETS.map((p) => /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("option", { value: p.id, children: p.label }, p.id)),
|
|
2656
|
+
source.widthProfile === "custom" && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("option", { value: "custom", disabled: true, children: "Custom" })
|
|
2609
2657
|
]
|
|
2610
2658
|
}
|
|
2611
2659
|
),
|
|
2612
|
-
/* @__PURE__ */ (0,
|
|
2660
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
2613
2661
|
"button",
|
|
2614
2662
|
{
|
|
2615
2663
|
type: "button",
|
|
2616
|
-
className:
|
|
2664
|
+
className: buttonClass14,
|
|
2617
2665
|
title: "Reset to uniform width",
|
|
2618
2666
|
"aria-label": "Reset to uniform width",
|
|
2619
2667
|
disabled: source.widthProfile === "uniform" && !style?.mixed.widthProfile,
|
|
@@ -2623,27 +2671,27 @@ function VectorStylePanel({ controller, className }) {
|
|
|
2623
2671
|
),
|
|
2624
2672
|
mixed("widthProfile")
|
|
2625
2673
|
] }),
|
|
2626
|
-
source.hasOpenPath && /* @__PURE__ */ (0,
|
|
2674
|
+
source.hasOpenPath && /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_jsx_runtime16.Fragment, { children: [
|
|
2627
2675
|
arrowRow("start", "Start"),
|
|
2628
2676
|
arrowRow("end", "End"),
|
|
2629
|
-
(source.startArrow || source.endArrow) && /* @__PURE__ */ (0,
|
|
2630
|
-
/* @__PURE__ */ (0,
|
|
2631
|
-
/* @__PURE__ */ (0,
|
|
2632
|
-
/* @__PURE__ */ (0,
|
|
2633
|
-
/* @__PURE__ */ (0,
|
|
2677
|
+
(source.startArrow || source.endArrow) && /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("label", { className: "flex items-center gap-2 text-xs text-foreground", "data-vector-style": "arrowAlign", children: [
|
|
2678
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "w-16", children: "Heads" }),
|
|
2679
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("select", { "aria-label": "Arrowhead alignment", className: selectClass11, value: source.arrowAlign, onChange: (e) => apply({ arrowAlign: e.target.value }), children: [
|
|
2680
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("option", { value: "extend", children: "Tip past end" }),
|
|
2681
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("option", { value: "tip", children: "Tip at end" })
|
|
2634
2682
|
] })
|
|
2635
2683
|
] })
|
|
2636
2684
|
] }),
|
|
2637
|
-
source.corners > 0 && /* @__PURE__ */ (0,
|
|
2638
|
-
/* @__PURE__ */ (0,
|
|
2639
|
-
/* @__PURE__ */ (0,
|
|
2685
|
+
source.corners > 0 && /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "flex items-center gap-2", "data-vector-style": "corners", children: [
|
|
2686
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "w-16 text-xs text-foreground", children: "Corners" }),
|
|
2687
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
2640
2688
|
"input",
|
|
2641
2689
|
{
|
|
2642
2690
|
type: "number",
|
|
2643
2691
|
min: 0,
|
|
2644
2692
|
step: 1,
|
|
2645
2693
|
"aria-label": "Corner radius",
|
|
2646
|
-
className:
|
|
2694
|
+
className: numberClass10,
|
|
2647
2695
|
value: Math.round(source.cornerRadius * 100) / 100,
|
|
2648
2696
|
onChange: (e) => {
|
|
2649
2697
|
const n = parseFloat(e.target.value);
|
|
@@ -2651,12 +2699,12 @@ function VectorStylePanel({ controller, className }) {
|
|
|
2651
2699
|
}
|
|
2652
2700
|
}
|
|
2653
2701
|
),
|
|
2654
|
-
/* @__PURE__ */ (0,
|
|
2702
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("select", { "aria-label": "Corner kind", className: selectClass11, value: source.cornerKind, onChange: (e) => setCorners({ kind: e.target.value }), children: import_vector16.VECTOR_CORNER_KINDS.map((k) => /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("option", { value: k, children: import_vector16.VECTOR_CORNER_KIND_LABELS[k] }, k)) }),
|
|
2655
2703
|
mixed("cornerRadius")
|
|
2656
2704
|
] }),
|
|
2657
|
-
style && source.corners > 0 && source.cornerKind === "round" && source.cornerRadius > 0 && /* @__PURE__ */ (0,
|
|
2658
|
-
/* @__PURE__ */ (0,
|
|
2659
|
-
/* @__PURE__ */ (0,
|
|
2705
|
+
style && source.corners > 0 && source.cornerKind === "round" && source.cornerRadius > 0 && /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("label", { className: "flex items-center gap-2 text-xs text-foreground", "data-vector-style": "corner-smoothing", title: "Corner smoothing: squircle corners that ease into the curve (0.6 is iOS-like)", children: [
|
|
2706
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "w-16", children: "Smoothing" }),
|
|
2707
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
2660
2708
|
"input",
|
|
2661
2709
|
{
|
|
2662
2710
|
type: "range",
|
|
@@ -2671,9 +2719,9 @@ function VectorStylePanel({ controller, className }) {
|
|
|
2671
2719
|
}
|
|
2672
2720
|
)
|
|
2673
2721
|
] }),
|
|
2674
|
-
style && /* @__PURE__ */ (0,
|
|
2675
|
-
/* @__PURE__ */ (0,
|
|
2676
|
-
/* @__PURE__ */ (0,
|
|
2722
|
+
style && /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("label", { className: "flex items-center gap-2 text-xs text-foreground", children: [
|
|
2723
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "w-16", children: "Opacity" }),
|
|
2724
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
2677
2725
|
"input",
|
|
2678
2726
|
{
|
|
2679
2727
|
type: "range",
|
|
@@ -2687,28 +2735,29 @@ function VectorStylePanel({ controller, className }) {
|
|
|
2687
2735
|
}
|
|
2688
2736
|
)
|
|
2689
2737
|
] }),
|
|
2690
|
-
/* @__PURE__ */ (0,
|
|
2691
|
-
style && /* @__PURE__ */ (0,
|
|
2692
|
-
style && /* @__PURE__ */ (0,
|
|
2693
|
-
style && /* @__PURE__ */ (0,
|
|
2694
|
-
style && /* @__PURE__ */ (0,
|
|
2695
|
-
/* @__PURE__ */ (0,
|
|
2696
|
-
/* @__PURE__ */ (0,
|
|
2697
|
-
/* @__PURE__ */ (0,
|
|
2698
|
-
/* @__PURE__ */ (0,
|
|
2699
|
-
/* @__PURE__ */ (0,
|
|
2700
|
-
/* @__PURE__ */ (0,
|
|
2738
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(VectorTextPanel, { controller }),
|
|
2739
|
+
style && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(VectorAppearancePanel, { controller }),
|
|
2740
|
+
style && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(VectorEffectsPanel, { controller }),
|
|
2741
|
+
style && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(VectorEnvelopePanel, { controller }),
|
|
2742
|
+
style && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(VectorMaskPanel, { controller }),
|
|
2743
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(VectorFramePanel, { controller }),
|
|
2744
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(VectorConnectorPanel, { controller }),
|
|
2745
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(VectorShadingPanel, { controller }),
|
|
2746
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(VectorSymmetryPanel, { controller }),
|
|
2747
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(VectorTracePanel, { controller }),
|
|
2748
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(VectorConstraintsPanel, { controller }),
|
|
2749
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(VectorSymbolsPanel, { controller })
|
|
2701
2750
|
] });
|
|
2702
2751
|
}
|
|
2703
2752
|
|
|
2704
2753
|
// src/vector/VectorEditor.tsx
|
|
2705
|
-
var
|
|
2754
|
+
var import_jsx_runtime17 = require("react/jsx-runtime");
|
|
2706
2755
|
function VectorEditor({ controller, tools, showStylePanel = true, height = 520, canvasProps, className }) {
|
|
2707
|
-
return /* @__PURE__ */ (0,
|
|
2708
|
-
/* @__PURE__ */ (0,
|
|
2709
|
-
/* @__PURE__ */ (0,
|
|
2710
|
-
/* @__PURE__ */ (0,
|
|
2711
|
-
showStylePanel && /* @__PURE__ */ (0,
|
|
2756
|
+
return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: `flex flex-col gap-2 ${className ?? ""}`, "data-vector-editor": "", children: [
|
|
2757
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(VectorToolbar, { controller, tools }),
|
|
2758
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "flex min-h-0 flex-col gap-2 md:flex-row", children: [
|
|
2759
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.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_runtime17.jsx)(VectorCanvas, { controller, ...canvasProps }) }),
|
|
2760
|
+
showStylePanel && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(VectorStylePanel, { controller, className: "w-full shrink-0 rounded-md border border-border p-3 md:w-56" })
|
|
2712
2761
|
] })
|
|
2713
2762
|
] });
|
|
2714
2763
|
}
|
|
@@ -2732,6 +2781,7 @@ function VectorEditor({ controller, tools, showStylePanel = true, height = 520,
|
|
|
2732
2781
|
VectorShadingPanel,
|
|
2733
2782
|
VectorStylePanel,
|
|
2734
2783
|
VectorSymbolsPanel,
|
|
2784
|
+
VectorSymmetryPanel,
|
|
2735
2785
|
VectorTextElement,
|
|
2736
2786
|
VectorTextPanel,
|
|
2737
2787
|
VectorToolbar,
|