@pixerate/editor-react 0.82.0 → 0.83.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 +319 -263
- package/dist/vector/index.cjs.map +1 -1
- package/dist/vector/index.d.cts +12 -1
- package/dist/vector/index.d.ts +12 -1
- package/dist/vector/index.js +220 -165
- package/dist/vector/index.js.map +1 -1
- package/package.json +3 -3
package/dist/vector/index.cjs
CHANGED
|
@@ -42,6 +42,7 @@ __export(vector_exports, {
|
|
|
42
42
|
VectorGradientAnnotator: () => VectorGradientAnnotator,
|
|
43
43
|
VectorGradientDefs: () => VectorGradientDefs,
|
|
44
44
|
VectorGradientEditor: () => VectorGradientEditor,
|
|
45
|
+
VectorLensPanel: () => VectorLensPanel,
|
|
45
46
|
VectorMaskPanel: () => VectorMaskPanel,
|
|
46
47
|
VectorMaskedNodes: () => VectorMaskedNodes,
|
|
47
48
|
VectorProviderEffectsPanel: () => VectorProviderEffectsPanel,
|
|
@@ -830,7 +831,7 @@ function VectorCanvas({
|
|
|
830
831
|
|
|
831
832
|
// src/vector/VectorToolbar.tsx
|
|
832
833
|
var import_react10 = __toESM(require("react"), 1);
|
|
833
|
-
var
|
|
834
|
+
var import_vector17 = require("@pixerate/editor/vector");
|
|
834
835
|
|
|
835
836
|
// src/vector/VectorEffectsPanel.tsx
|
|
836
837
|
var import_vector4 = require("@pixerate/editor/vector");
|
|
@@ -2081,16 +2082,69 @@ function VectorSymmetryPanel({ controller, className }) {
|
|
|
2081
2082
|
] });
|
|
2082
2083
|
}
|
|
2083
2084
|
|
|
2084
|
-
// src/vector/
|
|
2085
|
+
// src/vector/VectorLensPanel.tsx
|
|
2085
2086
|
var import_vector15 = require("@pixerate/editor/vector");
|
|
2086
2087
|
var import_jsx_runtime15 = require("react/jsx-runtime");
|
|
2087
2088
|
var selectClass10 = "h-7 min-w-0 flex-1 rounded border border-border bg-background px-1 text-xs";
|
|
2088
|
-
var numberClass9 = "h-7 w-
|
|
2089
|
+
var numberClass9 = "h-7 w-16 rounded border border-border bg-background px-1.5 text-xs";
|
|
2090
|
+
function VectorLensPanel({ controller, className }) {
|
|
2091
|
+
const state = useVectorEditorState(controller);
|
|
2092
|
+
const path = state.selection.map((id) => controller.getNode(id)).find((n) => n?.type === "path" && n.subpaths.some((sp) => sp.closed) && !n.connector);
|
|
2093
|
+
if (!path) return null;
|
|
2094
|
+
const lens = path.lens ?? null;
|
|
2095
|
+
const spec = lens ? import_vector15.VECTOR_LENS_SPECS[lens.type] : null;
|
|
2096
|
+
const ids = [path.id];
|
|
2097
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: `space-y-2 ${className ?? ""}`, "data-vector-lens-panel": "", "aria-label": "Lens", children: [
|
|
2098
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "flex flex-wrap items-center gap-1", children: [
|
|
2099
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "w-16 text-[11px] font-medium uppercase tracking-wide text-muted-foreground", children: "Lens" }),
|
|
2100
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
|
|
2101
|
+
"select",
|
|
2102
|
+
{
|
|
2103
|
+
"aria-label": "Lens type",
|
|
2104
|
+
className: selectClass10,
|
|
2105
|
+
value: lens?.type ?? "",
|
|
2106
|
+
onChange: (e) => e.target.value ? controller.setLens({ type: e.target.value }, { ids }) : controller.setLens(null, { ids }),
|
|
2107
|
+
children: [
|
|
2108
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)("option", { value: "", children: "None" }),
|
|
2109
|
+
import_vector15.VECTOR_LENS_TYPES.map((t) => /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("option", { value: t, children: import_vector15.VECTOR_LENS_LABELS[t] }, t))
|
|
2110
|
+
]
|
|
2111
|
+
}
|
|
2112
|
+
)
|
|
2113
|
+
] }),
|
|
2114
|
+
lens && spec && /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "flex flex-wrap items-center gap-1", children: [
|
|
2115
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "w-16" }),
|
|
2116
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
2117
|
+
"input",
|
|
2118
|
+
{
|
|
2119
|
+
type: "number",
|
|
2120
|
+
"aria-label": "Lens amount",
|
|
2121
|
+
title: `Amount: ${spec.unit} (${spec.min} to ${spec.max})`,
|
|
2122
|
+
className: numberClass9,
|
|
2123
|
+
min: spec.min,
|
|
2124
|
+
max: spec.max,
|
|
2125
|
+
step: lens.type === "magnify" ? 0.1 : 1,
|
|
2126
|
+
value: lens.amount,
|
|
2127
|
+
onChange: (e) => {
|
|
2128
|
+
const v = parseFloat(e.target.value);
|
|
2129
|
+
if (Number.isFinite(v)) controller.setLens({ amount: Math.min(spec.max, Math.max(spec.min, v)) }, { ids, merge: `lens-amount-${path.id}` });
|
|
2130
|
+
}
|
|
2131
|
+
}
|
|
2132
|
+
),
|
|
2133
|
+
spec.color !== null && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("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}` }) })
|
|
2134
|
+
] })
|
|
2135
|
+
] });
|
|
2136
|
+
}
|
|
2137
|
+
|
|
2138
|
+
// src/vector/VectorGradientEditor.tsx
|
|
2139
|
+
var import_vector16 = require("@pixerate/editor/vector");
|
|
2140
|
+
var import_jsx_runtime16 = require("react/jsx-runtime");
|
|
2141
|
+
var selectClass11 = "h-7 min-w-0 flex-1 rounded border border-border bg-background px-1 text-xs";
|
|
2142
|
+
var numberClass10 = "h-7 w-14 rounded border border-border bg-background px-1.5 text-xs";
|
|
2089
2143
|
var buttonClass13 = "inline-flex h-7 min-w-7 items-center justify-center rounded border border-border bg-background px-1.5 text-xs text-foreground hover:bg-muted disabled:cursor-not-allowed disabled:opacity-40 aria-pressed:bg-primary aria-pressed:text-primary-foreground";
|
|
2090
2144
|
var percent = (v) => Math.round(v * 1e3) / 10;
|
|
2091
2145
|
function VectorGradientEditor({ controller, className }) {
|
|
2092
2146
|
const state = useVectorEditorState(controller);
|
|
2093
|
-
const ed = (0,
|
|
2147
|
+
const ed = (0, import_vector16.getVectorGradientEditor)(state);
|
|
2094
2148
|
if (!ed) return null;
|
|
2095
2149
|
const g = ed.gradient;
|
|
2096
2150
|
const sel = ed.selected;
|
|
@@ -2098,26 +2152,26 @@ function VectorGradientEditor({ controller, className }) {
|
|
|
2098
2152
|
const setType = (value) => {
|
|
2099
2153
|
if (value === "solid") {
|
|
2100
2154
|
const first = ed.stops[0];
|
|
2101
|
-
controller.setStyle({ [ed.target]: (0,
|
|
2155
|
+
controller.setStyle({ [ed.target]: (0, import_vector16.vectorPaintToHex)(first?.color) ?? first?.color ?? "#000000" }, void 0, { label: "Solid Colour" });
|
|
2102
2156
|
} else controller.setGradient({ type: value });
|
|
2103
2157
|
};
|
|
2104
|
-
return /* @__PURE__ */ (0,
|
|
2105
|
-
/* @__PURE__ */ (0,
|
|
2106
|
-
/* @__PURE__ */ (0,
|
|
2107
|
-
["fill", "stroke"].map((t) => /* @__PURE__ */ (0,
|
|
2108
|
-
ed.mixed && /* @__PURE__ */ (0,
|
|
2158
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: `space-y-1.5 ${className ?? ""}`, "data-vector-gradient-editor": ed.target, "aria-label": "Gradient", children: [
|
|
2159
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "flex items-center gap-1.5", children: [
|
|
2160
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "w-16 text-xs text-foreground", children: "Gradient" }),
|
|
2161
|
+
["fill", "stroke"].map((t) => /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("button", { type: "button", className: buttonClass13, "aria-pressed": ed.target === t, onClick: () => controller.setGradientTarget(t), children: t === "fill" ? "Fill" : "Stroke" }, t)),
|
|
2162
|
+
ed.mixed && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "text-[11px] text-muted-foreground", children: "Mixed" })
|
|
2109
2163
|
] }),
|
|
2110
|
-
/* @__PURE__ */ (0,
|
|
2111
|
-
/* @__PURE__ */ (0,
|
|
2112
|
-
/* @__PURE__ */ (0,
|
|
2113
|
-
/* @__PURE__ */ (0,
|
|
2114
|
-
|
|
2164
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "flex items-center gap-1.5", children: [
|
|
2165
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "w-16 text-xs text-foreground", children: "Type" }),
|
|
2166
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("select", { "aria-label": "Gradient type", className: selectClass11, value: ed.type ?? "solid", onChange: (e) => setType(e.target.value), children: [
|
|
2167
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("option", { value: "solid", children: "Solid" }),
|
|
2168
|
+
import_vector16.VECTOR_GRADIENT_TYPES.map((t) => /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("option", { value: t, children: import_vector16.VECTOR_GRADIENT_TYPE_LABELS[t] }, t))
|
|
2115
2169
|
] }),
|
|
2116
|
-
/* @__PURE__ */ (0,
|
|
2170
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("button", { type: "button", className: buttonClass13, "aria-label": "Reverse gradient", title: "Reverse gradient", disabled: !g, onClick: () => controller.reverseGradient(), children: "\u21C4" })
|
|
2117
2171
|
] }),
|
|
2118
|
-
g && /* @__PURE__ */ (0,
|
|
2119
|
-
/* @__PURE__ */ (0,
|
|
2120
|
-
/* @__PURE__ */ (0,
|
|
2172
|
+
g && /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_jsx_runtime16.Fragment, { children: [
|
|
2173
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "relative h-8", "data-vector-gradient-ramp": "", children: [
|
|
2174
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
2121
2175
|
"div",
|
|
2122
2176
|
{
|
|
2123
2177
|
role: "button",
|
|
@@ -2131,7 +2185,7 @@ function VectorGradientEditor({ controller, className }) {
|
|
|
2131
2185
|
}
|
|
2132
2186
|
}
|
|
2133
2187
|
),
|
|
2134
|
-
ed.stops.map((s) => /* @__PURE__ */ (0,
|
|
2188
|
+
ed.stops.map((s) => /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
2135
2189
|
"button",
|
|
2136
2190
|
{
|
|
2137
2191
|
type: "button",
|
|
@@ -2145,21 +2199,21 @@ function VectorGradientEditor({ controller, className }) {
|
|
|
2145
2199
|
s.index
|
|
2146
2200
|
))
|
|
2147
2201
|
] }),
|
|
2148
|
-
sel && /* @__PURE__ */ (0,
|
|
2149
|
-
/* @__PURE__ */ (0,
|
|
2202
|
+
sel && /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "flex flex-wrap items-center gap-1.5", "data-vector-gradient-selected-stop": sel.index, children: [
|
|
2203
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
2150
2204
|
"input",
|
|
2151
2205
|
{
|
|
2152
2206
|
type: "color",
|
|
2153
2207
|
"aria-label": "Stop colour",
|
|
2154
2208
|
className: "h-7 w-9 cursor-pointer rounded border border-border bg-background",
|
|
2155
|
-
value: (0,
|
|
2209
|
+
value: (0, import_vector16.vectorPaintToHex)(sel.color) ?? "#000000",
|
|
2156
2210
|
onChange: (e) => controller.setGradientStop(sel.index, { color: e.target.value }, { merge: `gradient-stop-color-${sel.index}` }),
|
|
2157
2211
|
onBlur: end
|
|
2158
2212
|
}
|
|
2159
2213
|
),
|
|
2160
|
-
/* @__PURE__ */ (0,
|
|
2214
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("label", { className: "flex items-center gap-1 text-[11px] text-muted-foreground", children: [
|
|
2161
2215
|
"Opacity",
|
|
2162
|
-
/* @__PURE__ */ (0,
|
|
2216
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
2163
2217
|
"input",
|
|
2164
2218
|
{
|
|
2165
2219
|
type: "number",
|
|
@@ -2167,7 +2221,7 @@ function VectorGradientEditor({ controller, className }) {
|
|
|
2167
2221
|
max: 100,
|
|
2168
2222
|
step: 5,
|
|
2169
2223
|
"aria-label": "Stop opacity",
|
|
2170
|
-
className:
|
|
2224
|
+
className: numberClass10,
|
|
2171
2225
|
value: percent(sel.opacity ?? 1),
|
|
2172
2226
|
onChange: (e) => {
|
|
2173
2227
|
const n = parseFloat(e.target.value);
|
|
@@ -2176,9 +2230,9 @@ function VectorGradientEditor({ controller, className }) {
|
|
|
2176
2230
|
}
|
|
2177
2231
|
)
|
|
2178
2232
|
] }),
|
|
2179
|
-
/* @__PURE__ */ (0,
|
|
2233
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("label", { className: "flex items-center gap-1 text-[11px] text-muted-foreground", children: [
|
|
2180
2234
|
"At",
|
|
2181
|
-
/* @__PURE__ */ (0,
|
|
2235
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
2182
2236
|
"input",
|
|
2183
2237
|
{
|
|
2184
2238
|
type: "number",
|
|
@@ -2186,7 +2240,7 @@ function VectorGradientEditor({ controller, className }) {
|
|
|
2186
2240
|
max: 100,
|
|
2187
2241
|
step: 1,
|
|
2188
2242
|
"aria-label": "Stop position",
|
|
2189
|
-
className:
|
|
2243
|
+
className: numberClass10,
|
|
2190
2244
|
value: percent(sel.offset),
|
|
2191
2245
|
onChange: (e) => {
|
|
2192
2246
|
const n = parseFloat(e.target.value);
|
|
@@ -2195,9 +2249,9 @@ function VectorGradientEditor({ controller, className }) {
|
|
|
2195
2249
|
}
|
|
2196
2250
|
)
|
|
2197
2251
|
] }),
|
|
2198
|
-
!sel.last && /* @__PURE__ */ (0,
|
|
2252
|
+
!sel.last && /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("label", { className: "flex items-center gap-1 text-[11px] text-muted-foreground", children: [
|
|
2199
2253
|
"Midpoint",
|
|
2200
|
-
/* @__PURE__ */ (0,
|
|
2254
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
2201
2255
|
"input",
|
|
2202
2256
|
{
|
|
2203
2257
|
type: "number",
|
|
@@ -2205,7 +2259,7 @@ function VectorGradientEditor({ controller, className }) {
|
|
|
2205
2259
|
max: 95,
|
|
2206
2260
|
step: 1,
|
|
2207
2261
|
"aria-label": "Stop midpoint",
|
|
2208
|
-
className:
|
|
2262
|
+
className: numberClass10,
|
|
2209
2263
|
value: percent(sel.midpoint ?? 0.5),
|
|
2210
2264
|
onChange: (e) => {
|
|
2211
2265
|
const n = parseFloat(e.target.value);
|
|
@@ -2214,15 +2268,15 @@ function VectorGradientEditor({ controller, className }) {
|
|
|
2214
2268
|
}
|
|
2215
2269
|
)
|
|
2216
2270
|
] }),
|
|
2217
|
-
/* @__PURE__ */ (0,
|
|
2271
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("button", { type: "button", className: buttonClass13, "aria-label": "Delete stop", title: "Delete stop", disabled: ed.stops.length <= 2, onClick: () => controller.removeGradientStop(sel.index), children: "\u2715" })
|
|
2218
2272
|
] }),
|
|
2219
|
-
/* @__PURE__ */ (0,
|
|
2220
|
-
/* @__PURE__ */ (0,
|
|
2221
|
-
/* @__PURE__ */ (0,
|
|
2273
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("label", { className: "flex items-center gap-1.5 text-xs text-foreground", children: [
|
|
2274
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "w-16", children: "Colours" }),
|
|
2275
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("select", { "aria-label": "Gradient interpolation", className: selectClass11, value: ed.interpolation, onChange: (e) => controller.setGradient({ interpolation: e.target.value }), children: import_vector16.VECTOR_GRADIENT_INTERPOLATIONS.map((i) => /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("option", { value: i, children: import_vector16.VECTOR_GRADIENT_INTERPOLATION_LABELS[i] }, i)) })
|
|
2222
2276
|
] }),
|
|
2223
|
-
/* @__PURE__ */ (0,
|
|
2224
|
-
/* @__PURE__ */ (0,
|
|
2225
|
-
/* @__PURE__ */ (0,
|
|
2277
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("label", { className: "flex items-center gap-1.5 text-xs text-foreground", children: [
|
|
2278
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "w-16", children: "Smooth" }),
|
|
2279
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
2226
2280
|
"input",
|
|
2227
2281
|
{
|
|
2228
2282
|
type: "range",
|
|
@@ -2238,26 +2292,26 @@ function VectorGradientEditor({ controller, className }) {
|
|
|
2238
2292
|
}
|
|
2239
2293
|
)
|
|
2240
2294
|
] }),
|
|
2241
|
-
/* @__PURE__ */ (0,
|
|
2242
|
-
/* @__PURE__ */ (0,
|
|
2243
|
-
/* @__PURE__ */ (0,
|
|
2295
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("label", { className: "flex items-center gap-1.5 text-xs text-foreground", children: [
|
|
2296
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "w-16", children: "Spread" }),
|
|
2297
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("select", { "aria-label": "Gradient spread", className: selectClass11, value: ed.spread, onChange: (e) => controller.setGradient({ spread: e.target.value }), children: import_vector16.VECTOR_GRADIENT_SPREADS.map((sp) => /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("option", { value: sp, children: import_vector16.VECTOR_GRADIENT_SPREAD_LABELS[sp] }, sp)) })
|
|
2244
2298
|
] }),
|
|
2245
|
-
ed.target === "stroke" && /* @__PURE__ */ (0,
|
|
2246
|
-
/* @__PURE__ */ (0,
|
|
2247
|
-
/* @__PURE__ */ (0,
|
|
2299
|
+
ed.target === "stroke" && /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("label", { className: "flex items-center gap-1.5 text-xs text-foreground", children: [
|
|
2300
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "w-16", children: "On stroke" }),
|
|
2301
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("select", { "aria-label": "Gradient on stroke", className: selectClass11, value: ed.strokeMode, onChange: (e) => controller.setGradient({ strokeMode: e.target.value }), children: import_vector16.VECTOR_STROKE_GRADIENT_MODES.map((m) => /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("option", { value: m, children: import_vector16.VECTOR_STROKE_GRADIENT_MODE_LABELS[m] }, m)) })
|
|
2248
2302
|
] })
|
|
2249
2303
|
] })
|
|
2250
2304
|
] });
|
|
2251
2305
|
}
|
|
2252
2306
|
|
|
2253
2307
|
// src/vector/VectorToolbar.tsx
|
|
2254
|
-
var
|
|
2308
|
+
var import_jsx_runtime17 = require("react/jsx-runtime");
|
|
2255
2309
|
var VECTOR_SNAP_TITLE = "Snap to objects";
|
|
2256
2310
|
var modKeyLabel = () => typeof navigator !== "undefined" && /Mac|iPhone|iPad/.test(navigator.platform ?? "") ? "\u2318" : "Ctrl";
|
|
2257
2311
|
var buttonClass14 = "inline-flex h-8 min-w-8 items-center justify-center rounded-md border border-border bg-background px-2 text-xs font-medium text-foreground hover:bg-muted disabled:cursor-not-allowed disabled:opacity-40 aria-pressed:bg-primary aria-pressed:text-primary-foreground";
|
|
2258
2312
|
function VectorToolbar({
|
|
2259
2313
|
controller,
|
|
2260
|
-
tools =
|
|
2314
|
+
tools = import_vector17.VECTOR_TOOLS,
|
|
2261
2315
|
showHistory = true,
|
|
2262
2316
|
showArrange = true,
|
|
2263
2317
|
showSnap = true,
|
|
@@ -2271,31 +2325,31 @@ function VectorToolbar({
|
|
|
2271
2325
|
const points = state.tool === "direct" ? state.selectedAnchors.length : 0;
|
|
2272
2326
|
const editing = state.editing;
|
|
2273
2327
|
const groupSelected = state.selection.some((id) => controller.getNode(id)?.type === "group");
|
|
2274
|
-
const maskSelected = state.selection.some((id) => (0,
|
|
2328
|
+
const maskSelected = state.selection.some((id) => (0, import_vector17.isVectorMaskGroup)(controller.getNode(id)));
|
|
2275
2329
|
const [live, setLive] = import_react10.default.useState(false);
|
|
2276
2330
|
const booleanDisabled = live ? count < 1 : count < 2;
|
|
2277
|
-
const act = (label, title, run, disabled = false) => /* @__PURE__ */ (0,
|
|
2278
|
-
return /* @__PURE__ */ (0,
|
|
2279
|
-
/* @__PURE__ */ (0,
|
|
2331
|
+
const act = (label, title, run, disabled = false) => /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("button", { type: "button", className: buttonClass14, title, "aria-label": title, disabled, onClick: () => void run(), children: label }, label);
|
|
2332
|
+
return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { role: "toolbar", "aria-label": "Vector tools", className: `flex flex-wrap items-center gap-1 ${className ?? ""}`, children: [
|
|
2333
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { className: "flex items-center gap-1", role: "group", "aria-label": "Tools", children: tools.map((tool) => /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
2280
2334
|
"button",
|
|
2281
2335
|
{
|
|
2282
2336
|
type: "button",
|
|
2283
2337
|
"data-vector-tool": tool,
|
|
2284
2338
|
className: buttonClass14,
|
|
2285
2339
|
"aria-pressed": state.tool === tool,
|
|
2286
|
-
title: `${(0,
|
|
2287
|
-
"aria-label": (0,
|
|
2340
|
+
title: `${(0, import_vector17.vectorToolLabel)(tool)} (${import_vector17.VECTOR_TOOL_SHORTCUTS[tool]})`,
|
|
2341
|
+
"aria-label": (0, import_vector17.vectorToolLabel)(tool),
|
|
2288
2342
|
onClick: () => controller.setTool(tool),
|
|
2289
|
-
children:
|
|
2343
|
+
children: import_vector17.VECTOR_TOOL_GLYPHS[tool]
|
|
2290
2344
|
},
|
|
2291
2345
|
tool
|
|
2292
2346
|
)) }),
|
|
2293
|
-
showHistory && /* @__PURE__ */ (0,
|
|
2347
|
+
showHistory && /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "ml-1 flex items-center gap-1", role: "group", "aria-label": "History", children: [
|
|
2294
2348
|
act("\u21B6", state.canUndo ? `Undo ${state.undoLabel}` : "Undo", () => controller.undo(), !state.canUndo),
|
|
2295
2349
|
act("\u21B7", state.canRedo ? `Redo ${state.redoLabel}` : "Redo", () => controller.redo(), !state.canRedo)
|
|
2296
2350
|
] }),
|
|
2297
|
-
showSnap && /* @__PURE__ */ (0,
|
|
2298
|
-
/* @__PURE__ */ (0,
|
|
2351
|
+
showSnap && /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "ml-1 flex items-center gap-1", role: "group", "aria-label": "Snapping", children: [
|
|
2352
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
2299
2353
|
"button",
|
|
2300
2354
|
{
|
|
2301
2355
|
type: "button",
|
|
@@ -2308,18 +2362,18 @@ function VectorToolbar({
|
|
|
2308
2362
|
children: "Snap"
|
|
2309
2363
|
}
|
|
2310
2364
|
),
|
|
2311
|
-
/* @__PURE__ */ (0,
|
|
2365
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
|
|
2312
2366
|
"select",
|
|
2313
2367
|
{
|
|
2314
2368
|
"data-vector-polar": "",
|
|
2315
2369
|
"aria-label": "Polar tracking increment",
|
|
2316
2370
|
title: "Polar tracking: the angles drawn points snap to from where they leave",
|
|
2317
2371
|
className: "h-8 rounded-md border border-border bg-background px-1 text-xs",
|
|
2318
|
-
value: String((0,
|
|
2319
|
-
onChange: (e) => controller.setSnap({ angles: (0,
|
|
2372
|
+
value: String((0, import_vector17.vectorPolarIncrementOf)(state.snap.angles) ?? ""),
|
|
2373
|
+
onChange: (e) => controller.setSnap({ angles: (0, import_vector17.vectorPolarAngles)(Number(e.target.value)) }),
|
|
2320
2374
|
children: [
|
|
2321
|
-
(0,
|
|
2322
|
-
[90, 45, 30, 15].map((n) => /* @__PURE__ */ (0,
|
|
2375
|
+
(0, import_vector17.vectorPolarIncrementOf)(state.snap.angles) === null && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("option", { value: "", children: "Custom" }),
|
|
2376
|
+
[90, 45, 30, 15].map((n) => /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("option", { value: n, children: [
|
|
2323
2377
|
n,
|
|
2324
2378
|
"\xB0"
|
|
2325
2379
|
] }, n))
|
|
@@ -2327,8 +2381,8 @@ function VectorToolbar({
|
|
|
2327
2381
|
}
|
|
2328
2382
|
)
|
|
2329
2383
|
] }),
|
|
2330
|
-
showPathEdit && /* @__PURE__ */ (0,
|
|
2331
|
-
|
|
2384
|
+
showPathEdit && /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "ml-1 flex items-center gap-1", role: "group", "aria-label": "Path editing", children: [
|
|
2385
|
+
import_vector17.VECTOR_PATH_ACTIONS.map((a) => /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
2332
2386
|
"button",
|
|
2333
2387
|
{
|
|
2334
2388
|
type: "button",
|
|
@@ -2342,7 +2396,7 @@ function VectorToolbar({
|
|
|
2342
2396
|
},
|
|
2343
2397
|
a.id
|
|
2344
2398
|
)),
|
|
2345
|
-
|
|
2399
|
+
import_vector17.VECTOR_EDIT_TOGGLES.map((t) => /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
2346
2400
|
"button",
|
|
2347
2401
|
{
|
|
2348
2402
|
type: "button",
|
|
@@ -2356,9 +2410,9 @@ function VectorToolbar({
|
|
|
2356
2410
|
},
|
|
2357
2411
|
t.key
|
|
2358
2412
|
)),
|
|
2359
|
-
state.tool === "pencil" && /* @__PURE__ */ (0,
|
|
2413
|
+
state.tool === "pencil" && /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("label", { className: "flex items-center gap-1 text-xs text-foreground", children: [
|
|
2360
2414
|
"Smoothing",
|
|
2361
|
-
/* @__PURE__ */ (0,
|
|
2415
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
2362
2416
|
"input",
|
|
2363
2417
|
{
|
|
2364
2418
|
type: "range",
|
|
@@ -2372,9 +2426,9 @@ function VectorToolbar({
|
|
|
2372
2426
|
}
|
|
2373
2427
|
)
|
|
2374
2428
|
] }),
|
|
2375
|
-
state.tool === "eraser" && /* @__PURE__ */ (0,
|
|
2429
|
+
state.tool === "eraser" && /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("label", { className: "flex items-center gap-1 text-xs text-foreground", children: [
|
|
2376
2430
|
"Size",
|
|
2377
|
-
/* @__PURE__ */ (0,
|
|
2431
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
2378
2432
|
"input",
|
|
2379
2433
|
{
|
|
2380
2434
|
type: "number",
|
|
@@ -2390,7 +2444,7 @@ function VectorToolbar({
|
|
|
2390
2444
|
}
|
|
2391
2445
|
)
|
|
2392
2446
|
] }),
|
|
2393
|
-
state.tool === "paintBucket" && /* @__PURE__ */ (0,
|
|
2447
|
+
state.tool === "paintBucket" && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
2394
2448
|
"button",
|
|
2395
2449
|
{
|
|
2396
2450
|
type: "button",
|
|
@@ -2399,12 +2453,12 @@ function VectorToolbar({
|
|
|
2399
2453
|
"aria-pressed": editing.fillGap > 0,
|
|
2400
2454
|
title: "Close small gaps between path ends when filling",
|
|
2401
2455
|
"aria-label": "Close gaps",
|
|
2402
|
-
onClick: () => controller.setEditing({ fillGap: editing.fillGap > 0 ? 0 :
|
|
2456
|
+
onClick: () => controller.setEditing({ fillGap: editing.fillGap > 0 ? 0 : import_vector17.VECTOR_FILL_GAP }),
|
|
2403
2457
|
children: "Gaps"
|
|
2404
2458
|
}
|
|
2405
2459
|
)
|
|
2406
2460
|
] }),
|
|
2407
|
-
showDistort && /* @__PURE__ */ (0,
|
|
2461
|
+
showDistort && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { className: "ml-1 flex items-center gap-1", role: "group", "aria-label": "Distort", children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
2408
2462
|
"button",
|
|
2409
2463
|
{
|
|
2410
2464
|
type: "button",
|
|
@@ -2417,10 +2471,10 @@ function VectorToolbar({
|
|
|
2417
2471
|
children: "Distort"
|
|
2418
2472
|
}
|
|
2419
2473
|
) }),
|
|
2420
|
-
showBlend && /* @__PURE__ */ (0,
|
|
2421
|
-
showArrange && /* @__PURE__ */ (0,
|
|
2422
|
-
/* @__PURE__ */ (0,
|
|
2423
|
-
/* @__PURE__ */ (0,
|
|
2474
|
+
showBlend && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(VectorBlendControls, { controller }),
|
|
2475
|
+
showArrange && /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_jsx_runtime17.Fragment, { children: [
|
|
2476
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "ml-1 flex items-center gap-1", role: "group", "aria-label": "Combine", children: [
|
|
2477
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
2424
2478
|
"button",
|
|
2425
2479
|
{
|
|
2426
2480
|
type: "button",
|
|
@@ -2442,7 +2496,7 @@ function VectorToolbar({
|
|
|
2442
2496
|
act("\u25D0", `Make Clipping Mask (${modKeyLabel()}+7)`, () => controller.makeMask("clip"), count < 2),
|
|
2443
2497
|
act("\u25D1", `Release Mask (${modKeyLabel()}+Alt+7)`, () => controller.releaseMask(), !maskSelected)
|
|
2444
2498
|
] }),
|
|
2445
|
-
/* @__PURE__ */ (0,
|
|
2499
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { className: "ml-1 flex items-center gap-1", role: "group", "aria-label": "Pathfinder", children: import_vector17.VECTOR_PATHFINDER_ACTIONS.map((a) => /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
2446
2500
|
"button",
|
|
2447
2501
|
{
|
|
2448
2502
|
type: "button",
|
|
@@ -2456,7 +2510,7 @@ function VectorToolbar({
|
|
|
2456
2510
|
},
|
|
2457
2511
|
a.id
|
|
2458
2512
|
)) }),
|
|
2459
|
-
/* @__PURE__ */ (0,
|
|
2513
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "ml-1 flex items-center gap-1", role: "group", "aria-label": "Arrange", children: [
|
|
2460
2514
|
act("\u21C8", "Bring to Front", () => controller.arrange("front"), count < 1),
|
|
2461
2515
|
act("\u21CA", "Send to Back", () => controller.arrange("back"), count < 1),
|
|
2462
2516
|
act("\u21E4", "Align Left", () => controller.align("left"), count < 1),
|
|
@@ -2471,22 +2525,22 @@ function VectorToolbar({
|
|
|
2471
2525
|
}
|
|
2472
2526
|
function VectorBlendControls({ controller }) {
|
|
2473
2527
|
const state = useVectorEditorState(controller);
|
|
2474
|
-
const blend = (0,
|
|
2528
|
+
const blend = (0, import_vector17.getVectorBlendControls)(state);
|
|
2475
2529
|
const o = blend.options;
|
|
2476
2530
|
const selected = blend.ids.length > 0;
|
|
2477
|
-
return /* @__PURE__ */ (0,
|
|
2478
|
-
/* @__PURE__ */ (0,
|
|
2479
|
-
/* @__PURE__ */ (0,
|
|
2531
|
+
return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "ml-1 flex items-center gap-1", role: "group", "aria-label": "Blend", "data-vector-blend-controls": "", children: [
|
|
2532
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("button", { type: "button", "data-vector-blend-action": "make", className: buttonClass14, title: "Make Blend", "aria-label": "Make Blend", disabled: !blend.canBlend, onClick: () => controller.blend(), children: "\u29D3" }),
|
|
2533
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
2480
2534
|
"select",
|
|
2481
2535
|
{
|
|
2482
2536
|
"aria-label": "Blend spacing",
|
|
2483
2537
|
className: "h-7 rounded border border-border bg-background px-1 text-xs",
|
|
2484
2538
|
value: o.spacing,
|
|
2485
|
-
onChange: (e) => (0,
|
|
2486
|
-
children:
|
|
2539
|
+
onChange: (e) => (0, import_vector17.applyVectorBlendOptions)(controller, { spacing: e.target.value }),
|
|
2540
|
+
children: import_vector17.VECTOR_BLEND_SPACINGS.map((sp) => /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("option", { value: sp, children: import_vector17.VECTOR_BLEND_SPACING_LABELS[sp] }, sp))
|
|
2487
2541
|
}
|
|
2488
2542
|
),
|
|
2489
|
-
o.spacing !== "smoothColor" && /* @__PURE__ */ (0,
|
|
2543
|
+
o.spacing !== "smoothColor" && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
2490
2544
|
"input",
|
|
2491
2545
|
{
|
|
2492
2546
|
type: "number",
|
|
@@ -2498,11 +2552,11 @@ function VectorBlendControls({ controller }) {
|
|
|
2498
2552
|
onChange: (e) => {
|
|
2499
2553
|
const n = parseFloat(e.target.value);
|
|
2500
2554
|
if (!Number.isFinite(n) || n <= 0) return;
|
|
2501
|
-
(0,
|
|
2555
|
+
(0, import_vector17.applyVectorBlendOptions)(controller, o.spacing === "steps" ? { steps: n } : { distance: n });
|
|
2502
2556
|
}
|
|
2503
2557
|
}
|
|
2504
2558
|
),
|
|
2505
|
-
/* @__PURE__ */ (0,
|
|
2559
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
2506
2560
|
"button",
|
|
2507
2561
|
{
|
|
2508
2562
|
type: "button",
|
|
@@ -2511,11 +2565,11 @@ function VectorBlendControls({ controller }) {
|
|
|
2511
2565
|
"aria-pressed": o.orientToSpine,
|
|
2512
2566
|
title: "Orient steps to the spine",
|
|
2513
2567
|
"aria-label": "Orient to spine",
|
|
2514
|
-
onClick: () => (0,
|
|
2568
|
+
onClick: () => (0, import_vector17.applyVectorBlendOptions)(controller, { orientToSpine: !o.orientToSpine }),
|
|
2515
2569
|
children: "\u293F"
|
|
2516
2570
|
}
|
|
2517
2571
|
),
|
|
2518
|
-
/* @__PURE__ */ (0,
|
|
2572
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
2519
2573
|
"button",
|
|
2520
2574
|
{
|
|
2521
2575
|
type: "button",
|
|
@@ -2528,15 +2582,15 @@ function VectorBlendControls({ controller }) {
|
|
|
2528
2582
|
children: "\u2307"
|
|
2529
2583
|
}
|
|
2530
2584
|
),
|
|
2531
|
-
/* @__PURE__ */ (0,
|
|
2532
|
-
/* @__PURE__ */ (0,
|
|
2585
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("button", { type: "button", "data-vector-blend-action": "expand", className: buttonClass14, title: "Expand Blend", "aria-label": "Expand Blend", disabled: !selected, onClick: () => controller.expandBlend(), children: "\u29C9" }),
|
|
2586
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("button", { type: "button", "data-vector-blend-action": "release", className: buttonClass14, title: "Release Blend", "aria-label": "Release Blend", disabled: !selected, onClick: () => controller.releaseBlend(), children: "\u29C4" })
|
|
2533
2587
|
] });
|
|
2534
2588
|
}
|
|
2535
|
-
var
|
|
2536
|
-
var
|
|
2589
|
+
var selectClass12 = "h-7 min-w-0 flex-1 rounded border border-border bg-background px-1 text-xs";
|
|
2590
|
+
var numberClass11 = "h-7 w-16 rounded border border-border bg-background px-1.5 text-xs";
|
|
2537
2591
|
function VectorStylePanel({ controller, className }) {
|
|
2538
2592
|
const state = useVectorEditorState(controller);
|
|
2539
|
-
const style = (0,
|
|
2593
|
+
const style = (0, import_vector17.getVectorSelectionStyle)(state);
|
|
2540
2594
|
const d = state.defaults;
|
|
2541
2595
|
const source = style ?? {
|
|
2542
2596
|
fill: d.fill ?? null,
|
|
@@ -2549,7 +2603,7 @@ function VectorStylePanel({ controller, className }) {
|
|
|
2549
2603
|
arrowAlign: d.arrowAlign ?? "extend",
|
|
2550
2604
|
startArrowScale: d.startArrowScale ?? 1,
|
|
2551
2605
|
endArrowScale: d.endArrowScale ?? 1,
|
|
2552
|
-
widthProfile: (0,
|
|
2606
|
+
widthProfile: (0, import_vector17.widthProfilePresetId)(d.strokeWidthProfile),
|
|
2553
2607
|
cornerRadius: d.cornerRadius,
|
|
2554
2608
|
cornerKind: d.cornerKind ?? "round",
|
|
2555
2609
|
cornerSmoothing: 0,
|
|
@@ -2563,19 +2617,19 @@ function VectorStylePanel({ controller, className }) {
|
|
|
2563
2617
|
};
|
|
2564
2618
|
const setProfile = (id) => {
|
|
2565
2619
|
if (style) controller.setWidthProfile(id);
|
|
2566
|
-
else controller.setDefaults({ strokeWidthProfile: (0,
|
|
2620
|
+
else controller.setDefaults({ strokeWidthProfile: (0, import_vector17.widthProfilePreset)(id)?.length ? (0, import_vector17.widthProfilePreset)(id) : null });
|
|
2567
2621
|
};
|
|
2568
|
-
const mixed = (key) => style?.mixed[key] ? /* @__PURE__ */ (0,
|
|
2622
|
+
const mixed = (key) => style?.mixed[key] ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "text-[11px] text-muted-foreground", children: "Mixed" }) : null;
|
|
2569
2623
|
const arrowRow = (end, label) => {
|
|
2570
2624
|
const key = end === "start" ? "startArrow" : "endArrow";
|
|
2571
2625
|
const scaleKey = end === "start" ? "startArrowScale" : "endArrowScale";
|
|
2572
|
-
return /* @__PURE__ */ (0,
|
|
2573
|
-
/* @__PURE__ */ (0,
|
|
2574
|
-
/* @__PURE__ */ (0,
|
|
2575
|
-
/* @__PURE__ */ (0,
|
|
2576
|
-
|
|
2626
|
+
return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "flex items-center gap-2", "data-vector-style": key, children: [
|
|
2627
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "w-16 text-xs text-foreground", children: label }),
|
|
2628
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("select", { "aria-label": `${label} arrowhead`, className: selectClass12, value: source[key] ?? "", onChange: (e) => apply({ [key]: e.target.value || null }), children: [
|
|
2629
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("option", { value: "", children: "None" }),
|
|
2630
|
+
import_vector17.VECTOR_ARROWHEADS.map((h) => /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("option", { value: h, children: import_vector17.VECTOR_ARROWHEAD_LABELS[h] }, h))
|
|
2577
2631
|
] }),
|
|
2578
|
-
/* @__PURE__ */ (0,
|
|
2632
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
2579
2633
|
"input",
|
|
2580
2634
|
{
|
|
2581
2635
|
type: "number",
|
|
@@ -2583,7 +2637,7 @@ function VectorStylePanel({ controller, className }) {
|
|
|
2583
2637
|
step: 0.25,
|
|
2584
2638
|
"aria-label": `${label} arrowhead scale`,
|
|
2585
2639
|
title: "Scale (\xD7 stroke width)",
|
|
2586
|
-
className:
|
|
2640
|
+
className: numberClass11,
|
|
2587
2641
|
value: source[scaleKey],
|
|
2588
2642
|
onChange: (e) => {
|
|
2589
2643
|
const n = parseFloat(e.target.value);
|
|
@@ -2599,14 +2653,14 @@ function VectorStylePanel({ controller, className }) {
|
|
|
2599
2653
|
};
|
|
2600
2654
|
const paintRow = (key, label) => {
|
|
2601
2655
|
const paint = source[key];
|
|
2602
|
-
const hex = (0,
|
|
2656
|
+
const hex = (0, import_vector17.vectorPaintToHex)(paint);
|
|
2603
2657
|
const on = paint !== null && paint !== "none";
|
|
2604
|
-
return /* @__PURE__ */ (0,
|
|
2605
|
-
/* @__PURE__ */ (0,
|
|
2606
|
-
/* @__PURE__ */ (0,
|
|
2658
|
+
return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "flex items-center gap-2", "data-vector-style": key, children: [
|
|
2659
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("label", { className: "flex w-16 items-center gap-1.5 text-xs text-foreground", children: [
|
|
2660
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("input", { type: "checkbox", checked: on, "aria-label": `${label} on`, onChange: (e) => apply({ [key]: e.target.checked ? hex ?? "#000000" : null }) }),
|
|
2607
2661
|
label
|
|
2608
2662
|
] }),
|
|
2609
|
-
/* @__PURE__ */ (0,
|
|
2663
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
2610
2664
|
"input",
|
|
2611
2665
|
{
|
|
2612
2666
|
type: "color",
|
|
@@ -2617,18 +2671,18 @@ function VectorStylePanel({ controller, className }) {
|
|
|
2617
2671
|
onChange: (e) => apply({ [key]: e.target.value })
|
|
2618
2672
|
}
|
|
2619
2673
|
),
|
|
2620
|
-
on && !hex && /* @__PURE__ */ (0,
|
|
2621
|
-
style?.mixed[key] && /* @__PURE__ */ (0,
|
|
2674
|
+
on && !hex && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "truncate text-[11px] text-muted-foreground", children: typeof paint === "string" ? paint : "Gradient" }),
|
|
2675
|
+
style?.mixed[key] && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "text-[11px] text-muted-foreground", children: "Mixed" })
|
|
2622
2676
|
] });
|
|
2623
2677
|
};
|
|
2624
|
-
return /* @__PURE__ */ (0,
|
|
2625
|
-
/* @__PURE__ */ (0,
|
|
2678
|
+
return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: `space-y-2 ${className ?? ""}`, "aria-label": style ? "Selection style" : "New shape style", children: [
|
|
2679
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("p", { className: "text-[11px] font-medium uppercase tracking-wide text-muted-foreground", children: style ? "Selection" : "New shapes" }),
|
|
2626
2680
|
paintRow("fill", "Fill"),
|
|
2627
2681
|
paintRow("stroke", "Stroke"),
|
|
2628
|
-
style && /* @__PURE__ */ (0,
|
|
2629
|
-
/* @__PURE__ */ (0,
|
|
2630
|
-
/* @__PURE__ */ (0,
|
|
2631
|
-
/* @__PURE__ */ (0,
|
|
2682
|
+
style && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(VectorGradientEditor, { controller }),
|
|
2683
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("label", { className: "flex items-center gap-2 text-xs text-foreground", children: [
|
|
2684
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "w-16", children: "Width" }),
|
|
2685
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
2632
2686
|
"input",
|
|
2633
2687
|
{
|
|
2634
2688
|
type: "number",
|
|
@@ -2644,29 +2698,29 @@ function VectorStylePanel({ controller, className }) {
|
|
|
2644
2698
|
}
|
|
2645
2699
|
)
|
|
2646
2700
|
] }),
|
|
2647
|
-
/* @__PURE__ */ (0,
|
|
2648
|
-
/* @__PURE__ */ (0,
|
|
2649
|
-
/* @__PURE__ */ (0,
|
|
2701
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("label", { className: "flex items-center gap-2 text-xs text-foreground", "data-vector-style": "strokeAlign", children: [
|
|
2702
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "w-16", children: "Align" }),
|
|
2703
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("select", { "aria-label": "Stroke alignment", className: selectClass12, value: source.strokeAlign, onChange: (e) => apply({ strokeAlign: e.target.value }), children: Object.keys(import_vector17.VECTOR_STROKE_ALIGN_LABELS).map((a) => /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("option", { value: a, children: import_vector17.VECTOR_STROKE_ALIGN_LABELS[a] }, a)) }),
|
|
2650
2704
|
mixed("strokeAlign")
|
|
2651
2705
|
] }),
|
|
2652
|
-
/* @__PURE__ */ (0,
|
|
2653
|
-
/* @__PURE__ */ (0,
|
|
2654
|
-
/* @__PURE__ */ (0,
|
|
2706
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "flex items-center gap-2 text-xs text-foreground", "data-vector-style": "widthProfile", children: [
|
|
2707
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "w-16", children: "Profile" }),
|
|
2708
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
|
|
2655
2709
|
"select",
|
|
2656
2710
|
{
|
|
2657
2711
|
"aria-label": "Width profile",
|
|
2658
|
-
className:
|
|
2712
|
+
className: selectClass12,
|
|
2659
2713
|
value: source.widthProfile,
|
|
2660
2714
|
onChange: (e) => {
|
|
2661
2715
|
if (e.target.value !== "custom") setProfile(e.target.value);
|
|
2662
2716
|
},
|
|
2663
2717
|
children: [
|
|
2664
|
-
|
|
2665
|
-
source.widthProfile === "custom" && /* @__PURE__ */ (0,
|
|
2718
|
+
import_vector17.VECTOR_WIDTH_PRESETS.map((p) => /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("option", { value: p.id, children: p.label }, p.id)),
|
|
2719
|
+
source.widthProfile === "custom" && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("option", { value: "custom", disabled: true, children: "Custom" })
|
|
2666
2720
|
]
|
|
2667
2721
|
}
|
|
2668
2722
|
),
|
|
2669
|
-
/* @__PURE__ */ (0,
|
|
2723
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
2670
2724
|
"button",
|
|
2671
2725
|
{
|
|
2672
2726
|
type: "button",
|
|
@@ -2680,27 +2734,27 @@ function VectorStylePanel({ controller, className }) {
|
|
|
2680
2734
|
),
|
|
2681
2735
|
mixed("widthProfile")
|
|
2682
2736
|
] }),
|
|
2683
|
-
source.hasOpenPath && /* @__PURE__ */ (0,
|
|
2737
|
+
source.hasOpenPath && /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_jsx_runtime17.Fragment, { children: [
|
|
2684
2738
|
arrowRow("start", "Start"),
|
|
2685
2739
|
arrowRow("end", "End"),
|
|
2686
|
-
(source.startArrow || source.endArrow) && /* @__PURE__ */ (0,
|
|
2687
|
-
/* @__PURE__ */ (0,
|
|
2688
|
-
/* @__PURE__ */ (0,
|
|
2689
|
-
/* @__PURE__ */ (0,
|
|
2690
|
-
/* @__PURE__ */ (0,
|
|
2740
|
+
(source.startArrow || source.endArrow) && /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("label", { className: "flex items-center gap-2 text-xs text-foreground", "data-vector-style": "arrowAlign", children: [
|
|
2741
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "w-16", children: "Heads" }),
|
|
2742
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("select", { "aria-label": "Arrowhead alignment", className: selectClass12, value: source.arrowAlign, onChange: (e) => apply({ arrowAlign: e.target.value }), children: [
|
|
2743
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("option", { value: "extend", children: "Tip past end" }),
|
|
2744
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("option", { value: "tip", children: "Tip at end" })
|
|
2691
2745
|
] })
|
|
2692
2746
|
] })
|
|
2693
2747
|
] }),
|
|
2694
|
-
source.corners > 0 && /* @__PURE__ */ (0,
|
|
2695
|
-
/* @__PURE__ */ (0,
|
|
2696
|
-
/* @__PURE__ */ (0,
|
|
2748
|
+
source.corners > 0 && /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "flex items-center gap-2", "data-vector-style": "corners", children: [
|
|
2749
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "w-16 text-xs text-foreground", children: "Corners" }),
|
|
2750
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
2697
2751
|
"input",
|
|
2698
2752
|
{
|
|
2699
2753
|
type: "number",
|
|
2700
2754
|
min: 0,
|
|
2701
2755
|
step: 1,
|
|
2702
2756
|
"aria-label": "Corner radius",
|
|
2703
|
-
className:
|
|
2757
|
+
className: numberClass11,
|
|
2704
2758
|
value: Math.round(source.cornerRadius * 100) / 100,
|
|
2705
2759
|
onChange: (e) => {
|
|
2706
2760
|
const n = parseFloat(e.target.value);
|
|
@@ -2708,12 +2762,12 @@ function VectorStylePanel({ controller, className }) {
|
|
|
2708
2762
|
}
|
|
2709
2763
|
}
|
|
2710
2764
|
),
|
|
2711
|
-
/* @__PURE__ */ (0,
|
|
2765
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("select", { "aria-label": "Corner kind", className: selectClass12, value: source.cornerKind, onChange: (e) => setCorners({ kind: e.target.value }), children: import_vector17.VECTOR_CORNER_KINDS.map((k) => /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("option", { value: k, children: import_vector17.VECTOR_CORNER_KIND_LABELS[k] }, k)) }),
|
|
2712
2766
|
mixed("cornerRadius")
|
|
2713
2767
|
] }),
|
|
2714
|
-
style && source.corners > 0 && source.cornerKind === "round" && source.cornerRadius > 0 && /* @__PURE__ */ (0,
|
|
2715
|
-
/* @__PURE__ */ (0,
|
|
2716
|
-
/* @__PURE__ */ (0,
|
|
2768
|
+
style && source.corners > 0 && source.cornerKind === "round" && source.cornerRadius > 0 && /* @__PURE__ */ (0, import_jsx_runtime17.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: [
|
|
2769
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "w-16", children: "Smoothing" }),
|
|
2770
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
2717
2771
|
"input",
|
|
2718
2772
|
{
|
|
2719
2773
|
type: "range",
|
|
@@ -2728,9 +2782,9 @@ function VectorStylePanel({ controller, className }) {
|
|
|
2728
2782
|
}
|
|
2729
2783
|
)
|
|
2730
2784
|
] }),
|
|
2731
|
-
style && /* @__PURE__ */ (0,
|
|
2732
|
-
/* @__PURE__ */ (0,
|
|
2733
|
-
/* @__PURE__ */ (0,
|
|
2785
|
+
style && /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("label", { className: "flex items-center gap-2 text-xs text-foreground", children: [
|
|
2786
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "w-16", children: "Opacity" }),
|
|
2787
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
2734
2788
|
"input",
|
|
2735
2789
|
{
|
|
2736
2790
|
type: "range",
|
|
@@ -2744,18 +2798,19 @@ function VectorStylePanel({ controller, className }) {
|
|
|
2744
2798
|
}
|
|
2745
2799
|
)
|
|
2746
2800
|
] }),
|
|
2747
|
-
/* @__PURE__ */ (0,
|
|
2748
|
-
style && /* @__PURE__ */ (0,
|
|
2749
|
-
style && /* @__PURE__ */ (0,
|
|
2750
|
-
style && /* @__PURE__ */ (0,
|
|
2751
|
-
style && /* @__PURE__ */ (0,
|
|
2752
|
-
/* @__PURE__ */ (0,
|
|
2753
|
-
/* @__PURE__ */ (0,
|
|
2754
|
-
/* @__PURE__ */ (0,
|
|
2755
|
-
/* @__PURE__ */ (0,
|
|
2756
|
-
/* @__PURE__ */ (0,
|
|
2757
|
-
/* @__PURE__ */ (0,
|
|
2758
|
-
/* @__PURE__ */ (0,
|
|
2801
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(VectorTextPanel, { controller }),
|
|
2802
|
+
style && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(VectorAppearancePanel, { controller }),
|
|
2803
|
+
style && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(VectorEffectsPanel, { controller }),
|
|
2804
|
+
style && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(VectorEnvelopePanel, { controller }),
|
|
2805
|
+
style && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(VectorMaskPanel, { controller }),
|
|
2806
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(VectorFramePanel, { controller }),
|
|
2807
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(VectorConnectorPanel, { controller }),
|
|
2808
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(VectorShadingPanel, { controller }),
|
|
2809
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(VectorSymmetryPanel, { controller }),
|
|
2810
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(VectorLensPanel, { controller }),
|
|
2811
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(VectorTracePanel, { controller }),
|
|
2812
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(VectorConstraintsPanel, { controller }),
|
|
2813
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(VectorSymbolsPanel, { controller })
|
|
2759
2814
|
] });
|
|
2760
2815
|
}
|
|
2761
2816
|
|
|
@@ -2787,7 +2842,7 @@ function useEffectDescription(provider, effect) {
|
|
|
2787
2842
|
// src/effects/EffectThumbnail.tsx
|
|
2788
2843
|
var import_react12 = require("react");
|
|
2789
2844
|
var import_effects = require("@pixerate/editor/effects");
|
|
2790
|
-
var
|
|
2845
|
+
var import_jsx_runtime18 = require("react/jsx-runtime");
|
|
2791
2846
|
function EffectThumbnail({ provider, effect, width = 96, height = 54, className = "" }) {
|
|
2792
2847
|
const ref = (0, import_react12.useRef)(null);
|
|
2793
2848
|
const [failed, setFailed] = (0, import_react12.useState)(effect.kind === "motion");
|
|
@@ -2806,13 +2861,13 @@ function EffectThumbnail({ provider, effect, width = 96, height = 54, className
|
|
|
2806
2861
|
live = false;
|
|
2807
2862
|
};
|
|
2808
2863
|
}, [provider, effect, width, height]);
|
|
2809
|
-
return /* @__PURE__ */ (0,
|
|
2864
|
+
return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
2810
2865
|
"div",
|
|
2811
2866
|
{
|
|
2812
2867
|
className: `relative overflow-hidden rounded border border-border bg-[repeating-conic-gradient(#8884_0_25%,transparent_0_50%)] bg-[length:12px_12px] ${className}`,
|
|
2813
2868
|
style: { aspectRatio: `${width} / ${height}` },
|
|
2814
2869
|
"data-effect-thumbnail": effect.id,
|
|
2815
|
-
children: failed ? /* @__PURE__ */ (0,
|
|
2870
|
+
children: failed ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { className: "absolute inset-0 flex items-center justify-center text-[10px] text-muted-foreground", children: effect.kind === "motion" ? "Motion" : "No preview" }) : /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("canvas", { ref, width, height, className: "h-full w-full", "aria-hidden": "true" })
|
|
2816
2871
|
}
|
|
2817
2872
|
);
|
|
2818
2873
|
}
|
|
@@ -2820,7 +2875,7 @@ function EffectThumbnail({ provider, effect, width = 96, height = 54, className
|
|
|
2820
2875
|
// src/effects/EffectsBrowser.tsx
|
|
2821
2876
|
var import_react13 = require("react");
|
|
2822
2877
|
var import_effects2 = require("@pixerate/editor/effects");
|
|
2823
|
-
var
|
|
2878
|
+
var import_jsx_runtime19 = require("react/jsx-runtime");
|
|
2824
2879
|
function EffectsBrowser({ provider, uses, kinds, onPick, thumbnails = true, title = "Effects", className = "" }) {
|
|
2825
2880
|
const [all, setAll] = (0, import_react13.useState)([]);
|
|
2826
2881
|
const [query, setQuery] = (0, import_react13.useState)("");
|
|
@@ -2851,11 +2906,11 @@ function EffectsBrowser({ provider, uses, kinds, onPick, thumbnails = true, titl
|
|
|
2851
2906
|
const categories = (0, import_react13.useMemo)(() => [...new Set(all.filter(allowed).map((e) => e.category))], [all, uses, kinds]);
|
|
2852
2907
|
const shown = found.filter(allowed);
|
|
2853
2908
|
if (!provider)
|
|
2854
|
-
return /* @__PURE__ */ (0,
|
|
2855
|
-
return /* @__PURE__ */ (0,
|
|
2856
|
-
title && /* @__PURE__ */ (0,
|
|
2857
|
-
/* @__PURE__ */ (0,
|
|
2858
|
-
/* @__PURE__ */ (0,
|
|
2909
|
+
return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { className: `rounded-md border border-dashed border-border p-3 text-xs text-muted-foreground ${className}`, "data-effects-browser": "", "data-effects-unavailable": "", children: "No effects provider is registered, so effects cannot be added. Effects already in the document are kept." });
|
|
2910
|
+
return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("section", { className: `flex flex-col gap-2 ${className}`, "data-effects-browser": "", "aria-label": "Effects browser", children: [
|
|
2911
|
+
title && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("h3", { className: "text-xs font-semibold", children: title }),
|
|
2912
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "flex flex-wrap gap-1", children: [
|
|
2913
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
2859
2914
|
"input",
|
|
2860
2915
|
{
|
|
2861
2916
|
type: "search",
|
|
@@ -2866,17 +2921,17 @@ function EffectsBrowser({ provider, uses, kinds, onPick, thumbnails = true, titl
|
|
|
2866
2921
|
onChange: (e) => setQuery(e.currentTarget.value)
|
|
2867
2922
|
}
|
|
2868
2923
|
),
|
|
2869
|
-
/* @__PURE__ */ (0,
|
|
2870
|
-
/* @__PURE__ */ (0,
|
|
2871
|
-
categories.map((c) => /* @__PURE__ */ (0,
|
|
2924
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("select", { className: "rounded border border-border bg-transparent px-1 py-0.5 text-xs", "aria-label": "Category", value: category, onChange: (e) => setCategory(e.currentTarget.value), children: [
|
|
2925
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("option", { value: "", children: "All categories" }),
|
|
2926
|
+
categories.map((c) => /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("option", { value: c, children: c }, c))
|
|
2872
2927
|
] }),
|
|
2873
|
-
uses && uses.length > 1 && /* @__PURE__ */ (0,
|
|
2874
|
-
/* @__PURE__ */ (0,
|
|
2875
|
-
uses.map((u) => /* @__PURE__ */ (0,
|
|
2928
|
+
uses && uses.length > 1 && /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("select", { className: "rounded border border-border bg-transparent px-1 py-0.5 text-xs", "aria-label": "Use", value: use, onChange: (e) => setUse(e.currentTarget.value), children: [
|
|
2929
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("option", { value: "", children: "Any use" }),
|
|
2930
|
+
uses.map((u) => /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("option", { value: u, children: import_effects2.EFFECT_USE_LABELS[u] }, u))
|
|
2876
2931
|
] })
|
|
2877
2932
|
] }),
|
|
2878
|
-
error && /* @__PURE__ */ (0,
|
|
2879
|
-
/* @__PURE__ */ (0,
|
|
2933
|
+
error && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("p", { role: "alert", className: "text-[11px] text-destructive", children: error }),
|
|
2934
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("ul", { className: "grid max-h-96 grid-cols-[repeat(auto-fill,minmax(6.5rem,1fr))] gap-1.5 overflow-y-auto", role: "list", children: shown.map((e) => /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("li", { children: /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
|
|
2880
2935
|
"button",
|
|
2881
2936
|
{
|
|
2882
2937
|
type: "button",
|
|
@@ -2885,13 +2940,13 @@ function EffectsBrowser({ provider, uses, kinds, onPick, thumbnails = true, titl
|
|
|
2885
2940
|
"data-effect-id": e.id,
|
|
2886
2941
|
onClick: () => onPick(e),
|
|
2887
2942
|
children: [
|
|
2888
|
-
thumbnails && /* @__PURE__ */ (0,
|
|
2889
|
-
/* @__PURE__ */ (0,
|
|
2890
|
-
/* @__PURE__ */ (0,
|
|
2943
|
+
thumbnails && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(EffectThumbnail, { provider, effect: e }),
|
|
2944
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: "truncate text-[11px] font-medium", children: e.name }),
|
|
2945
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: "truncate text-[10px] text-muted-foreground", children: e.uses.map((u) => import_effects2.EFFECT_USE_LABELS[u]).join(" \xB7 ") })
|
|
2891
2946
|
]
|
|
2892
2947
|
}
|
|
2893
2948
|
) }, e.id)) }),
|
|
2894
|
-
!shown.length && !error && /* @__PURE__ */ (0,
|
|
2949
|
+
!shown.length && !error && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("p", { className: "text-[11px] text-muted-foreground", children: "No effects match." })
|
|
2895
2950
|
] });
|
|
2896
2951
|
}
|
|
2897
2952
|
|
|
@@ -2903,7 +2958,7 @@ var import_parameters2 = require("@pixerate/editor/parameters");
|
|
|
2903
2958
|
// src/parameters/fields.tsx
|
|
2904
2959
|
var import_react14 = require("react");
|
|
2905
2960
|
var import_parameters = require("@pixerate/editor/parameters");
|
|
2906
|
-
var
|
|
2961
|
+
var import_jsx_runtime20 = require("react/jsx-runtime");
|
|
2907
2962
|
var parameterInputClass = "h-7 w-full min-w-0 rounded-md border border-input bg-background px-2 text-xs text-foreground tabular-nums focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-primary disabled:cursor-not-allowed disabled:opacity-50";
|
|
2908
2963
|
var parameterButtonClass = "inline-flex h-7 items-center justify-center gap-1 rounded-md border border-input bg-background px-2 text-xs text-foreground hover:bg-muted focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-primary disabled:pointer-events-none disabled:opacity-50";
|
|
2909
2964
|
var rangeClass = "h-4 w-full min-w-0 flex-1 cursor-pointer accent-primary disabled:cursor-not-allowed disabled:opacity-50";
|
|
@@ -2927,7 +2982,7 @@ function ParameterCommitInput({ value, onCommit, multiline, className, onKeyDown
|
|
|
2927
2982
|
onKeyDown: keyDown,
|
|
2928
2983
|
...rest
|
|
2929
2984
|
};
|
|
2930
|
-
return multiline ? /* @__PURE__ */ (0,
|
|
2985
|
+
return multiline ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("textarea", { ...props, className: `${props.className} h-auto min-h-[3.5rem] py-1` }, value) : /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("input", { type: "text", ...props }, value);
|
|
2931
2986
|
}
|
|
2932
2987
|
var plainNumber = (field, value) => (0, import_parameters.formatParameterNumber)({ ...field, unit: void 0 }, value);
|
|
2933
2988
|
function ParameterNumberInput({
|
|
@@ -2938,8 +2993,8 @@ function ParameterNumberInput({
|
|
|
2938
2993
|
id,
|
|
2939
2994
|
"aria-label": ariaLabel
|
|
2940
2995
|
}) {
|
|
2941
|
-
return /* @__PURE__ */ (0,
|
|
2942
|
-
/* @__PURE__ */ (0,
|
|
2996
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "relative min-w-0 flex-1", children: [
|
|
2997
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
2943
2998
|
ParameterCommitInput,
|
|
2944
2999
|
{
|
|
2945
3000
|
id,
|
|
@@ -2961,7 +3016,7 @@ function ParameterNumberInput({
|
|
|
2961
3016
|
}
|
|
2962
3017
|
}
|
|
2963
3018
|
),
|
|
2964
|
-
field.unit && /* @__PURE__ */ (0,
|
|
3019
|
+
field.unit && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "pointer-events-none absolute right-2 top-1/2 -translate-y-1/2 text-[10px] text-muted-foreground", children: field.unit })
|
|
2965
3020
|
] });
|
|
2966
3021
|
}
|
|
2967
3022
|
function ParameterSlider(props) {
|
|
@@ -2972,10 +3027,10 @@ function ParameterSlider(props) {
|
|
|
2972
3027
|
dragging.current = false;
|
|
2973
3028
|
onGestureEnd?.();
|
|
2974
3029
|
};
|
|
2975
|
-
if (!(0, import_parameters.isSliderField)(field)) return /* @__PURE__ */ (0,
|
|
3030
|
+
if (!(0, import_parameters.isSliderField)(field)) return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(ParameterNumberInput, { ...props });
|
|
2976
3031
|
const step = (0, import_parameters.parameterStep)(field);
|
|
2977
|
-
return /* @__PURE__ */ (0,
|
|
2978
|
-
/* @__PURE__ */ (0,
|
|
3032
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
3033
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
2979
3034
|
"input",
|
|
2980
3035
|
{
|
|
2981
3036
|
type: "range",
|
|
@@ -2998,11 +3053,11 @@ function ParameterSlider(props) {
|
|
|
2998
3053
|
onChange: (e) => onChange((0, import_parameters.clampParameterNumber)(field, Number(e.target.value)))
|
|
2999
3054
|
}
|
|
3000
3055
|
),
|
|
3001
|
-
/* @__PURE__ */ (0,
|
|
3056
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className: "w-20 shrink-0", children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(ParameterNumberInput, { ...props, id: props.id, "aria-label": `${(0, import_parameters.parameterLabel)(field)} value` }) })
|
|
3002
3057
|
] });
|
|
3003
3058
|
}
|
|
3004
3059
|
function ParameterToggle({ field, value, onChange, disabled, id }) {
|
|
3005
|
-
return /* @__PURE__ */ (0,
|
|
3060
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
3006
3061
|
"button",
|
|
3007
3062
|
{
|
|
3008
3063
|
type: "button",
|
|
@@ -3013,7 +3068,7 @@ function ParameterToggle({ field, value, onChange, disabled, id }) {
|
|
|
3013
3068
|
disabled: disabled || field.readOnly,
|
|
3014
3069
|
onClick: () => onChange(!value),
|
|
3015
3070
|
className: `relative inline-flex h-5 w-9 shrink-0 items-center rounded-full border border-transparent transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-primary disabled:opacity-50 ${value ? "bg-primary" : "bg-muted"}`,
|
|
3016
|
-
children: /* @__PURE__ */ (0,
|
|
3071
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
3017
3072
|
"span",
|
|
3018
3073
|
{
|
|
3019
3074
|
className: `pointer-events-none block h-4 w-4 rounded-full bg-background shadow transition-transform ${value ? "translate-x-4" : "translate-x-0.5"}`
|
|
@@ -3026,7 +3081,7 @@ function ParameterSelect({ field, value, onChange, disabled, id }) {
|
|
|
3026
3081
|
const options = (0, import_parameters.getChoiceOptions)(field);
|
|
3027
3082
|
const off = disabled || field.readOnly;
|
|
3028
3083
|
if (field.control === "segmented") {
|
|
3029
|
-
return /* @__PURE__ */ (0,
|
|
3084
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { role: "radiogroup", "aria-label": (0, import_parameters.parameterLabel)(field), className: "inline-flex flex-wrap rounded-md border border-input bg-muted p-0.5", children: options.map((o) => /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
3030
3085
|
"button",
|
|
3031
3086
|
{
|
|
3032
3087
|
type: "button",
|
|
@@ -3042,7 +3097,7 @@ function ParameterSelect({ field, value, onChange, disabled, id }) {
|
|
|
3042
3097
|
)) });
|
|
3043
3098
|
}
|
|
3044
3099
|
const index = options.findIndex((o) => o.value === value);
|
|
3045
|
-
return /* @__PURE__ */ (0,
|
|
3100
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
3046
3101
|
"select",
|
|
3047
3102
|
{
|
|
3048
3103
|
id,
|
|
@@ -3054,7 +3109,7 @@ function ParameterSelect({ field, value, onChange, disabled, id }) {
|
|
|
3054
3109
|
if (option) onChange(option.value);
|
|
3055
3110
|
},
|
|
3056
3111
|
className: parameterInputClass,
|
|
3057
|
-
children: options.map((o, i) => /* @__PURE__ */ (0,
|
|
3112
|
+
children: options.map((o, i) => /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("option", { value: String(i), title: o.description, children: (0, import_parameters.choiceOptionLabel)(o) }, String(o.value)))
|
|
3058
3113
|
}
|
|
3059
3114
|
);
|
|
3060
3115
|
}
|
|
@@ -3075,11 +3130,11 @@ function ParameterColor({ field, value, onChange, onGestureStart, onGestureEnd,
|
|
|
3075
3130
|
picking.current = false;
|
|
3076
3131
|
onGestureEnd?.();
|
|
3077
3132
|
};
|
|
3078
|
-
return /* @__PURE__ */ (0,
|
|
3079
|
-
/* @__PURE__ */ (0,
|
|
3080
|
-
/* @__PURE__ */ (0,
|
|
3081
|
-
/* @__PURE__ */ (0,
|
|
3082
|
-
/* @__PURE__ */ (0,
|
|
3133
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "space-y-1.5", children: [
|
|
3134
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
3135
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("span", { className: "relative h-7 w-9 shrink-0 overflow-hidden rounded-md border border-input bg-[repeating-conic-gradient(#d4d4d8_0_25%,#fff_0_50%)] bg-[length:8px_8px]", children: [
|
|
3136
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "absolute inset-0", style: { background: alpha ? hex : rgb } }),
|
|
3137
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
3083
3138
|
"input",
|
|
3084
3139
|
{
|
|
3085
3140
|
type: "color",
|
|
@@ -3095,7 +3150,7 @@ function ParameterColor({ field, value, onChange, onGestureStart, onGestureEnd,
|
|
|
3095
3150
|
}
|
|
3096
3151
|
)
|
|
3097
3152
|
] }),
|
|
3098
|
-
/* @__PURE__ */ (0,
|
|
3153
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
3099
3154
|
ParameterCommitInput,
|
|
3100
3155
|
{
|
|
3101
3156
|
id,
|
|
@@ -3111,7 +3166,7 @@ function ParameterColor({ field, value, onChange, onGestureStart, onGestureEnd,
|
|
|
3111
3166
|
}
|
|
3112
3167
|
)
|
|
3113
3168
|
] }),
|
|
3114
|
-
alpha && /* @__PURE__ */ (0,
|
|
3169
|
+
alpha && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
3115
3170
|
"input",
|
|
3116
3171
|
{
|
|
3117
3172
|
type: "range",
|
|
@@ -3129,10 +3184,10 @@ function ParameterColor({ field, value, onChange, onGestureStart, onGestureEnd,
|
|
|
3129
3184
|
onChange: (e) => onChange(`${rgb}${Number(e.target.value).toString(16).padStart(2, "0")}`)
|
|
3130
3185
|
}
|
|
3131
3186
|
),
|
|
3132
|
-
field.swatches && field.swatches.length > 0 && /* @__PURE__ */ (0,
|
|
3187
|
+
field.swatches && field.swatches.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className: "flex flex-wrap gap-1", children: field.swatches.map((s) => {
|
|
3133
3188
|
const swatch = (0, import_parameters.normalizeHexColor)(s, alpha);
|
|
3134
3189
|
if (!swatch) return null;
|
|
3135
|
-
return /* @__PURE__ */ (0,
|
|
3190
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
3136
3191
|
"button",
|
|
3137
3192
|
{
|
|
3138
3193
|
type: "button",
|
|
@@ -3151,11 +3206,11 @@ function ParameterColor({ field, value, onChange, onGestureStart, onGestureEnd,
|
|
|
3151
3206
|
}
|
|
3152
3207
|
function ParameterVector({ field, value, onChange, disabled, id }) {
|
|
3153
3208
|
const size = (0, import_parameters.vectorSize)(field);
|
|
3154
|
-
return /* @__PURE__ */ (0,
|
|
3209
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className: "grid gap-1.5", style: { gridTemplateColumns: `repeat(${size}, minmax(0, 1fr))` }, children: Array.from({ length: size }, (_, i) => {
|
|
3155
3210
|
const component = (0, import_parameters.vectorComponentField)(field, i);
|
|
3156
|
-
return /* @__PURE__ */ (0,
|
|
3157
|
-
/* @__PURE__ */ (0,
|
|
3158
|
-
/* @__PURE__ */ (0,
|
|
3211
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("label", { className: "flex min-w-0 items-center gap-1", children: [
|
|
3212
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "w-3 shrink-0 text-[10px] uppercase text-muted-foreground", children: component.label }),
|
|
3213
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
3159
3214
|
ParameterNumberInput,
|
|
3160
3215
|
{
|
|
3161
3216
|
field: component,
|
|
@@ -3172,11 +3227,11 @@ function ParameterVector({ field, value, onChange, disabled, id }) {
|
|
|
3172
3227
|
function ParameterImage({ field, value, onChange, disabled, id, resolveFile }) {
|
|
3173
3228
|
const off = disabled || field.readOnly;
|
|
3174
3229
|
const name = (0, import_parameters.parameterLabel)(field);
|
|
3175
|
-
return /* @__PURE__ */ (0,
|
|
3176
|
-
/* @__PURE__ */ (0,
|
|
3177
|
-
/* @__PURE__ */ (0,
|
|
3178
|
-
/* @__PURE__ */ (0,
|
|
3179
|
-
/* @__PURE__ */ (0,
|
|
3230
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "space-y-1.5", children: [
|
|
3231
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
3232
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className: "flex h-12 w-16 shrink-0 items-center justify-center overflow-hidden rounded-md border border-input bg-muted", children: value ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("img", { src: value, alt: name, className: "h-full w-full object-cover" }) : /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "text-[10px] text-muted-foreground", children: "None" }) }),
|
|
3233
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "flex min-w-0 flex-1 flex-col gap-1", children: [
|
|
3234
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
3180
3235
|
ParameterCommitInput,
|
|
3181
3236
|
{
|
|
3182
3237
|
id,
|
|
@@ -3187,10 +3242,10 @@ function ParameterImage({ field, value, onChange, disabled, id, resolveFile }) {
|
|
|
3187
3242
|
onCommit: (text) => onChange(text.trim())
|
|
3188
3243
|
}
|
|
3189
3244
|
),
|
|
3190
|
-
/* @__PURE__ */ (0,
|
|
3191
|
-
resolveFile && /* @__PURE__ */ (0,
|
|
3245
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "flex gap-1", children: [
|
|
3246
|
+
resolveFile && /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("label", { className: `${parameterButtonClass} cursor-pointer ${off ? "pointer-events-none opacity-50" : ""}`, children: [
|
|
3192
3247
|
"Choose file\u2026",
|
|
3193
|
-
/* @__PURE__ */ (0,
|
|
3248
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
3194
3249
|
"input",
|
|
3195
3250
|
{
|
|
3196
3251
|
type: "file",
|
|
@@ -3206,11 +3261,11 @@ function ParameterImage({ field, value, onChange, disabled, id, resolveFile }) {
|
|
|
3206
3261
|
}
|
|
3207
3262
|
)
|
|
3208
3263
|
] }),
|
|
3209
|
-
value && /* @__PURE__ */ (0,
|
|
3264
|
+
value && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("button", { type: "button", className: parameterButtonClass, disabled: off, onClick: () => onChange(""), "aria-label": `Clear ${name}`, children: "Clear" })
|
|
3210
3265
|
] })
|
|
3211
3266
|
] })
|
|
3212
3267
|
] }),
|
|
3213
|
-
field.options && field.options.length > 0 && /* @__PURE__ */ (0,
|
|
3268
|
+
field.options && field.options.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className: "flex flex-wrap gap-1", children: field.options.map((o) => /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
3214
3269
|
"button",
|
|
3215
3270
|
{
|
|
3216
3271
|
type: "button",
|
|
@@ -3220,14 +3275,14 @@ function ParameterImage({ field, value, onChange, disabled, id, resolveFile }) {
|
|
|
3220
3275
|
disabled: off,
|
|
3221
3276
|
onClick: () => onChange(o.url),
|
|
3222
3277
|
className: "h-9 w-12 overflow-hidden rounded border border-input aria-pressed:ring-2 aria-pressed:ring-primary",
|
|
3223
|
-
children: /* @__PURE__ */ (0,
|
|
3278
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("img", { src: o.url, alt: "", className: "h-full w-full object-cover" })
|
|
3224
3279
|
},
|
|
3225
3280
|
o.url
|
|
3226
3281
|
)) })
|
|
3227
3282
|
] });
|
|
3228
3283
|
}
|
|
3229
3284
|
function ParameterText({ field, value, onChange, disabled, id }) {
|
|
3230
|
-
return /* @__PURE__ */ (0,
|
|
3285
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
3231
3286
|
ParameterCommitInput,
|
|
3232
3287
|
{
|
|
3233
3288
|
id,
|
|
@@ -3246,31 +3301,31 @@ function ParameterFieldControl({ field, value, onChange, resolveFile, ...rest })
|
|
|
3246
3301
|
switch (field.type) {
|
|
3247
3302
|
case "number":
|
|
3248
3303
|
case "int":
|
|
3249
|
-
return /* @__PURE__ */ (0,
|
|
3304
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(ParameterSlider, { field, value, onChange: set, ...rest });
|
|
3250
3305
|
case "boolean":
|
|
3251
|
-
return /* @__PURE__ */ (0,
|
|
3306
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(ParameterToggle, { field, value, onChange: set, ...rest });
|
|
3252
3307
|
case "choice":
|
|
3253
|
-
return /* @__PURE__ */ (0,
|
|
3308
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(ParameterSelect, { field, value, onChange: set, ...rest });
|
|
3254
3309
|
case "color":
|
|
3255
|
-
return /* @__PURE__ */ (0,
|
|
3310
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(ParameterColor, { field, value, onChange: set, ...rest });
|
|
3256
3311
|
case "vector":
|
|
3257
|
-
return /* @__PURE__ */ (0,
|
|
3312
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(ParameterVector, { field, value, onChange: set, ...rest });
|
|
3258
3313
|
case "image":
|
|
3259
|
-
return /* @__PURE__ */ (0,
|
|
3314
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(ParameterImage, { field, value, onChange: set, resolveFile, ...rest });
|
|
3260
3315
|
case "text":
|
|
3261
|
-
return /* @__PURE__ */ (0,
|
|
3316
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(ParameterText, { field, value, onChange: set, ...rest });
|
|
3262
3317
|
}
|
|
3263
3318
|
}
|
|
3264
3319
|
|
|
3265
3320
|
// src/effects/EffectParameters.tsx
|
|
3266
|
-
var
|
|
3321
|
+
var import_jsx_runtime21 = require("react/jsx-runtime");
|
|
3267
3322
|
function EffectParameters({ description, values, onChange, onReset, keyframed, onPreset, disabled = false, className = "" }) {
|
|
3268
3323
|
const fields = (0, import_react15.useMemo)(() => (0, import_effects3.effectParameterFields)(description), [description]);
|
|
3269
3324
|
const idBase = (0, import_react15.useId)();
|
|
3270
3325
|
const gesture = import_react15.default.useRef(null);
|
|
3271
3326
|
const count = import_react15.default.useRef(0);
|
|
3272
|
-
return /* @__PURE__ */ (0,
|
|
3273
|
-
onPreset && description.presets.length > 0 && /* @__PURE__ */ (0,
|
|
3327
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: `space-y-2 ${className}`, "data-effect-parameters": description.id, children: [
|
|
3328
|
+
onPreset && description.presets.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
|
|
3274
3329
|
"select",
|
|
3275
3330
|
{
|
|
3276
3331
|
className: "w-full rounded border border-border bg-transparent px-1 py-0.5 text-xs",
|
|
@@ -3282,8 +3337,8 @@ function EffectParameters({ description, values, onChange, onReset, keyframed, o
|
|
|
3282
3337
|
if (preset) onPreset({ ...description.defaults, ...preset.values });
|
|
3283
3338
|
},
|
|
3284
3339
|
children: [
|
|
3285
|
-
/* @__PURE__ */ (0,
|
|
3286
|
-
description.presets.map((p) => /* @__PURE__ */ (0,
|
|
3340
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("option", { value: "", children: "Presets\u2026" }),
|
|
3341
|
+
description.presets.map((p) => /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("option", { value: p.name, children: p.name }, p.name))
|
|
3287
3342
|
]
|
|
3288
3343
|
}
|
|
3289
3344
|
),
|
|
@@ -3293,13 +3348,13 @@ function EffectParameters({ description, values, onChange, onReset, keyframed, o
|
|
|
3293
3348
|
const keyed = keyframed?.has(field.id) ?? false;
|
|
3294
3349
|
const value = (0, import_effects3.effectFieldValue)(field, values[field.id]);
|
|
3295
3350
|
const changed = !keyed && !(0, import_parameters2.parameterValuesEqual)(value, field.default);
|
|
3296
|
-
return /* @__PURE__ */ (0,
|
|
3297
|
-
/* @__PURE__ */ (0,
|
|
3298
|
-
/* @__PURE__ */ (0,
|
|
3299
|
-
keyed && /* @__PURE__ */ (0,
|
|
3300
|
-
onReset && changed && !disabled && /* @__PURE__ */ (0,
|
|
3351
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "space-y-1", "data-effect-control": field.id, children: [
|
|
3352
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "flex items-center gap-1.5", children: [
|
|
3353
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("label", { htmlFor: inputId, className: "min-w-0 flex-1 truncate text-xs font-medium", title: field.description, children: label }),
|
|
3354
|
+
keyed && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "text-[10px] text-muted-foreground", children: "keyframed" }),
|
|
3355
|
+
onReset && changed && !disabled && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("button", { type: "button", className: "rounded px-1 text-[11px] text-muted-foreground hover:text-foreground", "aria-label": `Reset ${label}`, onClick: () => onReset(field.id), children: "\u21BA" })
|
|
3301
3356
|
] }),
|
|
3302
|
-
/* @__PURE__ */ (0,
|
|
3357
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
3303
3358
|
ParameterFieldControl,
|
|
3304
3359
|
{
|
|
3305
3360
|
field,
|
|
@@ -3313,13 +3368,13 @@ function EffectParameters({ description, values, onChange, onReset, keyframed, o
|
|
|
3313
3368
|
)
|
|
3314
3369
|
] }, field.id);
|
|
3315
3370
|
}),
|
|
3316
|
-
!fields.length && /* @__PURE__ */ (0,
|
|
3371
|
+
!fields.length && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("p", { className: "text-[11px] text-muted-foreground", children: "No controls." })
|
|
3317
3372
|
] });
|
|
3318
3373
|
}
|
|
3319
3374
|
|
|
3320
3375
|
// src/vector/VectorProviderEffectsPanel.tsx
|
|
3321
3376
|
var import_react16 = require("react");
|
|
3322
|
-
var
|
|
3377
|
+
var import_jsx_runtime22 = require("react/jsx-runtime");
|
|
3323
3378
|
var btn = "rounded border border-border px-1.5 py-0.5 text-[11px] disabled:opacity-40";
|
|
3324
3379
|
function Controls({ controller, group }) {
|
|
3325
3380
|
const provider = controller.effectsProvider;
|
|
@@ -3327,11 +3382,11 @@ function Controls({ controller, group }) {
|
|
|
3327
3382
|
const { description, error } = useEffectDescription(provider, tag.effect);
|
|
3328
3383
|
const [message, setMessage] = (0, import_react16.useState)(null);
|
|
3329
3384
|
const run = (work) => void work.then(() => setMessage(null), (e) => setMessage(e instanceof Error ? e.message : String(e)));
|
|
3330
|
-
if (!provider) return /* @__PURE__ */ (0,
|
|
3331
|
-
if (error) return /* @__PURE__ */ (0,
|
|
3332
|
-
if (!description) return /* @__PURE__ */ (0,
|
|
3333
|
-
return /* @__PURE__ */ (0,
|
|
3334
|
-
/* @__PURE__ */ (0,
|
|
3385
|
+
if (!provider) return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("p", { className: "text-[11px] text-muted-foreground", children: "No effects provider: the shapes are kept as they are." });
|
|
3386
|
+
if (error) return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("p", { className: "text-[11px] text-amber-500", children: error });
|
|
3387
|
+
if (!description) return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("p", { className: "text-[11px] text-muted-foreground", children: "Loading\u2026" });
|
|
3388
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(import_jsx_runtime22.Fragment, { children: [
|
|
3389
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
3335
3390
|
EffectParameters,
|
|
3336
3391
|
{
|
|
3337
3392
|
description,
|
|
@@ -3341,7 +3396,7 @@ function Controls({ controller, group }) {
|
|
|
3341
3396
|
onPreset: (v) => run(controller.updateVectorEffect(group.id, v))
|
|
3342
3397
|
}
|
|
3343
3398
|
),
|
|
3344
|
-
message && /* @__PURE__ */ (0,
|
|
3399
|
+
message && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("p", { role: "alert", className: "text-[11px] text-destructive", children: message })
|
|
3345
3400
|
] });
|
|
3346
3401
|
}
|
|
3347
3402
|
function VectorProviderEffectsPanel({ controller, className = "" }) {
|
|
@@ -3360,41 +3415,41 @@ function VectorProviderEffectsPanel({ controller, className = "" }) {
|
|
|
3360
3415
|
setMessage(null);
|
|
3361
3416
|
Promise.resolve().then(work).catch((e) => setMessage(e instanceof Error ? e.message : String(e)));
|
|
3362
3417
|
};
|
|
3363
|
-
return /* @__PURE__ */ (0,
|
|
3364
|
-
/* @__PURE__ */ (0,
|
|
3365
|
-
/* @__PURE__ */ (0,
|
|
3366
|
-
/* @__PURE__ */ (0,
|
|
3418
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("section", { className: `flex flex-col gap-2 text-xs ${className}`, "aria-label": "Vector effects", "data-vector-provider-effects": "", children: [
|
|
3419
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "flex items-center gap-1", children: [
|
|
3420
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "flex-1 font-semibold", children: "Effects" }),
|
|
3421
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("button", { type: "button", className: btn, disabled: !provider, "aria-pressed": browse, onClick: () => setBrowse(!browse), children: "Add effect\u2026" })
|
|
3367
3422
|
] }),
|
|
3368
|
-
!provider && /* @__PURE__ */ (0,
|
|
3369
|
-
browse && /* @__PURE__ */ (0,
|
|
3370
|
-
selected.map((g) => /* @__PURE__ */ (0,
|
|
3371
|
-
/* @__PURE__ */ (0,
|
|
3372
|
-
/* @__PURE__ */ (0,
|
|
3373
|
-
/* @__PURE__ */ (0,
|
|
3423
|
+
!provider && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("p", { className: "text-[11px] text-muted-foreground", children: "No effects provider is registered. Effect groups are kept as shapes." }),
|
|
3424
|
+
browse && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(EffectsBrowser, { provider, kinds: ["vector"], title: "Vector effects", onPick: (e) => (setBrowse(false), run(() => controller.addVectorEffect(e.id))) }),
|
|
3425
|
+
selected.map((g) => /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "space-y-1 rounded border border-border p-1", "data-vector-effect-group": g.id, children: [
|
|
3426
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "flex items-center gap-1", children: [
|
|
3427
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "min-w-0 flex-1 truncate font-medium", children: g.providerEffect.name ?? g.providerEffect.effect }),
|
|
3428
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("button", { type: "button", className: btn, title: "Keep the shapes as a plain group", onClick: () => run(() => controller.detachVectorEffect(g.id)), children: "Detach" })
|
|
3374
3429
|
] }),
|
|
3375
|
-
/* @__PURE__ */ (0,
|
|
3430
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(Controls, { controller, group: g })
|
|
3376
3431
|
] }, g.id)),
|
|
3377
|
-
groups.length > 0 && !selected.length && /* @__PURE__ */ (0,
|
|
3432
|
+
groups.length > 0 && !selected.length && /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("p", { className: "text-[11px] text-muted-foreground", children: [
|
|
3378
3433
|
"Select an effect group (",
|
|
3379
3434
|
groups.length,
|
|
3380
3435
|
" in the drawing) to change it."
|
|
3381
3436
|
] }),
|
|
3382
|
-
message && /* @__PURE__ */ (0,
|
|
3437
|
+
message && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("p", { role: "alert", className: "text-[11px] text-destructive", children: message })
|
|
3383
3438
|
] });
|
|
3384
3439
|
}
|
|
3385
3440
|
|
|
3386
3441
|
// src/vector/VectorEditor.tsx
|
|
3387
|
-
var
|
|
3442
|
+
var import_jsx_runtime23 = require("react/jsx-runtime");
|
|
3388
3443
|
function VectorEditor({ controller, tools, showStylePanel = true, height = 520, canvasProps, effects, className }) {
|
|
3389
3444
|
useEffects(controller, effects);
|
|
3390
3445
|
const effectsShown = !!effects || controller.vectorEffectGroups().length > 0;
|
|
3391
|
-
return /* @__PURE__ */ (0,
|
|
3392
|
-
/* @__PURE__ */ (0,
|
|
3393
|
-
/* @__PURE__ */ (0,
|
|
3394
|
-
/* @__PURE__ */ (0,
|
|
3395
|
-
showStylePanel && /* @__PURE__ */ (0,
|
|
3396
|
-
/* @__PURE__ */ (0,
|
|
3397
|
-
effectsShown && /* @__PURE__ */ (0,
|
|
3446
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: `flex flex-col gap-2 ${className ?? ""}`, "data-vector-editor": "", children: [
|
|
3447
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(VectorToolbar, { controller, tools }),
|
|
3448
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex min-h-0 flex-col gap-2 md:flex-row", children: [
|
|
3449
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "relative min-h-[320px] flex-1 overflow-hidden rounded-md border border-border bg-muted/40", style: { height }, children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(VectorCanvas, { controller, ...canvasProps }) }),
|
|
3450
|
+
showStylePanel && /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex w-full shrink-0 flex-col gap-2 md:w-56", children: [
|
|
3451
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(VectorStylePanel, { controller, className: "rounded-md border border-border p-3" }),
|
|
3452
|
+
effectsShown && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(VectorProviderEffectsPanel, { controller, className: "rounded-md border border-border p-3" })
|
|
3398
3453
|
] })
|
|
3399
3454
|
] })
|
|
3400
3455
|
] });
|
|
@@ -3413,6 +3468,7 @@ function VectorEditor({ controller, tools, showStylePanel = true, height = 520,
|
|
|
3413
3468
|
VectorGradientAnnotator,
|
|
3414
3469
|
VectorGradientDefs,
|
|
3415
3470
|
VectorGradientEditor,
|
|
3471
|
+
VectorLensPanel,
|
|
3416
3472
|
VectorMaskPanel,
|
|
3417
3473
|
VectorMaskedNodes,
|
|
3418
3474
|
VectorProviderEffectsPanel,
|