@pixerate/editor-react 0.70.0 → 0.72.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-LCTQWNTL.js → chunk-YAFNCBDA.js} +630 -231
- package/dist/chunk-YAFNCBDA.js.map +1 -0
- package/dist/image-editor/index.cjs +656 -273
- package/dist/image-editor/index.cjs.map +1 -1
- package/dist/image-editor/index.d.cts +33 -2
- package/dist/image-editor/index.d.ts +33 -2
- package/dist/image-editor/index.js +5 -1
- package/dist/index.cjs +1085 -702
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +5 -1
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
- package/dist/chunk-LCTQWNTL.js.map +0 -1
|
@@ -159,7 +159,7 @@ function useImageEditor(options = {}) {
|
|
|
159
159
|
}
|
|
160
160
|
|
|
161
161
|
// src/image-editor/ImageEditor.tsx
|
|
162
|
-
import
|
|
162
|
+
import React12, { useRef as useRef5, useEffect as useEffect10, useState as useState13, useCallback as useCallback2 } from "react";
|
|
163
163
|
import {
|
|
164
164
|
canvasToImagePoint,
|
|
165
165
|
hitTestCrop,
|
|
@@ -176,7 +176,11 @@ import {
|
|
|
176
176
|
handlePaintShortcut,
|
|
177
177
|
pointerPressure,
|
|
178
178
|
FreeTransformTool,
|
|
179
|
-
getViewportProjection
|
|
179
|
+
getViewportProjection,
|
|
180
|
+
ShapeDrawGesture,
|
|
181
|
+
TypeToolGesture,
|
|
182
|
+
DEFAULT_SHAPE_TOOL_OPTIONS,
|
|
183
|
+
DEFAULT_TYPE_TOOL_OPTIONS
|
|
180
184
|
} from "@pixerate/editor/image-editor";
|
|
181
185
|
|
|
182
186
|
// src/image-editor/ControlSlider.tsx
|
|
@@ -826,6 +830,8 @@ import {
|
|
|
826
830
|
dropZone,
|
|
827
831
|
openPsdFile,
|
|
828
832
|
layerBadge,
|
|
833
|
+
layerHasThumbnail,
|
|
834
|
+
layerWarning,
|
|
829
835
|
layerEffectsBadge,
|
|
830
836
|
layerMenu,
|
|
831
837
|
layerPanelRows,
|
|
@@ -918,7 +924,7 @@ var LayersPanel = ({ controller, thumbnailSize = 32, psd = true, psdFileName = "
|
|
|
918
924
|
const placement = dropPlacement(state.layers, id, row.layer.id, dropZone(fraction, row.layer.type === "group"));
|
|
919
925
|
if (placement) attempt(() => controller.moveLayer(id, placement));
|
|
920
926
|
};
|
|
921
|
-
const thumb = (layer) => layer
|
|
927
|
+
const thumb = (layer) => layerHasThumbnail(layer) ? controller.getLayerThumbnail(layer.id, { maxSide: 64 }) : null;
|
|
922
928
|
const maskThumb = (layer) => layer.mask && !layer.mask.source ? controller.getLayerThumbnail(layer.id, { maxSide: 64, mask: true }) : null;
|
|
923
929
|
const locked = (layer) => Boolean(layer.locks?.all || layer.locks?.pixels || layer.locks?.position || layer.locks?.transparency);
|
|
924
930
|
return /* @__PURE__ */ jsxs6("div", { className: `flex flex-col gap-2 text-xs text-slate-200 ${className ?? ""}`, "data-testid": "layers-panel", onClick: () => menu && setMenu(null), children: [
|
|
@@ -1111,15 +1117,25 @@ var LayersPanel = ({ controller, thumbnailSize = 32, psd = true, psdFileName = "
|
|
|
1111
1117
|
}
|
|
1112
1118
|
),
|
|
1113
1119
|
row.clipped && /* @__PURE__ */ jsx6("span", { className: "text-slate-500", "aria-label": "Clipped", children: "\u21B3" }),
|
|
1114
|
-
layer
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1120
|
+
layerHasThumbnail(layer) ? /* @__PURE__ */ jsxs6("span", { className: "relative shrink-0", children: [
|
|
1121
|
+
/* @__PURE__ */ jsx6(
|
|
1122
|
+
Thumbnail,
|
|
1123
|
+
{
|
|
1124
|
+
pixels: thumb(layer),
|
|
1125
|
+
size: thumbnailSize,
|
|
1126
|
+
label: `${row.label} pixels`,
|
|
1127
|
+
selected: row.active && state.activeTarget === "pixels" && Boolean(layer.mask)
|
|
1128
|
+
}
|
|
1129
|
+
),
|
|
1130
|
+
layer.type !== "pixel" && /* @__PURE__ */ jsx6(
|
|
1131
|
+
"span",
|
|
1132
|
+
{
|
|
1133
|
+
"data-testid": "layer-kind-badge",
|
|
1134
|
+
className: "absolute -bottom-1 -right-1 rounded bg-slate-700 px-0.5 text-[8px] font-bold leading-tight text-slate-100 ring-1 ring-slate-900",
|
|
1135
|
+
children: layerBadge(layer)
|
|
1136
|
+
}
|
|
1137
|
+
)
|
|
1138
|
+
] }) : /* @__PURE__ */ jsx6(
|
|
1123
1139
|
"span",
|
|
1124
1140
|
{
|
|
1125
1141
|
className: "shrink-0 grid place-items-center rounded bg-slate-800 text-[9px] text-slate-400 ring-1 ring-slate-700",
|
|
@@ -1186,6 +1202,7 @@ var LayersPanel = ({ controller, thumbnailSize = 32, psd = true, psdFileName = "
|
|
|
1186
1202
|
children: row.label
|
|
1187
1203
|
}
|
|
1188
1204
|
),
|
|
1205
|
+
layerWarning(layer) && /* @__PURE__ */ jsx6("span", { role: "img", "data-testid": "layer-warning", "aria-label": layerWarning(layer), title: layerWarning(layer), className: "text-[10px] text-amber-400", children: "\u26A0" }),
|
|
1189
1206
|
layerEffectsBadge(layer) && /* @__PURE__ */ jsx6(
|
|
1190
1207
|
"button",
|
|
1191
1208
|
{
|
|
@@ -1237,7 +1254,19 @@ var LayersPanel = ({ controller, thumbnailSize = 32, psd = true, psdFileName = "
|
|
|
1237
1254
|
|
|
1238
1255
|
// src/image-editor/BrushOptionsBar.tsx
|
|
1239
1256
|
import { useEffect as useEffect6, useState as useState7 } from "react";
|
|
1240
|
-
import {
|
|
1257
|
+
import {
|
|
1258
|
+
BRUSH_OPTION_CONTROLS,
|
|
1259
|
+
MIXER_MIXING_OPTIONS,
|
|
1260
|
+
MIXER_OPTION_CONTROLS,
|
|
1261
|
+
PAINT_TOOLS,
|
|
1262
|
+
RETOUCH_CHOICES,
|
|
1263
|
+
RETOUCH_OPTION_CONTROLS,
|
|
1264
|
+
RETOUCH_TOGGLES,
|
|
1265
|
+
cloneSourceLabel,
|
|
1266
|
+
isRetouchPaintTool,
|
|
1267
|
+
rgbUnitToHex,
|
|
1268
|
+
setRetouchChoice
|
|
1269
|
+
} from "@pixerate/editor/image-editor";
|
|
1241
1270
|
import { jsx as jsx7, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
1242
1271
|
var chip = (on) => `px-2 py-1 rounded text-[11px] ${on ? "bg-indigo-600 text-white" : "bg-slate-800 text-slate-300 hover:text-white"}`;
|
|
1243
1272
|
var BrushOptionsBar = ({ controller, className }) => {
|
|
@@ -1245,7 +1274,8 @@ var BrushOptionsBar = ({ controller, className }) => {
|
|
|
1245
1274
|
useEffect6(() => controller.subscribe(() => setTick((n) => n + 1)), [controller]);
|
|
1246
1275
|
const [error, setError] = useState7(null);
|
|
1247
1276
|
const state = controller.getState();
|
|
1248
|
-
const { brush, foreground, background, mixer, mixerLoad } = state.paint;
|
|
1277
|
+
const { brush, foreground, background, mixer, mixerLoad, retouch, cloneSource } = state.paint;
|
|
1278
|
+
const tool = state.activeTool;
|
|
1249
1279
|
const attempt = (fn) => {
|
|
1250
1280
|
try {
|
|
1251
1281
|
setError(null);
|
|
@@ -1255,12 +1285,12 @@ var BrushOptionsBar = ({ controller, className }) => {
|
|
|
1255
1285
|
}
|
|
1256
1286
|
};
|
|
1257
1287
|
return /* @__PURE__ */ jsxs7("div", { className: `flex flex-col gap-2 text-xs text-slate-200 ${className ?? ""}`, "data-testid": "brush-options", children: [
|
|
1258
|
-
/* @__PURE__ */ jsx7("div", { className: "flex gap-1", role: "toolbar", "aria-label": "Paint tools", children: PAINT_TOOLS.map((t) => /* @__PURE__ */ jsx7(
|
|
1288
|
+
/* @__PURE__ */ jsx7("div", { className: "flex flex-wrap gap-1", role: "toolbar", "aria-label": "Paint tools", children: PAINT_TOOLS.map((t) => /* @__PURE__ */ jsx7(
|
|
1259
1289
|
"button",
|
|
1260
1290
|
{
|
|
1261
1291
|
type: "button",
|
|
1262
1292
|
"aria-pressed": state.activeTool === t.id,
|
|
1263
|
-
title: `${t.label} (${t.shortcut})
|
|
1293
|
+
title: t.shortcut ? `${t.label} (${t.shortcut})` : t.label,
|
|
1264
1294
|
className: chip(state.activeTool === t.id),
|
|
1265
1295
|
onClick: () => controller.setTool(t.id),
|
|
1266
1296
|
children: t.label
|
|
@@ -1362,6 +1392,41 @@ var BrushOptionsBar = ({ controller, className }) => {
|
|
|
1362
1392
|
] })
|
|
1363
1393
|
] })
|
|
1364
1394
|
] }),
|
|
1395
|
+
isRetouchPaintTool(tool) && /* @__PURE__ */ jsxs7("div", { className: "flex flex-col gap-2 border-t border-slate-800 pt-2", role: "group", "aria-label": "Retouch options", "data-testid": "retouch-options", children: [
|
|
1396
|
+
(tool === "clone" || tool === "heal") && /* @__PURE__ */ jsxs7("div", { className: "flex items-center gap-2", children: [
|
|
1397
|
+
/* @__PURE__ */ jsx7("span", { className: "text-slate-400", "data-testid": "clone-source", children: cloneSourceLabel(controller) }),
|
|
1398
|
+
cloneSource && /* @__PURE__ */ jsx7("button", { type: "button", title: "Forget the source point", className: chip(false), onClick: () => controller.setCloneSource(null), children: "Clear source" })
|
|
1399
|
+
] }),
|
|
1400
|
+
RETOUCH_CHOICES.filter((c) => c.tools.includes(tool)).map((choice) => /* @__PURE__ */ jsxs7("div", { className: "flex flex-wrap items-center gap-1", role: "group", "aria-label": choice.label, children: [
|
|
1401
|
+
/* @__PURE__ */ jsx7("span", { className: "text-slate-400", children: choice.label }),
|
|
1402
|
+
choice.options.map((o) => /* @__PURE__ */ jsx7(
|
|
1403
|
+
"button",
|
|
1404
|
+
{
|
|
1405
|
+
type: "button",
|
|
1406
|
+
"aria-pressed": retouch[choice.id] === o.id,
|
|
1407
|
+
title: o.title,
|
|
1408
|
+
className: chip(retouch[choice.id] === o.id),
|
|
1409
|
+
onClick: () => setRetouchChoice(controller, choice.id, o.id),
|
|
1410
|
+
children: o.label
|
|
1411
|
+
},
|
|
1412
|
+
o.id
|
|
1413
|
+
))
|
|
1414
|
+
] }, choice.id)),
|
|
1415
|
+
RETOUCH_OPTION_CONTROLS.filter((c) => c.tools.includes(tool)).map((spec) => /* @__PURE__ */ jsx7(ControlSlider, { spec, value: retouch[spec.id], onChange: (v) => controller.setPaintOptions({ retouch: { [spec.id]: v } }) }, spec.id)),
|
|
1416
|
+
/* @__PURE__ */ jsx7("div", { className: "flex flex-wrap gap-3 text-slate-300", children: RETOUCH_TOGGLES.filter((t) => t.tools.includes(tool)).map((t) => /* @__PURE__ */ jsxs7("label", { className: "flex items-center gap-1.5", children: [
|
|
1417
|
+
/* @__PURE__ */ jsx7(
|
|
1418
|
+
"input",
|
|
1419
|
+
{
|
|
1420
|
+
type: "checkbox",
|
|
1421
|
+
"aria-label": t.label,
|
|
1422
|
+
checked: retouch[t.id],
|
|
1423
|
+
onChange: (e) => controller.setPaintOptions({ retouch: { [t.id]: e.target.checked } }),
|
|
1424
|
+
className: "accent-indigo-500"
|
|
1425
|
+
}
|
|
1426
|
+
),
|
|
1427
|
+
t.label
|
|
1428
|
+
] }, t.id)) })
|
|
1429
|
+
] }),
|
|
1365
1430
|
/* @__PURE__ */ jsxs7("div", { className: "flex flex-wrap gap-3 text-slate-300", role: "group", "aria-label": "Pressure", children: [
|
|
1366
1431
|
/* @__PURE__ */ jsxs7("label", { className: "flex items-center gap-1.5", children: [
|
|
1367
1432
|
/* @__PURE__ */ jsx7(
|
|
@@ -1803,8 +1868,215 @@ var FreeTransformOptionsBar = ({ tool, className }) => {
|
|
|
1803
1868
|
] });
|
|
1804
1869
|
};
|
|
1805
1870
|
|
|
1806
|
-
// src/image-editor/
|
|
1871
|
+
// src/image-editor/ShapeOptionsBar.tsx
|
|
1872
|
+
import { useEffect as useEffect8, useState as useState11 } from "react";
|
|
1873
|
+
import { LIVE_SHAPE_KINDS, SHAPE_KIND_LABELS, applyShapeOptions } from "@pixerate/editor/image-editor";
|
|
1807
1874
|
import { Fragment as Fragment3, jsx as jsx11, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
1875
|
+
var chip3 = (on) => `px-2 py-1 rounded text-[11px] ${on ? "bg-indigo-600 text-white" : "bg-slate-800 text-slate-300 hover:text-white"}`;
|
|
1876
|
+
var ShapeOptionsBar = ({ controller, options, onChange, className }) => {
|
|
1877
|
+
const [, setTick] = useState11(0);
|
|
1878
|
+
useEffect8(() => controller.subscribe(() => setTick((n) => n + 1)), [controller]);
|
|
1879
|
+
const [error, setError] = useState11(null);
|
|
1880
|
+
const active = controller.getActiveLayer();
|
|
1881
|
+
const shapeId = active?.type === "shape" ? active.id : null;
|
|
1882
|
+
const set = (change) => {
|
|
1883
|
+
onChange({ ...options, ...change });
|
|
1884
|
+
if (!shapeId) return;
|
|
1885
|
+
try {
|
|
1886
|
+
setError(null);
|
|
1887
|
+
applyShapeOptions(controller, shapeId, change);
|
|
1888
|
+
} catch (e) {
|
|
1889
|
+
setError(e instanceof Error ? e.message : String(e));
|
|
1890
|
+
}
|
|
1891
|
+
};
|
|
1892
|
+
const num = (v, min, max) => Math.max(min, Math.min(max, Number(v) || min));
|
|
1893
|
+
return /* @__PURE__ */ jsxs11("div", { className: `flex flex-col gap-2 text-xs text-slate-200 ${className ?? ""}`, "data-testid": "shape-options", children: [
|
|
1894
|
+
/* @__PURE__ */ jsx11("div", { className: "flex flex-wrap gap-1", role: "toolbar", "aria-label": "Shape kind", children: LIVE_SHAPE_KINDS.map((k) => /* @__PURE__ */ jsx11("button", { type: "button", "aria-pressed": options.kind === k, className: chip3(options.kind === k), onClick: () => onChange({ ...options, kind: k }), children: SHAPE_KIND_LABELS[k] }, k)) }),
|
|
1895
|
+
/* @__PURE__ */ jsxs11("div", { className: "flex flex-wrap items-center gap-3", children: [
|
|
1896
|
+
/* @__PURE__ */ jsxs11("label", { className: "flex items-center gap-1", children: [
|
|
1897
|
+
/* @__PURE__ */ jsx11("input", { type: "checkbox", "aria-label": "Fill", checked: options.fill !== null, onChange: (e) => set({ fill: e.target.checked ? "#4f46e5" : null }) }),
|
|
1898
|
+
"Fill",
|
|
1899
|
+
/* @__PURE__ */ jsx11(
|
|
1900
|
+
"input",
|
|
1901
|
+
{
|
|
1902
|
+
type: "color",
|
|
1903
|
+
"aria-label": "Fill colour",
|
|
1904
|
+
disabled: options.fill === null,
|
|
1905
|
+
value: options.fill ?? "#4f46e5",
|
|
1906
|
+
onChange: (e) => set({ fill: e.target.value }),
|
|
1907
|
+
className: "h-6 w-8 rounded border border-slate-700 bg-transparent"
|
|
1908
|
+
}
|
|
1909
|
+
)
|
|
1910
|
+
] }),
|
|
1911
|
+
/* @__PURE__ */ jsxs11("label", { className: "flex items-center gap-1", children: [
|
|
1912
|
+
/* @__PURE__ */ jsx11("input", { type: "checkbox", "aria-label": "Stroke", checked: options.stroke !== null, onChange: (e) => set({ stroke: e.target.checked ? "#000000" : null }) }),
|
|
1913
|
+
"Stroke",
|
|
1914
|
+
/* @__PURE__ */ jsx11(
|
|
1915
|
+
"input",
|
|
1916
|
+
{
|
|
1917
|
+
type: "color",
|
|
1918
|
+
"aria-label": "Stroke colour",
|
|
1919
|
+
disabled: options.stroke === null,
|
|
1920
|
+
value: options.stroke ?? "#000000",
|
|
1921
|
+
onChange: (e) => set({ stroke: e.target.value }),
|
|
1922
|
+
className: "h-6 w-8 rounded border border-slate-700 bg-transparent"
|
|
1923
|
+
}
|
|
1924
|
+
)
|
|
1925
|
+
] }),
|
|
1926
|
+
/* @__PURE__ */ jsxs11("label", { className: "flex items-center gap-1", children: [
|
|
1927
|
+
"Width",
|
|
1928
|
+
/* @__PURE__ */ jsx11(
|
|
1929
|
+
"input",
|
|
1930
|
+
{
|
|
1931
|
+
type: "number",
|
|
1932
|
+
"aria-label": "Stroke width",
|
|
1933
|
+
min: 0,
|
|
1934
|
+
max: 200,
|
|
1935
|
+
value: options.strokeWidth,
|
|
1936
|
+
onChange: (e) => set({ strokeWidth: num(e.target.value, 0, 200) }),
|
|
1937
|
+
className: "w-14 rounded border border-slate-700 bg-slate-950 px-1 py-0.5"
|
|
1938
|
+
}
|
|
1939
|
+
)
|
|
1940
|
+
] })
|
|
1941
|
+
] }),
|
|
1942
|
+
/* @__PURE__ */ jsxs11("div", { className: "flex flex-wrap items-center gap-3", children: [
|
|
1943
|
+
options.kind === "rect" && /* @__PURE__ */ jsxs11("label", { className: "flex items-center gap-1", children: [
|
|
1944
|
+
"Radius",
|
|
1945
|
+
/* @__PURE__ */ jsx11("input", { type: "number", "aria-label": "Corner radius", min: 0, max: 1e3, value: options.radius, onChange: (e) => set({ radius: num(e.target.value, 0, 1e3) }), className: "w-14 rounded border border-slate-700 bg-slate-950 px-1 py-0.5" })
|
|
1946
|
+
] }),
|
|
1947
|
+
options.kind === "polygon" && /* @__PURE__ */ jsxs11("label", { className: "flex items-center gap-1", children: [
|
|
1948
|
+
"Sides",
|
|
1949
|
+
/* @__PURE__ */ jsx11("input", { type: "number", "aria-label": "Sides", min: 3, max: 100, value: options.sides, onChange: (e) => set({ sides: num(e.target.value, 3, 100) }), className: "w-14 rounded border border-slate-700 bg-slate-950 px-1 py-0.5" })
|
|
1950
|
+
] }),
|
|
1951
|
+
options.kind === "star" && /* @__PURE__ */ jsxs11(Fragment3, { children: [
|
|
1952
|
+
/* @__PURE__ */ jsxs11("label", { className: "flex items-center gap-1", children: [
|
|
1953
|
+
"Points",
|
|
1954
|
+
/* @__PURE__ */ jsx11("input", { type: "number", "aria-label": "Points", min: 3, max: 100, value: options.points, onChange: (e) => set({ points: num(e.target.value, 3, 100) }), className: "w-14 rounded border border-slate-700 bg-slate-950 px-1 py-0.5" })
|
|
1955
|
+
] }),
|
|
1956
|
+
/* @__PURE__ */ jsxs11("label", { className: "flex items-center gap-1", children: [
|
|
1957
|
+
"Inner",
|
|
1958
|
+
/* @__PURE__ */ jsx11(
|
|
1959
|
+
"input",
|
|
1960
|
+
{
|
|
1961
|
+
type: "range",
|
|
1962
|
+
"aria-label": "Inner radius",
|
|
1963
|
+
min: 0.05,
|
|
1964
|
+
max: 1,
|
|
1965
|
+
step: 0.05,
|
|
1966
|
+
value: options.innerRatio,
|
|
1967
|
+
onChange: (e) => set({ innerRatio: Number(e.target.value) }),
|
|
1968
|
+
className: "accent-indigo-500"
|
|
1969
|
+
}
|
|
1970
|
+
)
|
|
1971
|
+
] })
|
|
1972
|
+
] }),
|
|
1973
|
+
options.kind === "line" && /* @__PURE__ */ jsxs11(Fragment3, { children: [
|
|
1974
|
+
/* @__PURE__ */ jsxs11("label", { className: "flex items-center gap-1", children: [
|
|
1975
|
+
"Weight",
|
|
1976
|
+
/* @__PURE__ */ jsx11("input", { type: "number", "aria-label": "Line weight", min: 1, max: 200, value: options.weight, onChange: (e) => set({ weight: num(e.target.value, 1, 200) }), className: "w-14 rounded border border-slate-700 bg-slate-950 px-1 py-0.5" })
|
|
1977
|
+
] }),
|
|
1978
|
+
/* @__PURE__ */ jsxs11("label", { className: "flex items-center gap-1", children: [
|
|
1979
|
+
/* @__PURE__ */ jsx11("input", { type: "checkbox", "aria-label": "Arrowhead", checked: options.arrow, onChange: (e) => set({ arrow: e.target.checked }) }),
|
|
1980
|
+
"Arrowhead"
|
|
1981
|
+
] })
|
|
1982
|
+
] })
|
|
1983
|
+
] }),
|
|
1984
|
+
/* @__PURE__ */ jsx11("p", { className: "text-[10px] text-slate-500", children: "Drag on the image to draw. Shift: square, circle or 45\xB0 line. Alt: from the centre." }),
|
|
1985
|
+
error && /* @__PURE__ */ jsx11("p", { role: "alert", className: "text-rose-400", children: error })
|
|
1986
|
+
] });
|
|
1987
|
+
};
|
|
1988
|
+
|
|
1989
|
+
// src/image-editor/TypeOptionsBar.tsx
|
|
1990
|
+
import { useEffect as useEffect9, useState as useState12 } from "react";
|
|
1991
|
+
import { TEXT_ALIGNS } from "@pixerate/editor/image-editor";
|
|
1992
|
+
import { jsx as jsx12, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
1993
|
+
var chip4 = (on) => `px-2 py-1 rounded text-[11px] ${on ? "bg-indigo-600 text-white" : "bg-slate-800 text-slate-300 hover:text-white"}`;
|
|
1994
|
+
var ALIGN_LABELS = { left: "Left", center: "Centre", right: "Right", justify: "Justify" };
|
|
1995
|
+
var TypeOptionsBar = ({ controller, options, onChange, session, className }) => {
|
|
1996
|
+
const [, setTick] = useState12(0);
|
|
1997
|
+
useEffect9(() => controller.subscribe(() => setTick((n) => n + 1)), [controller]);
|
|
1998
|
+
useEffect9(() => session?.subscribe(() => setTick((n) => n + 1)), [session]);
|
|
1999
|
+
const [error, setError] = useState12(null);
|
|
2000
|
+
const active = controller.getActiveLayer();
|
|
2001
|
+
const typeId = !session && active?.type === "type" ? active.id : null;
|
|
2002
|
+
const here = session?.alive ? session.styleHere() : {};
|
|
2003
|
+
const shown = {
|
|
2004
|
+
...options,
|
|
2005
|
+
...here.fontFamily ? { fontFamily: here.fontFamily } : {},
|
|
2006
|
+
...here.fontSize ? { fontSize: here.fontSize } : {},
|
|
2007
|
+
...here.fontWeight ? { fontWeight: here.fontWeight } : {},
|
|
2008
|
+
...session?.alive ? { italic: Boolean(here.italic), color: here.color ?? options.color } : {}
|
|
2009
|
+
};
|
|
2010
|
+
const fonts = controller.listFonts();
|
|
2011
|
+
const missing = active?.type === "type" ? active.missingFonts ?? [] : [];
|
|
2012
|
+
const style = (change) => {
|
|
2013
|
+
onChange({ ...options, ...change });
|
|
2014
|
+
const s = {};
|
|
2015
|
+
for (const k of ["fontFamily", "fontSize", "fontWeight", "italic", "color"]) if (k in change) s[k] = change[k];
|
|
2016
|
+
const p = change.align ? { align: change.align } : null;
|
|
2017
|
+
try {
|
|
2018
|
+
setError(null);
|
|
2019
|
+
if (session?.alive) {
|
|
2020
|
+
if (Object.keys(s).length) session.setStyle(s);
|
|
2021
|
+
if (p) session.setParagraph(p);
|
|
2022
|
+
if (session.error) setError(session.error);
|
|
2023
|
+
} else if (typeId) {
|
|
2024
|
+
if (Object.keys(s).length) controller.setTextStyle(typeId, s);
|
|
2025
|
+
if (p) controller.setParagraphStyle(typeId, p);
|
|
2026
|
+
}
|
|
2027
|
+
} catch (e) {
|
|
2028
|
+
setError(e instanceof Error ? e.message : String(e));
|
|
2029
|
+
}
|
|
2030
|
+
};
|
|
2031
|
+
return /* @__PURE__ */ jsxs12("div", { className: `flex flex-col gap-2 text-xs text-slate-200 ${className ?? ""}`, "data-testid": "type-options", children: [
|
|
2032
|
+
/* @__PURE__ */ jsxs12("div", { className: "flex flex-wrap items-center gap-2", children: [
|
|
2033
|
+
/* @__PURE__ */ jsxs12("label", { className: "flex items-center gap-1", children: [
|
|
2034
|
+
"Font",
|
|
2035
|
+
/* @__PURE__ */ jsx12(
|
|
2036
|
+
"input",
|
|
2037
|
+
{
|
|
2038
|
+
list: "pixerate-type-fonts",
|
|
2039
|
+
"aria-label": "Font family",
|
|
2040
|
+
value: shown.fontFamily,
|
|
2041
|
+
onChange: (e) => e.target.value.trim() && style({ fontFamily: e.target.value }),
|
|
2042
|
+
className: "w-32 rounded border border-slate-700 bg-slate-950 px-1 py-0.5"
|
|
2043
|
+
}
|
|
2044
|
+
),
|
|
2045
|
+
/* @__PURE__ */ jsx12("datalist", { id: "pixerate-type-fonts", children: fonts.map((f) => /* @__PURE__ */ jsx12("option", { value: f }, f)) })
|
|
2046
|
+
] }),
|
|
2047
|
+
/* @__PURE__ */ jsxs12("label", { className: "flex items-center gap-1", children: [
|
|
2048
|
+
"Size",
|
|
2049
|
+
/* @__PURE__ */ jsx12(
|
|
2050
|
+
"input",
|
|
2051
|
+
{
|
|
2052
|
+
type: "number",
|
|
2053
|
+
"aria-label": "Font size",
|
|
2054
|
+
min: 1,
|
|
2055
|
+
max: 2e3,
|
|
2056
|
+
value: Math.round(shown.fontSize * 10) / 10,
|
|
2057
|
+
onChange: (e) => Number(e.target.value) > 0 && style({ fontSize: Number(e.target.value) }),
|
|
2058
|
+
className: "w-16 rounded border border-slate-700 bg-slate-950 px-1 py-0.5"
|
|
2059
|
+
}
|
|
2060
|
+
)
|
|
2061
|
+
] }),
|
|
2062
|
+
/* @__PURE__ */ jsx12("button", { type: "button", "aria-pressed": shown.fontWeight >= 600, className: `${chip4(shown.fontWeight >= 600)} font-bold`, onClick: () => style({ fontWeight: shown.fontWeight >= 600 ? 400 : 700 }), children: "B" }),
|
|
2063
|
+
/* @__PURE__ */ jsx12("button", { type: "button", "aria-pressed": shown.italic, className: `${chip4(shown.italic)} italic`, onClick: () => style({ italic: !shown.italic }), children: "I" }),
|
|
2064
|
+
/* @__PURE__ */ jsx12("input", { type: "color", "aria-label": "Text colour", value: shown.color, onChange: (e) => style({ color: e.target.value }), className: "h-6 w-8 rounded border border-slate-700 bg-transparent" })
|
|
2065
|
+
] }),
|
|
2066
|
+
/* @__PURE__ */ jsx12("div", { className: "flex gap-1", role: "toolbar", "aria-label": "Alignment", children: TEXT_ALIGNS.map((a) => /* @__PURE__ */ jsx12("button", { type: "button", "aria-pressed": options.align === a, className: chip4(options.align === a), onClick: () => style({ align: a }), children: ALIGN_LABELS[a] }, a)) }),
|
|
2067
|
+
/* @__PURE__ */ jsx12("p", { className: "text-[10px] text-slate-500", children: "Click to type point text, drag for a paragraph box, click text to edit it. Esc finishes." }),
|
|
2068
|
+
missing.length > 0 && /* @__PURE__ */ jsxs12("p", { role: "status", className: "text-amber-400", "data-testid": "type-missing-fonts", children: [
|
|
2069
|
+
"Missing ",
|
|
2070
|
+
missing.length === 1 ? "font" : "fonts",
|
|
2071
|
+
": ",
|
|
2072
|
+
missing.join(", ")
|
|
2073
|
+
] }),
|
|
2074
|
+
error && /* @__PURE__ */ jsx12("p", { role: "alert", className: "text-rose-400", children: error })
|
|
2075
|
+
] });
|
|
2076
|
+
};
|
|
2077
|
+
|
|
2078
|
+
// src/image-editor/ImageEditor.tsx
|
|
2079
|
+
import { Fragment as Fragment4, jsx as jsx13, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
1808
2080
|
var ImageEditor = ({
|
|
1809
2081
|
editor: externalEditor,
|
|
1810
2082
|
src,
|
|
@@ -1822,9 +2094,9 @@ var ImageEditor = ({
|
|
|
1822
2094
|
const legacyProcess = normalizeProcessVersion(state.adjustments.process) < LATEST_PROCESS_VERSION;
|
|
1823
2095
|
const canvasRef = useRef5(null);
|
|
1824
2096
|
const containerRef = useRef5(null);
|
|
1825
|
-
const [activeTab, setActiveTab] =
|
|
1826
|
-
const [activeCropRatio, setActiveCropRatio] =
|
|
1827
|
-
const [selectionOptions, setSelectionOptions] =
|
|
2097
|
+
const [activeTab, setActiveTab] = useState13("crop");
|
|
2098
|
+
const [activeCropRatio, setActiveCropRatio] = useState13(null);
|
|
2099
|
+
const [selectionOptions, setSelectionOptions] = useState13(DEFAULT_SELECTION_TOOL_OPTIONS);
|
|
1828
2100
|
const selectionOptionsRef = useRef5(selectionOptions);
|
|
1829
2101
|
selectionOptionsRef.current = selectionOptions;
|
|
1830
2102
|
const selectionGestureRef = useRef5(null);
|
|
@@ -1832,7 +2104,7 @@ var ImageEditor = ({
|
|
|
1832
2104
|
selectionGestureRef.current = new SelectionGesture(controller, () => selectionOptionsRef.current);
|
|
1833
2105
|
}
|
|
1834
2106
|
const selectionDraftRef = useRef5(null);
|
|
1835
|
-
const [selectionError, setSelectionError] =
|
|
2107
|
+
const [selectionError, setSelectionError] = useState13(null);
|
|
1836
2108
|
const paintGestureRef = useRef5(null);
|
|
1837
2109
|
const paintControllerRef = useRef5(controller);
|
|
1838
2110
|
if (!paintGestureRef.current || paintControllerRef.current !== controller) {
|
|
@@ -1840,7 +2112,7 @@ var ImageEditor = ({
|
|
|
1840
2112
|
paintControllerRef.current = controller;
|
|
1841
2113
|
}
|
|
1842
2114
|
const brushCursorRef = useRef5(null);
|
|
1843
|
-
const [paintError, setPaintError] =
|
|
2115
|
+
const [paintError, setPaintError] = useState13(null);
|
|
1844
2116
|
const transformToolRef = useRef5(null);
|
|
1845
2117
|
const transformControllerRef = useRef5(controller);
|
|
1846
2118
|
if (!transformToolRef.current || transformControllerRef.current !== controller) {
|
|
@@ -1851,15 +2123,33 @@ var ImageEditor = ({
|
|
|
1851
2123
|
transformControllerRef.current = controller;
|
|
1852
2124
|
}
|
|
1853
2125
|
const transformTool = transformToolRef.current;
|
|
1854
|
-
const [, setTransformTick] =
|
|
1855
|
-
const [transformCursor, setTransformCursor] =
|
|
1856
|
-
const [
|
|
1857
|
-
const
|
|
1858
|
-
|
|
1859
|
-
const [
|
|
1860
|
-
const
|
|
1861
|
-
|
|
1862
|
-
const
|
|
2126
|
+
const [, setTransformTick] = useState13(0);
|
|
2127
|
+
const [transformCursor, setTransformCursor] = useState13("default");
|
|
2128
|
+
const [shapeOptions, setShapeOptions] = useState13(DEFAULT_SHAPE_TOOL_OPTIONS);
|
|
2129
|
+
const shapeOptionsRef = useRef5(shapeOptions);
|
|
2130
|
+
shapeOptionsRef.current = shapeOptions;
|
|
2131
|
+
const [typeOptions, setTypeOptions] = useState13(DEFAULT_TYPE_TOOL_OPTIONS);
|
|
2132
|
+
const typeOptionsRef = useRef5(typeOptions);
|
|
2133
|
+
typeOptionsRef.current = typeOptions;
|
|
2134
|
+
const shapeGestureRef = useRef5(null);
|
|
2135
|
+
const typeToolRef = useRef5(null);
|
|
2136
|
+
const shapeTypeControllerRef = useRef5(controller);
|
|
2137
|
+
if (!shapeGestureRef.current || !typeToolRef.current || shapeTypeControllerRef.current !== controller) {
|
|
2138
|
+
typeToolRef.current?.finish();
|
|
2139
|
+
shapeGestureRef.current = new ShapeDrawGesture(controller, () => shapeOptionsRef.current);
|
|
2140
|
+
typeToolRef.current = new TypeToolGesture(controller, () => typeOptionsRef.current);
|
|
2141
|
+
shapeTypeControllerRef.current = controller;
|
|
2142
|
+
}
|
|
2143
|
+
const typeInputRef = useRef5(null);
|
|
2144
|
+
const [typeSession, setTypeSession] = useState13(typeToolRef.current.session);
|
|
2145
|
+
const [shapeTypeError, setShapeTypeError] = useState13(null);
|
|
2146
|
+
const [inpaintPrompt, setInpaintPrompt] = useState13("");
|
|
2147
|
+
const [inpaintMaskMode, setInpaintMaskMode] = useState13("annotations");
|
|
2148
|
+
const [isRemovingBg, setIsRemovingBg] = useState13(false);
|
|
2149
|
+
const [isInpainting, setIsInpainting] = useState13(false);
|
|
2150
|
+
const [aiError, setAiError] = useState13(null);
|
|
2151
|
+
const [aiSuccess, setAiSuccess] = useState13(null);
|
|
2152
|
+
const [aiTarget, setAiTarget] = useState13("auto");
|
|
1863
2153
|
const aiOptions = aiTarget === "auto" ? {} : { target: aiTarget };
|
|
1864
2154
|
const effectiveOnInpaint = onInpaint || aiHooks?.onInpaint;
|
|
1865
2155
|
const effectiveOnRemoveBg = onRemoveBackground || aiHooks?.onRemoveBackground;
|
|
@@ -1922,10 +2212,10 @@ var ImageEditor = ({
|
|
|
1922
2212
|
setIsInpainting(false);
|
|
1923
2213
|
}
|
|
1924
2214
|
};
|
|
1925
|
-
const [activeColor, setActiveColor] =
|
|
1926
|
-
const [strokeWidth, setStrokeWidth] =
|
|
1927
|
-
const [fontSize, setFontSize] =
|
|
1928
|
-
const [textInput, setTextInput] =
|
|
2215
|
+
const [activeColor, setActiveColor] = useState13("#ef4444");
|
|
2216
|
+
const [strokeWidth, setStrokeWidth] = useState13(3);
|
|
2217
|
+
const [fontSize, setFontSize] = useState13(24);
|
|
2218
|
+
const [textInput, setTextInput] = useState13("");
|
|
1929
2219
|
const draftAnnotationRef = useRef5(null);
|
|
1930
2220
|
const draftCropRef = useRef5(null);
|
|
1931
2221
|
const cropDragInfoRef = useRef5(null);
|
|
@@ -1950,12 +2240,49 @@ var ImageEditor = ({
|
|
|
1950
2240
|
draftCrop: draftCrop !== void 0 ? draftCrop : draftCropRef.current,
|
|
1951
2241
|
draftSelectionPath: selectionDraftRef.current,
|
|
1952
2242
|
brushCursor: activeTab === "paint" && brushCursorRef.current && controller.getState().activeTool !== "move" && !transformTool.active ? { ...brushCursorRef.current, diameter: controller.getState().paint.brush.size } : null,
|
|
1953
|
-
freeTransform: transformTool.overlay()
|
|
2243
|
+
freeTransform: transformTool.overlay(),
|
|
2244
|
+
textEdit: typeToolRef.current?.session?.alive ? typeToolRef.current.session.overlay() : null
|
|
1954
2245
|
});
|
|
1955
2246
|
},
|
|
1956
2247
|
[controller, activeTab, transformTool]
|
|
1957
2248
|
);
|
|
1958
|
-
|
|
2249
|
+
useEffect10(() => typeSession?.subscribe(() => void renderCanvas()), [typeSession, renderCanvas]);
|
|
2250
|
+
useEffect10(() => {
|
|
2251
|
+
if (activeTab === "annotate" && state.activeTool === "type") return;
|
|
2252
|
+
if (typeToolRef.current?.session) {
|
|
2253
|
+
typeToolRef.current.finish();
|
|
2254
|
+
setTypeSession(null);
|
|
2255
|
+
void renderCanvas();
|
|
2256
|
+
}
|
|
2257
|
+
}, [activeTab, state.activeTool, renderCanvas]);
|
|
2258
|
+
const finishTyping = () => {
|
|
2259
|
+
typeToolRef.current?.finish();
|
|
2260
|
+
setTypeSession(null);
|
|
2261
|
+
void renderCanvas();
|
|
2262
|
+
};
|
|
2263
|
+
const handleTypeKeyDown = (e) => {
|
|
2264
|
+
const session = typeToolRef.current?.session;
|
|
2265
|
+
if (!session || e.nativeEvent.isComposing) return;
|
|
2266
|
+
if (e.key === "Escape") {
|
|
2267
|
+
e.preventDefault();
|
|
2268
|
+
finishTyping();
|
|
2269
|
+
return;
|
|
2270
|
+
}
|
|
2271
|
+
if ((e.metaKey || e.ctrlKey) && ["z", "y", "c", "x", "v"].includes(e.key.toLowerCase())) return;
|
|
2272
|
+
if (session.handleKey(e)) {
|
|
2273
|
+
e.preventDefault();
|
|
2274
|
+
setShapeTypeError(session.error);
|
|
2275
|
+
}
|
|
2276
|
+
};
|
|
2277
|
+
const handleTypeInput = (e) => {
|
|
2278
|
+
const el = e.currentTarget;
|
|
2279
|
+
const session = typeToolRef.current?.session;
|
|
2280
|
+
if (session && el.value && !e.nativeEvent.isComposing) {
|
|
2281
|
+
session.insert(el.value);
|
|
2282
|
+
el.value = "";
|
|
2283
|
+
}
|
|
2284
|
+
};
|
|
2285
|
+
useEffect10(() => transformTool.subscribe(() => {
|
|
1959
2286
|
setTransformTick((n) => n + 1);
|
|
1960
2287
|
void renderCanvas();
|
|
1961
2288
|
}), [transformTool, renderCanvas]);
|
|
@@ -1998,7 +2325,7 @@ var ImageEditor = ({
|
|
|
1998
2325
|
transformTool.up();
|
|
1999
2326
|
return true;
|
|
2000
2327
|
};
|
|
2001
|
-
|
|
2328
|
+
useEffect10(() => {
|
|
2002
2329
|
if (typeof window === "undefined") return;
|
|
2003
2330
|
const onKey = (e) => {
|
|
2004
2331
|
if (transformTool.key(e)) e.preventDefault();
|
|
@@ -2006,7 +2333,7 @@ var ImageEditor = ({
|
|
|
2006
2333
|
window.addEventListener("keydown", onKey);
|
|
2007
2334
|
return () => window.removeEventListener("keydown", onKey);
|
|
2008
2335
|
}, [transformTool]);
|
|
2009
|
-
|
|
2336
|
+
useEffect10(() => {
|
|
2010
2337
|
const raf = typeof requestAnimationFrame !== "undefined" ? requestAnimationFrame : (cb) => setTimeout(cb, 0);
|
|
2011
2338
|
const caf = typeof cancelAnimationFrame !== "undefined" ? cancelAnimationFrame : (id) => clearTimeout(id);
|
|
2012
2339
|
const animId = raf(() => {
|
|
@@ -2014,12 +2341,12 @@ var ImageEditor = ({
|
|
|
2014
2341
|
});
|
|
2015
2342
|
return () => caf(animId);
|
|
2016
2343
|
}, [renderCanvas, state]);
|
|
2017
|
-
|
|
2344
|
+
useEffect10(() => {
|
|
2018
2345
|
if (activeTab === "crop" && editor.state.activeTool !== "crop") {
|
|
2019
2346
|
editor.setTool("crop");
|
|
2020
2347
|
}
|
|
2021
2348
|
}, [activeTab, editor]);
|
|
2022
|
-
|
|
2349
|
+
useEffect10(() => {
|
|
2023
2350
|
const container = containerRef.current;
|
|
2024
2351
|
if (!container) return;
|
|
2025
2352
|
if (typeof ResizeObserver !== "undefined") {
|
|
@@ -2068,7 +2395,7 @@ var ImageEditor = ({
|
|
|
2068
2395
|
} catch {
|
|
2069
2396
|
}
|
|
2070
2397
|
const [first] = paintSamples(e);
|
|
2071
|
-
setPaintError(paintGestureRef.current.down(first));
|
|
2398
|
+
setPaintError(paintGestureRef.current.down({ ...first, altKey: e.altKey }));
|
|
2072
2399
|
};
|
|
2073
2400
|
const handlePaintPointerMove = (e) => {
|
|
2074
2401
|
if (handleTransformPointerMove(e)) return;
|
|
@@ -2087,7 +2414,7 @@ var ImageEditor = ({
|
|
|
2087
2414
|
if (g.error) setPaintError(g.error);
|
|
2088
2415
|
}
|
|
2089
2416
|
};
|
|
2090
|
-
|
|
2417
|
+
useEffect10(() => {
|
|
2091
2418
|
if (activeTab !== "paint" || typeof window === "undefined") return;
|
|
2092
2419
|
const onKey = (e) => {
|
|
2093
2420
|
if (handlePaintShortcut(controller, e)) e.preventDefault();
|
|
@@ -2131,6 +2458,17 @@ var ImageEditor = ({
|
|
|
2131
2458
|
}
|
|
2132
2459
|
return;
|
|
2133
2460
|
}
|
|
2461
|
+
if (activeTab === "annotate" && (state.activeTool === "shape" || state.activeTool === "type")) {
|
|
2462
|
+
const imgPt = canvasToImagePoint(canvasPt, state, canvas.width, canvas.height, false);
|
|
2463
|
+
setShapeTypeError(null);
|
|
2464
|
+
if (state.activeTool === "shape") shapeGestureRef.current.down(imgPt);
|
|
2465
|
+
else {
|
|
2466
|
+
typeToolRef.current.down(imgPt, { shift: e.shiftKey });
|
|
2467
|
+
setTypeSession(typeToolRef.current.session);
|
|
2468
|
+
void renderCanvas();
|
|
2469
|
+
}
|
|
2470
|
+
return;
|
|
2471
|
+
}
|
|
2134
2472
|
if (activeTab === "annotate") {
|
|
2135
2473
|
const imgPt = canvasToImagePoint(canvasPt, state, canvas.width, canvas.height, false);
|
|
2136
2474
|
dragStartPointRef.current = imgPt;
|
|
@@ -2221,6 +2559,14 @@ var ImageEditor = ({
|
|
|
2221
2559
|
}
|
|
2222
2560
|
return;
|
|
2223
2561
|
}
|
|
2562
|
+
if (activeTab === "annotate" && state.activeTool === "shape") {
|
|
2563
|
+
const g = shapeGestureRef.current;
|
|
2564
|
+
if (g.active) {
|
|
2565
|
+
g.move(canvasToImagePoint(canvasPt, state, canvas.width, canvas.height, false), { shift: e.shiftKey, alt: e.altKey });
|
|
2566
|
+
if (g.error) setShapeTypeError(g.error);
|
|
2567
|
+
}
|
|
2568
|
+
return;
|
|
2569
|
+
}
|
|
2224
2570
|
if (activeTab === "annotate") {
|
|
2225
2571
|
if (annotationDragInfoRef.current) {
|
|
2226
2572
|
const drag = annotationDragInfoRef.current;
|
|
@@ -2347,6 +2693,19 @@ var ImageEditor = ({
|
|
|
2347
2693
|
}
|
|
2348
2694
|
return;
|
|
2349
2695
|
}
|
|
2696
|
+
if (activeTab === "annotate" && state.activeTool === "shape") {
|
|
2697
|
+
shapeGestureRef.current.up();
|
|
2698
|
+
return;
|
|
2699
|
+
}
|
|
2700
|
+
if (activeTab === "annotate" && state.activeTool === "type") {
|
|
2701
|
+
const tool = typeToolRef.current;
|
|
2702
|
+
tool.up(canvasToImagePoint(canvasPt, state, canvas.width, canvas.height, false));
|
|
2703
|
+
setTypeSession(tool.session);
|
|
2704
|
+
if (tool.error) setShapeTypeError(tool.error);
|
|
2705
|
+
void renderCanvas();
|
|
2706
|
+
if (tool.session) setTimeout(() => typeInputRef.current?.focus(), 0);
|
|
2707
|
+
return;
|
|
2708
|
+
}
|
|
2350
2709
|
if (activeTab === "annotate") {
|
|
2351
2710
|
if (annotationDragInfoRef.current) {
|
|
2352
2711
|
annotationDragInfoRef.current = null;
|
|
@@ -2450,15 +2809,15 @@ var ImageEditor = ({
|
|
|
2450
2809
|
link.click();
|
|
2451
2810
|
}
|
|
2452
2811
|
};
|
|
2453
|
-
return /* @__PURE__ */
|
|
2812
|
+
return /* @__PURE__ */ jsxs13(
|
|
2454
2813
|
"div",
|
|
2455
2814
|
{
|
|
2456
2815
|
className: `flex flex-col bg-slate-900 border border-slate-800 rounded-xl overflow-hidden shadow-2xl text-slate-100 ${className}`,
|
|
2457
2816
|
style,
|
|
2458
2817
|
children: [
|
|
2459
|
-
/* @__PURE__ */
|
|
2460
|
-
/* @__PURE__ */
|
|
2461
|
-
/* @__PURE__ */
|
|
2818
|
+
/* @__PURE__ */ jsxs13("div", { className: "flex flex-wrap items-center justify-between px-4 py-3 bg-slate-950/80 border-b border-slate-800 gap-3", children: [
|
|
2819
|
+
/* @__PURE__ */ jsxs13("div", { className: "flex items-center gap-1 bg-slate-900 p-1 rounded-lg border border-slate-800 text-xs", children: [
|
|
2820
|
+
/* @__PURE__ */ jsx13(
|
|
2462
2821
|
"button",
|
|
2463
2822
|
{
|
|
2464
2823
|
type: "button",
|
|
@@ -2470,7 +2829,7 @@ var ImageEditor = ({
|
|
|
2470
2829
|
children: "Transform & Crop"
|
|
2471
2830
|
}
|
|
2472
2831
|
),
|
|
2473
|
-
/* @__PURE__ */
|
|
2832
|
+
/* @__PURE__ */ jsx13(
|
|
2474
2833
|
"button",
|
|
2475
2834
|
{
|
|
2476
2835
|
type: "button",
|
|
@@ -2482,7 +2841,7 @@ var ImageEditor = ({
|
|
|
2482
2841
|
children: "Adjustments"
|
|
2483
2842
|
}
|
|
2484
2843
|
),
|
|
2485
|
-
/* @__PURE__ */
|
|
2844
|
+
/* @__PURE__ */ jsx13(
|
|
2486
2845
|
"button",
|
|
2487
2846
|
{
|
|
2488
2847
|
type: "button",
|
|
@@ -2494,7 +2853,7 @@ var ImageEditor = ({
|
|
|
2494
2853
|
children: "Layers"
|
|
2495
2854
|
}
|
|
2496
2855
|
),
|
|
2497
|
-
/* @__PURE__ */
|
|
2856
|
+
/* @__PURE__ */ jsx13(
|
|
2498
2857
|
"button",
|
|
2499
2858
|
{
|
|
2500
2859
|
type: "button",
|
|
@@ -2506,7 +2865,7 @@ var ImageEditor = ({
|
|
|
2506
2865
|
children: "Paint"
|
|
2507
2866
|
}
|
|
2508
2867
|
),
|
|
2509
|
-
/* @__PURE__ */
|
|
2868
|
+
/* @__PURE__ */ jsx13(
|
|
2510
2869
|
"button",
|
|
2511
2870
|
{
|
|
2512
2871
|
type: "button",
|
|
@@ -2518,7 +2877,7 @@ var ImageEditor = ({
|
|
|
2518
2877
|
children: "Select & Mask"
|
|
2519
2878
|
}
|
|
2520
2879
|
),
|
|
2521
|
-
/* @__PURE__ */
|
|
2880
|
+
/* @__PURE__ */ jsx13(
|
|
2522
2881
|
"button",
|
|
2523
2882
|
{
|
|
2524
2883
|
type: "button",
|
|
@@ -2530,7 +2889,7 @@ var ImageEditor = ({
|
|
|
2530
2889
|
children: "Annotations"
|
|
2531
2890
|
}
|
|
2532
2891
|
),
|
|
2533
|
-
/* @__PURE__ */
|
|
2892
|
+
/* @__PURE__ */ jsx13(
|
|
2534
2893
|
"button",
|
|
2535
2894
|
{
|
|
2536
2895
|
type: "button",
|
|
@@ -2542,7 +2901,7 @@ var ImageEditor = ({
|
|
|
2542
2901
|
children: "Depth Mask"
|
|
2543
2902
|
}
|
|
2544
2903
|
),
|
|
2545
|
-
/* @__PURE__ */
|
|
2904
|
+
/* @__PURE__ */ jsxs13(
|
|
2546
2905
|
"button",
|
|
2547
2906
|
{
|
|
2548
2907
|
type: "button",
|
|
@@ -2552,14 +2911,14 @@ var ImageEditor = ({
|
|
|
2552
2911
|
},
|
|
2553
2912
|
className: `px-3 py-1.5 rounded-md font-medium transition-colors flex items-center gap-1.5 ${activeTab === "ai" ? "bg-indigo-600 text-white shadow" : "text-slate-400 hover:text-slate-200"}`,
|
|
2554
2913
|
children: [
|
|
2555
|
-
/* @__PURE__ */
|
|
2914
|
+
/* @__PURE__ */ jsx13("svg", { className: "w-3.5 h-3.5", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: /* @__PURE__ */ jsx13("path", { d: "M12 2v4M12 18v4M4.93 4.93l2.83 2.83M16.24 16.24l2.83 2.83M2 12h4M18 12h4M4.93 19.07l2.83-2.83M16.24 7.76l2.83-2.83" }) }),
|
|
2556
2915
|
"AI Tools"
|
|
2557
2916
|
]
|
|
2558
2917
|
}
|
|
2559
2918
|
)
|
|
2560
2919
|
] }),
|
|
2561
|
-
/* @__PURE__ */
|
|
2562
|
-
/* @__PURE__ */
|
|
2920
|
+
/* @__PURE__ */ jsxs13("div", { className: "flex items-center gap-2 text-xs", children: [
|
|
2921
|
+
/* @__PURE__ */ jsx13(
|
|
2563
2922
|
"button",
|
|
2564
2923
|
{
|
|
2565
2924
|
type: "button",
|
|
@@ -2570,7 +2929,7 @@ var ImageEditor = ({
|
|
|
2570
2929
|
children: "\u21A9"
|
|
2571
2930
|
}
|
|
2572
2931
|
),
|
|
2573
|
-
/* @__PURE__ */
|
|
2932
|
+
/* @__PURE__ */ jsx13(
|
|
2574
2933
|
"button",
|
|
2575
2934
|
{
|
|
2576
2935
|
type: "button",
|
|
@@ -2581,7 +2940,7 @@ var ImageEditor = ({
|
|
|
2581
2940
|
children: "\u21AA"
|
|
2582
2941
|
}
|
|
2583
2942
|
),
|
|
2584
|
-
/* @__PURE__ */
|
|
2943
|
+
/* @__PURE__ */ jsx13(
|
|
2585
2944
|
"button",
|
|
2586
2945
|
{
|
|
2587
2946
|
type: "button",
|
|
@@ -2590,8 +2949,8 @@ var ImageEditor = ({
|
|
|
2590
2949
|
children: "Reset"
|
|
2591
2950
|
}
|
|
2592
2951
|
),
|
|
2593
|
-
/* @__PURE__ */
|
|
2594
|
-
/* @__PURE__ */
|
|
2952
|
+
/* @__PURE__ */ jsx13("div", { className: "h-4 w-px bg-slate-800 mx-1" }),
|
|
2953
|
+
/* @__PURE__ */ jsx13(
|
|
2595
2954
|
"button",
|
|
2596
2955
|
{
|
|
2597
2956
|
type: "button",
|
|
@@ -2601,11 +2960,11 @@ var ImageEditor = ({
|
|
|
2601
2960
|
children: "-"
|
|
2602
2961
|
}
|
|
2603
2962
|
),
|
|
2604
|
-
/* @__PURE__ */
|
|
2963
|
+
/* @__PURE__ */ jsxs13("span", { className: "font-mono text-slate-400 w-10 text-center", children: [
|
|
2605
2964
|
Math.round(state.zoom * 100),
|
|
2606
2965
|
"%"
|
|
2607
2966
|
] }),
|
|
2608
|
-
/* @__PURE__ */
|
|
2967
|
+
/* @__PURE__ */ jsx13(
|
|
2609
2968
|
"button",
|
|
2610
2969
|
{
|
|
2611
2970
|
type: "button",
|
|
@@ -2615,8 +2974,8 @@ var ImageEditor = ({
|
|
|
2615
2974
|
children: "+"
|
|
2616
2975
|
}
|
|
2617
2976
|
),
|
|
2618
|
-
/* @__PURE__ */
|
|
2619
|
-
/* @__PURE__ */
|
|
2977
|
+
/* @__PURE__ */ jsx13("div", { className: "h-4 w-px bg-slate-800 mx-1" }),
|
|
2978
|
+
/* @__PURE__ */ jsx13(
|
|
2620
2979
|
"button",
|
|
2621
2980
|
{
|
|
2622
2981
|
type: "button",
|
|
@@ -2627,7 +2986,7 @@ var ImageEditor = ({
|
|
|
2627
2986
|
children: "Hold Compare"
|
|
2628
2987
|
}
|
|
2629
2988
|
),
|
|
2630
|
-
/* @__PURE__ */
|
|
2989
|
+
/* @__PURE__ */ jsx13(
|
|
2631
2990
|
"button",
|
|
2632
2991
|
{
|
|
2633
2992
|
type: "button",
|
|
@@ -2638,38 +2997,59 @@ var ImageEditor = ({
|
|
|
2638
2997
|
)
|
|
2639
2998
|
] })
|
|
2640
2999
|
] }),
|
|
2641
|
-
transformTool.active && /* @__PURE__ */
|
|
2642
|
-
!transformTool.active && transformTool.error && /* @__PURE__ */
|
|
2643
|
-
/* @__PURE__ */
|
|
2644
|
-
/* @__PURE__ */
|
|
3000
|
+
transformTool.active && /* @__PURE__ */ jsx13(FreeTransformOptionsBar, { tool: transformTool, className: "border-b border-slate-800 bg-slate-900/95 px-4 py-2" }),
|
|
3001
|
+
!transformTool.active && transformTool.error && /* @__PURE__ */ jsx13("div", { role: "alert", className: "border-b border-rose-900 bg-rose-950/80 px-4 py-1.5 text-xs text-rose-200", children: transformTool.error }),
|
|
3002
|
+
/* @__PURE__ */ jsxs13("div", { className: "flex flex-col md:flex-row flex-1 min-h-[520px] md:h-[560px]", children: [
|
|
3003
|
+
/* @__PURE__ */ jsxs13(
|
|
2645
3004
|
"div",
|
|
2646
3005
|
{
|
|
2647
3006
|
ref: containerRef,
|
|
2648
3007
|
className: "relative flex-1 h-[360px] md:h-full min-h-[320px] bg-slate-950 overflow-hidden select-none",
|
|
2649
|
-
children:
|
|
2650
|
-
|
|
2651
|
-
|
|
2652
|
-
|
|
2653
|
-
|
|
2654
|
-
|
|
2655
|
-
|
|
2656
|
-
|
|
2657
|
-
|
|
2658
|
-
|
|
2659
|
-
|
|
2660
|
-
|
|
2661
|
-
|
|
2662
|
-
|
|
2663
|
-
|
|
2664
|
-
|
|
2665
|
-
|
|
3008
|
+
children: [
|
|
3009
|
+
/* @__PURE__ */ jsx13(
|
|
3010
|
+
"canvas",
|
|
3011
|
+
{
|
|
3012
|
+
ref: canvasRef,
|
|
3013
|
+
onMouseDown: handleMouseDown,
|
|
3014
|
+
onMouseMove: handleMouseMove,
|
|
3015
|
+
onMouseUp: handleMouseUp,
|
|
3016
|
+
onMouseLeave: handleMouseUp,
|
|
3017
|
+
onPointerDown: handlePaintPointerDown,
|
|
3018
|
+
onPointerMove: handlePaintPointerMove,
|
|
3019
|
+
onPointerUp: handlePaintPointerUp,
|
|
3020
|
+
onPointerCancel: () => paintGestureRef.current?.cancel(),
|
|
3021
|
+
"data-testid": "image-editor-canvas",
|
|
3022
|
+
style: transformTool.active ? { cursor: transformCursor } : void 0,
|
|
3023
|
+
className: `absolute inset-0 w-full h-full block ${transformTool.active ? "touch-none" : activeTab === "paint" ? "touch-none cursor-crosshair" : activeTab === "annotate" && state.activeTool === "type" ? "cursor-text" : activeTab === "annotate" && state.activeTool === "shape" ? "cursor-crosshair" : ""}`
|
|
3024
|
+
}
|
|
3025
|
+
),
|
|
3026
|
+
typeSession && /* @__PURE__ */ jsx13(
|
|
3027
|
+
"textarea",
|
|
3028
|
+
{
|
|
3029
|
+
ref: typeInputRef,
|
|
3030
|
+
"aria-label": "Edit text",
|
|
3031
|
+
"data-testid": "type-input",
|
|
3032
|
+
autoCapitalize: "off",
|
|
3033
|
+
autoCorrect: "off",
|
|
3034
|
+
spellCheck: false,
|
|
3035
|
+
onKeyDown: handleTypeKeyDown,
|
|
3036
|
+
onInput: handleTypeInput,
|
|
3037
|
+
onCompositionEnd: (e) => {
|
|
3038
|
+
const session = typeToolRef.current?.session;
|
|
3039
|
+
if (session && e.data) session.insert(e.data);
|
|
3040
|
+
e.currentTarget.value = "";
|
|
3041
|
+
},
|
|
3042
|
+
className: "absolute left-0 top-0 h-px w-px opacity-0"
|
|
3043
|
+
}
|
|
3044
|
+
)
|
|
3045
|
+
]
|
|
2666
3046
|
}
|
|
2667
3047
|
),
|
|
2668
|
-
/* @__PURE__ */
|
|
2669
|
-
activeTab === "crop" && /* @__PURE__ */
|
|
2670
|
-
/* @__PURE__ */
|
|
2671
|
-
/* @__PURE__ */
|
|
2672
|
-
/* @__PURE__ */
|
|
3048
|
+
/* @__PURE__ */ jsxs13("div", { className: "w-full md:w-80 bg-slate-900/90 border-t md:border-t-0 md:border-l border-slate-800 p-4 overflow-y-auto h-auto md:h-full md:max-h-[560px]", children: [
|
|
3049
|
+
activeTab === "crop" && /* @__PURE__ */ jsxs13("div", { className: "flex flex-col gap-4 text-xs", children: [
|
|
3050
|
+
/* @__PURE__ */ jsx13("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Aspect Ratio Presets" }),
|
|
3051
|
+
/* @__PURE__ */ jsxs13("div", { className: "grid grid-cols-3 gap-2", children: [
|
|
3052
|
+
/* @__PURE__ */ jsx13(
|
|
2673
3053
|
"button",
|
|
2674
3054
|
{
|
|
2675
3055
|
type: "button",
|
|
@@ -2681,7 +3061,7 @@ var ImageEditor = ({
|
|
|
2681
3061
|
children: "Freeform"
|
|
2682
3062
|
}
|
|
2683
3063
|
),
|
|
2684
|
-
/* @__PURE__ */
|
|
3064
|
+
/* @__PURE__ */ jsx13(
|
|
2685
3065
|
"button",
|
|
2686
3066
|
{
|
|
2687
3067
|
type: "button",
|
|
@@ -2693,7 +3073,7 @@ var ImageEditor = ({
|
|
|
2693
3073
|
children: "1:1 Square"
|
|
2694
3074
|
}
|
|
2695
3075
|
),
|
|
2696
|
-
/* @__PURE__ */
|
|
3076
|
+
/* @__PURE__ */ jsx13(
|
|
2697
3077
|
"button",
|
|
2698
3078
|
{
|
|
2699
3079
|
type: "button",
|
|
@@ -2705,7 +3085,7 @@ var ImageEditor = ({
|
|
|
2705
3085
|
children: "4:3 Standard"
|
|
2706
3086
|
}
|
|
2707
3087
|
),
|
|
2708
|
-
/* @__PURE__ */
|
|
3088
|
+
/* @__PURE__ */ jsx13(
|
|
2709
3089
|
"button",
|
|
2710
3090
|
{
|
|
2711
3091
|
type: "button",
|
|
@@ -2717,7 +3097,7 @@ var ImageEditor = ({
|
|
|
2717
3097
|
children: "16:9 Wide"
|
|
2718
3098
|
}
|
|
2719
3099
|
),
|
|
2720
|
-
/* @__PURE__ */
|
|
3100
|
+
/* @__PURE__ */ jsx13(
|
|
2721
3101
|
"button",
|
|
2722
3102
|
{
|
|
2723
3103
|
type: "button",
|
|
@@ -2729,7 +3109,7 @@ var ImageEditor = ({
|
|
|
2729
3109
|
children: "3:2 Photo"
|
|
2730
3110
|
}
|
|
2731
3111
|
),
|
|
2732
|
-
/* @__PURE__ */
|
|
3112
|
+
/* @__PURE__ */ jsx13(
|
|
2733
3113
|
"button",
|
|
2734
3114
|
{
|
|
2735
3115
|
type: "button",
|
|
@@ -2742,10 +3122,10 @@ var ImageEditor = ({
|
|
|
2742
3122
|
}
|
|
2743
3123
|
)
|
|
2744
3124
|
] }),
|
|
2745
|
-
/* @__PURE__ */
|
|
2746
|
-
/* @__PURE__ */
|
|
2747
|
-
/* @__PURE__ */
|
|
2748
|
-
/* @__PURE__ */
|
|
3125
|
+
/* @__PURE__ */ jsx13("div", { className: "h-px bg-slate-800 my-1" }),
|
|
3126
|
+
/* @__PURE__ */ jsx13("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Orientation & Flips" }),
|
|
3127
|
+
/* @__PURE__ */ jsxs13("div", { className: "grid grid-cols-2 gap-2", children: [
|
|
3128
|
+
/* @__PURE__ */ jsx13(
|
|
2749
3129
|
"button",
|
|
2750
3130
|
{
|
|
2751
3131
|
type: "button",
|
|
@@ -2754,7 +3134,7 @@ var ImageEditor = ({
|
|
|
2754
3134
|
children: "Rotate -90\xB0"
|
|
2755
3135
|
}
|
|
2756
3136
|
),
|
|
2757
|
-
/* @__PURE__ */
|
|
3137
|
+
/* @__PURE__ */ jsx13(
|
|
2758
3138
|
"button",
|
|
2759
3139
|
{
|
|
2760
3140
|
type: "button",
|
|
@@ -2763,7 +3143,7 @@ var ImageEditor = ({
|
|
|
2763
3143
|
children: "Rotate +90\xB0"
|
|
2764
3144
|
}
|
|
2765
3145
|
),
|
|
2766
|
-
/* @__PURE__ */
|
|
3146
|
+
/* @__PURE__ */ jsx13(
|
|
2767
3147
|
"button",
|
|
2768
3148
|
{
|
|
2769
3149
|
type: "button",
|
|
@@ -2772,7 +3152,7 @@ var ImageEditor = ({
|
|
|
2772
3152
|
children: "Flip Horizontal"
|
|
2773
3153
|
}
|
|
2774
3154
|
),
|
|
2775
|
-
/* @__PURE__ */
|
|
3155
|
+
/* @__PURE__ */ jsx13(
|
|
2776
3156
|
"button",
|
|
2777
3157
|
{
|
|
2778
3158
|
type: "button",
|
|
@@ -2783,10 +3163,10 @@ var ImageEditor = ({
|
|
|
2783
3163
|
)
|
|
2784
3164
|
] })
|
|
2785
3165
|
] }),
|
|
2786
|
-
activeTab === "adjust" && /* @__PURE__ */
|
|
2787
|
-
/* @__PURE__ */
|
|
2788
|
-
/* @__PURE__ */
|
|
2789
|
-
/* @__PURE__ */
|
|
3166
|
+
activeTab === "adjust" && /* @__PURE__ */ jsxs13("div", { className: "flex flex-col gap-3 text-xs", children: [
|
|
3167
|
+
/* @__PURE__ */ jsxs13("div", { className: "flex items-center justify-between", children: [
|
|
3168
|
+
/* @__PURE__ */ jsx13("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Color Adjustments" }),
|
|
3169
|
+
/* @__PURE__ */ jsx13(
|
|
2790
3170
|
"button",
|
|
2791
3171
|
{
|
|
2792
3172
|
type: "button",
|
|
@@ -2796,9 +3176,9 @@ var ImageEditor = ({
|
|
|
2796
3176
|
}
|
|
2797
3177
|
)
|
|
2798
3178
|
] }),
|
|
2799
|
-
/* @__PURE__ */
|
|
2800
|
-
IMAGE_ADJUSTMENT_CONTROLS.map((spec) => /* @__PURE__ */
|
|
2801
|
-
/* @__PURE__ */
|
|
3179
|
+
/* @__PURE__ */ jsx13(Histogram, { histogram: editor.histogram }),
|
|
3180
|
+
IMAGE_ADJUSTMENT_CONTROLS.map((spec) => /* @__PURE__ */ jsxs13(React12.Fragment, { children: [
|
|
3181
|
+
/* @__PURE__ */ jsx13(
|
|
2802
3182
|
ControlSlider,
|
|
2803
3183
|
{
|
|
2804
3184
|
spec,
|
|
@@ -2807,14 +3187,14 @@ var ImageEditor = ({
|
|
|
2807
3187
|
onChange: (v) => editor.setAdjustments({ [spec.id]: v })
|
|
2808
3188
|
}
|
|
2809
3189
|
),
|
|
2810
|
-
spec.id === "tint" && legacyProcess && /* @__PURE__ */
|
|
3190
|
+
spec.id === "tint" && legacyProcess && /* @__PURE__ */ jsxs13(
|
|
2811
3191
|
"div",
|
|
2812
3192
|
{
|
|
2813
3193
|
className: "flex items-center justify-between gap-2 rounded border border-amber-500/30 bg-amber-500/10 px-2 py-1.5 text-[10px] text-amber-200",
|
|
2814
3194
|
"data-testid": "image-editor-process-notice",
|
|
2815
3195
|
children: [
|
|
2816
|
-
/* @__PURE__ */
|
|
2817
|
-
/* @__PURE__ */
|
|
3196
|
+
/* @__PURE__ */ jsx13("span", { children: "Legacy rendering (process 1). Tint needs the current process." }),
|
|
3197
|
+
/* @__PURE__ */ jsx13(
|
|
2818
3198
|
"button",
|
|
2819
3199
|
{
|
|
2820
3200
|
type: "button",
|
|
@@ -2827,7 +3207,7 @@ var ImageEditor = ({
|
|
|
2827
3207
|
}
|
|
2828
3208
|
)
|
|
2829
3209
|
] }, spec.id)),
|
|
2830
|
-
/* @__PURE__ */
|
|
3210
|
+
/* @__PURE__ */ jsx13("div", { className: "border-t border-slate-700/60 pt-3", children: /* @__PURE__ */ jsx13(
|
|
2831
3211
|
AdjustmentLayersPanel,
|
|
2832
3212
|
{
|
|
2833
3213
|
controller,
|
|
@@ -2836,9 +3216,9 @@ var ImageEditor = ({
|
|
|
2836
3216
|
}
|
|
2837
3217
|
) })
|
|
2838
3218
|
] }),
|
|
2839
|
-
activeTab === "layers" && /* @__PURE__ */
|
|
2840
|
-
/* @__PURE__ */
|
|
2841
|
-
/* @__PURE__ */
|
|
3219
|
+
activeTab === "layers" && /* @__PURE__ */ jsxs13("div", { className: "flex flex-col gap-3 text-xs", children: [
|
|
3220
|
+
/* @__PURE__ */ jsx13("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Layers" }),
|
|
3221
|
+
/* @__PURE__ */ jsx13(
|
|
2842
3222
|
"button",
|
|
2843
3223
|
{
|
|
2844
3224
|
type: "button",
|
|
@@ -2849,12 +3229,12 @@ var ImageEditor = ({
|
|
|
2849
3229
|
children: "Free Transform"
|
|
2850
3230
|
}
|
|
2851
3231
|
),
|
|
2852
|
-
/* @__PURE__ */
|
|
3232
|
+
/* @__PURE__ */ jsx13(LayersPanel, { controller })
|
|
2853
3233
|
] }),
|
|
2854
|
-
activeTab === "paint" && /* @__PURE__ */
|
|
2855
|
-
/* @__PURE__ */
|
|
2856
|
-
/* @__PURE__ */
|
|
2857
|
-
/* @__PURE__ */
|
|
3234
|
+
activeTab === "paint" && /* @__PURE__ */ jsxs13("div", { className: "flex flex-col gap-3 text-xs", children: [
|
|
3235
|
+
/* @__PURE__ */ jsx13("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Paint" }),
|
|
3236
|
+
/* @__PURE__ */ jsx13(BrushOptionsBar, { controller }),
|
|
3237
|
+
/* @__PURE__ */ jsx13(
|
|
2858
3238
|
"button",
|
|
2859
3239
|
{
|
|
2860
3240
|
type: "button",
|
|
@@ -2865,12 +3245,29 @@ var ImageEditor = ({
|
|
|
2865
3245
|
children: "Free Transform"
|
|
2866
3246
|
}
|
|
2867
3247
|
),
|
|
2868
|
-
paintError && /* @__PURE__ */
|
|
2869
|
-
/* @__PURE__ */
|
|
3248
|
+
paintError && /* @__PURE__ */ jsx13("p", { role: "alert", className: "text-rose-400", "data-testid": "paint-error", children: paintError }),
|
|
3249
|
+
/* @__PURE__ */ jsx13("div", { className: "border-t border-slate-700/60 pt-3", children: /* @__PURE__ */ jsx13(LayersPanel, { controller }) })
|
|
2870
3250
|
] }),
|
|
2871
|
-
activeTab === "annotate" && /* @__PURE__ */
|
|
2872
|
-
/* @__PURE__ */
|
|
2873
|
-
/* @__PURE__ */
|
|
3251
|
+
activeTab === "annotate" && /* @__PURE__ */ jsxs13("div", { className: "flex flex-col gap-3 text-xs", children: [
|
|
3252
|
+
/* @__PURE__ */ jsx13("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Shape & Type Layers" }),
|
|
3253
|
+
/* @__PURE__ */ jsx13("div", { className: "grid grid-cols-2 gap-1.5", children: ["shape", "type"].map((t) => /* @__PURE__ */ jsx13(
|
|
3254
|
+
"button",
|
|
3255
|
+
{
|
|
3256
|
+
type: "button",
|
|
3257
|
+
"aria-pressed": state.activeTool === t,
|
|
3258
|
+
onClick: () => editor.setTool(t),
|
|
3259
|
+
className: `py-1.5 px-2 rounded-lg font-medium border transition-colors ${state.activeTool === t ? "bg-indigo-600 border-indigo-500 text-white" : "bg-slate-800 border-slate-700 text-slate-300 hover:bg-slate-700"}`,
|
|
3260
|
+
children: t === "shape" ? "Shape" : "Type"
|
|
3261
|
+
},
|
|
3262
|
+
t
|
|
3263
|
+
)) }),
|
|
3264
|
+
state.activeTool === "shape" && /* @__PURE__ */ jsx13(ShapeOptionsBar, { controller, options: shapeOptions, onChange: setShapeOptions }),
|
|
3265
|
+
state.activeTool === "type" && /* @__PURE__ */ jsx13(TypeOptionsBar, { controller, options: typeOptions, onChange: setTypeOptions, session: typeSession }),
|
|
3266
|
+
state.activeTool === "type" && typeSession && /* @__PURE__ */ jsx13("button", { type: "button", onClick: finishTyping, className: "self-start rounded bg-slate-800 px-2 py-1 text-[11px] text-slate-200 hover:bg-slate-700", children: "Done editing text" }),
|
|
3267
|
+
shapeTypeError && /* @__PURE__ */ jsx13("p", { role: "alert", className: "text-rose-400", "data-testid": "shape-type-error", children: shapeTypeError }),
|
|
3268
|
+
/* @__PURE__ */ jsx13("div", { className: "h-px bg-slate-800 my-1" }),
|
|
3269
|
+
/* @__PURE__ */ jsx13("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Draw & Annotate" }),
|
|
3270
|
+
/* @__PURE__ */ jsx13("div", { className: "grid grid-cols-3 gap-1.5", children: ["pen", "rect", "circle", "arrow", "line"].map((t) => /* @__PURE__ */ jsx13(
|
|
2874
3271
|
"button",
|
|
2875
3272
|
{
|
|
2876
3273
|
type: "button",
|
|
@@ -2880,9 +3277,9 @@ var ImageEditor = ({
|
|
|
2880
3277
|
},
|
|
2881
3278
|
t
|
|
2882
3279
|
)) }),
|
|
2883
|
-
/* @__PURE__ */
|
|
2884
|
-
/* @__PURE__ */
|
|
2885
|
-
/* @__PURE__ */
|
|
3280
|
+
/* @__PURE__ */ jsxs13("div", { className: "flex items-center gap-2 mt-2", children: [
|
|
3281
|
+
/* @__PURE__ */ jsx13("label", { className: "text-slate-400", children: "Color:" }),
|
|
3282
|
+
/* @__PURE__ */ jsx13(
|
|
2886
3283
|
"input",
|
|
2887
3284
|
{
|
|
2888
3285
|
type: "color",
|
|
@@ -2891,15 +3288,15 @@ var ImageEditor = ({
|
|
|
2891
3288
|
className: "w-8 h-8 rounded border border-slate-700 cursor-pointer bg-transparent"
|
|
2892
3289
|
}
|
|
2893
3290
|
),
|
|
2894
|
-
/* @__PURE__ */
|
|
2895
|
-
/* @__PURE__ */
|
|
2896
|
-
/* @__PURE__ */
|
|
2897
|
-
/* @__PURE__ */
|
|
3291
|
+
/* @__PURE__ */ jsxs13("div", { className: "flex-1 ml-2", children: [
|
|
3292
|
+
/* @__PURE__ */ jsxs13("div", { className: "flex justify-between text-slate-400 mb-0.5", children: [
|
|
3293
|
+
/* @__PURE__ */ jsx13("span", { children: "Width:" }),
|
|
3294
|
+
/* @__PURE__ */ jsxs13("span", { className: "font-mono", children: [
|
|
2898
3295
|
strokeWidth,
|
|
2899
3296
|
"px"
|
|
2900
3297
|
] })
|
|
2901
3298
|
] }),
|
|
2902
|
-
/* @__PURE__ */
|
|
3299
|
+
/* @__PURE__ */ jsx13(
|
|
2903
3300
|
"input",
|
|
2904
3301
|
{
|
|
2905
3302
|
type: "range",
|
|
@@ -2912,10 +3309,10 @@ var ImageEditor = ({
|
|
|
2912
3309
|
)
|
|
2913
3310
|
] })
|
|
2914
3311
|
] }),
|
|
2915
|
-
/* @__PURE__ */
|
|
2916
|
-
/* @__PURE__ */
|
|
2917
|
-
/* @__PURE__ */
|
|
2918
|
-
/* @__PURE__ */
|
|
3312
|
+
/* @__PURE__ */ jsx13("div", { className: "h-px bg-slate-800 my-1" }),
|
|
3313
|
+
/* @__PURE__ */ jsx13("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Add Text" }),
|
|
3314
|
+
/* @__PURE__ */ jsxs13("div", { className: "flex gap-2", children: [
|
|
3315
|
+
/* @__PURE__ */ jsx13(
|
|
2919
3316
|
"input",
|
|
2920
3317
|
{
|
|
2921
3318
|
type: "text",
|
|
@@ -2926,7 +3323,7 @@ var ImageEditor = ({
|
|
|
2926
3323
|
className: "flex-1 bg-slate-950 border border-slate-700 rounded-lg px-2.5 py-1.5 text-xs text-slate-100 placeholder-slate-500 focus:outline-none focus:border-indigo-500"
|
|
2927
3324
|
}
|
|
2928
3325
|
),
|
|
2929
|
-
/* @__PURE__ */
|
|
3326
|
+
/* @__PURE__ */ jsx13(
|
|
2930
3327
|
"button",
|
|
2931
3328
|
{
|
|
2932
3329
|
type: "button",
|
|
@@ -2936,14 +3333,14 @@ var ImageEditor = ({
|
|
|
2936
3333
|
}
|
|
2937
3334
|
)
|
|
2938
3335
|
] }),
|
|
2939
|
-
/* @__PURE__ */
|
|
2940
|
-
/* @__PURE__ */
|
|
2941
|
-
/* @__PURE__ */
|
|
3336
|
+
/* @__PURE__ */ jsxs13("div", { className: "flex items-center justify-between text-slate-400", children: [
|
|
3337
|
+
/* @__PURE__ */ jsx13("span", { children: "Font Size:" }),
|
|
3338
|
+
/* @__PURE__ */ jsxs13("span", { className: "font-mono", children: [
|
|
2942
3339
|
fontSize,
|
|
2943
3340
|
"px"
|
|
2944
3341
|
] })
|
|
2945
3342
|
] }),
|
|
2946
|
-
/* @__PURE__ */
|
|
3343
|
+
/* @__PURE__ */ jsx13(
|
|
2947
3344
|
"input",
|
|
2948
3345
|
{
|
|
2949
3346
|
type: "range",
|
|
@@ -2954,14 +3351,14 @@ var ImageEditor = ({
|
|
|
2954
3351
|
className: "w-full accent-indigo-500"
|
|
2955
3352
|
}
|
|
2956
3353
|
),
|
|
2957
|
-
/* @__PURE__ */
|
|
2958
|
-
/* @__PURE__ */
|
|
2959
|
-
/* @__PURE__ */
|
|
3354
|
+
/* @__PURE__ */ jsx13("div", { className: "h-px bg-slate-800 my-1" }),
|
|
3355
|
+
/* @__PURE__ */ jsxs13("div", { className: "flex items-center justify-between", children: [
|
|
3356
|
+
/* @__PURE__ */ jsxs13("span", { className: "text-slate-400", children: [
|
|
2960
3357
|
"Layers (",
|
|
2961
3358
|
state.annotations.length,
|
|
2962
3359
|
")"
|
|
2963
3360
|
] }),
|
|
2964
|
-
state.selectedAnnotationId && /* @__PURE__ */
|
|
3361
|
+
state.selectedAnnotationId && /* @__PURE__ */ jsx13(
|
|
2965
3362
|
"button",
|
|
2966
3363
|
{
|
|
2967
3364
|
type: "button",
|
|
@@ -2970,7 +3367,7 @@ var ImageEditor = ({
|
|
|
2970
3367
|
children: "Delete Selected"
|
|
2971
3368
|
}
|
|
2972
3369
|
),
|
|
2973
|
-
state.annotations.length > 0 && /* @__PURE__ */
|
|
3370
|
+
state.annotations.length > 0 && /* @__PURE__ */ jsx13(
|
|
2974
3371
|
"button",
|
|
2975
3372
|
{
|
|
2976
3373
|
type: "button",
|
|
@@ -2981,10 +3378,10 @@ var ImageEditor = ({
|
|
|
2981
3378
|
)
|
|
2982
3379
|
] })
|
|
2983
3380
|
] }),
|
|
2984
|
-
activeTab === "depth" && /* @__PURE__ */
|
|
2985
|
-
/* @__PURE__ */
|
|
2986
|
-
/* @__PURE__ */
|
|
2987
|
-
/* @__PURE__ */
|
|
3381
|
+
activeTab === "depth" && /* @__PURE__ */ jsxs13("div", { className: "flex flex-col gap-3 text-xs", children: [
|
|
3382
|
+
/* @__PURE__ */ jsxs13("div", { className: "flex items-center justify-between", children: [
|
|
3383
|
+
/* @__PURE__ */ jsx13("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Depth Masking" }),
|
|
3384
|
+
/* @__PURE__ */ jsx13(
|
|
2988
3385
|
"button",
|
|
2989
3386
|
{
|
|
2990
3387
|
type: "button",
|
|
@@ -2994,8 +3391,8 @@ var ImageEditor = ({
|
|
|
2994
3391
|
}
|
|
2995
3392
|
)
|
|
2996
3393
|
] }),
|
|
2997
|
-
/* @__PURE__ */
|
|
2998
|
-
/* @__PURE__ */
|
|
3394
|
+
/* @__PURE__ */ jsxs13("label", { className: "flex items-center gap-2 cursor-pointer text-slate-300", children: [
|
|
3395
|
+
/* @__PURE__ */ jsx13(
|
|
2999
3396
|
"input",
|
|
3000
3397
|
{
|
|
3001
3398
|
type: "checkbox",
|
|
@@ -3004,12 +3401,12 @@ var ImageEditor = ({
|
|
|
3004
3401
|
className: "rounded accent-indigo-500"
|
|
3005
3402
|
}
|
|
3006
3403
|
),
|
|
3007
|
-
/* @__PURE__ */
|
|
3404
|
+
/* @__PURE__ */ jsx13("span", { children: "Enable Depth / Alpha Mask" })
|
|
3008
3405
|
] }),
|
|
3009
|
-
state.depthMask.enabled && /* @__PURE__ */
|
|
3010
|
-
/* @__PURE__ */
|
|
3011
|
-
/* @__PURE__ */
|
|
3012
|
-
/* @__PURE__ */
|
|
3406
|
+
state.depthMask.enabled && /* @__PURE__ */ jsxs13(Fragment4, { children: [
|
|
3407
|
+
/* @__PURE__ */ jsxs13("div", { children: [
|
|
3408
|
+
/* @__PURE__ */ jsx13("label", { className: "text-slate-400 block mb-1", children: "Mask Image URL:" }),
|
|
3409
|
+
/* @__PURE__ */ jsx13(
|
|
3013
3410
|
"input",
|
|
3014
3411
|
{
|
|
3015
3412
|
type: "text",
|
|
@@ -3020,8 +3417,8 @@ var ImageEditor = ({
|
|
|
3020
3417
|
}
|
|
3021
3418
|
)
|
|
3022
3419
|
] }),
|
|
3023
|
-
/* @__PURE__ */
|
|
3024
|
-
/* @__PURE__ */
|
|
3420
|
+
/* @__PURE__ */ jsxs13("div", { className: "flex gap-2", children: [
|
|
3421
|
+
/* @__PURE__ */ jsx13(
|
|
3025
3422
|
"button",
|
|
3026
3423
|
{
|
|
3027
3424
|
type: "button",
|
|
@@ -3030,7 +3427,7 @@ var ImageEditor = ({
|
|
|
3030
3427
|
children: "Threshold Mode"
|
|
3031
3428
|
}
|
|
3032
3429
|
),
|
|
3033
|
-
/* @__PURE__ */
|
|
3430
|
+
/* @__PURE__ */ jsx13(
|
|
3034
3431
|
"button",
|
|
3035
3432
|
{
|
|
3036
3433
|
type: "button",
|
|
@@ -3040,12 +3437,12 @@ var ImageEditor = ({
|
|
|
3040
3437
|
}
|
|
3041
3438
|
)
|
|
3042
3439
|
] }),
|
|
3043
|
-
/* @__PURE__ */
|
|
3044
|
-
/* @__PURE__ */
|
|
3045
|
-
/* @__PURE__ */
|
|
3046
|
-
/* @__PURE__ */
|
|
3440
|
+
/* @__PURE__ */ jsxs13("div", { children: [
|
|
3441
|
+
/* @__PURE__ */ jsxs13("div", { className: "flex justify-between text-slate-400 mb-1", children: [
|
|
3442
|
+
/* @__PURE__ */ jsx13("span", { children: "Depth Start (Lower):" }),
|
|
3443
|
+
/* @__PURE__ */ jsx13("span", { className: "font-mono", children: state.depthMask.depthRange[0] })
|
|
3047
3444
|
] }),
|
|
3048
|
-
/* @__PURE__ */
|
|
3445
|
+
/* @__PURE__ */ jsx13(
|
|
3049
3446
|
"input",
|
|
3050
3447
|
{
|
|
3051
3448
|
type: "range",
|
|
@@ -3059,12 +3456,12 @@ var ImageEditor = ({
|
|
|
3059
3456
|
}
|
|
3060
3457
|
)
|
|
3061
3458
|
] }),
|
|
3062
|
-
/* @__PURE__ */
|
|
3063
|
-
/* @__PURE__ */
|
|
3064
|
-
/* @__PURE__ */
|
|
3065
|
-
/* @__PURE__ */
|
|
3459
|
+
/* @__PURE__ */ jsxs13("div", { children: [
|
|
3460
|
+
/* @__PURE__ */ jsxs13("div", { className: "flex justify-between text-slate-400 mb-1", children: [
|
|
3461
|
+
/* @__PURE__ */ jsx13("span", { children: "Depth Stop (Upper):" }),
|
|
3462
|
+
/* @__PURE__ */ jsx13("span", { className: "font-mono", children: state.depthMask.depthRange[1] })
|
|
3066
3463
|
] }),
|
|
3067
|
-
/* @__PURE__ */
|
|
3464
|
+
/* @__PURE__ */ jsx13(
|
|
3068
3465
|
"input",
|
|
3069
3466
|
{
|
|
3070
3467
|
type: "range",
|
|
@@ -3078,12 +3475,12 @@ var ImageEditor = ({
|
|
|
3078
3475
|
}
|
|
3079
3476
|
)
|
|
3080
3477
|
] }),
|
|
3081
|
-
/* @__PURE__ */
|
|
3082
|
-
/* @__PURE__ */
|
|
3083
|
-
/* @__PURE__ */
|
|
3084
|
-
/* @__PURE__ */
|
|
3478
|
+
/* @__PURE__ */ jsxs13("div", { children: [
|
|
3479
|
+
/* @__PURE__ */ jsxs13("div", { className: "flex justify-between text-slate-400 mb-1", children: [
|
|
3480
|
+
/* @__PURE__ */ jsx13("span", { children: "Softness:" }),
|
|
3481
|
+
/* @__PURE__ */ jsx13("span", { className: "font-mono", children: state.depthMask.softness })
|
|
3085
3482
|
] }),
|
|
3086
|
-
/* @__PURE__ */
|
|
3483
|
+
/* @__PURE__ */ jsx13(
|
|
3087
3484
|
"input",
|
|
3088
3485
|
{
|
|
3089
3486
|
type: "range",
|
|
@@ -3095,8 +3492,8 @@ var ImageEditor = ({
|
|
|
3095
3492
|
}
|
|
3096
3493
|
)
|
|
3097
3494
|
] }),
|
|
3098
|
-
/* @__PURE__ */
|
|
3099
|
-
/* @__PURE__ */
|
|
3495
|
+
/* @__PURE__ */ jsxs13("label", { className: "flex items-center gap-2 cursor-pointer text-slate-300 mt-1", children: [
|
|
3496
|
+
/* @__PURE__ */ jsx13(
|
|
3100
3497
|
"input",
|
|
3101
3498
|
{
|
|
3102
3499
|
type: "checkbox",
|
|
@@ -3105,12 +3502,12 @@ var ImageEditor = ({
|
|
|
3105
3502
|
className: "rounded accent-indigo-500"
|
|
3106
3503
|
}
|
|
3107
3504
|
),
|
|
3108
|
-
/* @__PURE__ */
|
|
3505
|
+
/* @__PURE__ */ jsx13("span", { children: "Invert Mask" })
|
|
3109
3506
|
] })
|
|
3110
3507
|
] })
|
|
3111
3508
|
] }),
|
|
3112
|
-
activeTab === "select" && /* @__PURE__ */
|
|
3113
|
-
/* @__PURE__ */
|
|
3509
|
+
activeTab === "select" && /* @__PURE__ */ jsxs13("div", { className: "flex flex-col gap-4 text-xs", children: [
|
|
3510
|
+
/* @__PURE__ */ jsx13(
|
|
3114
3511
|
SelectionOptionsBar,
|
|
3115
3512
|
{
|
|
3116
3513
|
controller,
|
|
@@ -3120,9 +3517,9 @@ var ImageEditor = ({
|
|
|
3120
3517
|
quickMask: Boolean(state.quickMask)
|
|
3121
3518
|
}
|
|
3122
3519
|
),
|
|
3123
|
-
selectionError && /* @__PURE__ */
|
|
3124
|
-
/* @__PURE__ */
|
|
3125
|
-
/* @__PURE__ */
|
|
3520
|
+
selectionError && /* @__PURE__ */ jsx13("p", { role: "alert", className: "text-rose-400", children: selectionError }),
|
|
3521
|
+
/* @__PURE__ */ jsxs13("div", { className: "flex gap-1", children: [
|
|
3522
|
+
/* @__PURE__ */ jsx13(
|
|
3126
3523
|
"button",
|
|
3127
3524
|
{
|
|
3128
3525
|
type: "button",
|
|
@@ -3133,7 +3530,7 @@ var ImageEditor = ({
|
|
|
3133
3530
|
children: "Transform Selection"
|
|
3134
3531
|
}
|
|
3135
3532
|
),
|
|
3136
|
-
/* @__PURE__ */
|
|
3533
|
+
/* @__PURE__ */ jsx13(
|
|
3137
3534
|
"button",
|
|
3138
3535
|
{
|
|
3139
3536
|
type: "button",
|
|
@@ -3145,12 +3542,12 @@ var ImageEditor = ({
|
|
|
3145
3542
|
}
|
|
3146
3543
|
)
|
|
3147
3544
|
] }),
|
|
3148
|
-
/* @__PURE__ */
|
|
3545
|
+
/* @__PURE__ */ jsx13(RefineEdgePanel, { controller, selection: state.selection ?? null, layers: state.adjustments.layers })
|
|
3149
3546
|
] }),
|
|
3150
|
-
activeTab === "ai" && /* @__PURE__ */
|
|
3151
|
-
/* @__PURE__ */
|
|
3152
|
-
/* @__PURE__ */
|
|
3153
|
-
/* @__PURE__ */
|
|
3547
|
+
activeTab === "ai" && /* @__PURE__ */ jsxs13("div", { className: "flex flex-col gap-4 text-xs", children: [
|
|
3548
|
+
/* @__PURE__ */ jsxs13("label", { className: "flex items-center justify-between gap-2 text-slate-300", children: [
|
|
3549
|
+
/* @__PURE__ */ jsx13("span", { children: "Results go to" }),
|
|
3550
|
+
/* @__PURE__ */ jsxs13(
|
|
3154
3551
|
"select",
|
|
3155
3552
|
{
|
|
3156
3553
|
"aria-label": "AI result target",
|
|
@@ -3158,54 +3555,54 @@ var ImageEditor = ({
|
|
|
3158
3555
|
onChange: (e) => setAiTarget(e.target.value),
|
|
3159
3556
|
className: "bg-slate-800 border border-slate-700 rounded px-1.5 py-1",
|
|
3160
3557
|
children: [
|
|
3161
|
-
/* @__PURE__ */
|
|
3162
|
-
/* @__PURE__ */
|
|
3163
|
-
/* @__PURE__ */
|
|
3558
|
+
/* @__PURE__ */ jsx13("option", { value: "auto", children: controller.isMultiLayer ? "Auto (new layer)" : "Auto (replace image)" }),
|
|
3559
|
+
/* @__PURE__ */ jsx13("option", { value: "new-layer", children: "New layer / mask" }),
|
|
3560
|
+
/* @__PURE__ */ jsx13("option", { value: "replace", children: "Replace image" })
|
|
3164
3561
|
]
|
|
3165
3562
|
}
|
|
3166
3563
|
)
|
|
3167
3564
|
] }),
|
|
3168
|
-
/* @__PURE__ */
|
|
3169
|
-
/* @__PURE__ */
|
|
3170
|
-
/* @__PURE__ */
|
|
3171
|
-
/* @__PURE__ */
|
|
3565
|
+
/* @__PURE__ */ jsxs13("div", { className: "p-3 rounded-lg bg-slate-950/60 border border-slate-800 flex flex-col gap-2.5", children: [
|
|
3566
|
+
/* @__PURE__ */ jsxs13("div", { className: "flex items-center justify-between", children: [
|
|
3567
|
+
/* @__PURE__ */ jsxs13("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px] flex items-center gap-1.5", children: [
|
|
3568
|
+
/* @__PURE__ */ jsx13("svg", { className: "w-3.5 h-3.5 text-indigo-400", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: /* @__PURE__ */ jsx13("path", { d: "M6 3v12M18 9a3 3 0 1 0 0-6 3 3 0 0 0 0 6zM6 21a3 3 0 1 0 0-6 3 3 0 0 0 0 6z" }) }),
|
|
3172
3569
|
"Background Removal"
|
|
3173
3570
|
] }),
|
|
3174
|
-
isRemovingBg && /* @__PURE__ */
|
|
3571
|
+
isRemovingBg && /* @__PURE__ */ jsx13("span", { className: "inline-flex items-center px-1.5 py-0.5 rounded text-[10px] font-medium bg-indigo-900/60 text-indigo-300 animate-pulse", children: "Removing..." })
|
|
3175
3572
|
] }),
|
|
3176
|
-
/* @__PURE__ */
|
|
3177
|
-
/* @__PURE__ */
|
|
3573
|
+
/* @__PURE__ */ jsx13("p", { className: "text-slate-400 text-[11px] leading-relaxed", children: "Isolate foreground subject with AI alpha transparency segmentation." }),
|
|
3574
|
+
/* @__PURE__ */ jsx13(
|
|
3178
3575
|
"button",
|
|
3179
3576
|
{
|
|
3180
3577
|
type: "button",
|
|
3181
3578
|
onClick: handleRemoveBackground,
|
|
3182
3579
|
disabled: isRemovingBg || isInpainting,
|
|
3183
3580
|
className: "mt-1 px-3 py-2 rounded-lg bg-indigo-600 hover:bg-indigo-500 disabled:opacity-50 text-white font-medium shadow transition-colors flex items-center justify-center gap-2",
|
|
3184
|
-
children: isRemovingBg ? /* @__PURE__ */
|
|
3185
|
-
/* @__PURE__ */
|
|
3581
|
+
children: isRemovingBg ? /* @__PURE__ */ jsxs13(Fragment4, { children: [
|
|
3582
|
+
/* @__PURE__ */ jsx13("div", { className: "w-3.5 h-3.5 border-2 border-white/30 border-t-white rounded-full animate-spin" }),
|
|
3186
3583
|
"Removing Background..."
|
|
3187
|
-
] }) : /* @__PURE__ */
|
|
3188
|
-
/* @__PURE__ */
|
|
3584
|
+
] }) : /* @__PURE__ */ jsxs13(Fragment4, { children: [
|
|
3585
|
+
/* @__PURE__ */ jsx13("svg", { className: "w-3.5 h-3.5", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: /* @__PURE__ */ jsx13("path", { d: "M12 2v4M12 18v4M4.93 4.93l2.83 2.83M16.24 16.24l2.83 2.83M2 12h4M18 12h4M4.93 19.07l2.83-2.83M16.24 7.76l2.83-2.83" }) }),
|
|
3189
3586
|
"Remove Background"
|
|
3190
3587
|
] })
|
|
3191
3588
|
}
|
|
3192
3589
|
)
|
|
3193
3590
|
] }),
|
|
3194
|
-
/* @__PURE__ */
|
|
3195
|
-
/* @__PURE__ */
|
|
3196
|
-
/* @__PURE__ */
|
|
3197
|
-
/* @__PURE__ */
|
|
3198
|
-
/* @__PURE__ */
|
|
3199
|
-
/* @__PURE__ */
|
|
3591
|
+
/* @__PURE__ */ jsxs13("div", { className: "p-3 rounded-lg bg-slate-950/60 border border-slate-800 flex flex-col gap-2.5", children: [
|
|
3592
|
+
/* @__PURE__ */ jsxs13("div", { className: "flex items-center justify-between", children: [
|
|
3593
|
+
/* @__PURE__ */ jsxs13("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px] flex items-center gap-1.5", children: [
|
|
3594
|
+
/* @__PURE__ */ jsxs13("svg", { className: "w-3.5 h-3.5 text-purple-400", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: [
|
|
3595
|
+
/* @__PURE__ */ jsx13("path", { d: "m21.64 3.64-1.28-1.28a1.2 1.2 0 0 0-1.7 0l-9.72 9.72-1.94 4.86 4.86-1.94 9.72-9.72a1.2 1.2 0 0 0 .06-1.64z" }),
|
|
3596
|
+
/* @__PURE__ */ jsx13("path", { d: "m14 7 3 3" })
|
|
3200
3597
|
] }),
|
|
3201
3598
|
"Generative Inpainting"
|
|
3202
3599
|
] }),
|
|
3203
|
-
isInpainting && /* @__PURE__ */
|
|
3600
|
+
isInpainting && /* @__PURE__ */ jsx13("span", { className: "inline-flex items-center px-1.5 py-0.5 rounded text-[10px] font-medium bg-purple-900/60 text-purple-300 animate-pulse", children: "Inpainting..." })
|
|
3204
3601
|
] }),
|
|
3205
|
-
/* @__PURE__ */
|
|
3206
|
-
/* @__PURE__ */
|
|
3207
|
-
/* @__PURE__ */
|
|
3208
|
-
/* @__PURE__ */
|
|
3602
|
+
/* @__PURE__ */ jsx13("p", { className: "text-slate-400 text-[11px] leading-relaxed", children: "Replace, modify, or fill selected regions using prompt-guided generative inpainting." }),
|
|
3603
|
+
/* @__PURE__ */ jsxs13("div", { className: "flex flex-col gap-1", children: [
|
|
3604
|
+
/* @__PURE__ */ jsx13("label", { htmlFor: "ai-inpaint-prompt-react", className: "text-slate-300 text-[11px] font-medium", children: "Prompt" }),
|
|
3605
|
+
/* @__PURE__ */ jsx13(
|
|
3209
3606
|
"textarea",
|
|
3210
3607
|
{
|
|
3211
3608
|
id: "ai-inpaint-prompt-react",
|
|
@@ -3217,10 +3614,10 @@ var ImageEditor = ({
|
|
|
3217
3614
|
}
|
|
3218
3615
|
)
|
|
3219
3616
|
] }),
|
|
3220
|
-
/* @__PURE__ */
|
|
3221
|
-
/* @__PURE__ */
|
|
3222
|
-
/* @__PURE__ */
|
|
3223
|
-
/* @__PURE__ */
|
|
3617
|
+
/* @__PURE__ */ jsxs13("div", { className: "flex flex-col gap-1", children: [
|
|
3618
|
+
/* @__PURE__ */ jsx13("span", { className: "text-slate-300 text-[11px] font-medium", children: "Target Mask Region" }),
|
|
3619
|
+
/* @__PURE__ */ jsxs13("div", { className: "grid grid-cols-2 gap-1.5", children: [
|
|
3620
|
+
/* @__PURE__ */ jsxs13(
|
|
3224
3621
|
"button",
|
|
3225
3622
|
{
|
|
3226
3623
|
type: "button",
|
|
@@ -3233,7 +3630,7 @@ var ImageEditor = ({
|
|
|
3233
3630
|
]
|
|
3234
3631
|
}
|
|
3235
3632
|
),
|
|
3236
|
-
/* @__PURE__ */
|
|
3633
|
+
/* @__PURE__ */ jsxs13(
|
|
3237
3634
|
"button",
|
|
3238
3635
|
{
|
|
3239
3636
|
type: "button",
|
|
@@ -3248,25 +3645,25 @@ var ImageEditor = ({
|
|
|
3248
3645
|
)
|
|
3249
3646
|
] })
|
|
3250
3647
|
] }),
|
|
3251
|
-
/* @__PURE__ */
|
|
3648
|
+
/* @__PURE__ */ jsx13(
|
|
3252
3649
|
"button",
|
|
3253
3650
|
{
|
|
3254
3651
|
type: "button",
|
|
3255
3652
|
onClick: handleInpaint,
|
|
3256
3653
|
disabled: isInpainting || isRemovingBg || !inpaintPrompt.trim(),
|
|
3257
3654
|
className: "mt-1 px-3 py-2 rounded-lg bg-purple-600 hover:bg-purple-500 disabled:opacity-50 text-white font-medium shadow transition-colors flex items-center justify-center gap-2",
|
|
3258
|
-
children: isInpainting ? /* @__PURE__ */
|
|
3259
|
-
/* @__PURE__ */
|
|
3655
|
+
children: isInpainting ? /* @__PURE__ */ jsxs13(Fragment4, { children: [
|
|
3656
|
+
/* @__PURE__ */ jsx13("div", { className: "w-3.5 h-3.5 border-2 border-white/30 border-t-white rounded-full animate-spin" }),
|
|
3260
3657
|
"Generating Inpaint..."
|
|
3261
|
-
] }) : /* @__PURE__ */
|
|
3262
|
-
/* @__PURE__ */
|
|
3658
|
+
] }) : /* @__PURE__ */ jsxs13(Fragment4, { children: [
|
|
3659
|
+
/* @__PURE__ */ jsx13("svg", { className: "w-3.5 h-3.5", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: /* @__PURE__ */ jsx13("path", { d: "M12 2v4M12 18v4M4.93 4.93l2.83 2.83M16.24 16.24l2.83 2.83M2 12h4M18 12h4M4.93 19.07l2.83-2.83M16.24 7.76l2.83-2.83" }) }),
|
|
3263
3660
|
"Apply Inpainting"
|
|
3264
3661
|
] })
|
|
3265
3662
|
}
|
|
3266
3663
|
)
|
|
3267
3664
|
] }),
|
|
3268
|
-
aiError && /* @__PURE__ */
|
|
3269
|
-
aiSuccess && /* @__PURE__ */
|
|
3665
|
+
aiError && /* @__PURE__ */ jsx13("div", { className: "p-2.5 rounded-lg bg-rose-950/60 border border-rose-800 text-rose-300 text-[11px]", children: aiError }),
|
|
3666
|
+
aiSuccess && /* @__PURE__ */ jsx13("div", { className: "p-2.5 rounded-lg bg-emerald-950/60 border border-emerald-800 text-emerald-300 text-[11px]", children: aiSuccess })
|
|
3270
3667
|
] })
|
|
3271
3668
|
] })
|
|
3272
3669
|
] })
|
|
@@ -3288,6 +3685,8 @@ export {
|
|
|
3288
3685
|
SelectionOptionsBar,
|
|
3289
3686
|
RefineEdgePanel,
|
|
3290
3687
|
FreeTransformOptionsBar,
|
|
3688
|
+
ShapeOptionsBar,
|
|
3689
|
+
TypeOptionsBar,
|
|
3291
3690
|
ImageEditor
|
|
3292
3691
|
};
|
|
3293
|
-
//# sourceMappingURL=chunk-
|
|
3692
|
+
//# sourceMappingURL=chunk-YAFNCBDA.js.map
|