@pixerate/editor-react 0.85.0 → 0.87.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-VKWTKESA.js → chunk-4FQXRPBN.js} +12 -1
- package/dist/chunk-4FQXRPBN.js.map +1 -0
- package/dist/image-editor/index.cjs +8 -0
- package/dist/image-editor/index.cjs.map +1 -1
- package/dist/image-editor/index.js +1 -1
- package/dist/index.cjs +8 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +1 -1
- package/dist/vector/index.cjs +131 -47
- package/dist/vector/index.cjs.map +1 -1
- package/dist/vector/index.d.cts +25 -4
- package/dist/vector/index.d.ts +25 -4
- package/dist/vector/index.js +88 -4
- package/dist/vector/index.js.map +1 -1
- package/package.json +3 -3
- package/dist/chunk-VKWTKESA.js.map +0 -1
package/dist/index.js
CHANGED
package/dist/vector/index.cjs
CHANGED
|
@@ -39,6 +39,7 @@ __export(vector_exports, {
|
|
|
39
39
|
VectorEnvelopePanel: () => VectorEnvelopePanel,
|
|
40
40
|
VectorFilterDefs: () => VectorFilterDefs,
|
|
41
41
|
VectorFramePanel: () => VectorFramePanel,
|
|
42
|
+
VectorGeneratePanel: () => VectorGeneratePanel,
|
|
42
43
|
VectorGradientAnnotator: () => VectorGradientAnnotator,
|
|
43
44
|
VectorGradientDefs: () => VectorGradientDefs,
|
|
44
45
|
VectorGradientEditor: () => VectorGradientEditor,
|
|
@@ -62,7 +63,8 @@ __export(vector_exports, {
|
|
|
62
63
|
useVectorEditor: () => useVectorEditor,
|
|
63
64
|
useVectorEditorController: () => useVectorEditorController,
|
|
64
65
|
useVectorEditorState: () => useVectorEditorState,
|
|
65
|
-
useVectorEffectsTools: () => useVectorEffectsTools
|
|
66
|
+
useVectorEffectsTools: () => useVectorEffectsTools,
|
|
67
|
+
useVectorGenerationTools: () => useVectorGenerationTools
|
|
66
68
|
});
|
|
67
69
|
module.exports = __toCommonJS(vector_exports);
|
|
68
70
|
|
|
@@ -114,6 +116,30 @@ function useVectorEffectsTools(registry, controller, options = {}) {
|
|
|
114
116
|
return registry.register((0, import_vector.createVectorEffectsToolProvider)(controller, { id, namespace, readOnly }));
|
|
115
117
|
}, [registry, controller, id, namespace, readOnly]);
|
|
116
118
|
}
|
|
119
|
+
function useVectorGenerationTools(registry, controller, options) {
|
|
120
|
+
const latest = (0, import_react.useRef)(options);
|
|
121
|
+
latest.current = options;
|
|
122
|
+
const { id, namespace } = options;
|
|
123
|
+
(0, import_react.useEffect)(() => {
|
|
124
|
+
if (!registry) return;
|
|
125
|
+
const models = () => {
|
|
126
|
+
const m = latest.current.models;
|
|
127
|
+
return typeof m === "function" ? m() : m;
|
|
128
|
+
};
|
|
129
|
+
return registry.register(
|
|
130
|
+
(0, import_vector.createVectorGenerationToolProvider)(controller, {
|
|
131
|
+
id,
|
|
132
|
+
namespace,
|
|
133
|
+
models,
|
|
134
|
+
generate: (request, context) => latest.current.generate(request, context),
|
|
135
|
+
readOnly: () => {
|
|
136
|
+
const r = latest.current.readOnly;
|
|
137
|
+
return (typeof r === "function" ? r() : r) ?? false;
|
|
138
|
+
}
|
|
139
|
+
})
|
|
140
|
+
);
|
|
141
|
+
}, [registry, controller, id, namespace]);
|
|
142
|
+
}
|
|
117
143
|
|
|
118
144
|
// src/vector/VectorCanvas.tsx
|
|
119
145
|
var import_react3 = __toESM(require("react"), 1);
|
|
@@ -658,6 +684,7 @@ function VectorCanvas({
|
|
|
658
684
|
overlay.builder.lines.map((d, i) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { "data-vector-builder-line": "", d, fill: "none", stroke: import_vector3.VECTOR_OVERLAY_THEME.builderErase, strokeWidth: 3, strokeLinecap: "round" }, `l${i}`)),
|
|
659
685
|
overlay.builder.trail && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { "data-vector-builder-trail": "", d: overlay.builder.trail, fill: "none", stroke: overlay.builder.mode === "erase" ? import_vector3.VECTOR_OVERLAY_THEME.builderErase : accentColor, strokeWidth: 1 })
|
|
660
686
|
] }),
|
|
687
|
+
overlay.brush && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("circle", { "data-vector-brush": "", cx: overlay.brush.x, cy: overlay.brush.y, r: overlay.brush.r, fill: "none", stroke: accentColor, strokeWidth: 1, strokeDasharray: "4 3", pointerEvents: "none" }),
|
|
661
688
|
overlay.toolStroke && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
662
689
|
"path",
|
|
663
690
|
{
|
|
@@ -838,7 +865,7 @@ function VectorCanvas({
|
|
|
838
865
|
|
|
839
866
|
// src/vector/VectorToolbar.tsx
|
|
840
867
|
var import_react11 = __toESM(require("react"), 1);
|
|
841
|
-
var
|
|
868
|
+
var import_vector20 = require("@pixerate/editor/vector");
|
|
842
869
|
|
|
843
870
|
// src/vector/VectorEffectsPanel.tsx
|
|
844
871
|
var import_vector4 = require("@pixerate/editor/vector");
|
|
@@ -2021,6 +2048,7 @@ function VectorShadingPanel({ controller, className }) {
|
|
|
2021
2048
|
|
|
2022
2049
|
// src/vector/VectorTracePanel.tsx
|
|
2023
2050
|
var import_react9 = require("react");
|
|
2051
|
+
var import_vector15 = require("@pixerate/editor/vector");
|
|
2024
2052
|
var import_jsx_runtime14 = require("react/jsx-runtime");
|
|
2025
2053
|
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";
|
|
2026
2054
|
var selectClass9 = "h-7 min-w-0 flex-1 rounded border border-border bg-background px-1 text-xs";
|
|
@@ -2047,7 +2075,8 @@ function VectorTracePanel({ controller, className }) {
|
|
|
2047
2075
|
const pixels = await filePixels(file);
|
|
2048
2076
|
const doc = controller.getState().document;
|
|
2049
2077
|
const width = Math.min(doc.width, pixels.width);
|
|
2050
|
-
const
|
|
2078
|
+
const name = file.name.replace(/\.[^.]+$/, "") || void 0;
|
|
2079
|
+
const r = mode === "threshold" || mode === "color" ? controller.traceImage(pixels, { mode, colors, width, name: name ?? "Image Trace" }) : controller.stylizeImage(pixels, mode, { width, ...name ? { name } : {} });
|
|
2051
2080
|
setMessage(r.ok ? null : r.message);
|
|
2052
2081
|
} catch {
|
|
2053
2082
|
setMessage("That file could not be read as an image.");
|
|
@@ -2058,7 +2087,8 @@ function VectorTracePanel({ controller, className }) {
|
|
|
2058
2087
|
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "w-16 text-[11px] font-medium uppercase tracking-wide text-muted-foreground", children: "Trace" }),
|
|
2059
2088
|
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("select", { "aria-label": "Trace mode", className: selectClass9, value: mode, onChange: (e) => setMode(e.target.value), children: [
|
|
2060
2089
|
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("option", { value: "threshold", children: "Black & white" }),
|
|
2061
|
-
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("option", { value: "color", children: "Colours" })
|
|
2090
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("option", { value: "color", children: "Colours" }),
|
|
2091
|
+
import_vector15.VECTOR_STYLIZE_STYLES.map((s) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("option", { value: s, children: import_vector15.VECTOR_STYLIZE_LABELS[s] }, s))
|
|
2062
2092
|
] }),
|
|
2063
2093
|
mode === "color" && /* @__PURE__ */ (0, import_jsx_runtime14.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))) }),
|
|
2064
2094
|
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("button", { type: "button", className: buttonClass12, "data-vector-trace-action": "", title: "Image Trace: pick an image to turn into paths", onClick: () => input.current?.click(), children: "Image\u2026" }),
|
|
@@ -2082,14 +2112,14 @@ function VectorTracePanel({ controller, className }) {
|
|
|
2082
2112
|
}
|
|
2083
2113
|
|
|
2084
2114
|
// src/vector/VectorSymmetryPanel.tsx
|
|
2085
|
-
var
|
|
2115
|
+
var import_vector16 = require("@pixerate/editor/vector");
|
|
2086
2116
|
var import_jsx_runtime15 = require("react/jsx-runtime");
|
|
2087
2117
|
var buttonClass13 = "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";
|
|
2088
2118
|
var selectClass10 = "h-7 min-w-0 flex-1 rounded border border-border bg-background px-1 text-xs";
|
|
2089
2119
|
var numberClass8 = "h-7 w-12 rounded border border-border bg-background px-1.5 text-xs";
|
|
2090
2120
|
function VectorSymmetryPanel({ controller, className }) {
|
|
2091
2121
|
const state = useVectorEditorState(controller);
|
|
2092
|
-
const group = state.selection.map((id) => controller.getNode(id)).find(
|
|
2122
|
+
const group = state.selection.map((id) => controller.getNode(id)).find(import_vector16.isVectorSymmetryGroup) ?? null;
|
|
2093
2123
|
const s = group?.symmetry;
|
|
2094
2124
|
const ids = group ? [group.id] : void 0;
|
|
2095
2125
|
const drawing = !!group && state.symmetryTarget === group.id;
|
|
@@ -2099,7 +2129,7 @@ function VectorSymmetryPanel({ controller, className }) {
|
|
|
2099
2129
|
!group && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("button", { type: "button", className: buttonClass13, "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" }),
|
|
2100
2130
|
!group && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("button", { type: "button", className: buttonClass13, "data-vector-symmetry-action": "radial", title: "Make Symmetry: the selection repeated round its centre", onClick: () => controller.makeSymmetry({ mode: "radial", copies: 6 }), children: "Radial" }),
|
|
2101
2131
|
group && s && /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_jsx_runtime15.Fragment, { children: [
|
|
2102
|
-
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)("select", { "aria-label": "Symmetry mode", className: selectClass10, value: s.mode, onChange: (e) => controller.setSymmetry({ mode: e.target.value }, { ids }), children:
|
|
2132
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)("select", { "aria-label": "Symmetry mode", className: selectClass10, value: s.mode, onChange: (e) => controller.setSymmetry({ mode: e.target.value }, { ids }), children: import_vector16.VECTOR_SYMMETRY_MODES.map((m) => /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("option", { value: m, children: import_vector16.VECTOR_SYMMETRY_MODE_LABELS[m] }, m)) }),
|
|
2103
2133
|
s.mode === "radial" && /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_jsx_runtime15.Fragment, { children: [
|
|
2104
2134
|
/* @__PURE__ */ (0, import_jsx_runtime15.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 }) }),
|
|
2105
2135
|
/* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("label", { className: "flex items-center gap-1 text-xs text-foreground", title: "Mirror each copy too (kaleidoscope)", children: [
|
|
@@ -2120,7 +2150,7 @@ function VectorSymmetryPanel({ controller, className }) {
|
|
|
2120
2150
|
|
|
2121
2151
|
// src/vector/VectorPerspectivePanel.tsx
|
|
2122
2152
|
var import_react10 = __toESM(require("react"), 1);
|
|
2123
|
-
var
|
|
2153
|
+
var import_vector17 = require("@pixerate/editor/vector");
|
|
2124
2154
|
var import_jsx_runtime16 = require("react/jsx-runtime");
|
|
2125
2155
|
var buttonClass14 = "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";
|
|
2126
2156
|
var selectClass11 = "h-7 min-w-0 flex-1 rounded border border-border bg-background px-1 text-xs";
|
|
@@ -2128,10 +2158,10 @@ var PLANE_LABELS = { floor: "Floor", left: "Left wall", right: "Right wall", sid
|
|
|
2128
2158
|
function VectorPerspectivePanel({ controller, className }) {
|
|
2129
2159
|
const state = useVectorEditorState(controller);
|
|
2130
2160
|
const grid = state.document.perspective ?? null;
|
|
2131
|
-
const planes = grid ? (0,
|
|
2161
|
+
const planes = grid ? (0, import_vector17.vectorPerspectivePlanes)(grid) : [];
|
|
2132
2162
|
const [attachTo, setAttachTo] = import_react10.default.useState("");
|
|
2133
2163
|
const target = (state.perspectivePlane ?? attachTo) || planes[0];
|
|
2134
|
-
const add = (n) => controller.setPerspective((0,
|
|
2164
|
+
const add = (n) => controller.setPerspective((0, import_vector17.vectorPerspectivePreset)(n, state.document.width, state.document.height));
|
|
2135
2165
|
return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: `space-y-2 ${className ?? ""}`, "data-vector-perspective-panel": "", "aria-label": "Perspective", children: [
|
|
2136
2166
|
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "flex flex-wrap items-center gap-1", children: [
|
|
2137
2167
|
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "w-16 text-[11px] font-medium uppercase tracking-wide text-muted-foreground", children: "Perspective" }),
|
|
@@ -2164,7 +2194,7 @@ function VectorPerspectivePanel({ controller, className }) {
|
|
|
2164
2194
|
}
|
|
2165
2195
|
|
|
2166
2196
|
// src/vector/VectorLensPanel.tsx
|
|
2167
|
-
var
|
|
2197
|
+
var import_vector18 = require("@pixerate/editor/vector");
|
|
2168
2198
|
var import_jsx_runtime17 = require("react/jsx-runtime");
|
|
2169
2199
|
var selectClass12 = "h-7 min-w-0 flex-1 rounded border border-border bg-background px-1 text-xs";
|
|
2170
2200
|
var numberClass9 = "h-7 w-16 rounded border border-border bg-background px-1.5 text-xs";
|
|
@@ -2173,7 +2203,7 @@ function VectorLensPanel({ controller, className }) {
|
|
|
2173
2203
|
const path = state.selection.map((id) => controller.getNode(id)).find((n) => n?.type === "path" && n.subpaths.some((sp) => sp.closed) && !n.connector);
|
|
2174
2204
|
if (!path) return null;
|
|
2175
2205
|
const lens = path.lens ?? null;
|
|
2176
|
-
const spec = lens ?
|
|
2206
|
+
const spec = lens ? import_vector18.VECTOR_LENS_SPECS[lens.type] : null;
|
|
2177
2207
|
const ids = [path.id];
|
|
2178
2208
|
return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: `space-y-2 ${className ?? ""}`, "data-vector-lens-panel": "", "aria-label": "Lens", children: [
|
|
2179
2209
|
/* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "flex flex-wrap items-center gap-1", children: [
|
|
@@ -2187,7 +2217,7 @@ function VectorLensPanel({ controller, className }) {
|
|
|
2187
2217
|
onChange: (e) => e.target.value ? controller.setLens({ type: e.target.value }, { ids }) : controller.setLens(null, { ids }),
|
|
2188
2218
|
children: [
|
|
2189
2219
|
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("option", { value: "", children: "None" }),
|
|
2190
|
-
|
|
2220
|
+
import_vector18.VECTOR_LENS_TYPES.map((t) => /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("option", { value: t, children: import_vector18.VECTOR_LENS_LABELS[t] }, t))
|
|
2191
2221
|
]
|
|
2192
2222
|
}
|
|
2193
2223
|
)
|
|
@@ -2217,7 +2247,7 @@ function VectorLensPanel({ controller, className }) {
|
|
|
2217
2247
|
}
|
|
2218
2248
|
|
|
2219
2249
|
// src/vector/VectorGradientEditor.tsx
|
|
2220
|
-
var
|
|
2250
|
+
var import_vector19 = require("@pixerate/editor/vector");
|
|
2221
2251
|
var import_jsx_runtime18 = require("react/jsx-runtime");
|
|
2222
2252
|
var selectClass13 = "h-7 min-w-0 flex-1 rounded border border-border bg-background px-1 text-xs";
|
|
2223
2253
|
var numberClass10 = "h-7 w-14 rounded border border-border bg-background px-1.5 text-xs";
|
|
@@ -2225,7 +2255,7 @@ var buttonClass15 = "inline-flex h-7 min-w-7 items-center justify-center rounded
|
|
|
2225
2255
|
var percent = (v) => Math.round(v * 1e3) / 10;
|
|
2226
2256
|
function VectorGradientEditor({ controller, className }) {
|
|
2227
2257
|
const state = useVectorEditorState(controller);
|
|
2228
|
-
const ed = (0,
|
|
2258
|
+
const ed = (0, import_vector19.getVectorGradientEditor)(state);
|
|
2229
2259
|
if (!ed) return null;
|
|
2230
2260
|
const g = ed.gradient;
|
|
2231
2261
|
const sel = ed.selected;
|
|
@@ -2233,7 +2263,7 @@ function VectorGradientEditor({ controller, className }) {
|
|
|
2233
2263
|
const setType = (value) => {
|
|
2234
2264
|
if (value === "solid") {
|
|
2235
2265
|
const first = ed.stops[0];
|
|
2236
|
-
controller.setStyle({ [ed.target]: (0,
|
|
2266
|
+
controller.setStyle({ [ed.target]: (0, import_vector19.vectorPaintToHex)(first?.color) ?? first?.color ?? "#000000" }, void 0, { label: "Solid Colour" });
|
|
2237
2267
|
} else controller.setGradient({ type: value });
|
|
2238
2268
|
};
|
|
2239
2269
|
return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: `space-y-1.5 ${className ?? ""}`, "data-vector-gradient-editor": ed.target, "aria-label": "Gradient", children: [
|
|
@@ -2246,7 +2276,7 @@ function VectorGradientEditor({ controller, className }) {
|
|
|
2246
2276
|
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { className: "w-16 text-xs text-foreground", children: "Type" }),
|
|
2247
2277
|
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("select", { "aria-label": "Gradient type", className: selectClass13, value: ed.type ?? "solid", onChange: (e) => setType(e.target.value), children: [
|
|
2248
2278
|
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("option", { value: "solid", children: "Solid" }),
|
|
2249
|
-
|
|
2279
|
+
import_vector19.VECTOR_GRADIENT_TYPES.map((t) => /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("option", { value: t, children: import_vector19.VECTOR_GRADIENT_TYPE_LABELS[t] }, t))
|
|
2250
2280
|
] }),
|
|
2251
2281
|
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("button", { type: "button", className: buttonClass15, "aria-label": "Reverse gradient", title: "Reverse gradient", disabled: !g, onClick: () => controller.reverseGradient(), children: "\u21C4" })
|
|
2252
2282
|
] }),
|
|
@@ -2287,7 +2317,7 @@ function VectorGradientEditor({ controller, className }) {
|
|
|
2287
2317
|
type: "color",
|
|
2288
2318
|
"aria-label": "Stop colour",
|
|
2289
2319
|
className: "h-7 w-9 cursor-pointer rounded border border-border bg-background",
|
|
2290
|
-
value: (0,
|
|
2320
|
+
value: (0, import_vector19.vectorPaintToHex)(sel.color) ?? "#000000",
|
|
2291
2321
|
onChange: (e) => controller.setGradientStop(sel.index, { color: e.target.value }, { merge: `gradient-stop-color-${sel.index}` }),
|
|
2292
2322
|
onBlur: end
|
|
2293
2323
|
}
|
|
@@ -2353,7 +2383,7 @@ function VectorGradientEditor({ controller, className }) {
|
|
|
2353
2383
|
] }),
|
|
2354
2384
|
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("label", { className: "flex items-center gap-1.5 text-xs text-foreground", children: [
|
|
2355
2385
|
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { className: "w-16", children: "Colours" }),
|
|
2356
|
-
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("select", { "aria-label": "Gradient interpolation", className: selectClass13, value: ed.interpolation, onChange: (e) => controller.setGradient({ interpolation: e.target.value }), children:
|
|
2386
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("select", { "aria-label": "Gradient interpolation", className: selectClass13, value: ed.interpolation, onChange: (e) => controller.setGradient({ interpolation: e.target.value }), children: import_vector19.VECTOR_GRADIENT_INTERPOLATIONS.map((i) => /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("option", { value: i, children: import_vector19.VECTOR_GRADIENT_INTERPOLATION_LABELS[i] }, i)) })
|
|
2357
2387
|
] }),
|
|
2358
2388
|
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("label", { className: "flex items-center gap-1.5 text-xs text-foreground", children: [
|
|
2359
2389
|
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { className: "w-16", children: "Smooth" }),
|
|
@@ -2375,11 +2405,11 @@ function VectorGradientEditor({ controller, className }) {
|
|
|
2375
2405
|
] }),
|
|
2376
2406
|
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("label", { className: "flex items-center gap-1.5 text-xs text-foreground", children: [
|
|
2377
2407
|
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { className: "w-16", children: "Spread" }),
|
|
2378
|
-
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("select", { "aria-label": "Gradient spread", className: selectClass13, value: ed.spread, onChange: (e) => controller.setGradient({ spread: e.target.value }), children:
|
|
2408
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("select", { "aria-label": "Gradient spread", className: selectClass13, value: ed.spread, onChange: (e) => controller.setGradient({ spread: e.target.value }), children: import_vector19.VECTOR_GRADIENT_SPREADS.map((sp) => /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("option", { value: sp, children: import_vector19.VECTOR_GRADIENT_SPREAD_LABELS[sp] }, sp)) })
|
|
2379
2409
|
] }),
|
|
2380
2410
|
ed.target === "stroke" && /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("label", { className: "flex items-center gap-1.5 text-xs text-foreground", children: [
|
|
2381
2411
|
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { className: "w-16", children: "On stroke" }),
|
|
2382
|
-
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("select", { "aria-label": "Gradient on stroke", className: selectClass13, value: ed.strokeMode, onChange: (e) => controller.setGradient({ strokeMode: e.target.value }), children:
|
|
2412
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("select", { "aria-label": "Gradient on stroke", className: selectClass13, value: ed.strokeMode, onChange: (e) => controller.setGradient({ strokeMode: e.target.value }), children: import_vector19.VECTOR_STROKE_GRADIENT_MODES.map((m) => /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("option", { value: m, children: import_vector19.VECTOR_STROKE_GRADIENT_MODE_LABELS[m] }, m)) })
|
|
2383
2413
|
] })
|
|
2384
2414
|
] })
|
|
2385
2415
|
] });
|
|
@@ -2392,7 +2422,7 @@ var modKeyLabel = () => typeof navigator !== "undefined" && /Mac|iPhone|iPad/.te
|
|
|
2392
2422
|
var buttonClass16 = "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";
|
|
2393
2423
|
function VectorToolbar({
|
|
2394
2424
|
controller,
|
|
2395
|
-
tools =
|
|
2425
|
+
tools = import_vector20.VECTOR_TOOLS,
|
|
2396
2426
|
showHistory = true,
|
|
2397
2427
|
showArrange = true,
|
|
2398
2428
|
showSnap = true,
|
|
@@ -2406,7 +2436,7 @@ function VectorToolbar({
|
|
|
2406
2436
|
const points = state.tool === "direct" ? state.selectedAnchors.length : 0;
|
|
2407
2437
|
const editing = state.editing;
|
|
2408
2438
|
const groupSelected = state.selection.some((id) => controller.getNode(id)?.type === "group");
|
|
2409
|
-
const maskSelected = state.selection.some((id) => (0,
|
|
2439
|
+
const maskSelected = state.selection.some((id) => (0, import_vector20.isVectorMaskGroup)(controller.getNode(id)));
|
|
2410
2440
|
const [live, setLive] = import_react11.default.useState(false);
|
|
2411
2441
|
const booleanDisabled = live ? count < 1 : count < 2;
|
|
2412
2442
|
const act = (label, title, run, disabled = false) => /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("button", { type: "button", className: buttonClass16, title, "aria-label": title, disabled, onClick: () => void run(), children: label }, label);
|
|
@@ -2418,10 +2448,10 @@ function VectorToolbar({
|
|
|
2418
2448
|
"data-vector-tool": tool,
|
|
2419
2449
|
className: buttonClass16,
|
|
2420
2450
|
"aria-pressed": state.tool === tool,
|
|
2421
|
-
title: `${(0,
|
|
2422
|
-
"aria-label": (0,
|
|
2451
|
+
title: `${(0, import_vector20.vectorToolLabel)(tool)} (${import_vector20.VECTOR_TOOL_SHORTCUTS[tool]})`,
|
|
2452
|
+
"aria-label": (0, import_vector20.vectorToolLabel)(tool),
|
|
2423
2453
|
onClick: () => controller.setTool(tool),
|
|
2424
|
-
children:
|
|
2454
|
+
children: import_vector20.VECTOR_TOOL_GLYPHS[tool]
|
|
2425
2455
|
},
|
|
2426
2456
|
tool
|
|
2427
2457
|
)) }),
|
|
@@ -2450,10 +2480,10 @@ function VectorToolbar({
|
|
|
2450
2480
|
"aria-label": "Polar tracking increment",
|
|
2451
2481
|
title: "Polar tracking: the angles drawn points snap to from where they leave",
|
|
2452
2482
|
className: "h-8 rounded-md border border-border bg-background px-1 text-xs",
|
|
2453
|
-
value: String((0,
|
|
2454
|
-
onChange: (e) => controller.setSnap({ angles: (0,
|
|
2483
|
+
value: String((0, import_vector20.vectorPolarIncrementOf)(state.snap.angles) ?? ""),
|
|
2484
|
+
onChange: (e) => controller.setSnap({ angles: (0, import_vector20.vectorPolarAngles)(Number(e.target.value)) }),
|
|
2455
2485
|
children: [
|
|
2456
|
-
(0,
|
|
2486
|
+
(0, import_vector20.vectorPolarIncrementOf)(state.snap.angles) === null && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("option", { value: "", children: "Custom" }),
|
|
2457
2487
|
[90, 45, 30, 15].map((n) => /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("option", { value: n, children: [
|
|
2458
2488
|
n,
|
|
2459
2489
|
"\xB0"
|
|
@@ -2463,7 +2493,7 @@ function VectorToolbar({
|
|
|
2463
2493
|
)
|
|
2464
2494
|
] }),
|
|
2465
2495
|
showPathEdit && /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "ml-1 flex items-center gap-1", role: "group", "aria-label": "Path editing", children: [
|
|
2466
|
-
|
|
2496
|
+
import_vector20.VECTOR_PATH_ACTIONS.map((a) => /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
2467
2497
|
"button",
|
|
2468
2498
|
{
|
|
2469
2499
|
type: "button",
|
|
@@ -2477,7 +2507,7 @@ function VectorToolbar({
|
|
|
2477
2507
|
},
|
|
2478
2508
|
a.id
|
|
2479
2509
|
)),
|
|
2480
|
-
|
|
2510
|
+
import_vector20.VECTOR_EDIT_TOGGLES.map((t) => /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
2481
2511
|
"button",
|
|
2482
2512
|
{
|
|
2483
2513
|
type: "button",
|
|
@@ -2525,6 +2555,20 @@ function VectorToolbar({
|
|
|
2525
2555
|
}
|
|
2526
2556
|
)
|
|
2527
2557
|
] }),
|
|
2558
|
+
state.tool === "distort" && /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("span", { className: "flex flex-wrap items-center gap-1", "data-vector-distort-options": "", children: [
|
|
2559
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("select", { "aria-label": "Distort brush", title: "What the brush does to the outlines it passes over", className: "h-7 rounded border border-border bg-background px-1 text-xs", value: editing.distortMode, onChange: (e) => controller.setEditing({ distortMode: e.target.value }), children: import_vector20.VECTOR_DISTORT_BRUSH_MODES.map((m) => /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("option", { value: m, children: m[0].toUpperCase() + m.slice(1) }, m)) }),
|
|
2560
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("label", { className: "flex items-center gap-1 text-xs text-foreground", children: [
|
|
2561
|
+
"Size",
|
|
2562
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("input", { type: "number", min: 1, step: 1, "aria-label": "Distort brush size", className: "h-7 w-16 rounded border border-border bg-background px-1.5 text-xs", value: editing.distortSize, onChange: (e) => {
|
|
2563
|
+
const n = parseFloat(e.target.value);
|
|
2564
|
+
if (Number.isFinite(n) && n > 0) controller.setEditing({ distortSize: n });
|
|
2565
|
+
} })
|
|
2566
|
+
] }),
|
|
2567
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("label", { className: "flex items-center gap-1 text-xs text-foreground", children: [
|
|
2568
|
+
"Strength",
|
|
2569
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("input", { type: "range", min: 0, max: 1, step: 0.05, "aria-label": "Distort brush strength", className: "h-4 w-20 accent-primary", value: editing.distortStrength, onChange: (e) => controller.setEditing({ distortStrength: parseFloat(e.target.value) }) })
|
|
2570
|
+
] })
|
|
2571
|
+
] }),
|
|
2528
2572
|
state.tool === "paintBucket" && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
2529
2573
|
"button",
|
|
2530
2574
|
{
|
|
@@ -2534,7 +2578,7 @@ function VectorToolbar({
|
|
|
2534
2578
|
"aria-pressed": editing.fillGap > 0,
|
|
2535
2579
|
title: "Close small gaps between path ends when filling",
|
|
2536
2580
|
"aria-label": "Close gaps",
|
|
2537
|
-
onClick: () => controller.setEditing({ fillGap: editing.fillGap > 0 ? 0 :
|
|
2581
|
+
onClick: () => controller.setEditing({ fillGap: editing.fillGap > 0 ? 0 : import_vector20.VECTOR_FILL_GAP }),
|
|
2538
2582
|
children: "Gaps"
|
|
2539
2583
|
}
|
|
2540
2584
|
)
|
|
@@ -2577,7 +2621,7 @@ function VectorToolbar({
|
|
|
2577
2621
|
act("\u25D0", `Make Clipping Mask (${modKeyLabel()}+7)`, () => controller.makeMask("clip"), count < 2),
|
|
2578
2622
|
act("\u25D1", `Release Mask (${modKeyLabel()}+Alt+7)`, () => controller.releaseMask(), !maskSelected)
|
|
2579
2623
|
] }),
|
|
2580
|
-
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { className: "ml-1 flex items-center gap-1", role: "group", "aria-label": "Pathfinder", children:
|
|
2624
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { className: "ml-1 flex items-center gap-1", role: "group", "aria-label": "Pathfinder", children: import_vector20.VECTOR_PATHFINDER_ACTIONS.map((a) => /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
2581
2625
|
"button",
|
|
2582
2626
|
{
|
|
2583
2627
|
type: "button",
|
|
@@ -2606,7 +2650,7 @@ function VectorToolbar({
|
|
|
2606
2650
|
}
|
|
2607
2651
|
function VectorBlendControls({ controller }) {
|
|
2608
2652
|
const state = useVectorEditorState(controller);
|
|
2609
|
-
const blend = (0,
|
|
2653
|
+
const blend = (0, import_vector20.getVectorBlendControls)(state);
|
|
2610
2654
|
const o = blend.options;
|
|
2611
2655
|
const selected = blend.ids.length > 0;
|
|
2612
2656
|
return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "ml-1 flex items-center gap-1", role: "group", "aria-label": "Blend", "data-vector-blend-controls": "", children: [
|
|
@@ -2617,8 +2661,8 @@ function VectorBlendControls({ controller }) {
|
|
|
2617
2661
|
"aria-label": "Blend spacing",
|
|
2618
2662
|
className: "h-7 rounded border border-border bg-background px-1 text-xs",
|
|
2619
2663
|
value: o.spacing,
|
|
2620
|
-
onChange: (e) => (0,
|
|
2621
|
-
children:
|
|
2664
|
+
onChange: (e) => (0, import_vector20.applyVectorBlendOptions)(controller, { spacing: e.target.value }),
|
|
2665
|
+
children: import_vector20.VECTOR_BLEND_SPACINGS.map((sp) => /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("option", { value: sp, children: import_vector20.VECTOR_BLEND_SPACING_LABELS[sp] }, sp))
|
|
2622
2666
|
}
|
|
2623
2667
|
),
|
|
2624
2668
|
o.spacing !== "smoothColor" && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
@@ -2633,7 +2677,7 @@ function VectorBlendControls({ controller }) {
|
|
|
2633
2677
|
onChange: (e) => {
|
|
2634
2678
|
const n = parseFloat(e.target.value);
|
|
2635
2679
|
if (!Number.isFinite(n) || n <= 0) return;
|
|
2636
|
-
(0,
|
|
2680
|
+
(0, import_vector20.applyVectorBlendOptions)(controller, o.spacing === "steps" ? { steps: n } : { distance: n });
|
|
2637
2681
|
}
|
|
2638
2682
|
}
|
|
2639
2683
|
),
|
|
@@ -2646,7 +2690,7 @@ function VectorBlendControls({ controller }) {
|
|
|
2646
2690
|
"aria-pressed": o.orientToSpine,
|
|
2647
2691
|
title: "Orient steps to the spine",
|
|
2648
2692
|
"aria-label": "Orient to spine",
|
|
2649
|
-
onClick: () => (0,
|
|
2693
|
+
onClick: () => (0, import_vector20.applyVectorBlendOptions)(controller, { orientToSpine: !o.orientToSpine }),
|
|
2650
2694
|
children: "\u293F"
|
|
2651
2695
|
}
|
|
2652
2696
|
),
|
|
@@ -2671,7 +2715,7 @@ var selectClass14 = "h-7 min-w-0 flex-1 rounded border border-border bg-backgrou
|
|
|
2671
2715
|
var numberClass11 = "h-7 w-16 rounded border border-border bg-background px-1.5 text-xs";
|
|
2672
2716
|
function VectorStylePanel({ controller, className }) {
|
|
2673
2717
|
const state = useVectorEditorState(controller);
|
|
2674
|
-
const style = (0,
|
|
2718
|
+
const style = (0, import_vector20.getVectorSelectionStyle)(state);
|
|
2675
2719
|
const d = state.defaults;
|
|
2676
2720
|
const source = style ?? {
|
|
2677
2721
|
fill: d.fill ?? null,
|
|
@@ -2684,7 +2728,7 @@ function VectorStylePanel({ controller, className }) {
|
|
|
2684
2728
|
arrowAlign: d.arrowAlign ?? "extend",
|
|
2685
2729
|
startArrowScale: d.startArrowScale ?? 1,
|
|
2686
2730
|
endArrowScale: d.endArrowScale ?? 1,
|
|
2687
|
-
widthProfile: (0,
|
|
2731
|
+
widthProfile: (0, import_vector20.widthProfilePresetId)(d.strokeWidthProfile),
|
|
2688
2732
|
cornerRadius: d.cornerRadius,
|
|
2689
2733
|
cornerKind: d.cornerKind ?? "round",
|
|
2690
2734
|
cornerSmoothing: 0,
|
|
@@ -2698,7 +2742,7 @@ function VectorStylePanel({ controller, className }) {
|
|
|
2698
2742
|
};
|
|
2699
2743
|
const setProfile = (id) => {
|
|
2700
2744
|
if (style) controller.setWidthProfile(id);
|
|
2701
|
-
else controller.setDefaults({ strokeWidthProfile: (0,
|
|
2745
|
+
else controller.setDefaults({ strokeWidthProfile: (0, import_vector20.widthProfilePreset)(id)?.length ? (0, import_vector20.widthProfilePreset)(id) : null });
|
|
2702
2746
|
};
|
|
2703
2747
|
const mixed = (key) => style?.mixed[key] ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: "text-[11px] text-muted-foreground", children: "Mixed" }) : null;
|
|
2704
2748
|
const arrowRow = (end, label) => {
|
|
@@ -2708,7 +2752,7 @@ function VectorStylePanel({ controller, className }) {
|
|
|
2708
2752
|
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: "w-16 text-xs text-foreground", children: label }),
|
|
2709
2753
|
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("select", { "aria-label": `${label} arrowhead`, className: selectClass14, value: source[key] ?? "", onChange: (e) => apply({ [key]: e.target.value || null }), children: [
|
|
2710
2754
|
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("option", { value: "", children: "None" }),
|
|
2711
|
-
|
|
2755
|
+
import_vector20.VECTOR_ARROWHEADS.map((h) => /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("option", { value: h, children: import_vector20.VECTOR_ARROWHEAD_LABELS[h] }, h))
|
|
2712
2756
|
] }),
|
|
2713
2757
|
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
2714
2758
|
"input",
|
|
@@ -2734,7 +2778,7 @@ function VectorStylePanel({ controller, className }) {
|
|
|
2734
2778
|
};
|
|
2735
2779
|
const paintRow = (key, label) => {
|
|
2736
2780
|
const paint = source[key];
|
|
2737
|
-
const hex = (0,
|
|
2781
|
+
const hex = (0, import_vector20.vectorPaintToHex)(paint);
|
|
2738
2782
|
const on = paint !== null && paint !== "none";
|
|
2739
2783
|
return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "flex items-center gap-2", "data-vector-style": key, children: [
|
|
2740
2784
|
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("label", { className: "flex w-16 items-center gap-1.5 text-xs text-foreground", children: [
|
|
@@ -2781,7 +2825,7 @@ function VectorStylePanel({ controller, className }) {
|
|
|
2781
2825
|
] }),
|
|
2782
2826
|
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("label", { className: "flex items-center gap-2 text-xs text-foreground", "data-vector-style": "strokeAlign", children: [
|
|
2783
2827
|
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: "w-16", children: "Align" }),
|
|
2784
|
-
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("select", { "aria-label": "Stroke alignment", className: selectClass14, value: source.strokeAlign, onChange: (e) => apply({ strokeAlign: e.target.value }), children: Object.keys(
|
|
2828
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("select", { "aria-label": "Stroke alignment", className: selectClass14, value: source.strokeAlign, onChange: (e) => apply({ strokeAlign: e.target.value }), children: Object.keys(import_vector20.VECTOR_STROKE_ALIGN_LABELS).map((a) => /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("option", { value: a, children: import_vector20.VECTOR_STROKE_ALIGN_LABELS[a] }, a)) }),
|
|
2785
2829
|
mixed("strokeAlign")
|
|
2786
2830
|
] }),
|
|
2787
2831
|
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "flex items-center gap-2 text-xs text-foreground", "data-vector-style": "widthProfile", children: [
|
|
@@ -2796,7 +2840,7 @@ function VectorStylePanel({ controller, className }) {
|
|
|
2796
2840
|
if (e.target.value !== "custom") setProfile(e.target.value);
|
|
2797
2841
|
},
|
|
2798
2842
|
children: [
|
|
2799
|
-
|
|
2843
|
+
import_vector20.VECTOR_WIDTH_PRESETS.map((p) => /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("option", { value: p.id, children: p.label }, p.id)),
|
|
2800
2844
|
source.widthProfile === "custom" && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("option", { value: "custom", disabled: true, children: "Custom" })
|
|
2801
2845
|
]
|
|
2802
2846
|
}
|
|
@@ -2843,7 +2887,7 @@ function VectorStylePanel({ controller, className }) {
|
|
|
2843
2887
|
}
|
|
2844
2888
|
}
|
|
2845
2889
|
),
|
|
2846
|
-
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("select", { "aria-label": "Corner kind", className: selectClass14, value: source.cornerKind, onChange: (e) => setCorners({ kind: e.target.value }), children:
|
|
2890
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("select", { "aria-label": "Corner kind", className: selectClass14, value: source.cornerKind, onChange: (e) => setCorners({ kind: e.target.value }), children: import_vector20.VECTOR_CORNER_KINDS.map((k) => /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("option", { value: k, children: import_vector20.VECTOR_CORNER_KIND_LABELS[k] }, k)) }),
|
|
2847
2891
|
mixed("cornerRadius")
|
|
2848
2892
|
] }),
|
|
2849
2893
|
style && source.corners > 0 && source.cornerKind === "round" && source.cornerRadius > 0 && /* @__PURE__ */ (0, import_jsx_runtime19.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: [
|
|
@@ -3537,6 +3581,44 @@ function VectorEditor({ controller, tools, showStylePanel = true, height = 520,
|
|
|
3537
3581
|
] })
|
|
3538
3582
|
] });
|
|
3539
3583
|
}
|
|
3584
|
+
|
|
3585
|
+
// src/vector/VectorGeneratePanel.tsx
|
|
3586
|
+
var import_react18 = require("react");
|
|
3587
|
+
var import_vector21 = require("@pixerate/editor/vector");
|
|
3588
|
+
var import_jsx_runtime26 = require("react/jsx-runtime");
|
|
3589
|
+
var buttonClass17 = "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";
|
|
3590
|
+
var selectClass15 = "h-7 min-w-0 flex-1 rounded border border-border bg-background px-1 text-xs";
|
|
3591
|
+
var AS_LABELS = { color: "Traced in colour", threshold: "Traced in one colour", mosaic: "Mosaic", halftone: "Halftone", lowPoly: "Low poly", hatch: "Engraving" };
|
|
3592
|
+
function VectorGeneratePanel({ controller, models, generate, className }) {
|
|
3593
|
+
const usable = (0, import_vector21.vectorArtModels)(models);
|
|
3594
|
+
const [prompt, setPrompt] = (0, import_react18.useState)("");
|
|
3595
|
+
const [model, setModel] = (0, import_react18.useState)("");
|
|
3596
|
+
const [as, setAs] = (0, import_react18.useState)("color");
|
|
3597
|
+
const [busy, setBusy] = (0, import_react18.useState)(false);
|
|
3598
|
+
const [message, setMessage] = (0, import_react18.useState)(null);
|
|
3599
|
+
const chosen = usable.find((m) => m.id === model) ?? usable[0];
|
|
3600
|
+
if (!usable.length) return null;
|
|
3601
|
+
const run = async () => {
|
|
3602
|
+
setBusy(true);
|
|
3603
|
+
setMessage(null);
|
|
3604
|
+
const r = await (0, import_vector21.generateVectorArt)(controller, { prompt, model: chosen.id, as, idempotencyKey: `${Date.now()}-${Math.random().toString(36).slice(2)}` }, { models, generate });
|
|
3605
|
+
setBusy(false);
|
|
3606
|
+
setMessage(r.ok ? null : r.message ?? "Generation failed.");
|
|
3607
|
+
};
|
|
3608
|
+
return /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: `space-y-1 ${className ?? ""}`, "data-vector-generate-panel": "", "aria-label": "Generate", children: [
|
|
3609
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "flex items-center gap-1", children: [
|
|
3610
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { className: "w-16 text-[11px] font-medium uppercase tracking-wide text-muted-foreground", children: "Generate" }),
|
|
3611
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("select", { "aria-label": "Generation model", className: selectClass15, value: chosen.id, onChange: (e) => setModel(e.target.value), children: usable.map((m) => /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("option", { value: m.id, children: m.name ?? m.id }, m.id)) }),
|
|
3612
|
+
chosen.media === "image" && /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("select", { "aria-label": "Image to vectors", className: selectClass15, value: as, onChange: (e) => setAs(e.target.value), children: import_vector21.VECTOR_GENERATED_IMAGE_AS.map((a) => /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("option", { value: a, children: AS_LABELS[a] }, a)) })
|
|
3613
|
+
] }),
|
|
3614
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "flex items-center gap-1", children: [
|
|
3615
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { className: "w-16" }),
|
|
3616
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("input", { type: "text", "aria-label": "Prompt", placeholder: "Describe the art\u2026", className: "h-7 min-w-0 flex-1 rounded border border-border bg-background px-1.5 text-xs", value: prompt, onChange: (e) => setPrompt(e.target.value), onKeyDown: (e) => e.key === "Enter" && prompt.trim() && !busy && void run() }),
|
|
3617
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("button", { type: "button", className: buttonClass17, "data-vector-generate-action": "", disabled: !prompt.trim() || busy, onClick: () => void run(), children: busy ? "Generating\u2026" : "Generate" })
|
|
3618
|
+
] }),
|
|
3619
|
+
message && /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("p", { className: "text-[11px] text-red-600", children: message })
|
|
3620
|
+
] });
|
|
3621
|
+
}
|
|
3540
3622
|
// Annotate the CommonJS export names for ESM import in node:
|
|
3541
3623
|
0 && (module.exports = {
|
|
3542
3624
|
VectorAppearancePanel,
|
|
@@ -3548,6 +3630,7 @@ function VectorEditor({ controller, tools, showStylePanel = true, height = 520,
|
|
|
3548
3630
|
VectorEnvelopePanel,
|
|
3549
3631
|
VectorFilterDefs,
|
|
3550
3632
|
VectorFramePanel,
|
|
3633
|
+
VectorGeneratePanel,
|
|
3551
3634
|
VectorGradientAnnotator,
|
|
3552
3635
|
VectorGradientDefs,
|
|
3553
3636
|
VectorGradientEditor,
|
|
@@ -3571,6 +3654,7 @@ function VectorEditor({ controller, tools, showStylePanel = true, height = 520,
|
|
|
3571
3654
|
useVectorEditor,
|
|
3572
3655
|
useVectorEditorController,
|
|
3573
3656
|
useVectorEditorState,
|
|
3574
|
-
useVectorEffectsTools
|
|
3657
|
+
useVectorEffectsTools,
|
|
3658
|
+
useVectorGenerationTools
|
|
3575
3659
|
});
|
|
3576
3660
|
//# sourceMappingURL=index.cjs.map
|