@pixerate/editor-react 0.82.0 → 0.84.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/vector/index.cjs +418 -309
- package/dist/vector/index.cjs.map +1 -1
- package/dist/vector/index.d.cts +23 -1
- package/dist/vector/index.d.ts +23 -1
- package/dist/vector/index.js +287 -180
- package/dist/vector/index.js.map +1 -1
- package/package.json +3 -3
package/dist/vector/index.js
CHANGED
|
@@ -649,6 +649,11 @@ function VectorCanvas({
|
|
|
649
649
|
sh.lines.map((d, i) => /* @__PURE__ */ jsx2("path", { d, stroke: accentColor, strokeWidth: 1, opacity: 0.7 }, i)),
|
|
650
650
|
sh.points.map((p) => /* @__PURE__ */ jsx2("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))
|
|
651
651
|
] }, `shading:${sh.nodeId}`)),
|
|
652
|
+
overlay.perspective && /* @__PURE__ */ jsxs2("g", { "data-vector-perspective-grid": "", fill: "none", pointerEvents: "none", children: [
|
|
653
|
+
overlay.perspective.planes.map((pl) => /* @__PURE__ */ jsx2("path", { "data-vector-perspective-plane": pl.plane, "data-active": pl.active || void 0, d: pl.d, stroke: pl.active ? accentColor : guideColor, strokeWidth: pl.active ? 1 : 0.75, opacity: pl.active ? 0.55 : 0.25 }, pl.plane)),
|
|
654
|
+
overlay.perspective.vanishingPoints.map((v, i) => /* @__PURE__ */ jsx2("circle", { "data-vector-vanishing-point": i, cx: v.x, cy: v.y, r: 4, stroke: accentColor, strokeWidth: 1.5 }, i)),
|
|
655
|
+
/* @__PURE__ */ jsx2("circle", { "data-vector-perspective-origin": "", cx: overlay.perspective.origin.x, cy: overlay.perspective.origin.y, r: 3, fill: accentColor })
|
|
656
|
+
] }),
|
|
652
657
|
overlay.symmetry.map((sy) => /* @__PURE__ */ jsx2("g", { "data-vector-symmetry-axes": sy.nodeId, stroke: accentColor, strokeDasharray: sy.drawing ? void 0 : "6 4", opacity: sy.drawing ? 0.9 : 0.6, children: sy.lines.map((l, i) => /* @__PURE__ */ jsx2("line", { x1: l.x1, y1: l.y1, x2: l.x2, y2: l.y2 }, i)) }, `sym:${sy.nodeId}`)),
|
|
653
658
|
overlay.trackingPoints.map((t, i) => /* @__PURE__ */ jsx2("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}`)),
|
|
654
659
|
overlay.typedEntry && /* @__PURE__ */ jsxs2("g", { "data-vector-typed-entry": "", transform: `translate(${overlay.typedEntry.x + 14} ${overlay.typedEntry.y + 18})`, children: [
|
|
@@ -785,7 +790,7 @@ function VectorCanvas({
|
|
|
785
790
|
}
|
|
786
791
|
|
|
787
792
|
// src/vector/VectorToolbar.tsx
|
|
788
|
-
import
|
|
793
|
+
import React10 from "react";
|
|
789
794
|
import {
|
|
790
795
|
VECTOR_TOOLS,
|
|
791
796
|
VECTOR_TOOL_GLYPHS,
|
|
@@ -2091,6 +2096,104 @@ function VectorSymmetryPanel({ controller, className }) {
|
|
|
2091
2096
|
] });
|
|
2092
2097
|
}
|
|
2093
2098
|
|
|
2099
|
+
// src/vector/VectorPerspectivePanel.tsx
|
|
2100
|
+
import React9 from "react";
|
|
2101
|
+
import { vectorPerspectivePlanes, vectorPerspectivePreset } from "@pixerate/editor/vector";
|
|
2102
|
+
import { jsx as jsx15, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
2103
|
+
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";
|
|
2104
|
+
var selectClass10 = "h-7 min-w-0 flex-1 rounded border border-border bg-background px-1 text-xs";
|
|
2105
|
+
var PLANE_LABELS = { floor: "Floor", left: "Left wall", right: "Right wall", side: "Side wall", front: "Front" };
|
|
2106
|
+
function VectorPerspectivePanel({ controller, className }) {
|
|
2107
|
+
const state = useVectorEditorState(controller);
|
|
2108
|
+
const grid = state.document.perspective ?? null;
|
|
2109
|
+
const planes = grid ? vectorPerspectivePlanes(grid) : [];
|
|
2110
|
+
const [attachTo, setAttachTo] = React9.useState("");
|
|
2111
|
+
const target = (state.perspectivePlane ?? attachTo) || planes[0];
|
|
2112
|
+
const add = (n) => controller.setPerspective(vectorPerspectivePreset(n, state.document.width, state.document.height));
|
|
2113
|
+
return /* @__PURE__ */ jsxs15("div", { className: `space-y-2 ${className ?? ""}`, "data-vector-perspective-panel": "", "aria-label": "Perspective", children: [
|
|
2114
|
+
/* @__PURE__ */ jsxs15("div", { className: "flex flex-wrap items-center gap-1", children: [
|
|
2115
|
+
/* @__PURE__ */ jsx15("span", { className: "w-16 text-[11px] font-medium uppercase tracking-wide text-muted-foreground", children: "Perspective" }),
|
|
2116
|
+
[1, 2, 3].map((n) => /* @__PURE__ */ jsxs15("button", { type: "button", className: buttonClass13, "aria-pressed": grid?.vanishingPoints.length === n, "data-vector-perspective-preset": n, title: `A ${n}-point perspective grid for the page`, onClick: () => add(n), children: [
|
|
2117
|
+
n,
|
|
2118
|
+
"-pt"
|
|
2119
|
+
] }, n))
|
|
2120
|
+
] }),
|
|
2121
|
+
grid && /* @__PURE__ */ jsxs15("div", { className: "flex flex-wrap items-center gap-1", children: [
|
|
2122
|
+
/* @__PURE__ */ jsx15("span", { className: "w-16" }),
|
|
2123
|
+
/* @__PURE__ */ jsxs15("select", { "aria-label": "Draw on plane", title: "New rectangles, ellipses, polygons and stars are drawn on this plane", className: selectClass10, value: state.perspectivePlane ?? "", onChange: (e) => controller.setPerspectivePlane(e.target.value || null), children: [
|
|
2124
|
+
/* @__PURE__ */ jsx15("option", { value: "", children: "Draw flat" }),
|
|
2125
|
+
planes.map((p) => /* @__PURE__ */ jsxs15("option", { value: p, children: [
|
|
2126
|
+
"Draw on ",
|
|
2127
|
+
PLANE_LABELS[p].toLowerCase()
|
|
2128
|
+
] }, p))
|
|
2129
|
+
] })
|
|
2130
|
+
] }),
|
|
2131
|
+
grid && /* @__PURE__ */ jsxs15("div", { className: "flex flex-wrap items-center gap-1", children: [
|
|
2132
|
+
/* @__PURE__ */ jsx15("span", { className: "w-16" }),
|
|
2133
|
+
!state.perspectivePlane && /* @__PURE__ */ jsx15("select", { "aria-label": "Attach to plane", className: "h-7 w-24 rounded border border-border bg-background px-1 text-xs", value: attachTo || planes[0], onChange: (e) => setAttachTo(e.target.value), children: planes.map((p) => /* @__PURE__ */ jsx15("option", { value: p, children: PLANE_LABELS[p] }, p)) }),
|
|
2134
|
+
/* @__PURE__ */ jsx15("button", { type: "button", className: buttonClass13, disabled: !state.selection.length, title: "Lay the selection onto the plane (read flat from the grid's origin)", onClick: () => controller.attachToPerspective(target), children: "Attach" }),
|
|
2135
|
+
/* @__PURE__ */ jsxs15("label", { className: "flex items-center gap-1 text-xs text-foreground", title: "Show the grid on the canvas", children: [
|
|
2136
|
+
/* @__PURE__ */ jsx15("input", { type: "checkbox", "aria-label": "Show perspective grid", checked: grid.visible !== false, onChange: (e) => controller.setPerspective({ ...grid, visible: e.target.checked }) }),
|
|
2137
|
+
"Show"
|
|
2138
|
+
] }),
|
|
2139
|
+
/* @__PURE__ */ jsx15("button", { type: "button", className: buttonClass13, title: "Remove the grid (art on it stays)", onClick: () => controller.setPerspective(null), children: "Remove" })
|
|
2140
|
+
] })
|
|
2141
|
+
] });
|
|
2142
|
+
}
|
|
2143
|
+
|
|
2144
|
+
// src/vector/VectorLensPanel.tsx
|
|
2145
|
+
import { VECTOR_LENS_LABELS, VECTOR_LENS_SPECS, VECTOR_LENS_TYPES } from "@pixerate/editor/vector";
|
|
2146
|
+
import { jsx as jsx16, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
2147
|
+
var selectClass11 = "h-7 min-w-0 flex-1 rounded border border-border bg-background px-1 text-xs";
|
|
2148
|
+
var numberClass9 = "h-7 w-16 rounded border border-border bg-background px-1.5 text-xs";
|
|
2149
|
+
function VectorLensPanel({ controller, className }) {
|
|
2150
|
+
const state = useVectorEditorState(controller);
|
|
2151
|
+
const path = state.selection.map((id) => controller.getNode(id)).find((n) => n?.type === "path" && n.subpaths.some((sp) => sp.closed) && !n.connector);
|
|
2152
|
+
if (!path) return null;
|
|
2153
|
+
const lens = path.lens ?? null;
|
|
2154
|
+
const spec = lens ? VECTOR_LENS_SPECS[lens.type] : null;
|
|
2155
|
+
const ids = [path.id];
|
|
2156
|
+
return /* @__PURE__ */ jsxs16("div", { className: `space-y-2 ${className ?? ""}`, "data-vector-lens-panel": "", "aria-label": "Lens", children: [
|
|
2157
|
+
/* @__PURE__ */ jsxs16("div", { className: "flex flex-wrap items-center gap-1", children: [
|
|
2158
|
+
/* @__PURE__ */ jsx16("span", { className: "w-16 text-[11px] font-medium uppercase tracking-wide text-muted-foreground", children: "Lens" }),
|
|
2159
|
+
/* @__PURE__ */ jsxs16(
|
|
2160
|
+
"select",
|
|
2161
|
+
{
|
|
2162
|
+
"aria-label": "Lens type",
|
|
2163
|
+
className: selectClass11,
|
|
2164
|
+
value: lens?.type ?? "",
|
|
2165
|
+
onChange: (e) => e.target.value ? controller.setLens({ type: e.target.value }, { ids }) : controller.setLens(null, { ids }),
|
|
2166
|
+
children: [
|
|
2167
|
+
/* @__PURE__ */ jsx16("option", { value: "", children: "None" }),
|
|
2168
|
+
VECTOR_LENS_TYPES.map((t) => /* @__PURE__ */ jsx16("option", { value: t, children: VECTOR_LENS_LABELS[t] }, t))
|
|
2169
|
+
]
|
|
2170
|
+
}
|
|
2171
|
+
)
|
|
2172
|
+
] }),
|
|
2173
|
+
lens && spec && /* @__PURE__ */ jsxs16("div", { className: "flex flex-wrap items-center gap-1", children: [
|
|
2174
|
+
/* @__PURE__ */ jsx16("span", { className: "w-16" }),
|
|
2175
|
+
/* @__PURE__ */ jsx16(
|
|
2176
|
+
"input",
|
|
2177
|
+
{
|
|
2178
|
+
type: "number",
|
|
2179
|
+
"aria-label": "Lens amount",
|
|
2180
|
+
title: `Amount: ${spec.unit} (${spec.min} to ${spec.max})`,
|
|
2181
|
+
className: numberClass9,
|
|
2182
|
+
min: spec.min,
|
|
2183
|
+
max: spec.max,
|
|
2184
|
+
step: lens.type === "magnify" ? 0.1 : 1,
|
|
2185
|
+
value: lens.amount,
|
|
2186
|
+
onChange: (e) => {
|
|
2187
|
+
const v = parseFloat(e.target.value);
|
|
2188
|
+
if (Number.isFinite(v)) controller.setLens({ amount: Math.min(spec.max, Math.max(spec.min, v)) }, { ids, merge: `lens-amount-${path.id}` });
|
|
2189
|
+
}
|
|
2190
|
+
}
|
|
2191
|
+
),
|
|
2192
|
+
spec.color !== null && /* @__PURE__ */ jsx16("input", { type: "color", "aria-label": "Lens colour", title: "Lens colour", className: "h-7 w-9 rounded border border-border bg-background", value: lens.color ?? spec.color, onChange: (e) => controller.setLens({ color: e.target.value }, { ids, merge: `lens-color-${path.id}` }) })
|
|
2193
|
+
] })
|
|
2194
|
+
] });
|
|
2195
|
+
}
|
|
2196
|
+
|
|
2094
2197
|
// src/vector/VectorGradientEditor.tsx
|
|
2095
2198
|
import {
|
|
2096
2199
|
VECTOR_GRADIENT_TYPES,
|
|
@@ -2104,10 +2207,10 @@ import {
|
|
|
2104
2207
|
getVectorGradientEditor,
|
|
2105
2208
|
vectorPaintToHex as vectorPaintToHex5
|
|
2106
2209
|
} from "@pixerate/editor/vector";
|
|
2107
|
-
import { Fragment as Fragment5, jsx as
|
|
2108
|
-
var
|
|
2109
|
-
var
|
|
2110
|
-
var
|
|
2210
|
+
import { Fragment as Fragment5, jsx as jsx17, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
2211
|
+
var selectClass12 = "h-7 min-w-0 flex-1 rounded border border-border bg-background px-1 text-xs";
|
|
2212
|
+
var numberClass10 = "h-7 w-14 rounded border border-border bg-background px-1.5 text-xs";
|
|
2213
|
+
var buttonClass14 = "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";
|
|
2111
2214
|
var percent = (v) => Math.round(v * 1e3) / 10;
|
|
2112
2215
|
function VectorGradientEditor({ controller, className }) {
|
|
2113
2216
|
const state = useVectorEditorState(controller);
|
|
@@ -2122,23 +2225,23 @@ function VectorGradientEditor({ controller, className }) {
|
|
|
2122
2225
|
controller.setStyle({ [ed.target]: vectorPaintToHex5(first?.color) ?? first?.color ?? "#000000" }, void 0, { label: "Solid Colour" });
|
|
2123
2226
|
} else controller.setGradient({ type: value });
|
|
2124
2227
|
};
|
|
2125
|
-
return /* @__PURE__ */
|
|
2126
|
-
/* @__PURE__ */
|
|
2127
|
-
/* @__PURE__ */
|
|
2128
|
-
["fill", "stroke"].map((t) => /* @__PURE__ */
|
|
2129
|
-
ed.mixed && /* @__PURE__ */
|
|
2228
|
+
return /* @__PURE__ */ jsxs17("div", { className: `space-y-1.5 ${className ?? ""}`, "data-vector-gradient-editor": ed.target, "aria-label": "Gradient", children: [
|
|
2229
|
+
/* @__PURE__ */ jsxs17("div", { className: "flex items-center gap-1.5", children: [
|
|
2230
|
+
/* @__PURE__ */ jsx17("span", { className: "w-16 text-xs text-foreground", children: "Gradient" }),
|
|
2231
|
+
["fill", "stroke"].map((t) => /* @__PURE__ */ jsx17("button", { type: "button", className: buttonClass14, "aria-pressed": ed.target === t, onClick: () => controller.setGradientTarget(t), children: t === "fill" ? "Fill" : "Stroke" }, t)),
|
|
2232
|
+
ed.mixed && /* @__PURE__ */ jsx17("span", { className: "text-[11px] text-muted-foreground", children: "Mixed" })
|
|
2130
2233
|
] }),
|
|
2131
|
-
/* @__PURE__ */
|
|
2132
|
-
/* @__PURE__ */
|
|
2133
|
-
/* @__PURE__ */
|
|
2134
|
-
/* @__PURE__ */
|
|
2135
|
-
VECTOR_GRADIENT_TYPES.map((t) => /* @__PURE__ */
|
|
2234
|
+
/* @__PURE__ */ jsxs17("div", { className: "flex items-center gap-1.5", children: [
|
|
2235
|
+
/* @__PURE__ */ jsx17("span", { className: "w-16 text-xs text-foreground", children: "Type" }),
|
|
2236
|
+
/* @__PURE__ */ jsxs17("select", { "aria-label": "Gradient type", className: selectClass12, value: ed.type ?? "solid", onChange: (e) => setType(e.target.value), children: [
|
|
2237
|
+
/* @__PURE__ */ jsx17("option", { value: "solid", children: "Solid" }),
|
|
2238
|
+
VECTOR_GRADIENT_TYPES.map((t) => /* @__PURE__ */ jsx17("option", { value: t, children: VECTOR_GRADIENT_TYPE_LABELS[t] }, t))
|
|
2136
2239
|
] }),
|
|
2137
|
-
/* @__PURE__ */
|
|
2240
|
+
/* @__PURE__ */ jsx17("button", { type: "button", className: buttonClass14, "aria-label": "Reverse gradient", title: "Reverse gradient", disabled: !g, onClick: () => controller.reverseGradient(), children: "\u21C4" })
|
|
2138
2241
|
] }),
|
|
2139
|
-
g && /* @__PURE__ */
|
|
2140
|
-
/* @__PURE__ */
|
|
2141
|
-
/* @__PURE__ */
|
|
2242
|
+
g && /* @__PURE__ */ jsxs17(Fragment5, { children: [
|
|
2243
|
+
/* @__PURE__ */ jsxs17("div", { className: "relative h-8", "data-vector-gradient-ramp": "", children: [
|
|
2244
|
+
/* @__PURE__ */ jsx17(
|
|
2142
2245
|
"div",
|
|
2143
2246
|
{
|
|
2144
2247
|
role: "button",
|
|
@@ -2152,7 +2255,7 @@ function VectorGradientEditor({ controller, className }) {
|
|
|
2152
2255
|
}
|
|
2153
2256
|
}
|
|
2154
2257
|
),
|
|
2155
|
-
ed.stops.map((s) => /* @__PURE__ */
|
|
2258
|
+
ed.stops.map((s) => /* @__PURE__ */ jsx17(
|
|
2156
2259
|
"button",
|
|
2157
2260
|
{
|
|
2158
2261
|
type: "button",
|
|
@@ -2166,8 +2269,8 @@ function VectorGradientEditor({ controller, className }) {
|
|
|
2166
2269
|
s.index
|
|
2167
2270
|
))
|
|
2168
2271
|
] }),
|
|
2169
|
-
sel && /* @__PURE__ */
|
|
2170
|
-
/* @__PURE__ */
|
|
2272
|
+
sel && /* @__PURE__ */ jsxs17("div", { className: "flex flex-wrap items-center gap-1.5", "data-vector-gradient-selected-stop": sel.index, children: [
|
|
2273
|
+
/* @__PURE__ */ jsx17(
|
|
2171
2274
|
"input",
|
|
2172
2275
|
{
|
|
2173
2276
|
type: "color",
|
|
@@ -2178,9 +2281,9 @@ function VectorGradientEditor({ controller, className }) {
|
|
|
2178
2281
|
onBlur: end
|
|
2179
2282
|
}
|
|
2180
2283
|
),
|
|
2181
|
-
/* @__PURE__ */
|
|
2284
|
+
/* @__PURE__ */ jsxs17("label", { className: "flex items-center gap-1 text-[11px] text-muted-foreground", children: [
|
|
2182
2285
|
"Opacity",
|
|
2183
|
-
/* @__PURE__ */
|
|
2286
|
+
/* @__PURE__ */ jsx17(
|
|
2184
2287
|
"input",
|
|
2185
2288
|
{
|
|
2186
2289
|
type: "number",
|
|
@@ -2188,7 +2291,7 @@ function VectorGradientEditor({ controller, className }) {
|
|
|
2188
2291
|
max: 100,
|
|
2189
2292
|
step: 5,
|
|
2190
2293
|
"aria-label": "Stop opacity",
|
|
2191
|
-
className:
|
|
2294
|
+
className: numberClass10,
|
|
2192
2295
|
value: percent(sel.opacity ?? 1),
|
|
2193
2296
|
onChange: (e) => {
|
|
2194
2297
|
const n = parseFloat(e.target.value);
|
|
@@ -2197,9 +2300,9 @@ function VectorGradientEditor({ controller, className }) {
|
|
|
2197
2300
|
}
|
|
2198
2301
|
)
|
|
2199
2302
|
] }),
|
|
2200
|
-
/* @__PURE__ */
|
|
2303
|
+
/* @__PURE__ */ jsxs17("label", { className: "flex items-center gap-1 text-[11px] text-muted-foreground", children: [
|
|
2201
2304
|
"At",
|
|
2202
|
-
/* @__PURE__ */
|
|
2305
|
+
/* @__PURE__ */ jsx17(
|
|
2203
2306
|
"input",
|
|
2204
2307
|
{
|
|
2205
2308
|
type: "number",
|
|
@@ -2207,7 +2310,7 @@ function VectorGradientEditor({ controller, className }) {
|
|
|
2207
2310
|
max: 100,
|
|
2208
2311
|
step: 1,
|
|
2209
2312
|
"aria-label": "Stop position",
|
|
2210
|
-
className:
|
|
2313
|
+
className: numberClass10,
|
|
2211
2314
|
value: percent(sel.offset),
|
|
2212
2315
|
onChange: (e) => {
|
|
2213
2316
|
const n = parseFloat(e.target.value);
|
|
@@ -2216,9 +2319,9 @@ function VectorGradientEditor({ controller, className }) {
|
|
|
2216
2319
|
}
|
|
2217
2320
|
)
|
|
2218
2321
|
] }),
|
|
2219
|
-
!sel.last && /* @__PURE__ */
|
|
2322
|
+
!sel.last && /* @__PURE__ */ jsxs17("label", { className: "flex items-center gap-1 text-[11px] text-muted-foreground", children: [
|
|
2220
2323
|
"Midpoint",
|
|
2221
|
-
/* @__PURE__ */
|
|
2324
|
+
/* @__PURE__ */ jsx17(
|
|
2222
2325
|
"input",
|
|
2223
2326
|
{
|
|
2224
2327
|
type: "number",
|
|
@@ -2226,7 +2329,7 @@ function VectorGradientEditor({ controller, className }) {
|
|
|
2226
2329
|
max: 95,
|
|
2227
2330
|
step: 1,
|
|
2228
2331
|
"aria-label": "Stop midpoint",
|
|
2229
|
-
className:
|
|
2332
|
+
className: numberClass10,
|
|
2230
2333
|
value: percent(sel.midpoint ?? 0.5),
|
|
2231
2334
|
onChange: (e) => {
|
|
2232
2335
|
const n = parseFloat(e.target.value);
|
|
@@ -2235,15 +2338,15 @@ function VectorGradientEditor({ controller, className }) {
|
|
|
2235
2338
|
}
|
|
2236
2339
|
)
|
|
2237
2340
|
] }),
|
|
2238
|
-
/* @__PURE__ */
|
|
2341
|
+
/* @__PURE__ */ jsx17("button", { type: "button", className: buttonClass14, "aria-label": "Delete stop", title: "Delete stop", disabled: ed.stops.length <= 2, onClick: () => controller.removeGradientStop(sel.index), children: "\u2715" })
|
|
2239
2342
|
] }),
|
|
2240
|
-
/* @__PURE__ */
|
|
2241
|
-
/* @__PURE__ */
|
|
2242
|
-
/* @__PURE__ */
|
|
2343
|
+
/* @__PURE__ */ jsxs17("label", { className: "flex items-center gap-1.5 text-xs text-foreground", children: [
|
|
2344
|
+
/* @__PURE__ */ jsx17("span", { className: "w-16", children: "Colours" }),
|
|
2345
|
+
/* @__PURE__ */ jsx17("select", { "aria-label": "Gradient interpolation", className: selectClass12, value: ed.interpolation, onChange: (e) => controller.setGradient({ interpolation: e.target.value }), children: VECTOR_GRADIENT_INTERPOLATIONS.map((i) => /* @__PURE__ */ jsx17("option", { value: i, children: VECTOR_GRADIENT_INTERPOLATION_LABELS[i] }, i)) })
|
|
2243
2346
|
] }),
|
|
2244
|
-
/* @__PURE__ */
|
|
2245
|
-
/* @__PURE__ */
|
|
2246
|
-
/* @__PURE__ */
|
|
2347
|
+
/* @__PURE__ */ jsxs17("label", { className: "flex items-center gap-1.5 text-xs text-foreground", children: [
|
|
2348
|
+
/* @__PURE__ */ jsx17("span", { className: "w-16", children: "Smooth" }),
|
|
2349
|
+
/* @__PURE__ */ jsx17(
|
|
2247
2350
|
"input",
|
|
2248
2351
|
{
|
|
2249
2352
|
type: "range",
|
|
@@ -2259,23 +2362,23 @@ function VectorGradientEditor({ controller, className }) {
|
|
|
2259
2362
|
}
|
|
2260
2363
|
)
|
|
2261
2364
|
] }),
|
|
2262
|
-
/* @__PURE__ */
|
|
2263
|
-
/* @__PURE__ */
|
|
2264
|
-
/* @__PURE__ */
|
|
2365
|
+
/* @__PURE__ */ jsxs17("label", { className: "flex items-center gap-1.5 text-xs text-foreground", children: [
|
|
2366
|
+
/* @__PURE__ */ jsx17("span", { className: "w-16", children: "Spread" }),
|
|
2367
|
+
/* @__PURE__ */ jsx17("select", { "aria-label": "Gradient spread", className: selectClass12, value: ed.spread, onChange: (e) => controller.setGradient({ spread: e.target.value }), children: VECTOR_GRADIENT_SPREADS.map((sp) => /* @__PURE__ */ jsx17("option", { value: sp, children: VECTOR_GRADIENT_SPREAD_LABELS[sp] }, sp)) })
|
|
2265
2368
|
] }),
|
|
2266
|
-
ed.target === "stroke" && /* @__PURE__ */
|
|
2267
|
-
/* @__PURE__ */
|
|
2268
|
-
/* @__PURE__ */
|
|
2369
|
+
ed.target === "stroke" && /* @__PURE__ */ jsxs17("label", { className: "flex items-center gap-1.5 text-xs text-foreground", children: [
|
|
2370
|
+
/* @__PURE__ */ jsx17("span", { className: "w-16", children: "On stroke" }),
|
|
2371
|
+
/* @__PURE__ */ jsx17("select", { "aria-label": "Gradient on stroke", className: selectClass12, value: ed.strokeMode, onChange: (e) => controller.setGradient({ strokeMode: e.target.value }), children: VECTOR_STROKE_GRADIENT_MODES.map((m) => /* @__PURE__ */ jsx17("option", { value: m, children: VECTOR_STROKE_GRADIENT_MODE_LABELS[m] }, m)) })
|
|
2269
2372
|
] })
|
|
2270
2373
|
] })
|
|
2271
2374
|
] });
|
|
2272
2375
|
}
|
|
2273
2376
|
|
|
2274
2377
|
// src/vector/VectorToolbar.tsx
|
|
2275
|
-
import { Fragment as Fragment6, jsx as
|
|
2378
|
+
import { Fragment as Fragment6, jsx as jsx18, jsxs as jsxs18 } from "react/jsx-runtime";
|
|
2276
2379
|
var VECTOR_SNAP_TITLE = "Snap to objects";
|
|
2277
2380
|
var modKeyLabel = () => typeof navigator !== "undefined" && /Mac|iPhone|iPad/.test(navigator.platform ?? "") ? "\u2318" : "Ctrl";
|
|
2278
|
-
var
|
|
2381
|
+
var buttonClass15 = "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";
|
|
2279
2382
|
function VectorToolbar({
|
|
2280
2383
|
controller,
|
|
2281
2384
|
tools = VECTOR_TOOLS,
|
|
@@ -2293,16 +2396,16 @@ function VectorToolbar({
|
|
|
2293
2396
|
const editing = state.editing;
|
|
2294
2397
|
const groupSelected = state.selection.some((id) => controller.getNode(id)?.type === "group");
|
|
2295
2398
|
const maskSelected = state.selection.some((id) => isVectorMaskGroup(controller.getNode(id)));
|
|
2296
|
-
const [live, setLive] =
|
|
2399
|
+
const [live, setLive] = React10.useState(false);
|
|
2297
2400
|
const booleanDisabled = live ? count < 1 : count < 2;
|
|
2298
|
-
const act = (label, title, run, disabled = false) => /* @__PURE__ */
|
|
2299
|
-
return /* @__PURE__ */
|
|
2300
|
-
/* @__PURE__ */
|
|
2401
|
+
const act = (label, title, run, disabled = false) => /* @__PURE__ */ jsx18("button", { type: "button", className: buttonClass15, title, "aria-label": title, disabled, onClick: () => void run(), children: label }, label);
|
|
2402
|
+
return /* @__PURE__ */ jsxs18("div", { role: "toolbar", "aria-label": "Vector tools", className: `flex flex-wrap items-center gap-1 ${className ?? ""}`, children: [
|
|
2403
|
+
/* @__PURE__ */ jsx18("div", { className: "flex items-center gap-1", role: "group", "aria-label": "Tools", children: tools.map((tool) => /* @__PURE__ */ jsx18(
|
|
2301
2404
|
"button",
|
|
2302
2405
|
{
|
|
2303
2406
|
type: "button",
|
|
2304
2407
|
"data-vector-tool": tool,
|
|
2305
|
-
className:
|
|
2408
|
+
className: buttonClass15,
|
|
2306
2409
|
"aria-pressed": state.tool === tool,
|
|
2307
2410
|
title: `${vectorToolLabel(tool)} (${VECTOR_TOOL_SHORTCUTS[tool]})`,
|
|
2308
2411
|
"aria-label": vectorToolLabel(tool),
|
|
@@ -2311,17 +2414,17 @@ function VectorToolbar({
|
|
|
2311
2414
|
},
|
|
2312
2415
|
tool
|
|
2313
2416
|
)) }),
|
|
2314
|
-
showHistory && /* @__PURE__ */
|
|
2417
|
+
showHistory && /* @__PURE__ */ jsxs18("div", { className: "ml-1 flex items-center gap-1", role: "group", "aria-label": "History", children: [
|
|
2315
2418
|
act("\u21B6", state.canUndo ? `Undo ${state.undoLabel}` : "Undo", () => controller.undo(), !state.canUndo),
|
|
2316
2419
|
act("\u21B7", state.canRedo ? `Redo ${state.redoLabel}` : "Redo", () => controller.redo(), !state.canRedo)
|
|
2317
2420
|
] }),
|
|
2318
|
-
showSnap && /* @__PURE__ */
|
|
2319
|
-
/* @__PURE__ */
|
|
2421
|
+
showSnap && /* @__PURE__ */ jsxs18("div", { className: "ml-1 flex items-center gap-1", role: "group", "aria-label": "Snapping", children: [
|
|
2422
|
+
/* @__PURE__ */ jsx18(
|
|
2320
2423
|
"button",
|
|
2321
2424
|
{
|
|
2322
2425
|
type: "button",
|
|
2323
2426
|
"data-vector-snap": "",
|
|
2324
|
-
className:
|
|
2427
|
+
className: buttonClass15,
|
|
2325
2428
|
"aria-pressed": state.snap.objects,
|
|
2326
2429
|
title: `${VECTOR_SNAP_TITLE} (hold ${modKeyLabel()} to bypass)`,
|
|
2327
2430
|
"aria-label": VECTOR_SNAP_TITLE,
|
|
@@ -2329,7 +2432,7 @@ function VectorToolbar({
|
|
|
2329
2432
|
children: "Snap"
|
|
2330
2433
|
}
|
|
2331
2434
|
),
|
|
2332
|
-
/* @__PURE__ */
|
|
2435
|
+
/* @__PURE__ */ jsxs18(
|
|
2333
2436
|
"select",
|
|
2334
2437
|
{
|
|
2335
2438
|
"data-vector-polar": "",
|
|
@@ -2339,8 +2442,8 @@ function VectorToolbar({
|
|
|
2339
2442
|
value: String(vectorPolarIncrementOf(state.snap.angles) ?? ""),
|
|
2340
2443
|
onChange: (e) => controller.setSnap({ angles: vectorPolarAngles(Number(e.target.value)) }),
|
|
2341
2444
|
children: [
|
|
2342
|
-
vectorPolarIncrementOf(state.snap.angles) === null && /* @__PURE__ */
|
|
2343
|
-
[90, 45, 30, 15].map((n) => /* @__PURE__ */
|
|
2445
|
+
vectorPolarIncrementOf(state.snap.angles) === null && /* @__PURE__ */ jsx18("option", { value: "", children: "Custom" }),
|
|
2446
|
+
[90, 45, 30, 15].map((n) => /* @__PURE__ */ jsxs18("option", { value: n, children: [
|
|
2344
2447
|
n,
|
|
2345
2448
|
"\xB0"
|
|
2346
2449
|
] }, n))
|
|
@@ -2348,13 +2451,13 @@ function VectorToolbar({
|
|
|
2348
2451
|
}
|
|
2349
2452
|
)
|
|
2350
2453
|
] }),
|
|
2351
|
-
showPathEdit && /* @__PURE__ */
|
|
2352
|
-
VECTOR_PATH_ACTIONS.map((a) => /* @__PURE__ */
|
|
2454
|
+
showPathEdit && /* @__PURE__ */ jsxs18("div", { className: "ml-1 flex items-center gap-1", role: "group", "aria-label": "Path editing", children: [
|
|
2455
|
+
VECTOR_PATH_ACTIONS.map((a) => /* @__PURE__ */ jsx18(
|
|
2353
2456
|
"button",
|
|
2354
2457
|
{
|
|
2355
2458
|
type: "button",
|
|
2356
2459
|
"data-vector-path-action": a.id,
|
|
2357
|
-
className:
|
|
2460
|
+
className: buttonClass15,
|
|
2358
2461
|
title: a.shortcut ? `${a.title} (${modKeyLabel()}+${a.shortcut})` : a.title,
|
|
2359
2462
|
"aria-label": a.title,
|
|
2360
2463
|
disabled: !a.enabled(count, points),
|
|
@@ -2363,12 +2466,12 @@ function VectorToolbar({
|
|
|
2363
2466
|
},
|
|
2364
2467
|
a.id
|
|
2365
2468
|
)),
|
|
2366
|
-
VECTOR_EDIT_TOGGLES.map((t) => /* @__PURE__ */
|
|
2469
|
+
VECTOR_EDIT_TOGGLES.map((t) => /* @__PURE__ */ jsx18(
|
|
2367
2470
|
"button",
|
|
2368
2471
|
{
|
|
2369
2472
|
type: "button",
|
|
2370
2473
|
"data-vector-edit": t.key,
|
|
2371
|
-
className:
|
|
2474
|
+
className: buttonClass15,
|
|
2372
2475
|
"aria-pressed": editing[t.key],
|
|
2373
2476
|
title: t.title,
|
|
2374
2477
|
"aria-label": t.title,
|
|
@@ -2377,9 +2480,9 @@ function VectorToolbar({
|
|
|
2377
2480
|
},
|
|
2378
2481
|
t.key
|
|
2379
2482
|
)),
|
|
2380
|
-
state.tool === "pencil" && /* @__PURE__ */
|
|
2483
|
+
state.tool === "pencil" && /* @__PURE__ */ jsxs18("label", { className: "flex items-center gap-1 text-xs text-foreground", children: [
|
|
2381
2484
|
"Smoothing",
|
|
2382
|
-
/* @__PURE__ */
|
|
2485
|
+
/* @__PURE__ */ jsx18(
|
|
2383
2486
|
"input",
|
|
2384
2487
|
{
|
|
2385
2488
|
type: "range",
|
|
@@ -2393,9 +2496,9 @@ function VectorToolbar({
|
|
|
2393
2496
|
}
|
|
2394
2497
|
)
|
|
2395
2498
|
] }),
|
|
2396
|
-
state.tool === "eraser" && /* @__PURE__ */
|
|
2499
|
+
state.tool === "eraser" && /* @__PURE__ */ jsxs18("label", { className: "flex items-center gap-1 text-xs text-foreground", children: [
|
|
2397
2500
|
"Size",
|
|
2398
|
-
/* @__PURE__ */
|
|
2501
|
+
/* @__PURE__ */ jsx18(
|
|
2399
2502
|
"input",
|
|
2400
2503
|
{
|
|
2401
2504
|
type: "number",
|
|
@@ -2411,12 +2514,12 @@ function VectorToolbar({
|
|
|
2411
2514
|
}
|
|
2412
2515
|
)
|
|
2413
2516
|
] }),
|
|
2414
|
-
state.tool === "paintBucket" && /* @__PURE__ */
|
|
2517
|
+
state.tool === "paintBucket" && /* @__PURE__ */ jsx18(
|
|
2415
2518
|
"button",
|
|
2416
2519
|
{
|
|
2417
2520
|
type: "button",
|
|
2418
2521
|
"data-vector-fill-gap": "",
|
|
2419
|
-
className:
|
|
2522
|
+
className: buttonClass15,
|
|
2420
2523
|
"aria-pressed": editing.fillGap > 0,
|
|
2421
2524
|
title: "Close small gaps between path ends when filling",
|
|
2422
2525
|
"aria-label": "Close gaps",
|
|
@@ -2425,12 +2528,12 @@ function VectorToolbar({
|
|
|
2425
2528
|
}
|
|
2426
2529
|
)
|
|
2427
2530
|
] }),
|
|
2428
|
-
showDistort && /* @__PURE__ */
|
|
2531
|
+
showDistort && /* @__PURE__ */ jsx18("div", { className: "ml-1 flex items-center gap-1", role: "group", "aria-label": "Distort", children: /* @__PURE__ */ jsx18(
|
|
2429
2532
|
"button",
|
|
2430
2533
|
{
|
|
2431
2534
|
type: "button",
|
|
2432
2535
|
"data-vector-free-distort": "",
|
|
2433
|
-
className:
|
|
2536
|
+
className: buttonClass15,
|
|
2434
2537
|
"aria-pressed": state.freeDistort,
|
|
2435
2538
|
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)`,
|
|
2436
2539
|
"aria-label": "Free Distort",
|
|
@@ -2438,15 +2541,15 @@ function VectorToolbar({
|
|
|
2438
2541
|
children: "Distort"
|
|
2439
2542
|
}
|
|
2440
2543
|
) }),
|
|
2441
|
-
showBlend && /* @__PURE__ */
|
|
2442
|
-
showArrange && /* @__PURE__ */
|
|
2443
|
-
/* @__PURE__ */
|
|
2444
|
-
/* @__PURE__ */
|
|
2544
|
+
showBlend && /* @__PURE__ */ jsx18(VectorBlendControls, { controller }),
|
|
2545
|
+
showArrange && /* @__PURE__ */ jsxs18(Fragment6, { children: [
|
|
2546
|
+
/* @__PURE__ */ jsxs18("div", { className: "ml-1 flex items-center gap-1", role: "group", "aria-label": "Combine", children: [
|
|
2547
|
+
/* @__PURE__ */ jsx18(
|
|
2445
2548
|
"button",
|
|
2446
2549
|
{
|
|
2447
2550
|
type: "button",
|
|
2448
2551
|
"data-vector-live-boolean": "",
|
|
2449
|
-
className:
|
|
2552
|
+
className: buttonClass15,
|
|
2450
2553
|
"aria-pressed": live,
|
|
2451
2554
|
title: "Live booleans: keep the shapes editable",
|
|
2452
2555
|
"aria-label": "Live booleans",
|
|
@@ -2463,12 +2566,12 @@ function VectorToolbar({
|
|
|
2463
2566
|
act("\u25D0", `Make Clipping Mask (${modKeyLabel()}+7)`, () => controller.makeMask("clip"), count < 2),
|
|
2464
2567
|
act("\u25D1", `Release Mask (${modKeyLabel()}+Alt+7)`, () => controller.releaseMask(), !maskSelected)
|
|
2465
2568
|
] }),
|
|
2466
|
-
/* @__PURE__ */
|
|
2569
|
+
/* @__PURE__ */ jsx18("div", { className: "ml-1 flex items-center gap-1", role: "group", "aria-label": "Pathfinder", children: VECTOR_PATHFINDER_ACTIONS.map((a) => /* @__PURE__ */ jsx18(
|
|
2467
2570
|
"button",
|
|
2468
2571
|
{
|
|
2469
2572
|
type: "button",
|
|
2470
2573
|
"data-vector-pathfinder": a.id,
|
|
2471
|
-
className:
|
|
2574
|
+
className: buttonClass15,
|
|
2472
2575
|
title: a.title,
|
|
2473
2576
|
"aria-label": a.title,
|
|
2474
2577
|
disabled: count < a.min,
|
|
@@ -2477,7 +2580,7 @@ function VectorToolbar({
|
|
|
2477
2580
|
},
|
|
2478
2581
|
a.id
|
|
2479
2582
|
)) }),
|
|
2480
|
-
/* @__PURE__ */
|
|
2583
|
+
/* @__PURE__ */ jsxs18("div", { className: "ml-1 flex items-center gap-1", role: "group", "aria-label": "Arrange", children: [
|
|
2481
2584
|
act("\u21C8", "Bring to Front", () => controller.arrange("front"), count < 1),
|
|
2482
2585
|
act("\u21CA", "Send to Back", () => controller.arrange("back"), count < 1),
|
|
2483
2586
|
act("\u21E4", "Align Left", () => controller.align("left"), count < 1),
|
|
@@ -2495,19 +2598,19 @@ function VectorBlendControls({ controller }) {
|
|
|
2495
2598
|
const blend = getVectorBlendControls(state);
|
|
2496
2599
|
const o = blend.options;
|
|
2497
2600
|
const selected = blend.ids.length > 0;
|
|
2498
|
-
return /* @__PURE__ */
|
|
2499
|
-
/* @__PURE__ */
|
|
2500
|
-
/* @__PURE__ */
|
|
2601
|
+
return /* @__PURE__ */ jsxs18("div", { className: "ml-1 flex items-center gap-1", role: "group", "aria-label": "Blend", "data-vector-blend-controls": "", children: [
|
|
2602
|
+
/* @__PURE__ */ jsx18("button", { type: "button", "data-vector-blend-action": "make", className: buttonClass15, title: "Make Blend", "aria-label": "Make Blend", disabled: !blend.canBlend, onClick: () => controller.blend(), children: "\u29D3" }),
|
|
2603
|
+
/* @__PURE__ */ jsx18(
|
|
2501
2604
|
"select",
|
|
2502
2605
|
{
|
|
2503
2606
|
"aria-label": "Blend spacing",
|
|
2504
2607
|
className: "h-7 rounded border border-border bg-background px-1 text-xs",
|
|
2505
2608
|
value: o.spacing,
|
|
2506
2609
|
onChange: (e) => applyVectorBlendOptions(controller, { spacing: e.target.value }),
|
|
2507
|
-
children: VECTOR_BLEND_SPACINGS.map((sp) => /* @__PURE__ */
|
|
2610
|
+
children: VECTOR_BLEND_SPACINGS.map((sp) => /* @__PURE__ */ jsx18("option", { value: sp, children: VECTOR_BLEND_SPACING_LABELS[sp] }, sp))
|
|
2508
2611
|
}
|
|
2509
2612
|
),
|
|
2510
|
-
o.spacing !== "smoothColor" && /* @__PURE__ */
|
|
2613
|
+
o.spacing !== "smoothColor" && /* @__PURE__ */ jsx18(
|
|
2511
2614
|
"input",
|
|
2512
2615
|
{
|
|
2513
2616
|
type: "number",
|
|
@@ -2523,12 +2626,12 @@ function VectorBlendControls({ controller }) {
|
|
|
2523
2626
|
}
|
|
2524
2627
|
}
|
|
2525
2628
|
),
|
|
2526
|
-
/* @__PURE__ */
|
|
2629
|
+
/* @__PURE__ */ jsx18(
|
|
2527
2630
|
"button",
|
|
2528
2631
|
{
|
|
2529
2632
|
type: "button",
|
|
2530
2633
|
"data-vector-blend-action": "orient",
|
|
2531
|
-
className:
|
|
2634
|
+
className: buttonClass15,
|
|
2532
2635
|
"aria-pressed": o.orientToSpine,
|
|
2533
2636
|
title: "Orient steps to the spine",
|
|
2534
2637
|
"aria-label": "Orient to spine",
|
|
@@ -2536,12 +2639,12 @@ function VectorBlendControls({ controller }) {
|
|
|
2536
2639
|
children: "\u293F"
|
|
2537
2640
|
}
|
|
2538
2641
|
),
|
|
2539
|
-
/* @__PURE__ */
|
|
2642
|
+
/* @__PURE__ */ jsx18(
|
|
2540
2643
|
"button",
|
|
2541
2644
|
{
|
|
2542
2645
|
type: "button",
|
|
2543
2646
|
"data-vector-blend-action": "spine",
|
|
2544
|
-
className:
|
|
2647
|
+
className: buttonClass15,
|
|
2545
2648
|
title: "Replace Spine (select a blend and a path)",
|
|
2546
2649
|
"aria-label": "Replace Spine",
|
|
2547
2650
|
disabled: !blend.canReplaceSpine,
|
|
@@ -2549,12 +2652,12 @@ function VectorBlendControls({ controller }) {
|
|
|
2549
2652
|
children: "\u2307"
|
|
2550
2653
|
}
|
|
2551
2654
|
),
|
|
2552
|
-
/* @__PURE__ */
|
|
2553
|
-
/* @__PURE__ */
|
|
2655
|
+
/* @__PURE__ */ jsx18("button", { type: "button", "data-vector-blend-action": "expand", className: buttonClass15, title: "Expand Blend", "aria-label": "Expand Blend", disabled: !selected, onClick: () => controller.expandBlend(), children: "\u29C9" }),
|
|
2656
|
+
/* @__PURE__ */ jsx18("button", { type: "button", "data-vector-blend-action": "release", className: buttonClass15, title: "Release Blend", "aria-label": "Release Blend", disabled: !selected, onClick: () => controller.releaseBlend(), children: "\u29C4" })
|
|
2554
2657
|
] });
|
|
2555
2658
|
}
|
|
2556
|
-
var
|
|
2557
|
-
var
|
|
2659
|
+
var selectClass13 = "h-7 min-w-0 flex-1 rounded border border-border bg-background px-1 text-xs";
|
|
2660
|
+
var numberClass11 = "h-7 w-16 rounded border border-border bg-background px-1.5 text-xs";
|
|
2558
2661
|
function VectorStylePanel({ controller, className }) {
|
|
2559
2662
|
const state = useVectorEditorState(controller);
|
|
2560
2663
|
const style = getVectorSelectionStyle(state);
|
|
@@ -2586,17 +2689,17 @@ function VectorStylePanel({ controller, className }) {
|
|
|
2586
2689
|
if (style) controller.setWidthProfile(id);
|
|
2587
2690
|
else controller.setDefaults({ strokeWidthProfile: widthProfilePreset(id)?.length ? widthProfilePreset(id) : null });
|
|
2588
2691
|
};
|
|
2589
|
-
const mixed = (key) => style?.mixed[key] ? /* @__PURE__ */
|
|
2692
|
+
const mixed = (key) => style?.mixed[key] ? /* @__PURE__ */ jsx18("span", { className: "text-[11px] text-muted-foreground", children: "Mixed" }) : null;
|
|
2590
2693
|
const arrowRow = (end, label) => {
|
|
2591
2694
|
const key = end === "start" ? "startArrow" : "endArrow";
|
|
2592
2695
|
const scaleKey = end === "start" ? "startArrowScale" : "endArrowScale";
|
|
2593
|
-
return /* @__PURE__ */
|
|
2594
|
-
/* @__PURE__ */
|
|
2595
|
-
/* @__PURE__ */
|
|
2596
|
-
/* @__PURE__ */
|
|
2597
|
-
VECTOR_ARROWHEADS.map((h) => /* @__PURE__ */
|
|
2696
|
+
return /* @__PURE__ */ jsxs18("div", { className: "flex items-center gap-2", "data-vector-style": key, children: [
|
|
2697
|
+
/* @__PURE__ */ jsx18("span", { className: "w-16 text-xs text-foreground", children: label }),
|
|
2698
|
+
/* @__PURE__ */ jsxs18("select", { "aria-label": `${label} arrowhead`, className: selectClass13, value: source[key] ?? "", onChange: (e) => apply({ [key]: e.target.value || null }), children: [
|
|
2699
|
+
/* @__PURE__ */ jsx18("option", { value: "", children: "None" }),
|
|
2700
|
+
VECTOR_ARROWHEADS.map((h) => /* @__PURE__ */ jsx18("option", { value: h, children: VECTOR_ARROWHEAD_LABELS[h] }, h))
|
|
2598
2701
|
] }),
|
|
2599
|
-
/* @__PURE__ */
|
|
2702
|
+
/* @__PURE__ */ jsx18(
|
|
2600
2703
|
"input",
|
|
2601
2704
|
{
|
|
2602
2705
|
type: "number",
|
|
@@ -2604,7 +2707,7 @@ function VectorStylePanel({ controller, className }) {
|
|
|
2604
2707
|
step: 0.25,
|
|
2605
2708
|
"aria-label": `${label} arrowhead scale`,
|
|
2606
2709
|
title: "Scale (\xD7 stroke width)",
|
|
2607
|
-
className:
|
|
2710
|
+
className: numberClass11,
|
|
2608
2711
|
value: source[scaleKey],
|
|
2609
2712
|
onChange: (e) => {
|
|
2610
2713
|
const n = parseFloat(e.target.value);
|
|
@@ -2622,12 +2725,12 @@ function VectorStylePanel({ controller, className }) {
|
|
|
2622
2725
|
const paint = source[key];
|
|
2623
2726
|
const hex = vectorPaintToHex6(paint);
|
|
2624
2727
|
const on = paint !== null && paint !== "none";
|
|
2625
|
-
return /* @__PURE__ */
|
|
2626
|
-
/* @__PURE__ */
|
|
2627
|
-
/* @__PURE__ */
|
|
2728
|
+
return /* @__PURE__ */ jsxs18("div", { className: "flex items-center gap-2", "data-vector-style": key, children: [
|
|
2729
|
+
/* @__PURE__ */ jsxs18("label", { className: "flex w-16 items-center gap-1.5 text-xs text-foreground", children: [
|
|
2730
|
+
/* @__PURE__ */ jsx18("input", { type: "checkbox", checked: on, "aria-label": `${label} on`, onChange: (e) => apply({ [key]: e.target.checked ? hex ?? "#000000" : null }) }),
|
|
2628
2731
|
label
|
|
2629
2732
|
] }),
|
|
2630
|
-
/* @__PURE__ */
|
|
2733
|
+
/* @__PURE__ */ jsx18(
|
|
2631
2734
|
"input",
|
|
2632
2735
|
{
|
|
2633
2736
|
type: "color",
|
|
@@ -2638,18 +2741,18 @@ function VectorStylePanel({ controller, className }) {
|
|
|
2638
2741
|
onChange: (e) => apply({ [key]: e.target.value })
|
|
2639
2742
|
}
|
|
2640
2743
|
),
|
|
2641
|
-
on && !hex && /* @__PURE__ */
|
|
2642
|
-
style?.mixed[key] && /* @__PURE__ */
|
|
2744
|
+
on && !hex && /* @__PURE__ */ jsx18("span", { className: "truncate text-[11px] text-muted-foreground", children: typeof paint === "string" ? paint : "Gradient" }),
|
|
2745
|
+
style?.mixed[key] && /* @__PURE__ */ jsx18("span", { className: "text-[11px] text-muted-foreground", children: "Mixed" })
|
|
2643
2746
|
] });
|
|
2644
2747
|
};
|
|
2645
|
-
return /* @__PURE__ */
|
|
2646
|
-
/* @__PURE__ */
|
|
2748
|
+
return /* @__PURE__ */ jsxs18("div", { className: `space-y-2 ${className ?? ""}`, "aria-label": style ? "Selection style" : "New shape style", children: [
|
|
2749
|
+
/* @__PURE__ */ jsx18("p", { className: "text-[11px] font-medium uppercase tracking-wide text-muted-foreground", children: style ? "Selection" : "New shapes" }),
|
|
2647
2750
|
paintRow("fill", "Fill"),
|
|
2648
2751
|
paintRow("stroke", "Stroke"),
|
|
2649
|
-
style && /* @__PURE__ */
|
|
2650
|
-
/* @__PURE__ */
|
|
2651
|
-
/* @__PURE__ */
|
|
2652
|
-
/* @__PURE__ */
|
|
2752
|
+
style && /* @__PURE__ */ jsx18(VectorGradientEditor, { controller }),
|
|
2753
|
+
/* @__PURE__ */ jsxs18("label", { className: "flex items-center gap-2 text-xs text-foreground", children: [
|
|
2754
|
+
/* @__PURE__ */ jsx18("span", { className: "w-16", children: "Width" }),
|
|
2755
|
+
/* @__PURE__ */ jsx18(
|
|
2653
2756
|
"input",
|
|
2654
2757
|
{
|
|
2655
2758
|
type: "number",
|
|
@@ -2665,33 +2768,33 @@ function VectorStylePanel({ controller, className }) {
|
|
|
2665
2768
|
}
|
|
2666
2769
|
)
|
|
2667
2770
|
] }),
|
|
2668
|
-
/* @__PURE__ */
|
|
2669
|
-
/* @__PURE__ */
|
|
2670
|
-
/* @__PURE__ */
|
|
2771
|
+
/* @__PURE__ */ jsxs18("label", { className: "flex items-center gap-2 text-xs text-foreground", "data-vector-style": "strokeAlign", children: [
|
|
2772
|
+
/* @__PURE__ */ jsx18("span", { className: "w-16", children: "Align" }),
|
|
2773
|
+
/* @__PURE__ */ jsx18("select", { "aria-label": "Stroke alignment", className: selectClass13, value: source.strokeAlign, onChange: (e) => apply({ strokeAlign: e.target.value }), children: Object.keys(VECTOR_STROKE_ALIGN_LABELS2).map((a) => /* @__PURE__ */ jsx18("option", { value: a, children: VECTOR_STROKE_ALIGN_LABELS2[a] }, a)) }),
|
|
2671
2774
|
mixed("strokeAlign")
|
|
2672
2775
|
] }),
|
|
2673
|
-
/* @__PURE__ */
|
|
2674
|
-
/* @__PURE__ */
|
|
2675
|
-
/* @__PURE__ */
|
|
2776
|
+
/* @__PURE__ */ jsxs18("div", { className: "flex items-center gap-2 text-xs text-foreground", "data-vector-style": "widthProfile", children: [
|
|
2777
|
+
/* @__PURE__ */ jsx18("span", { className: "w-16", children: "Profile" }),
|
|
2778
|
+
/* @__PURE__ */ jsxs18(
|
|
2676
2779
|
"select",
|
|
2677
2780
|
{
|
|
2678
2781
|
"aria-label": "Width profile",
|
|
2679
|
-
className:
|
|
2782
|
+
className: selectClass13,
|
|
2680
2783
|
value: source.widthProfile,
|
|
2681
2784
|
onChange: (e) => {
|
|
2682
2785
|
if (e.target.value !== "custom") setProfile(e.target.value);
|
|
2683
2786
|
},
|
|
2684
2787
|
children: [
|
|
2685
|
-
VECTOR_WIDTH_PRESETS.map((p) => /* @__PURE__ */
|
|
2686
|
-
source.widthProfile === "custom" && /* @__PURE__ */
|
|
2788
|
+
VECTOR_WIDTH_PRESETS.map((p) => /* @__PURE__ */ jsx18("option", { value: p.id, children: p.label }, p.id)),
|
|
2789
|
+
source.widthProfile === "custom" && /* @__PURE__ */ jsx18("option", { value: "custom", disabled: true, children: "Custom" })
|
|
2687
2790
|
]
|
|
2688
2791
|
}
|
|
2689
2792
|
),
|
|
2690
|
-
/* @__PURE__ */
|
|
2793
|
+
/* @__PURE__ */ jsx18(
|
|
2691
2794
|
"button",
|
|
2692
2795
|
{
|
|
2693
2796
|
type: "button",
|
|
2694
|
-
className:
|
|
2797
|
+
className: buttonClass15,
|
|
2695
2798
|
title: "Reset to uniform width",
|
|
2696
2799
|
"aria-label": "Reset to uniform width",
|
|
2697
2800
|
disabled: source.widthProfile === "uniform" && !style?.mixed.widthProfile,
|
|
@@ -2701,27 +2804,27 @@ function VectorStylePanel({ controller, className }) {
|
|
|
2701
2804
|
),
|
|
2702
2805
|
mixed("widthProfile")
|
|
2703
2806
|
] }),
|
|
2704
|
-
source.hasOpenPath && /* @__PURE__ */
|
|
2807
|
+
source.hasOpenPath && /* @__PURE__ */ jsxs18(Fragment6, { children: [
|
|
2705
2808
|
arrowRow("start", "Start"),
|
|
2706
2809
|
arrowRow("end", "End"),
|
|
2707
|
-
(source.startArrow || source.endArrow) && /* @__PURE__ */
|
|
2708
|
-
/* @__PURE__ */
|
|
2709
|
-
/* @__PURE__ */
|
|
2710
|
-
/* @__PURE__ */
|
|
2711
|
-
/* @__PURE__ */
|
|
2810
|
+
(source.startArrow || source.endArrow) && /* @__PURE__ */ jsxs18("label", { className: "flex items-center gap-2 text-xs text-foreground", "data-vector-style": "arrowAlign", children: [
|
|
2811
|
+
/* @__PURE__ */ jsx18("span", { className: "w-16", children: "Heads" }),
|
|
2812
|
+
/* @__PURE__ */ jsxs18("select", { "aria-label": "Arrowhead alignment", className: selectClass13, value: source.arrowAlign, onChange: (e) => apply({ arrowAlign: e.target.value }), children: [
|
|
2813
|
+
/* @__PURE__ */ jsx18("option", { value: "extend", children: "Tip past end" }),
|
|
2814
|
+
/* @__PURE__ */ jsx18("option", { value: "tip", children: "Tip at end" })
|
|
2712
2815
|
] })
|
|
2713
2816
|
] })
|
|
2714
2817
|
] }),
|
|
2715
|
-
source.corners > 0 && /* @__PURE__ */
|
|
2716
|
-
/* @__PURE__ */
|
|
2717
|
-
/* @__PURE__ */
|
|
2818
|
+
source.corners > 0 && /* @__PURE__ */ jsxs18("div", { className: "flex items-center gap-2", "data-vector-style": "corners", children: [
|
|
2819
|
+
/* @__PURE__ */ jsx18("span", { className: "w-16 text-xs text-foreground", children: "Corners" }),
|
|
2820
|
+
/* @__PURE__ */ jsx18(
|
|
2718
2821
|
"input",
|
|
2719
2822
|
{
|
|
2720
2823
|
type: "number",
|
|
2721
2824
|
min: 0,
|
|
2722
2825
|
step: 1,
|
|
2723
2826
|
"aria-label": "Corner radius",
|
|
2724
|
-
className:
|
|
2827
|
+
className: numberClass11,
|
|
2725
2828
|
value: Math.round(source.cornerRadius * 100) / 100,
|
|
2726
2829
|
onChange: (e) => {
|
|
2727
2830
|
const n = parseFloat(e.target.value);
|
|
@@ -2729,12 +2832,12 @@ function VectorStylePanel({ controller, className }) {
|
|
|
2729
2832
|
}
|
|
2730
2833
|
}
|
|
2731
2834
|
),
|
|
2732
|
-
/* @__PURE__ */
|
|
2835
|
+
/* @__PURE__ */ jsx18("select", { "aria-label": "Corner kind", className: selectClass13, value: source.cornerKind, onChange: (e) => setCorners({ kind: e.target.value }), children: VECTOR_CORNER_KINDS.map((k) => /* @__PURE__ */ jsx18("option", { value: k, children: VECTOR_CORNER_KIND_LABELS[k] }, k)) }),
|
|
2733
2836
|
mixed("cornerRadius")
|
|
2734
2837
|
] }),
|
|
2735
|
-
style && source.corners > 0 && source.cornerKind === "round" && source.cornerRadius > 0 && /* @__PURE__ */
|
|
2736
|
-
/* @__PURE__ */
|
|
2737
|
-
/* @__PURE__ */
|
|
2838
|
+
style && source.corners > 0 && source.cornerKind === "round" && source.cornerRadius > 0 && /* @__PURE__ */ jsxs18("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: [
|
|
2839
|
+
/* @__PURE__ */ jsx18("span", { className: "w-16", children: "Smoothing" }),
|
|
2840
|
+
/* @__PURE__ */ jsx18(
|
|
2738
2841
|
"input",
|
|
2739
2842
|
{
|
|
2740
2843
|
type: "range",
|
|
@@ -2749,9 +2852,9 @@ function VectorStylePanel({ controller, className }) {
|
|
|
2749
2852
|
}
|
|
2750
2853
|
)
|
|
2751
2854
|
] }),
|
|
2752
|
-
style && /* @__PURE__ */
|
|
2753
|
-
/* @__PURE__ */
|
|
2754
|
-
/* @__PURE__ */
|
|
2855
|
+
style && /* @__PURE__ */ jsxs18("label", { className: "flex items-center gap-2 text-xs text-foreground", children: [
|
|
2856
|
+
/* @__PURE__ */ jsx18("span", { className: "w-16", children: "Opacity" }),
|
|
2857
|
+
/* @__PURE__ */ jsx18(
|
|
2755
2858
|
"input",
|
|
2756
2859
|
{
|
|
2757
2860
|
type: "range",
|
|
@@ -2765,24 +2868,26 @@ function VectorStylePanel({ controller, className }) {
|
|
|
2765
2868
|
}
|
|
2766
2869
|
)
|
|
2767
2870
|
] }),
|
|
2768
|
-
/* @__PURE__ */
|
|
2769
|
-
style && /* @__PURE__ */
|
|
2770
|
-
style && /* @__PURE__ */
|
|
2771
|
-
style && /* @__PURE__ */
|
|
2772
|
-
style && /* @__PURE__ */
|
|
2773
|
-
/* @__PURE__ */
|
|
2774
|
-
/* @__PURE__ */
|
|
2775
|
-
/* @__PURE__ */
|
|
2776
|
-
/* @__PURE__ */
|
|
2777
|
-
/* @__PURE__ */
|
|
2778
|
-
/* @__PURE__ */
|
|
2779
|
-
/* @__PURE__ */
|
|
2871
|
+
/* @__PURE__ */ jsx18(VectorTextPanel, { controller }),
|
|
2872
|
+
style && /* @__PURE__ */ jsx18(VectorAppearancePanel, { controller }),
|
|
2873
|
+
style && /* @__PURE__ */ jsx18(VectorEffectsPanel, { controller }),
|
|
2874
|
+
style && /* @__PURE__ */ jsx18(VectorEnvelopePanel, { controller }),
|
|
2875
|
+
style && /* @__PURE__ */ jsx18(VectorMaskPanel, { controller }),
|
|
2876
|
+
/* @__PURE__ */ jsx18(VectorFramePanel, { controller }),
|
|
2877
|
+
/* @__PURE__ */ jsx18(VectorConnectorPanel, { controller }),
|
|
2878
|
+
/* @__PURE__ */ jsx18(VectorShadingPanel, { controller }),
|
|
2879
|
+
/* @__PURE__ */ jsx18(VectorSymmetryPanel, { controller }),
|
|
2880
|
+
/* @__PURE__ */ jsx18(VectorPerspectivePanel, { controller }),
|
|
2881
|
+
/* @__PURE__ */ jsx18(VectorLensPanel, { controller }),
|
|
2882
|
+
/* @__PURE__ */ jsx18(VectorTracePanel, { controller }),
|
|
2883
|
+
/* @__PURE__ */ jsx18(VectorConstraintsPanel, { controller }),
|
|
2884
|
+
/* @__PURE__ */ jsx18(VectorSymbolsPanel, { controller })
|
|
2780
2885
|
] });
|
|
2781
2886
|
}
|
|
2782
2887
|
|
|
2783
2888
|
// src/vector/VectorProviderEffectsPanel.tsx
|
|
2784
2889
|
import { useState as useState7, useSyncExternalStore as useSyncExternalStore2 } from "react";
|
|
2785
|
-
import { Fragment as Fragment7, jsx as
|
|
2890
|
+
import { Fragment as Fragment7, jsx as jsx19, jsxs as jsxs19 } from "react/jsx-runtime";
|
|
2786
2891
|
var btn = "rounded border border-border px-1.5 py-0.5 text-[11px] disabled:opacity-40";
|
|
2787
2892
|
function Controls({ controller, group }) {
|
|
2788
2893
|
const provider = controller.effectsProvider;
|
|
@@ -2790,11 +2895,11 @@ function Controls({ controller, group }) {
|
|
|
2790
2895
|
const { description, error } = useEffectDescription(provider, tag.effect);
|
|
2791
2896
|
const [message, setMessage] = useState7(null);
|
|
2792
2897
|
const run = (work) => void work.then(() => setMessage(null), (e) => setMessage(e instanceof Error ? e.message : String(e)));
|
|
2793
|
-
if (!provider) return /* @__PURE__ */
|
|
2794
|
-
if (error) return /* @__PURE__ */
|
|
2795
|
-
if (!description) return /* @__PURE__ */
|
|
2796
|
-
return /* @__PURE__ */
|
|
2797
|
-
/* @__PURE__ */
|
|
2898
|
+
if (!provider) return /* @__PURE__ */ jsx19("p", { className: "text-[11px] text-muted-foreground", children: "No effects provider: the shapes are kept as they are." });
|
|
2899
|
+
if (error) return /* @__PURE__ */ jsx19("p", { className: "text-[11px] text-amber-500", children: error });
|
|
2900
|
+
if (!description) return /* @__PURE__ */ jsx19("p", { className: "text-[11px] text-muted-foreground", children: "Loading\u2026" });
|
|
2901
|
+
return /* @__PURE__ */ jsxs19(Fragment7, { children: [
|
|
2902
|
+
/* @__PURE__ */ jsx19(
|
|
2798
2903
|
EffectParameters,
|
|
2799
2904
|
{
|
|
2800
2905
|
description,
|
|
@@ -2804,7 +2909,7 @@ function Controls({ controller, group }) {
|
|
|
2804
2909
|
onPreset: (v) => run(controller.updateVectorEffect(group.id, v))
|
|
2805
2910
|
}
|
|
2806
2911
|
),
|
|
2807
|
-
message && /* @__PURE__ */
|
|
2912
|
+
message && /* @__PURE__ */ jsx19("p", { role: "alert", className: "text-[11px] text-destructive", children: message })
|
|
2808
2913
|
] });
|
|
2809
2914
|
}
|
|
2810
2915
|
function VectorProviderEffectsPanel({ controller, className = "" }) {
|
|
@@ -2823,41 +2928,41 @@ function VectorProviderEffectsPanel({ controller, className = "" }) {
|
|
|
2823
2928
|
setMessage(null);
|
|
2824
2929
|
Promise.resolve().then(work).catch((e) => setMessage(e instanceof Error ? e.message : String(e)));
|
|
2825
2930
|
};
|
|
2826
|
-
return /* @__PURE__ */
|
|
2827
|
-
/* @__PURE__ */
|
|
2828
|
-
/* @__PURE__ */
|
|
2829
|
-
/* @__PURE__ */
|
|
2931
|
+
return /* @__PURE__ */ jsxs19("section", { className: `flex flex-col gap-2 text-xs ${className}`, "aria-label": "Vector effects", "data-vector-provider-effects": "", children: [
|
|
2932
|
+
/* @__PURE__ */ jsxs19("div", { className: "flex items-center gap-1", children: [
|
|
2933
|
+
/* @__PURE__ */ jsx19("span", { className: "flex-1 font-semibold", children: "Effects" }),
|
|
2934
|
+
/* @__PURE__ */ jsx19("button", { type: "button", className: btn, disabled: !provider, "aria-pressed": browse, onClick: () => setBrowse(!browse), children: "Add effect\u2026" })
|
|
2830
2935
|
] }),
|
|
2831
|
-
!provider && /* @__PURE__ */
|
|
2832
|
-
browse && /* @__PURE__ */
|
|
2833
|
-
selected.map((g) => /* @__PURE__ */
|
|
2834
|
-
/* @__PURE__ */
|
|
2835
|
-
/* @__PURE__ */
|
|
2836
|
-
/* @__PURE__ */
|
|
2936
|
+
!provider && /* @__PURE__ */ jsx19("p", { className: "text-[11px] text-muted-foreground", children: "No effects provider is registered. Effect groups are kept as shapes." }),
|
|
2937
|
+
browse && /* @__PURE__ */ jsx19(EffectsBrowser, { provider, kinds: ["vector"], title: "Vector effects", onPick: (e) => (setBrowse(false), run(() => controller.addVectorEffect(e.id))) }),
|
|
2938
|
+
selected.map((g) => /* @__PURE__ */ jsxs19("div", { className: "space-y-1 rounded border border-border p-1", "data-vector-effect-group": g.id, children: [
|
|
2939
|
+
/* @__PURE__ */ jsxs19("div", { className: "flex items-center gap-1", children: [
|
|
2940
|
+
/* @__PURE__ */ jsx19("span", { className: "min-w-0 flex-1 truncate font-medium", children: g.providerEffect.name ?? g.providerEffect.effect }),
|
|
2941
|
+
/* @__PURE__ */ jsx19("button", { type: "button", className: btn, title: "Keep the shapes as a plain group", onClick: () => run(() => controller.detachVectorEffect(g.id)), children: "Detach" })
|
|
2837
2942
|
] }),
|
|
2838
|
-
/* @__PURE__ */
|
|
2943
|
+
/* @__PURE__ */ jsx19(Controls, { controller, group: g })
|
|
2839
2944
|
] }, g.id)),
|
|
2840
|
-
groups.length > 0 && !selected.length && /* @__PURE__ */
|
|
2945
|
+
groups.length > 0 && !selected.length && /* @__PURE__ */ jsxs19("p", { className: "text-[11px] text-muted-foreground", children: [
|
|
2841
2946
|
"Select an effect group (",
|
|
2842
2947
|
groups.length,
|
|
2843
2948
|
" in the drawing) to change it."
|
|
2844
2949
|
] }),
|
|
2845
|
-
message && /* @__PURE__ */
|
|
2950
|
+
message && /* @__PURE__ */ jsx19("p", { role: "alert", className: "text-[11px] text-destructive", children: message })
|
|
2846
2951
|
] });
|
|
2847
2952
|
}
|
|
2848
2953
|
|
|
2849
2954
|
// src/vector/VectorEditor.tsx
|
|
2850
|
-
import { jsx as
|
|
2955
|
+
import { jsx as jsx20, jsxs as jsxs20 } from "react/jsx-runtime";
|
|
2851
2956
|
function VectorEditor({ controller, tools, showStylePanel = true, height = 520, canvasProps, effects, className }) {
|
|
2852
2957
|
useEffects(controller, effects);
|
|
2853
2958
|
const effectsShown = !!effects || controller.vectorEffectGroups().length > 0;
|
|
2854
|
-
return /* @__PURE__ */
|
|
2855
|
-
/* @__PURE__ */
|
|
2856
|
-
/* @__PURE__ */
|
|
2857
|
-
/* @__PURE__ */
|
|
2858
|
-
showStylePanel && /* @__PURE__ */
|
|
2859
|
-
/* @__PURE__ */
|
|
2860
|
-
effectsShown && /* @__PURE__ */
|
|
2959
|
+
return /* @__PURE__ */ jsxs20("div", { className: `flex flex-col gap-2 ${className ?? ""}`, "data-vector-editor": "", children: [
|
|
2960
|
+
/* @__PURE__ */ jsx20(VectorToolbar, { controller, tools }),
|
|
2961
|
+
/* @__PURE__ */ jsxs20("div", { className: "flex min-h-0 flex-col gap-2 md:flex-row", children: [
|
|
2962
|
+
/* @__PURE__ */ jsx20("div", { className: "relative min-h-[320px] flex-1 overflow-hidden rounded-md border border-border bg-muted/40", style: { height }, children: /* @__PURE__ */ jsx20(VectorCanvas, { controller, ...canvasProps }) }),
|
|
2963
|
+
showStylePanel && /* @__PURE__ */ jsxs20("div", { className: "flex w-full shrink-0 flex-col gap-2 md:w-56", children: [
|
|
2964
|
+
/* @__PURE__ */ jsx20(VectorStylePanel, { controller, className: "rounded-md border border-border p-3" }),
|
|
2965
|
+
effectsShown && /* @__PURE__ */ jsx20(VectorProviderEffectsPanel, { controller, className: "rounded-md border border-border p-3" })
|
|
2861
2966
|
] })
|
|
2862
2967
|
] })
|
|
2863
2968
|
] });
|
|
@@ -2875,8 +2980,10 @@ export {
|
|
|
2875
2980
|
VectorGradientAnnotator,
|
|
2876
2981
|
VectorGradientDefs,
|
|
2877
2982
|
VectorGradientEditor,
|
|
2983
|
+
VectorLensPanel,
|
|
2878
2984
|
VectorMaskPanel,
|
|
2879
2985
|
VectorMaskedNodes,
|
|
2986
|
+
VectorPerspectivePanel,
|
|
2880
2987
|
VectorProviderEffectsPanel,
|
|
2881
2988
|
VectorSceneNodes,
|
|
2882
2989
|
VectorShadingPanel,
|