@pixerate/editor-react 0.59.0 → 0.61.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-SYTV33TW.js → chunk-OSOGA2OJ.js} +90 -18
- package/dist/chunk-OSOGA2OJ.js.map +1 -0
- package/dist/image-editor/index.cjs +77 -8
- package/dist/image-editor/index.cjs.map +1 -1
- package/dist/image-editor/index.d.cts +9 -3
- package/dist/image-editor/index.d.ts +9 -3
- package/dist/image-editor/index.js +1 -1
- package/dist/index.cjs +77 -8
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +1 -1
- package/dist/video-editor/index.cjs +36 -0
- package/dist/video-editor/index.cjs.map +1 -1
- package/dist/video-editor/index.d.cts +1 -11
- package/dist/video-editor/index.d.ts +1 -11
- package/dist/video-editor/index.js +37 -1
- package/dist/video-editor/index.js.map +1 -1
- package/package.json +3 -3
- package/dist/chunk-SYTV33TW.js.map +0 -1
|
@@ -96,11 +96,11 @@ function useImageEditor(options = {}) {
|
|
|
96
96
|
[controller]
|
|
97
97
|
);
|
|
98
98
|
const applyInpaintedImage = useCallback(
|
|
99
|
-
(newDataUrl) => controller.applyInpaintedImage(newDataUrl),
|
|
99
|
+
(newDataUrl, options2) => controller.applyInpaintedImage(newDataUrl, options2),
|
|
100
100
|
[controller]
|
|
101
101
|
);
|
|
102
102
|
const applyBackgroundRemovedImage = useCallback(
|
|
103
|
-
(newDataUrl) => controller.applyBackgroundRemovedImage(newDataUrl),
|
|
103
|
+
(newDataUrl, options2) => controller.applyBackgroundRemovedImage(newDataUrl, options2),
|
|
104
104
|
[controller]
|
|
105
105
|
);
|
|
106
106
|
return useMemo(
|
|
@@ -629,14 +629,17 @@ var AdjustmentLayersPanel = ({ controller, layers: layersProp, histogram }) => {
|
|
|
629
629
|
import { useEffect as useEffect4, useRef as useRef3, useState as useState5 } from "react";
|
|
630
630
|
import {
|
|
631
631
|
BLEND_MODES as BLEND_MODES2,
|
|
632
|
+
PSD_FILE_ACCEPT,
|
|
633
|
+
downloadPsd,
|
|
632
634
|
dropPlacement,
|
|
633
635
|
dropZone,
|
|
636
|
+
openPsdFile,
|
|
634
637
|
layerBadge,
|
|
635
638
|
layerMenu,
|
|
636
639
|
layerPanelRows,
|
|
637
640
|
runLayerMenuAction
|
|
638
641
|
} from "@pixerate/editor/image-editor";
|
|
639
|
-
import { jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
642
|
+
import { Fragment, jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
640
643
|
var iconButton = "px-1.5 py-0.5 rounded text-[10px] bg-slate-800 text-slate-300 hover:text-white disabled:opacity-40";
|
|
641
644
|
var rowClass = (active) => `flex items-center gap-1.5 px-1.5 py-1 rounded cursor-pointer select-none ${active ? "bg-indigo-600/30 ring-1 ring-indigo-500" : "hover:bg-slate-800"}`;
|
|
642
645
|
var Thumbnail = ({
|
|
@@ -671,13 +674,23 @@ var Thumbnail = ({
|
|
|
671
674
|
}
|
|
672
675
|
);
|
|
673
676
|
};
|
|
674
|
-
var LayersPanel = ({ controller, thumbnailSize = 32, className }) => {
|
|
677
|
+
var LayersPanel = ({ controller, thumbnailSize = 32, psd = true, psdFileName = "image", className }) => {
|
|
675
678
|
const [, setTick] = useState5(0);
|
|
676
679
|
useEffect4(() => controller.subscribe(() => setTick((n) => n + 1)), [controller]);
|
|
677
680
|
const [error, setError] = useState5(null);
|
|
678
681
|
const [renaming, setRenaming] = useState5(null);
|
|
679
682
|
const [menu, setMenu] = useState5(null);
|
|
680
683
|
const [drag, setDrag] = useState5(null);
|
|
684
|
+
const [psdNotes, setPsdNotes] = useState5([]);
|
|
685
|
+
const fileInput = useRef3(null);
|
|
686
|
+
const psdTask = async (fn) => {
|
|
687
|
+
try {
|
|
688
|
+
setError(null);
|
|
689
|
+
setPsdNotes(await fn());
|
|
690
|
+
} catch (err) {
|
|
691
|
+
setError(err instanceof Error ? err.message : String(err));
|
|
692
|
+
}
|
|
693
|
+
};
|
|
681
694
|
const commitNext = useRef3(true);
|
|
682
695
|
const state = controller.getState();
|
|
683
696
|
const rows = layerPanelRows(state.layers, state.activeLayerId);
|
|
@@ -737,7 +750,31 @@ var LayersPanel = ({ controller, thumbnailSize = 32, className }) => {
|
|
|
737
750
|
},
|
|
738
751
|
children: "\u22EF"
|
|
739
752
|
}
|
|
740
|
-
)
|
|
753
|
+
),
|
|
754
|
+
psd && /* @__PURE__ */ jsxs5(Fragment, { children: [
|
|
755
|
+
/* @__PURE__ */ jsx5("button", { type: "button", className: iconButton, onClick: () => fileInput.current?.click(), children: "Open PSD\u2026" }),
|
|
756
|
+
/* @__PURE__ */ jsx5("button", { type: "button", className: iconButton, onClick: () => psdTask(async () => (await downloadPsd(controller, psdFileName)).warnings), children: "Export PSD" }),
|
|
757
|
+
/* @__PURE__ */ jsx5(
|
|
758
|
+
"input",
|
|
759
|
+
{
|
|
760
|
+
ref: fileInput,
|
|
761
|
+
type: "file",
|
|
762
|
+
accept: PSD_FILE_ACCEPT,
|
|
763
|
+
className: "hidden",
|
|
764
|
+
"data-testid": "psd-file-input",
|
|
765
|
+
"aria-label": "Open a PSD file",
|
|
766
|
+
onChange: (e) => {
|
|
767
|
+
const file = e.currentTarget.files?.[0];
|
|
768
|
+
e.currentTarget.value = "";
|
|
769
|
+
if (file) psdTask(() => openPsdFile(controller, file));
|
|
770
|
+
}
|
|
771
|
+
}
|
|
772
|
+
)
|
|
773
|
+
] })
|
|
774
|
+
] }),
|
|
775
|
+
psdNotes.length > 0 && /* @__PURE__ */ jsxs5("ul", { className: "rounded bg-amber-900/30 text-amber-200 px-2 py-1 space-y-0.5", "data-testid": "psd-warnings", "aria-label": "PSD warnings", children: [
|
|
776
|
+
psdNotes.map((n) => /* @__PURE__ */ jsx5("li", { children: n }, n)),
|
|
777
|
+
/* @__PURE__ */ jsx5("li", { children: /* @__PURE__ */ jsx5("button", { type: "button", className: "underline", onClick: () => setPsdNotes([]), children: "Dismiss" }) })
|
|
741
778
|
] }),
|
|
742
779
|
active && /* @__PURE__ */ jsxs5("div", { className: "grid grid-cols-2 gap-x-2 gap-y-1 items-center", "data-testid": "layer-properties", children: [
|
|
743
780
|
/* @__PURE__ */ jsxs5("label", { className: "flex flex-col gap-0.5", children: [
|
|
@@ -1140,6 +1177,22 @@ var SelectionOptionsBar = ({
|
|
|
1140
1177
|
/* @__PURE__ */ jsxs7("label", { className: "flex items-center gap-2 text-slate-300", children: [
|
|
1141
1178
|
/* @__PURE__ */ jsx7("input", { type: "checkbox", checked: options.sampleMerged, onChange: (e) => set({ sampleMerged: e.target.checked }) }),
|
|
1142
1179
|
"Sample adjusted image"
|
|
1180
|
+
] }),
|
|
1181
|
+
/* @__PURE__ */ jsxs7("label", { className: "flex items-center gap-2 text-slate-300", children: [
|
|
1182
|
+
"Sample",
|
|
1183
|
+
/* @__PURE__ */ jsxs7(
|
|
1184
|
+
"select",
|
|
1185
|
+
{
|
|
1186
|
+
"aria-label": "Sample from",
|
|
1187
|
+
value: options.sample ?? "composite",
|
|
1188
|
+
onChange: (e) => set({ sample: e.target.value }),
|
|
1189
|
+
className: "bg-slate-800 border border-slate-700 rounded px-1 py-0.5",
|
|
1190
|
+
children: [
|
|
1191
|
+
/* @__PURE__ */ jsx7("option", { value: "composite", children: "All layers" }),
|
|
1192
|
+
/* @__PURE__ */ jsx7("option", { value: "active-layer", children: "Active layer" })
|
|
1193
|
+
]
|
|
1194
|
+
}
|
|
1195
|
+
)
|
|
1143
1196
|
] })
|
|
1144
1197
|
] }),
|
|
1145
1198
|
/* @__PURE__ */ jsxs7("label", { className: "flex items-center gap-2 text-slate-300", children: [
|
|
@@ -1183,7 +1236,7 @@ import {
|
|
|
1183
1236
|
adjustmentKindLabel as adjustmentKindLabel2,
|
|
1184
1237
|
layerMaskFromSelection
|
|
1185
1238
|
} from "@pixerate/editor/image-editor";
|
|
1186
|
-
import { Fragment, jsx as jsx8, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
1239
|
+
import { Fragment as Fragment2, jsx as jsx8, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
1187
1240
|
var DEFAULT_PARAMS = { radius: 8, smartRadius: false, smooth: 0, feather: 0, contrast: 0, shiftEdge: 0 };
|
|
1188
1241
|
var button = "px-2 py-1 rounded-md border border-slate-800 bg-slate-950 text-[11px] text-slate-200 hover:text-white disabled:opacity-40";
|
|
1189
1242
|
var RefineEdgePanel = ({ controller, selection, layers, className = "" }) => {
|
|
@@ -1281,7 +1334,7 @@ var RefineEdgePanel = ({ controller, selection, layers, className = "" }) => {
|
|
|
1281
1334
|
/* @__PURE__ */ jsx8("button", { type: "button", className: button, disabled: !target.mask, onClick: () => controller.selectionFromLayerMask(target.id), children: "Load as Selection" }),
|
|
1282
1335
|
/* @__PURE__ */ jsx8("button", { type: "button", className: button, disabled: !target.mask, onClick: () => controller.setAdjustmentLayerMask(target.id, null), children: "Remove Mask" })
|
|
1283
1336
|
] }),
|
|
1284
|
-
target.mask && /* @__PURE__ */ jsxs8(
|
|
1337
|
+
target.mask && /* @__PURE__ */ jsxs8(Fragment2, { children: [
|
|
1285
1338
|
/* @__PURE__ */ jsxs8("label", { className: "flex flex-col gap-1", children: [
|
|
1286
1339
|
/* @__PURE__ */ jsxs8("span", { className: "flex justify-between text-slate-400", children: [
|
|
1287
1340
|
/* @__PURE__ */ jsx8("span", { children: "Density" }),
|
|
@@ -1332,7 +1385,7 @@ var RefineEdgePanel = ({ controller, selection, layers, className = "" }) => {
|
|
|
1332
1385
|
};
|
|
1333
1386
|
|
|
1334
1387
|
// src/image-editor/ImageEditor.tsx
|
|
1335
|
-
import { Fragment as
|
|
1388
|
+
import { Fragment as Fragment3, jsx as jsx9, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
1336
1389
|
var ImageEditor = ({
|
|
1337
1390
|
editor: externalEditor,
|
|
1338
1391
|
src,
|
|
@@ -1375,6 +1428,8 @@ var ImageEditor = ({
|
|
|
1375
1428
|
const [isInpainting, setIsInpainting] = useState9(false);
|
|
1376
1429
|
const [aiError, setAiError] = useState9(null);
|
|
1377
1430
|
const [aiSuccess, setAiSuccess] = useState9(null);
|
|
1431
|
+
const [aiTarget, setAiTarget] = useState9("auto");
|
|
1432
|
+
const aiOptions = aiTarget === "auto" ? {} : { target: aiTarget };
|
|
1378
1433
|
const effectiveOnInpaint = onInpaint || aiHooks?.onInpaint;
|
|
1379
1434
|
const effectiveOnRemoveBg = onRemoveBackground || aiHooks?.onRemoveBackground;
|
|
1380
1435
|
const handleRemoveBackground = async () => {
|
|
@@ -1386,10 +1441,10 @@ var ImageEditor = ({
|
|
|
1386
1441
|
setAiSuccess(null);
|
|
1387
1442
|
setIsRemovingBg(true);
|
|
1388
1443
|
try {
|
|
1389
|
-
const imageDataUrl = await
|
|
1444
|
+
const imageDataUrl = await controller.toAIInputDataURL(aiOptions);
|
|
1390
1445
|
const result = await effectiveOnRemoveBg({ imageDataUrl });
|
|
1391
1446
|
if (typeof result === "string") {
|
|
1392
|
-
await editor.applyBackgroundRemovedImage(result);
|
|
1447
|
+
await editor.applyBackgroundRemovedImage(result, aiOptions);
|
|
1393
1448
|
setAiSuccess("Background removed successfully!");
|
|
1394
1449
|
} else {
|
|
1395
1450
|
setAiSuccess("Background removal complete.");
|
|
@@ -1413,7 +1468,7 @@ var ImageEditor = ({
|
|
|
1413
1468
|
setAiSuccess(null);
|
|
1414
1469
|
setIsInpainting(true);
|
|
1415
1470
|
try {
|
|
1416
|
-
const imageDataUrl = await
|
|
1471
|
+
const imageDataUrl = await controller.toAIInputDataURL(aiOptions);
|
|
1417
1472
|
const maskDataUrl = await editor.toMaskDataURL({
|
|
1418
1473
|
useAnnotations: inpaintMaskMode === "annotations",
|
|
1419
1474
|
useCrop: inpaintMaskMode === "crop"
|
|
@@ -1425,7 +1480,7 @@ var ImageEditor = ({
|
|
|
1425
1480
|
cropBox: inpaintMaskMode === "crop" ? editor.state.crop : null
|
|
1426
1481
|
});
|
|
1427
1482
|
if (typeof result === "string") {
|
|
1428
|
-
await editor.applyInpaintedImage(result);
|
|
1483
|
+
await editor.applyInpaintedImage(result, aiOptions);
|
|
1429
1484
|
setAiSuccess("Inpainting applied successfully!");
|
|
1430
1485
|
} else {
|
|
1431
1486
|
setAiSuccess("Inpainting complete.");
|
|
@@ -2440,7 +2495,7 @@ var ImageEditor = ({
|
|
|
2440
2495
|
),
|
|
2441
2496
|
/* @__PURE__ */ jsx9("span", { children: "Enable Depth / Alpha Mask" })
|
|
2442
2497
|
] }),
|
|
2443
|
-
state.depthMask.enabled && /* @__PURE__ */ jsxs9(
|
|
2498
|
+
state.depthMask.enabled && /* @__PURE__ */ jsxs9(Fragment3, { children: [
|
|
2444
2499
|
/* @__PURE__ */ jsxs9("div", { children: [
|
|
2445
2500
|
/* @__PURE__ */ jsx9("label", { className: "text-slate-400 block mb-1", children: "Mask Image URL:" }),
|
|
2446
2501
|
/* @__PURE__ */ jsx9(
|
|
@@ -2558,6 +2613,23 @@ var ImageEditor = ({
|
|
|
2558
2613
|
/* @__PURE__ */ jsx9(RefineEdgePanel, { controller, selection: state.selection ?? null, layers: state.adjustments.layers })
|
|
2559
2614
|
] }),
|
|
2560
2615
|
activeTab === "ai" && /* @__PURE__ */ jsxs9("div", { className: "flex flex-col gap-4 text-xs", children: [
|
|
2616
|
+
/* @__PURE__ */ jsxs9("label", { className: "flex items-center justify-between gap-2 text-slate-300", children: [
|
|
2617
|
+
/* @__PURE__ */ jsx9("span", { children: "Results go to" }),
|
|
2618
|
+
/* @__PURE__ */ jsxs9(
|
|
2619
|
+
"select",
|
|
2620
|
+
{
|
|
2621
|
+
"aria-label": "AI result target",
|
|
2622
|
+
value: aiTarget,
|
|
2623
|
+
onChange: (e) => setAiTarget(e.target.value),
|
|
2624
|
+
className: "bg-slate-800 border border-slate-700 rounded px-1.5 py-1",
|
|
2625
|
+
children: [
|
|
2626
|
+
/* @__PURE__ */ jsx9("option", { value: "auto", children: controller.isMultiLayer ? "Auto (new layer)" : "Auto (replace image)" }),
|
|
2627
|
+
/* @__PURE__ */ jsx9("option", { value: "new-layer", children: "New layer / mask" }),
|
|
2628
|
+
/* @__PURE__ */ jsx9("option", { value: "replace", children: "Replace image" })
|
|
2629
|
+
]
|
|
2630
|
+
}
|
|
2631
|
+
)
|
|
2632
|
+
] }),
|
|
2561
2633
|
/* @__PURE__ */ jsxs9("div", { className: "p-3 rounded-lg bg-slate-950/60 border border-slate-800 flex flex-col gap-2.5", children: [
|
|
2562
2634
|
/* @__PURE__ */ jsxs9("div", { className: "flex items-center justify-between", children: [
|
|
2563
2635
|
/* @__PURE__ */ jsxs9("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px] flex items-center gap-1.5", children: [
|
|
@@ -2574,10 +2646,10 @@ var ImageEditor = ({
|
|
|
2574
2646
|
onClick: handleRemoveBackground,
|
|
2575
2647
|
disabled: isRemovingBg || isInpainting,
|
|
2576
2648
|
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",
|
|
2577
|
-
children: isRemovingBg ? /* @__PURE__ */ jsxs9(
|
|
2649
|
+
children: isRemovingBg ? /* @__PURE__ */ jsxs9(Fragment3, { children: [
|
|
2578
2650
|
/* @__PURE__ */ jsx9("div", { className: "w-3.5 h-3.5 border-2 border-white/30 border-t-white rounded-full animate-spin" }),
|
|
2579
2651
|
"Removing Background..."
|
|
2580
|
-
] }) : /* @__PURE__ */ jsxs9(
|
|
2652
|
+
] }) : /* @__PURE__ */ jsxs9(Fragment3, { children: [
|
|
2581
2653
|
/* @__PURE__ */ jsx9("svg", { className: "w-3.5 h-3.5", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: /* @__PURE__ */ jsx9("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" }) }),
|
|
2582
2654
|
"Remove Background"
|
|
2583
2655
|
] })
|
|
@@ -2648,10 +2720,10 @@ var ImageEditor = ({
|
|
|
2648
2720
|
onClick: handleInpaint,
|
|
2649
2721
|
disabled: isInpainting || isRemovingBg || !inpaintPrompt.trim(),
|
|
2650
2722
|
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",
|
|
2651
|
-
children: isInpainting ? /* @__PURE__ */ jsxs9(
|
|
2723
|
+
children: isInpainting ? /* @__PURE__ */ jsxs9(Fragment3, { children: [
|
|
2652
2724
|
/* @__PURE__ */ jsx9("div", { className: "w-3.5 h-3.5 border-2 border-white/30 border-t-white rounded-full animate-spin" }),
|
|
2653
2725
|
"Generating Inpaint..."
|
|
2654
|
-
] }) : /* @__PURE__ */ jsxs9(
|
|
2726
|
+
] }) : /* @__PURE__ */ jsxs9(Fragment3, { children: [
|
|
2655
2727
|
/* @__PURE__ */ jsx9("svg", { className: "w-3.5 h-3.5", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: /* @__PURE__ */ jsx9("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" }) }),
|
|
2656
2728
|
"Apply Inpainting"
|
|
2657
2729
|
] })
|
|
@@ -2681,4 +2753,4 @@ export {
|
|
|
2681
2753
|
RefineEdgePanel,
|
|
2682
2754
|
ImageEditor
|
|
2683
2755
|
};
|
|
2684
|
-
//# sourceMappingURL=chunk-
|
|
2756
|
+
//# sourceMappingURL=chunk-OSOGA2OJ.js.map
|