@pixerate/editor-react 0.73.0 → 0.75.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/{chunk-VNZKHFEM.js → chunk-LWMUV5TC.js} +7 -2
- package/dist/{chunk-VNZKHFEM.js.map → chunk-LWMUV5TC.js.map} +1 -1
- package/dist/image-editor/index.cjs +5 -0
- package/dist/image-editor/index.cjs.map +1 -1
- package/dist/image-editor/index.d.cts +2 -2
- package/dist/image-editor/index.d.ts +2 -2
- package/dist/image-editor/index.js +1 -1
- package/dist/index.cjs +5 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +1 -1
- package/dist/paint-editor/index.cjs +216 -19
- package/dist/paint-editor/index.cjs.map +1 -1
- package/dist/paint-editor/index.d.cts +31 -6
- package/dist/paint-editor/index.d.ts +31 -6
- package/dist/paint-editor/index.js +244 -34
- package/dist/paint-editor/index.js.map +1 -1
- package/dist/vector/index.cjs +298 -174
- package/dist/vector/index.cjs.map +1 -1
- package/dist/vector/index.d.cts +22 -1
- package/dist/vector/index.d.ts +22 -1
- package/dist/vector/index.js +282 -160
- package/dist/vector/index.js.map +1 -1
- package/package.json +3 -3
package/dist/vector/index.cjs
CHANGED
|
@@ -45,11 +45,13 @@ __export(vector_exports, {
|
|
|
45
45
|
VectorMaskPanel: () => VectorMaskPanel,
|
|
46
46
|
VectorMaskedNodes: () => VectorMaskedNodes,
|
|
47
47
|
VectorSceneNodes: () => VectorSceneNodes,
|
|
48
|
+
VectorShadingPanel: () => VectorShadingPanel,
|
|
48
49
|
VectorStylePanel: () => VectorStylePanel,
|
|
49
50
|
VectorSymbolsPanel: () => VectorSymbolsPanel,
|
|
50
51
|
VectorTextElement: () => VectorTextElement,
|
|
51
52
|
VectorTextPanel: () => VectorTextPanel,
|
|
52
53
|
VectorToolbar: () => VectorToolbar,
|
|
54
|
+
VectorTracePanel: () => VectorTracePanel,
|
|
53
55
|
VectorWidthPointEditor: () => VectorWidthPointEditor,
|
|
54
56
|
useVectorCommands: () => useVectorCommands,
|
|
55
57
|
useVectorEditor: () => useVectorEditor,
|
|
@@ -693,6 +695,10 @@ function VectorCanvas({
|
|
|
693
695
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M-3 0H3M0 -3V3", stroke: "#dc2626" })
|
|
694
696
|
] })
|
|
695
697
|
] }),
|
|
698
|
+
overlay.shading.map((sh) => /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("g", { "data-vector-shading": sh.kind, children: [
|
|
699
|
+
sh.lines.map((d, i) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d, stroke: accentColor, strokeWidth: 1, opacity: 0.7 }, i)),
|
|
700
|
+
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))
|
|
701
|
+
] }, `shading:${sh.nodeId}`)),
|
|
696
702
|
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}`)),
|
|
697
703
|
overlay.typedEntry && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("g", { "data-vector-typed-entry": "", transform: `translate(${overlay.typedEntry.x + 14} ${overlay.typedEntry.y + 18})`, children: [
|
|
698
704
|
/* @__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 }),
|
|
@@ -828,8 +834,8 @@ function VectorCanvas({
|
|
|
828
834
|
}
|
|
829
835
|
|
|
830
836
|
// src/vector/VectorToolbar.tsx
|
|
831
|
-
var
|
|
832
|
-
var
|
|
837
|
+
var import_react10 = __toESM(require("react"), 1);
|
|
838
|
+
var import_vector15 = require("@pixerate/editor/vector");
|
|
833
839
|
|
|
834
840
|
// src/vector/VectorEffectsPanel.tsx
|
|
835
841
|
var import_vector4 = require("@pixerate/editor/vector");
|
|
@@ -1920,16 +1926,130 @@ function VectorConnectorPanel({ controller, className }) {
|
|
|
1920
1926
|
] });
|
|
1921
1927
|
}
|
|
1922
1928
|
|
|
1923
|
-
// src/vector/
|
|
1929
|
+
// src/vector/VectorShadingPanel.tsx
|
|
1930
|
+
var import_react8 = require("react");
|
|
1924
1931
|
var import_vector13 = require("@pixerate/editor/vector");
|
|
1925
1932
|
var import_jsx_runtime12 = require("react/jsx-runtime");
|
|
1933
|
+
var buttonClass10 = "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";
|
|
1934
|
+
var numberClass6 = "h-7 w-12 rounded border border-border bg-background px-1.5 text-xs";
|
|
1935
|
+
function VectorShadingPanel({ controller, className }) {
|
|
1936
|
+
const state = useVectorEditorState(controller);
|
|
1937
|
+
const [rows, setRows] = (0, import_react8.useState)(2);
|
|
1938
|
+
const [columns, setColumns] = (0, import_react8.useState)(2);
|
|
1939
|
+
const path = state.selection.map((id) => controller.getNode(id)).find((n) => n?.type === "path");
|
|
1940
|
+
if (!path) return null;
|
|
1941
|
+
const fill = path.fill;
|
|
1942
|
+
const sel = state.shadingPoint?.nodeId === path.id ? state.shadingPoint : null;
|
|
1943
|
+
const mesh = (0, import_vector13.isVectorMeshGradient)(fill) ? fill : null;
|
|
1944
|
+
const free = (0, import_vector13.isVectorFreeformGradient)(fill) ? fill : null;
|
|
1945
|
+
const color = sel ? mesh ? mesh.colors[sel.index] : free?.points[sel.index]?.color : void 0;
|
|
1946
|
+
const opacity = sel ? mesh ? mesh.opacities?.[sel.index] ?? 1 : free?.points[sel.index]?.opacity ?? 1 : 1;
|
|
1947
|
+
const spread = sel && free ? free.points[sel.index]?.spread ?? 0 : 0;
|
|
1948
|
+
const edit = (patch, merge) => {
|
|
1949
|
+
if (!sel) return;
|
|
1950
|
+
if (mesh) controller.setMeshPoint(path.id, sel.index, patch, merge ? { merge } : {});
|
|
1951
|
+
else controller.setFreeformPoint(path.id, sel.index, patch, merge ? { merge } : {});
|
|
1952
|
+
};
|
|
1953
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: `space-y-2 ${className ?? ""}`, "data-vector-shading-panel": path.id, "aria-label": "Mesh and freeform gradient", children: [
|
|
1954
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "flex flex-wrap items-center gap-1", children: [
|
|
1955
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "w-16 text-[11px] font-medium uppercase tracking-wide text-muted-foreground", children: "Shading" }),
|
|
1956
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("input", { type: "number", min: 1, max: 32, "aria-label": "Mesh rows", title: "Mesh rows", className: numberClass6, value: rows, onChange: (e) => setRows(Math.max(1, Math.min(32, parseInt(e.target.value, 10) || 1))) }),
|
|
1957
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "text-xs text-muted-foreground", children: "\xD7" }),
|
|
1958
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("input", { type: "number", min: 1, max: 32, "aria-label": "Mesh columns", title: "Mesh columns", className: numberClass6, value: columns, onChange: (e) => setColumns(Math.max(1, Math.min(32, parseInt(e.target.value, 10) || 1))) }),
|
|
1959
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("button", { type: "button", className: buttonClass10, "data-vector-shading-action": "mesh", title: "Create Gradient Mesh: smooth patches whose points blend colours (edit them with the Gradient tool)", onClick: () => controller.setMeshGradient({ rows, columns }, { ids: [path.id] }), children: "Mesh" }),
|
|
1960
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("button", { type: "button", className: buttonClass10, "data-vector-shading-action": "freeform", title: "Freeform Gradient: colour points blended across the shape (click inside with the Gradient tool to add one)", onClick: () => controller.setFreeformGradient({}, { ids: [path.id] }), children: "Freeform" })
|
|
1961
|
+
] }),
|
|
1962
|
+
(mesh || free) && !sel && /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("p", { className: "text-[11px] text-muted-foreground", children: [
|
|
1963
|
+
"Gradient tool (G): drag points; ",
|
|
1964
|
+
free ? "click inside to add one, Alt-click to remove." : "pick one to colour it."
|
|
1965
|
+
] }),
|
|
1966
|
+
sel && /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "flex flex-wrap items-center gap-2", "data-vector-shading-point": sel.index, children: [
|
|
1967
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("span", { className: "w-16 text-xs text-foreground", children: [
|
|
1968
|
+
"Point ",
|
|
1969
|
+
sel.index
|
|
1970
|
+
] }),
|
|
1971
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("input", { type: "color", "aria-label": "Point colour", className: "h-7 w-10 cursor-pointer rounded border border-border bg-background", value: (0, import_vector13.vectorPaintToHex)(color ?? "#000000") ?? "#000000", onChange: (e) => edit({ color: e.target.value }, "shading-color") }),
|
|
1972
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("input", { type: "range", min: 0, max: 1, step: 0.05, "aria-label": "Point opacity", title: "Opacity", className: "h-4 w-20 accent-primary", value: opacity, onChange: (e) => edit({ opacity: parseFloat(e.target.value) }, "shading-opacity") }),
|
|
1973
|
+
free && /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_jsx_runtime12.Fragment, { children: [
|
|
1974
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("input", { type: "range", min: 0, max: 1, step: 0.05, "aria-label": "Point spread", title: "Spread: pure colour round the point", className: "h-4 w-20 accent-primary", value: spread, onChange: (e) => edit({ spread: parseFloat(e.target.value) }, "shading-spread") }),
|
|
1975
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("button", { type: "button", className: buttonClass10, "aria-label": "Remove point", onClick: () => controller.removeFreeformPoint(path.id, sel.index), children: "Remove" })
|
|
1976
|
+
] })
|
|
1977
|
+
] })
|
|
1978
|
+
] });
|
|
1979
|
+
}
|
|
1980
|
+
|
|
1981
|
+
// src/vector/VectorTracePanel.tsx
|
|
1982
|
+
var import_react9 = require("react");
|
|
1983
|
+
var import_jsx_runtime13 = require("react/jsx-runtime");
|
|
1984
|
+
var buttonClass11 = "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";
|
|
1926
1985
|
var selectClass8 = "h-7 min-w-0 flex-1 rounded border border-border bg-background px-1 text-xs";
|
|
1927
|
-
var
|
|
1928
|
-
|
|
1986
|
+
var numberClass7 = "h-7 w-12 rounded border border-border bg-background px-1.5 text-xs";
|
|
1987
|
+
async function filePixels(file, max = 1e6) {
|
|
1988
|
+
const bitmap = await createImageBitmap(file);
|
|
1989
|
+
const k = Math.min(1, Math.sqrt(max / (bitmap.width * bitmap.height)));
|
|
1990
|
+
const width = Math.max(1, Math.round(bitmap.width * k));
|
|
1991
|
+
const height = Math.max(1, Math.round(bitmap.height * k));
|
|
1992
|
+
const canvas = document.createElement("canvas");
|
|
1993
|
+
canvas.width = width;
|
|
1994
|
+
canvas.height = height;
|
|
1995
|
+
const ctx = canvas.getContext("2d");
|
|
1996
|
+
ctx.drawImage(bitmap, 0, 0, width, height);
|
|
1997
|
+
return { width, height, data: ctx.getImageData(0, 0, width, height).data };
|
|
1998
|
+
}
|
|
1999
|
+
function VectorTracePanel({ controller, className }) {
|
|
2000
|
+
const input = (0, import_react9.useRef)(null);
|
|
2001
|
+
const [mode, setMode] = (0, import_react9.useState)("threshold");
|
|
2002
|
+
const [colors, setColors] = (0, import_react9.useState)(6);
|
|
2003
|
+
const [message, setMessage] = (0, import_react9.useState)(null);
|
|
2004
|
+
const trace = async (file) => {
|
|
2005
|
+
try {
|
|
2006
|
+
const pixels = await filePixels(file);
|
|
2007
|
+
const doc = controller.getState().document;
|
|
2008
|
+
const width = Math.min(doc.width, pixels.width);
|
|
2009
|
+
const r = controller.traceImage(pixels, { mode, colors, width, name: file.name.replace(/\.[^.]+$/, "") || "Image Trace" });
|
|
2010
|
+
setMessage(r.ok ? null : r.message);
|
|
2011
|
+
} catch {
|
|
2012
|
+
setMessage("That file could not be read as an image.");
|
|
2013
|
+
}
|
|
2014
|
+
};
|
|
2015
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: `space-y-1 ${className ?? ""}`, "data-vector-trace-panel": "", "aria-label": "Image trace", children: [
|
|
2016
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex items-center gap-1", children: [
|
|
2017
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "w-16 text-[11px] font-medium uppercase tracking-wide text-muted-foreground", children: "Trace" }),
|
|
2018
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("select", { "aria-label": "Trace mode", className: selectClass8, value: mode, onChange: (e) => setMode(e.target.value), children: [
|
|
2019
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("option", { value: "threshold", children: "Black & white" }),
|
|
2020
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("option", { value: "color", children: "Colours" })
|
|
2021
|
+
] }),
|
|
2022
|
+
mode === "color" && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("input", { type: "number", min: 2, max: 32, "aria-label": "Trace colours", title: "Colours", className: numberClass7, value: colors, onChange: (e) => setColors(Math.max(2, Math.min(32, parseInt(e.target.value, 10) || 2))) }),
|
|
2023
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("button", { type: "button", className: buttonClass11, "data-vector-trace-action": "", title: "Image Trace: pick an image to turn into paths", onClick: () => input.current?.click(), children: "Image\u2026" }),
|
|
2024
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
2025
|
+
"input",
|
|
2026
|
+
{
|
|
2027
|
+
ref: input,
|
|
2028
|
+
type: "file",
|
|
2029
|
+
accept: "image/*",
|
|
2030
|
+
hidden: true,
|
|
2031
|
+
onChange: (e) => {
|
|
2032
|
+
const file = e.target.files?.[0];
|
|
2033
|
+
e.target.value = "";
|
|
2034
|
+
if (file) void trace(file);
|
|
2035
|
+
}
|
|
2036
|
+
}
|
|
2037
|
+
)
|
|
2038
|
+
] }),
|
|
2039
|
+
message && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("p", { className: "text-[11px] text-red-600", children: message })
|
|
2040
|
+
] });
|
|
2041
|
+
}
|
|
2042
|
+
|
|
2043
|
+
// src/vector/VectorGradientEditor.tsx
|
|
2044
|
+
var import_vector14 = require("@pixerate/editor/vector");
|
|
2045
|
+
var import_jsx_runtime14 = require("react/jsx-runtime");
|
|
2046
|
+
var selectClass9 = "h-7 min-w-0 flex-1 rounded border border-border bg-background px-1 text-xs";
|
|
2047
|
+
var numberClass8 = "h-7 w-14 rounded border border-border bg-background px-1.5 text-xs";
|
|
2048
|
+
var buttonClass12 = "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";
|
|
1929
2049
|
var percent = (v) => Math.round(v * 1e3) / 10;
|
|
1930
2050
|
function VectorGradientEditor({ controller, className }) {
|
|
1931
2051
|
const state = useVectorEditorState(controller);
|
|
1932
|
-
const ed = (0,
|
|
2052
|
+
const ed = (0, import_vector14.getVectorGradientEditor)(state);
|
|
1933
2053
|
if (!ed) return null;
|
|
1934
2054
|
const g = ed.gradient;
|
|
1935
2055
|
const sel = ed.selected;
|
|
@@ -1937,26 +2057,26 @@ function VectorGradientEditor({ controller, className }) {
|
|
|
1937
2057
|
const setType = (value) => {
|
|
1938
2058
|
if (value === "solid") {
|
|
1939
2059
|
const first = ed.stops[0];
|
|
1940
|
-
controller.setStyle({ [ed.target]: (0,
|
|
2060
|
+
controller.setStyle({ [ed.target]: (0, import_vector14.vectorPaintToHex)(first?.color) ?? first?.color ?? "#000000" }, void 0, { label: "Solid Colour" });
|
|
1941
2061
|
} else controller.setGradient({ type: value });
|
|
1942
2062
|
};
|
|
1943
|
-
return /* @__PURE__ */ (0,
|
|
1944
|
-
/* @__PURE__ */ (0,
|
|
1945
|
-
/* @__PURE__ */ (0,
|
|
1946
|
-
["fill", "stroke"].map((t) => /* @__PURE__ */ (0,
|
|
1947
|
-
ed.mixed && /* @__PURE__ */ (0,
|
|
2063
|
+
return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: `space-y-1.5 ${className ?? ""}`, "data-vector-gradient-editor": ed.target, "aria-label": "Gradient", children: [
|
|
2064
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex items-center gap-1.5", children: [
|
|
2065
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "w-16 text-xs text-foreground", children: "Gradient" }),
|
|
2066
|
+
["fill", "stroke"].map((t) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("button", { type: "button", className: buttonClass12, "aria-pressed": ed.target === t, onClick: () => controller.setGradientTarget(t), children: t === "fill" ? "Fill" : "Stroke" }, t)),
|
|
2067
|
+
ed.mixed && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "text-[11px] text-muted-foreground", children: "Mixed" })
|
|
1948
2068
|
] }),
|
|
1949
|
-
/* @__PURE__ */ (0,
|
|
1950
|
-
/* @__PURE__ */ (0,
|
|
1951
|
-
/* @__PURE__ */ (0,
|
|
1952
|
-
/* @__PURE__ */ (0,
|
|
1953
|
-
|
|
2069
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex items-center gap-1.5", children: [
|
|
2070
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "w-16 text-xs text-foreground", children: "Type" }),
|
|
2071
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("select", { "aria-label": "Gradient type", className: selectClass9, value: ed.type ?? "solid", onChange: (e) => setType(e.target.value), children: [
|
|
2072
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("option", { value: "solid", children: "Solid" }),
|
|
2073
|
+
import_vector14.VECTOR_GRADIENT_TYPES.map((t) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("option", { value: t, children: import_vector14.VECTOR_GRADIENT_TYPE_LABELS[t] }, t))
|
|
1954
2074
|
] }),
|
|
1955
|
-
/* @__PURE__ */ (0,
|
|
2075
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("button", { type: "button", className: buttonClass12, "aria-label": "Reverse gradient", title: "Reverse gradient", disabled: !g, onClick: () => controller.reverseGradient(), children: "\u21C4" })
|
|
1956
2076
|
] }),
|
|
1957
|
-
g && /* @__PURE__ */ (0,
|
|
1958
|
-
/* @__PURE__ */ (0,
|
|
1959
|
-
/* @__PURE__ */ (0,
|
|
2077
|
+
g && /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_jsx_runtime14.Fragment, { children: [
|
|
2078
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "relative h-8", "data-vector-gradient-ramp": "", children: [
|
|
2079
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
1960
2080
|
"div",
|
|
1961
2081
|
{
|
|
1962
2082
|
role: "button",
|
|
@@ -1970,7 +2090,7 @@ function VectorGradientEditor({ controller, className }) {
|
|
|
1970
2090
|
}
|
|
1971
2091
|
}
|
|
1972
2092
|
),
|
|
1973
|
-
ed.stops.map((s) => /* @__PURE__ */ (0,
|
|
2093
|
+
ed.stops.map((s) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
1974
2094
|
"button",
|
|
1975
2095
|
{
|
|
1976
2096
|
type: "button",
|
|
@@ -1984,21 +2104,21 @@ function VectorGradientEditor({ controller, className }) {
|
|
|
1984
2104
|
s.index
|
|
1985
2105
|
))
|
|
1986
2106
|
] }),
|
|
1987
|
-
sel && /* @__PURE__ */ (0,
|
|
1988
|
-
/* @__PURE__ */ (0,
|
|
2107
|
+
sel && /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex flex-wrap items-center gap-1.5", "data-vector-gradient-selected-stop": sel.index, children: [
|
|
2108
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
1989
2109
|
"input",
|
|
1990
2110
|
{
|
|
1991
2111
|
type: "color",
|
|
1992
2112
|
"aria-label": "Stop colour",
|
|
1993
2113
|
className: "h-7 w-9 cursor-pointer rounded border border-border bg-background",
|
|
1994
|
-
value: (0,
|
|
2114
|
+
value: (0, import_vector14.vectorPaintToHex)(sel.color) ?? "#000000",
|
|
1995
2115
|
onChange: (e) => controller.setGradientStop(sel.index, { color: e.target.value }, { merge: `gradient-stop-color-${sel.index}` }),
|
|
1996
2116
|
onBlur: end
|
|
1997
2117
|
}
|
|
1998
2118
|
),
|
|
1999
|
-
/* @__PURE__ */ (0,
|
|
2119
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("label", { className: "flex items-center gap-1 text-[11px] text-muted-foreground", children: [
|
|
2000
2120
|
"Opacity",
|
|
2001
|
-
/* @__PURE__ */ (0,
|
|
2121
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
2002
2122
|
"input",
|
|
2003
2123
|
{
|
|
2004
2124
|
type: "number",
|
|
@@ -2006,7 +2126,7 @@ function VectorGradientEditor({ controller, className }) {
|
|
|
2006
2126
|
max: 100,
|
|
2007
2127
|
step: 5,
|
|
2008
2128
|
"aria-label": "Stop opacity",
|
|
2009
|
-
className:
|
|
2129
|
+
className: numberClass8,
|
|
2010
2130
|
value: percent(sel.opacity ?? 1),
|
|
2011
2131
|
onChange: (e) => {
|
|
2012
2132
|
const n = parseFloat(e.target.value);
|
|
@@ -2015,9 +2135,9 @@ function VectorGradientEditor({ controller, className }) {
|
|
|
2015
2135
|
}
|
|
2016
2136
|
)
|
|
2017
2137
|
] }),
|
|
2018
|
-
/* @__PURE__ */ (0,
|
|
2138
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("label", { className: "flex items-center gap-1 text-[11px] text-muted-foreground", children: [
|
|
2019
2139
|
"At",
|
|
2020
|
-
/* @__PURE__ */ (0,
|
|
2140
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
2021
2141
|
"input",
|
|
2022
2142
|
{
|
|
2023
2143
|
type: "number",
|
|
@@ -2025,7 +2145,7 @@ function VectorGradientEditor({ controller, className }) {
|
|
|
2025
2145
|
max: 100,
|
|
2026
2146
|
step: 1,
|
|
2027
2147
|
"aria-label": "Stop position",
|
|
2028
|
-
className:
|
|
2148
|
+
className: numberClass8,
|
|
2029
2149
|
value: percent(sel.offset),
|
|
2030
2150
|
onChange: (e) => {
|
|
2031
2151
|
const n = parseFloat(e.target.value);
|
|
@@ -2034,9 +2154,9 @@ function VectorGradientEditor({ controller, className }) {
|
|
|
2034
2154
|
}
|
|
2035
2155
|
)
|
|
2036
2156
|
] }),
|
|
2037
|
-
!sel.last && /* @__PURE__ */ (0,
|
|
2157
|
+
!sel.last && /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("label", { className: "flex items-center gap-1 text-[11px] text-muted-foreground", children: [
|
|
2038
2158
|
"Midpoint",
|
|
2039
|
-
/* @__PURE__ */ (0,
|
|
2159
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
2040
2160
|
"input",
|
|
2041
2161
|
{
|
|
2042
2162
|
type: "number",
|
|
@@ -2044,7 +2164,7 @@ function VectorGradientEditor({ controller, className }) {
|
|
|
2044
2164
|
max: 95,
|
|
2045
2165
|
step: 1,
|
|
2046
2166
|
"aria-label": "Stop midpoint",
|
|
2047
|
-
className:
|
|
2167
|
+
className: numberClass8,
|
|
2048
2168
|
value: percent(sel.midpoint ?? 0.5),
|
|
2049
2169
|
onChange: (e) => {
|
|
2050
2170
|
const n = parseFloat(e.target.value);
|
|
@@ -2053,15 +2173,15 @@ function VectorGradientEditor({ controller, className }) {
|
|
|
2053
2173
|
}
|
|
2054
2174
|
)
|
|
2055
2175
|
] }),
|
|
2056
|
-
/* @__PURE__ */ (0,
|
|
2176
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("button", { type: "button", className: buttonClass12, "aria-label": "Delete stop", title: "Delete stop", disabled: ed.stops.length <= 2, onClick: () => controller.removeGradientStop(sel.index), children: "\u2715" })
|
|
2057
2177
|
] }),
|
|
2058
|
-
/* @__PURE__ */ (0,
|
|
2059
|
-
/* @__PURE__ */ (0,
|
|
2060
|
-
/* @__PURE__ */ (0,
|
|
2178
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("label", { className: "flex items-center gap-1.5 text-xs text-foreground", children: [
|
|
2179
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "w-16", children: "Colours" }),
|
|
2180
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("select", { "aria-label": "Gradient interpolation", className: selectClass9, value: ed.interpolation, onChange: (e) => controller.setGradient({ interpolation: e.target.value }), children: import_vector14.VECTOR_GRADIENT_INTERPOLATIONS.map((i) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("option", { value: i, children: import_vector14.VECTOR_GRADIENT_INTERPOLATION_LABELS[i] }, i)) })
|
|
2061
2181
|
] }),
|
|
2062
|
-
/* @__PURE__ */ (0,
|
|
2063
|
-
/* @__PURE__ */ (0,
|
|
2064
|
-
/* @__PURE__ */ (0,
|
|
2182
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("label", { className: "flex items-center gap-1.5 text-xs text-foreground", children: [
|
|
2183
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "w-16", children: "Smooth" }),
|
|
2184
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
2065
2185
|
"input",
|
|
2066
2186
|
{
|
|
2067
2187
|
type: "range",
|
|
@@ -2077,26 +2197,26 @@ function VectorGradientEditor({ controller, className }) {
|
|
|
2077
2197
|
}
|
|
2078
2198
|
)
|
|
2079
2199
|
] }),
|
|
2080
|
-
/* @__PURE__ */ (0,
|
|
2081
|
-
/* @__PURE__ */ (0,
|
|
2082
|
-
/* @__PURE__ */ (0,
|
|
2200
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("label", { className: "flex items-center gap-1.5 text-xs text-foreground", children: [
|
|
2201
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "w-16", children: "Spread" }),
|
|
2202
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("select", { "aria-label": "Gradient spread", className: selectClass9, value: ed.spread, onChange: (e) => controller.setGradient({ spread: e.target.value }), children: import_vector14.VECTOR_GRADIENT_SPREADS.map((sp) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("option", { value: sp, children: import_vector14.VECTOR_GRADIENT_SPREAD_LABELS[sp] }, sp)) })
|
|
2083
2203
|
] }),
|
|
2084
|
-
ed.target === "stroke" && /* @__PURE__ */ (0,
|
|
2085
|
-
/* @__PURE__ */ (0,
|
|
2086
|
-
/* @__PURE__ */ (0,
|
|
2204
|
+
ed.target === "stroke" && /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("label", { className: "flex items-center gap-1.5 text-xs text-foreground", children: [
|
|
2205
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "w-16", children: "On stroke" }),
|
|
2206
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("select", { "aria-label": "Gradient on stroke", className: selectClass9, value: ed.strokeMode, onChange: (e) => controller.setGradient({ strokeMode: e.target.value }), children: import_vector14.VECTOR_STROKE_GRADIENT_MODES.map((m) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("option", { value: m, children: import_vector14.VECTOR_STROKE_GRADIENT_MODE_LABELS[m] }, m)) })
|
|
2087
2207
|
] })
|
|
2088
2208
|
] })
|
|
2089
2209
|
] });
|
|
2090
2210
|
}
|
|
2091
2211
|
|
|
2092
2212
|
// src/vector/VectorToolbar.tsx
|
|
2093
|
-
var
|
|
2213
|
+
var import_jsx_runtime15 = require("react/jsx-runtime");
|
|
2094
2214
|
var VECTOR_SNAP_TITLE = "Snap to objects";
|
|
2095
2215
|
var modKeyLabel = () => typeof navigator !== "undefined" && /Mac|iPhone|iPad/.test(navigator.platform ?? "") ? "\u2318" : "Ctrl";
|
|
2096
|
-
var
|
|
2216
|
+
var buttonClass13 = "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";
|
|
2097
2217
|
function VectorToolbar({
|
|
2098
2218
|
controller,
|
|
2099
|
-
tools =
|
|
2219
|
+
tools = import_vector15.VECTOR_TOOLS,
|
|
2100
2220
|
showHistory = true,
|
|
2101
2221
|
showArrange = true,
|
|
2102
2222
|
showSnap = true,
|
|
@@ -2110,36 +2230,36 @@ function VectorToolbar({
|
|
|
2110
2230
|
const points = state.tool === "direct" ? state.selectedAnchors.length : 0;
|
|
2111
2231
|
const editing = state.editing;
|
|
2112
2232
|
const groupSelected = state.selection.some((id) => controller.getNode(id)?.type === "group");
|
|
2113
|
-
const maskSelected = state.selection.some((id) => (0,
|
|
2114
|
-
const [live, setLive] =
|
|
2233
|
+
const maskSelected = state.selection.some((id) => (0, import_vector15.isVectorMaskGroup)(controller.getNode(id)));
|
|
2234
|
+
const [live, setLive] = import_react10.default.useState(false);
|
|
2115
2235
|
const booleanDisabled = live ? count < 1 : count < 2;
|
|
2116
|
-
const act = (label, title, run, disabled = false) => /* @__PURE__ */ (0,
|
|
2117
|
-
return /* @__PURE__ */ (0,
|
|
2118
|
-
/* @__PURE__ */ (0,
|
|
2236
|
+
const act = (label, title, run, disabled = false) => /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("button", { type: "button", className: buttonClass13, title, "aria-label": title, disabled, onClick: () => void run(), children: label }, label);
|
|
2237
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { role: "toolbar", "aria-label": "Vector tools", className: `flex flex-wrap items-center gap-1 ${className ?? ""}`, children: [
|
|
2238
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: "flex items-center gap-1", role: "group", "aria-label": "Tools", children: tools.map((tool) => /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
2119
2239
|
"button",
|
|
2120
2240
|
{
|
|
2121
2241
|
type: "button",
|
|
2122
2242
|
"data-vector-tool": tool,
|
|
2123
|
-
className:
|
|
2243
|
+
className: buttonClass13,
|
|
2124
2244
|
"aria-pressed": state.tool === tool,
|
|
2125
|
-
title: `${(0,
|
|
2126
|
-
"aria-label": (0,
|
|
2245
|
+
title: `${(0, import_vector15.vectorToolLabel)(tool)} (${import_vector15.VECTOR_TOOL_SHORTCUTS[tool]})`,
|
|
2246
|
+
"aria-label": (0, import_vector15.vectorToolLabel)(tool),
|
|
2127
2247
|
onClick: () => controller.setTool(tool),
|
|
2128
|
-
children:
|
|
2248
|
+
children: import_vector15.VECTOR_TOOL_GLYPHS[tool]
|
|
2129
2249
|
},
|
|
2130
2250
|
tool
|
|
2131
2251
|
)) }),
|
|
2132
|
-
showHistory && /* @__PURE__ */ (0,
|
|
2252
|
+
showHistory && /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "ml-1 flex items-center gap-1", role: "group", "aria-label": "History", children: [
|
|
2133
2253
|
act("\u21B6", state.canUndo ? `Undo ${state.undoLabel}` : "Undo", () => controller.undo(), !state.canUndo),
|
|
2134
2254
|
act("\u21B7", state.canRedo ? `Redo ${state.redoLabel}` : "Redo", () => controller.redo(), !state.canRedo)
|
|
2135
2255
|
] }),
|
|
2136
|
-
showSnap && /* @__PURE__ */ (0,
|
|
2137
|
-
/* @__PURE__ */ (0,
|
|
2256
|
+
showSnap && /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "ml-1 flex items-center gap-1", role: "group", "aria-label": "Snapping", children: [
|
|
2257
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
2138
2258
|
"button",
|
|
2139
2259
|
{
|
|
2140
2260
|
type: "button",
|
|
2141
2261
|
"data-vector-snap": "",
|
|
2142
|
-
className:
|
|
2262
|
+
className: buttonClass13,
|
|
2143
2263
|
"aria-pressed": state.snap.objects,
|
|
2144
2264
|
title: `${VECTOR_SNAP_TITLE} (hold ${modKeyLabel()} to bypass)`,
|
|
2145
2265
|
"aria-label": VECTOR_SNAP_TITLE,
|
|
@@ -2147,18 +2267,18 @@ function VectorToolbar({
|
|
|
2147
2267
|
children: "Snap"
|
|
2148
2268
|
}
|
|
2149
2269
|
),
|
|
2150
|
-
/* @__PURE__ */ (0,
|
|
2270
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
|
|
2151
2271
|
"select",
|
|
2152
2272
|
{
|
|
2153
2273
|
"data-vector-polar": "",
|
|
2154
2274
|
"aria-label": "Polar tracking increment",
|
|
2155
2275
|
title: "Polar tracking: the angles drawn points snap to from where they leave",
|
|
2156
2276
|
className: "h-8 rounded-md border border-border bg-background px-1 text-xs",
|
|
2157
|
-
value: String((0,
|
|
2158
|
-
onChange: (e) => controller.setSnap({ angles: (0,
|
|
2277
|
+
value: String((0, import_vector15.vectorPolarIncrementOf)(state.snap.angles) ?? ""),
|
|
2278
|
+
onChange: (e) => controller.setSnap({ angles: (0, import_vector15.vectorPolarAngles)(Number(e.target.value)) }),
|
|
2159
2279
|
children: [
|
|
2160
|
-
(0,
|
|
2161
|
-
[90, 45, 30, 15].map((n) => /* @__PURE__ */ (0,
|
|
2280
|
+
(0, import_vector15.vectorPolarIncrementOf)(state.snap.angles) === null && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("option", { value: "", children: "Custom" }),
|
|
2281
|
+
[90, 45, 30, 15].map((n) => /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("option", { value: n, children: [
|
|
2162
2282
|
n,
|
|
2163
2283
|
"\xB0"
|
|
2164
2284
|
] }, n))
|
|
@@ -2166,13 +2286,13 @@ function VectorToolbar({
|
|
|
2166
2286
|
}
|
|
2167
2287
|
)
|
|
2168
2288
|
] }),
|
|
2169
|
-
showPathEdit && /* @__PURE__ */ (0,
|
|
2170
|
-
|
|
2289
|
+
showPathEdit && /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "ml-1 flex items-center gap-1", role: "group", "aria-label": "Path editing", children: [
|
|
2290
|
+
import_vector15.VECTOR_PATH_ACTIONS.map((a) => /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
2171
2291
|
"button",
|
|
2172
2292
|
{
|
|
2173
2293
|
type: "button",
|
|
2174
2294
|
"data-vector-path-action": a.id,
|
|
2175
|
-
className:
|
|
2295
|
+
className: buttonClass13,
|
|
2176
2296
|
title: a.shortcut ? `${a.title} (${modKeyLabel()}+${a.shortcut})` : a.title,
|
|
2177
2297
|
"aria-label": a.title,
|
|
2178
2298
|
disabled: !a.enabled(count, points),
|
|
@@ -2181,12 +2301,12 @@ function VectorToolbar({
|
|
|
2181
2301
|
},
|
|
2182
2302
|
a.id
|
|
2183
2303
|
)),
|
|
2184
|
-
|
|
2304
|
+
import_vector15.VECTOR_EDIT_TOGGLES.map((t) => /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
2185
2305
|
"button",
|
|
2186
2306
|
{
|
|
2187
2307
|
type: "button",
|
|
2188
2308
|
"data-vector-edit": t.key,
|
|
2189
|
-
className:
|
|
2309
|
+
className: buttonClass13,
|
|
2190
2310
|
"aria-pressed": editing[t.key],
|
|
2191
2311
|
title: t.title,
|
|
2192
2312
|
"aria-label": t.title,
|
|
@@ -2195,9 +2315,9 @@ function VectorToolbar({
|
|
|
2195
2315
|
},
|
|
2196
2316
|
t.key
|
|
2197
2317
|
)),
|
|
2198
|
-
state.tool === "pencil" && /* @__PURE__ */ (0,
|
|
2318
|
+
state.tool === "pencil" && /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("label", { className: "flex items-center gap-1 text-xs text-foreground", children: [
|
|
2199
2319
|
"Smoothing",
|
|
2200
|
-
/* @__PURE__ */ (0,
|
|
2320
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
2201
2321
|
"input",
|
|
2202
2322
|
{
|
|
2203
2323
|
type: "range",
|
|
@@ -2211,9 +2331,9 @@ function VectorToolbar({
|
|
|
2211
2331
|
}
|
|
2212
2332
|
)
|
|
2213
2333
|
] }),
|
|
2214
|
-
state.tool === "eraser" && /* @__PURE__ */ (0,
|
|
2334
|
+
state.tool === "eraser" && /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("label", { className: "flex items-center gap-1 text-xs text-foreground", children: [
|
|
2215
2335
|
"Size",
|
|
2216
|
-
/* @__PURE__ */ (0,
|
|
2336
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
2217
2337
|
"input",
|
|
2218
2338
|
{
|
|
2219
2339
|
type: "number",
|
|
@@ -2229,26 +2349,26 @@ function VectorToolbar({
|
|
|
2229
2349
|
}
|
|
2230
2350
|
)
|
|
2231
2351
|
] }),
|
|
2232
|
-
state.tool === "paintBucket" && /* @__PURE__ */ (0,
|
|
2352
|
+
state.tool === "paintBucket" && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
2233
2353
|
"button",
|
|
2234
2354
|
{
|
|
2235
2355
|
type: "button",
|
|
2236
2356
|
"data-vector-fill-gap": "",
|
|
2237
|
-
className:
|
|
2357
|
+
className: buttonClass13,
|
|
2238
2358
|
"aria-pressed": editing.fillGap > 0,
|
|
2239
2359
|
title: "Close small gaps between path ends when filling",
|
|
2240
2360
|
"aria-label": "Close gaps",
|
|
2241
|
-
onClick: () => controller.setEditing({ fillGap: editing.fillGap > 0 ? 0 :
|
|
2361
|
+
onClick: () => controller.setEditing({ fillGap: editing.fillGap > 0 ? 0 : import_vector15.VECTOR_FILL_GAP }),
|
|
2242
2362
|
children: "Gaps"
|
|
2243
2363
|
}
|
|
2244
2364
|
)
|
|
2245
2365
|
] }),
|
|
2246
|
-
showDistort && /* @__PURE__ */ (0,
|
|
2366
|
+
showDistort && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: "ml-1 flex items-center gap-1", role: "group", "aria-label": "Distort", children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
2247
2367
|
"button",
|
|
2248
2368
|
{
|
|
2249
2369
|
type: "button",
|
|
2250
2370
|
"data-vector-free-distort": "",
|
|
2251
|
-
className:
|
|
2371
|
+
className: buttonClass13,
|
|
2252
2372
|
"aria-pressed": state.freeDistort,
|
|
2253
2373
|
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)`,
|
|
2254
2374
|
"aria-label": "Free Distort",
|
|
@@ -2256,15 +2376,15 @@ function VectorToolbar({
|
|
|
2256
2376
|
children: "Distort"
|
|
2257
2377
|
}
|
|
2258
2378
|
) }),
|
|
2259
|
-
showBlend && /* @__PURE__ */ (0,
|
|
2260
|
-
showArrange && /* @__PURE__ */ (0,
|
|
2261
|
-
/* @__PURE__ */ (0,
|
|
2262
|
-
/* @__PURE__ */ (0,
|
|
2379
|
+
showBlend && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(VectorBlendControls, { controller }),
|
|
2380
|
+
showArrange && /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_jsx_runtime15.Fragment, { children: [
|
|
2381
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "ml-1 flex items-center gap-1", role: "group", "aria-label": "Combine", children: [
|
|
2382
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
2263
2383
|
"button",
|
|
2264
2384
|
{
|
|
2265
2385
|
type: "button",
|
|
2266
2386
|
"data-vector-live-boolean": "",
|
|
2267
|
-
className:
|
|
2387
|
+
className: buttonClass13,
|
|
2268
2388
|
"aria-pressed": live,
|
|
2269
2389
|
title: "Live booleans: keep the shapes editable",
|
|
2270
2390
|
"aria-label": "Live booleans",
|
|
@@ -2281,12 +2401,12 @@ function VectorToolbar({
|
|
|
2281
2401
|
act("\u25D0", `Make Clipping Mask (${modKeyLabel()}+7)`, () => controller.makeMask("clip"), count < 2),
|
|
2282
2402
|
act("\u25D1", `Release Mask (${modKeyLabel()}+Alt+7)`, () => controller.releaseMask(), !maskSelected)
|
|
2283
2403
|
] }),
|
|
2284
|
-
/* @__PURE__ */ (0,
|
|
2404
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: "ml-1 flex items-center gap-1", role: "group", "aria-label": "Pathfinder", children: import_vector15.VECTOR_PATHFINDER_ACTIONS.map((a) => /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
2285
2405
|
"button",
|
|
2286
2406
|
{
|
|
2287
2407
|
type: "button",
|
|
2288
2408
|
"data-vector-pathfinder": a.id,
|
|
2289
|
-
className:
|
|
2409
|
+
className: buttonClass13,
|
|
2290
2410
|
title: a.title,
|
|
2291
2411
|
"aria-label": a.title,
|
|
2292
2412
|
disabled: count < a.min,
|
|
@@ -2295,7 +2415,7 @@ function VectorToolbar({
|
|
|
2295
2415
|
},
|
|
2296
2416
|
a.id
|
|
2297
2417
|
)) }),
|
|
2298
|
-
/* @__PURE__ */ (0,
|
|
2418
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "ml-1 flex items-center gap-1", role: "group", "aria-label": "Arrange", children: [
|
|
2299
2419
|
act("\u21C8", "Bring to Front", () => controller.arrange("front"), count < 1),
|
|
2300
2420
|
act("\u21CA", "Send to Back", () => controller.arrange("back"), count < 1),
|
|
2301
2421
|
act("\u21E4", "Align Left", () => controller.align("left"), count < 1),
|
|
@@ -2310,22 +2430,22 @@ function VectorToolbar({
|
|
|
2310
2430
|
}
|
|
2311
2431
|
function VectorBlendControls({ controller }) {
|
|
2312
2432
|
const state = useVectorEditorState(controller);
|
|
2313
|
-
const blend = (0,
|
|
2433
|
+
const blend = (0, import_vector15.getVectorBlendControls)(state);
|
|
2314
2434
|
const o = blend.options;
|
|
2315
2435
|
const selected = blend.ids.length > 0;
|
|
2316
|
-
return /* @__PURE__ */ (0,
|
|
2317
|
-
/* @__PURE__ */ (0,
|
|
2318
|
-
/* @__PURE__ */ (0,
|
|
2436
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "ml-1 flex items-center gap-1", role: "group", "aria-label": "Blend", "data-vector-blend-controls": "", children: [
|
|
2437
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)("button", { type: "button", "data-vector-blend-action": "make", className: buttonClass13, title: "Make Blend", "aria-label": "Make Blend", disabled: !blend.canBlend, onClick: () => controller.blend(), children: "\u29D3" }),
|
|
2438
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
2319
2439
|
"select",
|
|
2320
2440
|
{
|
|
2321
2441
|
"aria-label": "Blend spacing",
|
|
2322
2442
|
className: "h-7 rounded border border-border bg-background px-1 text-xs",
|
|
2323
2443
|
value: o.spacing,
|
|
2324
|
-
onChange: (e) => (0,
|
|
2325
|
-
children:
|
|
2444
|
+
onChange: (e) => (0, import_vector15.applyVectorBlendOptions)(controller, { spacing: e.target.value }),
|
|
2445
|
+
children: import_vector15.VECTOR_BLEND_SPACINGS.map((sp) => /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("option", { value: sp, children: import_vector15.VECTOR_BLEND_SPACING_LABELS[sp] }, sp))
|
|
2326
2446
|
}
|
|
2327
2447
|
),
|
|
2328
|
-
o.spacing !== "smoothColor" && /* @__PURE__ */ (0,
|
|
2448
|
+
o.spacing !== "smoothColor" && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
2329
2449
|
"input",
|
|
2330
2450
|
{
|
|
2331
2451
|
type: "number",
|
|
@@ -2337,29 +2457,29 @@ function VectorBlendControls({ controller }) {
|
|
|
2337
2457
|
onChange: (e) => {
|
|
2338
2458
|
const n = parseFloat(e.target.value);
|
|
2339
2459
|
if (!Number.isFinite(n) || n <= 0) return;
|
|
2340
|
-
(0,
|
|
2460
|
+
(0, import_vector15.applyVectorBlendOptions)(controller, o.spacing === "steps" ? { steps: n } : { distance: n });
|
|
2341
2461
|
}
|
|
2342
2462
|
}
|
|
2343
2463
|
),
|
|
2344
|
-
/* @__PURE__ */ (0,
|
|
2464
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
2345
2465
|
"button",
|
|
2346
2466
|
{
|
|
2347
2467
|
type: "button",
|
|
2348
2468
|
"data-vector-blend-action": "orient",
|
|
2349
|
-
className:
|
|
2469
|
+
className: buttonClass13,
|
|
2350
2470
|
"aria-pressed": o.orientToSpine,
|
|
2351
2471
|
title: "Orient steps to the spine",
|
|
2352
2472
|
"aria-label": "Orient to spine",
|
|
2353
|
-
onClick: () => (0,
|
|
2473
|
+
onClick: () => (0, import_vector15.applyVectorBlendOptions)(controller, { orientToSpine: !o.orientToSpine }),
|
|
2354
2474
|
children: "\u293F"
|
|
2355
2475
|
}
|
|
2356
2476
|
),
|
|
2357
|
-
/* @__PURE__ */ (0,
|
|
2477
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
2358
2478
|
"button",
|
|
2359
2479
|
{
|
|
2360
2480
|
type: "button",
|
|
2361
2481
|
"data-vector-blend-action": "spine",
|
|
2362
|
-
className:
|
|
2482
|
+
className: buttonClass13,
|
|
2363
2483
|
title: "Replace Spine (select a blend and a path)",
|
|
2364
2484
|
"aria-label": "Replace Spine",
|
|
2365
2485
|
disabled: !blend.canReplaceSpine,
|
|
@@ -2367,15 +2487,15 @@ function VectorBlendControls({ controller }) {
|
|
|
2367
2487
|
children: "\u2307"
|
|
2368
2488
|
}
|
|
2369
2489
|
),
|
|
2370
|
-
/* @__PURE__ */ (0,
|
|
2371
|
-
/* @__PURE__ */ (0,
|
|
2490
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)("button", { type: "button", "data-vector-blend-action": "expand", className: buttonClass13, title: "Expand Blend", "aria-label": "Expand Blend", disabled: !selected, onClick: () => controller.expandBlend(), children: "\u29C9" }),
|
|
2491
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)("button", { type: "button", "data-vector-blend-action": "release", className: buttonClass13, title: "Release Blend", "aria-label": "Release Blend", disabled: !selected, onClick: () => controller.releaseBlend(), children: "\u29C4" })
|
|
2372
2492
|
] });
|
|
2373
2493
|
}
|
|
2374
|
-
var
|
|
2375
|
-
var
|
|
2494
|
+
var selectClass10 = "h-7 min-w-0 flex-1 rounded border border-border bg-background px-1 text-xs";
|
|
2495
|
+
var numberClass9 = "h-7 w-16 rounded border border-border bg-background px-1.5 text-xs";
|
|
2376
2496
|
function VectorStylePanel({ controller, className }) {
|
|
2377
2497
|
const state = useVectorEditorState(controller);
|
|
2378
|
-
const style = (0,
|
|
2498
|
+
const style = (0, import_vector15.getVectorSelectionStyle)(state);
|
|
2379
2499
|
const d = state.defaults;
|
|
2380
2500
|
const source = style ?? {
|
|
2381
2501
|
fill: d.fill ?? null,
|
|
@@ -2388,7 +2508,7 @@ function VectorStylePanel({ controller, className }) {
|
|
|
2388
2508
|
arrowAlign: d.arrowAlign ?? "extend",
|
|
2389
2509
|
startArrowScale: d.startArrowScale ?? 1,
|
|
2390
2510
|
endArrowScale: d.endArrowScale ?? 1,
|
|
2391
|
-
widthProfile: (0,
|
|
2511
|
+
widthProfile: (0, import_vector15.widthProfilePresetId)(d.strokeWidthProfile),
|
|
2392
2512
|
cornerRadius: d.cornerRadius,
|
|
2393
2513
|
cornerKind: d.cornerKind ?? "round",
|
|
2394
2514
|
cornerSmoothing: 0,
|
|
@@ -2402,19 +2522,19 @@ function VectorStylePanel({ controller, className }) {
|
|
|
2402
2522
|
};
|
|
2403
2523
|
const setProfile = (id) => {
|
|
2404
2524
|
if (style) controller.setWidthProfile(id);
|
|
2405
|
-
else controller.setDefaults({ strokeWidthProfile: (0,
|
|
2525
|
+
else controller.setDefaults({ strokeWidthProfile: (0, import_vector15.widthProfilePreset)(id)?.length ? (0, import_vector15.widthProfilePreset)(id) : null });
|
|
2406
2526
|
};
|
|
2407
|
-
const mixed = (key) => style?.mixed[key] ? /* @__PURE__ */ (0,
|
|
2527
|
+
const mixed = (key) => style?.mixed[key] ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "text-[11px] text-muted-foreground", children: "Mixed" }) : null;
|
|
2408
2528
|
const arrowRow = (end, label) => {
|
|
2409
2529
|
const key = end === "start" ? "startArrow" : "endArrow";
|
|
2410
2530
|
const scaleKey = end === "start" ? "startArrowScale" : "endArrowScale";
|
|
2411
|
-
return /* @__PURE__ */ (0,
|
|
2412
|
-
/* @__PURE__ */ (0,
|
|
2413
|
-
/* @__PURE__ */ (0,
|
|
2414
|
-
/* @__PURE__ */ (0,
|
|
2415
|
-
|
|
2531
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "flex items-center gap-2", "data-vector-style": key, children: [
|
|
2532
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "w-16 text-xs text-foreground", children: label }),
|
|
2533
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("select", { "aria-label": `${label} arrowhead`, className: selectClass10, value: source[key] ?? "", onChange: (e) => apply({ [key]: e.target.value || null }), children: [
|
|
2534
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)("option", { value: "", children: "None" }),
|
|
2535
|
+
import_vector15.VECTOR_ARROWHEADS.map((h) => /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("option", { value: h, children: import_vector15.VECTOR_ARROWHEAD_LABELS[h] }, h))
|
|
2416
2536
|
] }),
|
|
2417
|
-
/* @__PURE__ */ (0,
|
|
2537
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
2418
2538
|
"input",
|
|
2419
2539
|
{
|
|
2420
2540
|
type: "number",
|
|
@@ -2422,7 +2542,7 @@ function VectorStylePanel({ controller, className }) {
|
|
|
2422
2542
|
step: 0.25,
|
|
2423
2543
|
"aria-label": `${label} arrowhead scale`,
|
|
2424
2544
|
title: "Scale (\xD7 stroke width)",
|
|
2425
|
-
className:
|
|
2545
|
+
className: numberClass9,
|
|
2426
2546
|
value: source[scaleKey],
|
|
2427
2547
|
onChange: (e) => {
|
|
2428
2548
|
const n = parseFloat(e.target.value);
|
|
@@ -2438,14 +2558,14 @@ function VectorStylePanel({ controller, className }) {
|
|
|
2438
2558
|
};
|
|
2439
2559
|
const paintRow = (key, label) => {
|
|
2440
2560
|
const paint = source[key];
|
|
2441
|
-
const hex = (0,
|
|
2561
|
+
const hex = (0, import_vector15.vectorPaintToHex)(paint);
|
|
2442
2562
|
const on = paint !== null && paint !== "none";
|
|
2443
|
-
return /* @__PURE__ */ (0,
|
|
2444
|
-
/* @__PURE__ */ (0,
|
|
2445
|
-
/* @__PURE__ */ (0,
|
|
2563
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "flex items-center gap-2", "data-vector-style": key, children: [
|
|
2564
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("label", { className: "flex w-16 items-center gap-1.5 text-xs text-foreground", children: [
|
|
2565
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)("input", { type: "checkbox", checked: on, "aria-label": `${label} on`, onChange: (e) => apply({ [key]: e.target.checked ? hex ?? "#000000" : null }) }),
|
|
2446
2566
|
label
|
|
2447
2567
|
] }),
|
|
2448
|
-
/* @__PURE__ */ (0,
|
|
2568
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
2449
2569
|
"input",
|
|
2450
2570
|
{
|
|
2451
2571
|
type: "color",
|
|
@@ -2456,18 +2576,18 @@ function VectorStylePanel({ controller, className }) {
|
|
|
2456
2576
|
onChange: (e) => apply({ [key]: e.target.value })
|
|
2457
2577
|
}
|
|
2458
2578
|
),
|
|
2459
|
-
on && !hex && /* @__PURE__ */ (0,
|
|
2460
|
-
style?.mixed[key] && /* @__PURE__ */ (0,
|
|
2579
|
+
on && !hex && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "truncate text-[11px] text-muted-foreground", children: typeof paint === "string" ? paint : "Gradient" }),
|
|
2580
|
+
style?.mixed[key] && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "text-[11px] text-muted-foreground", children: "Mixed" })
|
|
2461
2581
|
] });
|
|
2462
2582
|
};
|
|
2463
|
-
return /* @__PURE__ */ (0,
|
|
2464
|
-
/* @__PURE__ */ (0,
|
|
2583
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: `space-y-2 ${className ?? ""}`, "aria-label": style ? "Selection style" : "New shape style", children: [
|
|
2584
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)("p", { className: "text-[11px] font-medium uppercase tracking-wide text-muted-foreground", children: style ? "Selection" : "New shapes" }),
|
|
2465
2585
|
paintRow("fill", "Fill"),
|
|
2466
2586
|
paintRow("stroke", "Stroke"),
|
|
2467
|
-
style && /* @__PURE__ */ (0,
|
|
2468
|
-
/* @__PURE__ */ (0,
|
|
2469
|
-
/* @__PURE__ */ (0,
|
|
2470
|
-
/* @__PURE__ */ (0,
|
|
2587
|
+
style && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(VectorGradientEditor, { controller }),
|
|
2588
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("label", { className: "flex items-center gap-2 text-xs text-foreground", children: [
|
|
2589
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "w-16", children: "Width" }),
|
|
2590
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
2471
2591
|
"input",
|
|
2472
2592
|
{
|
|
2473
2593
|
type: "number",
|
|
@@ -2483,33 +2603,33 @@ function VectorStylePanel({ controller, className }) {
|
|
|
2483
2603
|
}
|
|
2484
2604
|
)
|
|
2485
2605
|
] }),
|
|
2486
|
-
/* @__PURE__ */ (0,
|
|
2487
|
-
/* @__PURE__ */ (0,
|
|
2488
|
-
/* @__PURE__ */ (0,
|
|
2606
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("label", { className: "flex items-center gap-2 text-xs text-foreground", "data-vector-style": "strokeAlign", children: [
|
|
2607
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "w-16", children: "Align" }),
|
|
2608
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)("select", { "aria-label": "Stroke alignment", className: selectClass10, value: source.strokeAlign, onChange: (e) => apply({ strokeAlign: e.target.value }), children: Object.keys(import_vector15.VECTOR_STROKE_ALIGN_LABELS).map((a) => /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("option", { value: a, children: import_vector15.VECTOR_STROKE_ALIGN_LABELS[a] }, a)) }),
|
|
2489
2609
|
mixed("strokeAlign")
|
|
2490
2610
|
] }),
|
|
2491
|
-
/* @__PURE__ */ (0,
|
|
2492
|
-
/* @__PURE__ */ (0,
|
|
2493
|
-
/* @__PURE__ */ (0,
|
|
2611
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "flex items-center gap-2 text-xs text-foreground", "data-vector-style": "widthProfile", children: [
|
|
2612
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "w-16", children: "Profile" }),
|
|
2613
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
|
|
2494
2614
|
"select",
|
|
2495
2615
|
{
|
|
2496
2616
|
"aria-label": "Width profile",
|
|
2497
|
-
className:
|
|
2617
|
+
className: selectClass10,
|
|
2498
2618
|
value: source.widthProfile,
|
|
2499
2619
|
onChange: (e) => {
|
|
2500
2620
|
if (e.target.value !== "custom") setProfile(e.target.value);
|
|
2501
2621
|
},
|
|
2502
2622
|
children: [
|
|
2503
|
-
|
|
2504
|
-
source.widthProfile === "custom" && /* @__PURE__ */ (0,
|
|
2623
|
+
import_vector15.VECTOR_WIDTH_PRESETS.map((p) => /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("option", { value: p.id, children: p.label }, p.id)),
|
|
2624
|
+
source.widthProfile === "custom" && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("option", { value: "custom", disabled: true, children: "Custom" })
|
|
2505
2625
|
]
|
|
2506
2626
|
}
|
|
2507
2627
|
),
|
|
2508
|
-
/* @__PURE__ */ (0,
|
|
2628
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
2509
2629
|
"button",
|
|
2510
2630
|
{
|
|
2511
2631
|
type: "button",
|
|
2512
|
-
className:
|
|
2632
|
+
className: buttonClass13,
|
|
2513
2633
|
title: "Reset to uniform width",
|
|
2514
2634
|
"aria-label": "Reset to uniform width",
|
|
2515
2635
|
disabled: source.widthProfile === "uniform" && !style?.mixed.widthProfile,
|
|
@@ -2519,27 +2639,27 @@ function VectorStylePanel({ controller, className }) {
|
|
|
2519
2639
|
),
|
|
2520
2640
|
mixed("widthProfile")
|
|
2521
2641
|
] }),
|
|
2522
|
-
source.hasOpenPath && /* @__PURE__ */ (0,
|
|
2642
|
+
source.hasOpenPath && /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_jsx_runtime15.Fragment, { children: [
|
|
2523
2643
|
arrowRow("start", "Start"),
|
|
2524
2644
|
arrowRow("end", "End"),
|
|
2525
|
-
(source.startArrow || source.endArrow) && /* @__PURE__ */ (0,
|
|
2526
|
-
/* @__PURE__ */ (0,
|
|
2527
|
-
/* @__PURE__ */ (0,
|
|
2528
|
-
/* @__PURE__ */ (0,
|
|
2529
|
-
/* @__PURE__ */ (0,
|
|
2645
|
+
(source.startArrow || source.endArrow) && /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("label", { className: "flex items-center gap-2 text-xs text-foreground", "data-vector-style": "arrowAlign", children: [
|
|
2646
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "w-16", children: "Heads" }),
|
|
2647
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("select", { "aria-label": "Arrowhead alignment", className: selectClass10, value: source.arrowAlign, onChange: (e) => apply({ arrowAlign: e.target.value }), children: [
|
|
2648
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)("option", { value: "extend", children: "Tip past end" }),
|
|
2649
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)("option", { value: "tip", children: "Tip at end" })
|
|
2530
2650
|
] })
|
|
2531
2651
|
] })
|
|
2532
2652
|
] }),
|
|
2533
|
-
source.corners > 0 && /* @__PURE__ */ (0,
|
|
2534
|
-
/* @__PURE__ */ (0,
|
|
2535
|
-
/* @__PURE__ */ (0,
|
|
2653
|
+
source.corners > 0 && /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "flex items-center gap-2", "data-vector-style": "corners", children: [
|
|
2654
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "w-16 text-xs text-foreground", children: "Corners" }),
|
|
2655
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
2536
2656
|
"input",
|
|
2537
2657
|
{
|
|
2538
2658
|
type: "number",
|
|
2539
2659
|
min: 0,
|
|
2540
2660
|
step: 1,
|
|
2541
2661
|
"aria-label": "Corner radius",
|
|
2542
|
-
className:
|
|
2662
|
+
className: numberClass9,
|
|
2543
2663
|
value: Math.round(source.cornerRadius * 100) / 100,
|
|
2544
2664
|
onChange: (e) => {
|
|
2545
2665
|
const n = parseFloat(e.target.value);
|
|
@@ -2547,12 +2667,12 @@ function VectorStylePanel({ controller, className }) {
|
|
|
2547
2667
|
}
|
|
2548
2668
|
}
|
|
2549
2669
|
),
|
|
2550
|
-
/* @__PURE__ */ (0,
|
|
2670
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)("select", { "aria-label": "Corner kind", className: selectClass10, value: source.cornerKind, onChange: (e) => setCorners({ kind: e.target.value }), children: import_vector15.VECTOR_CORNER_KINDS.map((k) => /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("option", { value: k, children: import_vector15.VECTOR_CORNER_KIND_LABELS[k] }, k)) }),
|
|
2551
2671
|
mixed("cornerRadius")
|
|
2552
2672
|
] }),
|
|
2553
|
-
style && source.corners > 0 && source.cornerKind === "round" && source.cornerRadius > 0 && /* @__PURE__ */ (0,
|
|
2554
|
-
/* @__PURE__ */ (0,
|
|
2555
|
-
/* @__PURE__ */ (0,
|
|
2673
|
+
style && source.corners > 0 && source.cornerKind === "round" && source.cornerRadius > 0 && /* @__PURE__ */ (0, import_jsx_runtime15.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: [
|
|
2674
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "w-16", children: "Smoothing" }),
|
|
2675
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
2556
2676
|
"input",
|
|
2557
2677
|
{
|
|
2558
2678
|
type: "range",
|
|
@@ -2567,9 +2687,9 @@ function VectorStylePanel({ controller, className }) {
|
|
|
2567
2687
|
}
|
|
2568
2688
|
)
|
|
2569
2689
|
] }),
|
|
2570
|
-
style && /* @__PURE__ */ (0,
|
|
2571
|
-
/* @__PURE__ */ (0,
|
|
2572
|
-
/* @__PURE__ */ (0,
|
|
2690
|
+
style && /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("label", { className: "flex items-center gap-2 text-xs text-foreground", children: [
|
|
2691
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "w-16", children: "Opacity" }),
|
|
2692
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
2573
2693
|
"input",
|
|
2574
2694
|
{
|
|
2575
2695
|
type: "range",
|
|
@@ -2583,26 +2703,28 @@ function VectorStylePanel({ controller, className }) {
|
|
|
2583
2703
|
}
|
|
2584
2704
|
)
|
|
2585
2705
|
] }),
|
|
2586
|
-
/* @__PURE__ */ (0,
|
|
2587
|
-
style && /* @__PURE__ */ (0,
|
|
2588
|
-
style && /* @__PURE__ */ (0,
|
|
2589
|
-
style && /* @__PURE__ */ (0,
|
|
2590
|
-
style && /* @__PURE__ */ (0,
|
|
2591
|
-
/* @__PURE__ */ (0,
|
|
2592
|
-
/* @__PURE__ */ (0,
|
|
2593
|
-
/* @__PURE__ */ (0,
|
|
2594
|
-
/* @__PURE__ */ (0,
|
|
2706
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(VectorTextPanel, { controller }),
|
|
2707
|
+
style && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(VectorAppearancePanel, { controller }),
|
|
2708
|
+
style && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(VectorEffectsPanel, { controller }),
|
|
2709
|
+
style && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(VectorEnvelopePanel, { controller }),
|
|
2710
|
+
style && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(VectorMaskPanel, { controller }),
|
|
2711
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(VectorFramePanel, { controller }),
|
|
2712
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(VectorConnectorPanel, { controller }),
|
|
2713
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(VectorShadingPanel, { controller }),
|
|
2714
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(VectorTracePanel, { controller }),
|
|
2715
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(VectorConstraintsPanel, { controller }),
|
|
2716
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(VectorSymbolsPanel, { controller })
|
|
2595
2717
|
] });
|
|
2596
2718
|
}
|
|
2597
2719
|
|
|
2598
2720
|
// src/vector/VectorEditor.tsx
|
|
2599
|
-
var
|
|
2721
|
+
var import_jsx_runtime16 = require("react/jsx-runtime");
|
|
2600
2722
|
function VectorEditor({ controller, tools, showStylePanel = true, height = 520, canvasProps, className }) {
|
|
2601
|
-
return /* @__PURE__ */ (0,
|
|
2602
|
-
/* @__PURE__ */ (0,
|
|
2603
|
-
/* @__PURE__ */ (0,
|
|
2604
|
-
/* @__PURE__ */ (0,
|
|
2605
|
-
showStylePanel && /* @__PURE__ */ (0,
|
|
2723
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: `flex flex-col gap-2 ${className ?? ""}`, "data-vector-editor": "", children: [
|
|
2724
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(VectorToolbar, { controller, tools }),
|
|
2725
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "flex min-h-0 flex-col gap-2 md:flex-row", children: [
|
|
2726
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.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_runtime16.jsx)(VectorCanvas, { controller, ...canvasProps }) }),
|
|
2727
|
+
showStylePanel && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(VectorStylePanel, { controller, className: "w-full shrink-0 rounded-md border border-border p-3 md:w-56" })
|
|
2606
2728
|
] })
|
|
2607
2729
|
] });
|
|
2608
2730
|
}
|
|
@@ -2623,11 +2745,13 @@ function VectorEditor({ controller, tools, showStylePanel = true, height = 520,
|
|
|
2623
2745
|
VectorMaskPanel,
|
|
2624
2746
|
VectorMaskedNodes,
|
|
2625
2747
|
VectorSceneNodes,
|
|
2748
|
+
VectorShadingPanel,
|
|
2626
2749
|
VectorStylePanel,
|
|
2627
2750
|
VectorSymbolsPanel,
|
|
2628
2751
|
VectorTextElement,
|
|
2629
2752
|
VectorTextPanel,
|
|
2630
2753
|
VectorToolbar,
|
|
2754
|
+
VectorTracePanel,
|
|
2631
2755
|
VectorWidthPointEditor,
|
|
2632
2756
|
useVectorCommands,
|
|
2633
2757
|
useVectorEditor,
|