@pixerate/editor-react 0.71.0 → 0.73.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-63FQB5BT.js → chunk-VNZKHFEM.js} +525 -382
- package/dist/chunk-VNZKHFEM.js.map +1 -0
- package/dist/image-editor/index.cjs +575 -444
- package/dist/image-editor/index.cjs.map +1 -1
- package/dist/image-editor/index.d.cts +15 -1
- package/dist/image-editor/index.d.ts +15 -1
- package/dist/image-editor/index.js +3 -1
- package/dist/index.cjs +1004 -873
- 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 +3 -1
- package/dist/index.js.map +1 -1
- package/dist/vector/index.cjs +910 -175
- package/dist/vector/index.cjs.map +1 -1
- package/dist/vector/index.d.cts +67 -3
- package/dist/vector/index.d.ts +67 -3
- package/dist/vector/index.js +915 -164
- package/dist/vector/index.js.map +1 -1
- package/package.json +3 -3
- package/dist/chunk-63FQB5BT.js.map +0 -1
package/dist/index.cjs
CHANGED
|
@@ -35,6 +35,7 @@ __export(src_exports, {
|
|
|
35
35
|
BrushOptionsBar: () => BrushOptionsBar,
|
|
36
36
|
BubbleMenu: () => BubbleMenu,
|
|
37
37
|
ChartNodeView: () => ChartNodeView,
|
|
38
|
+
ColorProfilePanel: () => ColorProfilePanel,
|
|
38
39
|
CommandPalette: () => CommandPalette,
|
|
39
40
|
CommentButton: () => CommentButton,
|
|
40
41
|
CommentsPanel: () => CommentsPanel,
|
|
@@ -3787,8 +3788,8 @@ function useImageEditor(options = {}) {
|
|
|
3787
3788
|
}
|
|
3788
3789
|
|
|
3789
3790
|
// src/image-editor/ImageEditor.tsx
|
|
3790
|
-
var
|
|
3791
|
-
var
|
|
3791
|
+
var import_react47 = __toESM(require("react"), 1);
|
|
3792
|
+
var import_image_editor15 = require("@pixerate/editor/image-editor");
|
|
3792
3793
|
|
|
3793
3794
|
// src/image-editor/ControlSlider.tsx
|
|
3794
3795
|
var import_image_editor2 = require("@pixerate/editor/image-editor");
|
|
@@ -4523,6 +4524,17 @@ var LayersPanel = ({ controller, thumbnailSize = 32, psd = true, psdFileName = "
|
|
|
4523
4524
|
children: "\u22EF"
|
|
4524
4525
|
}
|
|
4525
4526
|
),
|
|
4527
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
4528
|
+
"select",
|
|
4529
|
+
{
|
|
4530
|
+
"aria-label": "Bits per channel",
|
|
4531
|
+
title: "Image \u203A Mode: bits per channel",
|
|
4532
|
+
className: "rounded bg-slate-800 px-1 py-0.5 text-[11px] text-slate-200",
|
|
4533
|
+
value: controller.bitDepth,
|
|
4534
|
+
onChange: (e) => attempt(() => controller.setBitDepth(Number(e.target.value))),
|
|
4535
|
+
children: import_image_editor7.BIT_DEPTH_OPTIONS.map((o) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("option", { value: o.depth, title: o.title, children: o.label }, o.depth))
|
|
4536
|
+
}
|
|
4537
|
+
),
|
|
4526
4538
|
psd && /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(import_jsx_runtime22.Fragment, { children: [
|
|
4527
4539
|
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("button", { type: "button", className: iconButton, onClick: () => fileInput.current?.click(), children: "Open PSD\u2026" }),
|
|
4528
4540
|
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("button", { type: "button", className: iconButton, onClick: () => psdTask(async () => (await (0, import_image_editor7.downloadPsd)(controller, psdFileName)).warnings), children: "Export PSD" }),
|
|
@@ -4836,7 +4848,8 @@ var BrushOptionsBar = ({ controller, className }) => {
|
|
|
4836
4848
|
(0, import_react40.useEffect)(() => controller.subscribe(() => setTick((n) => n + 1)), [controller]);
|
|
4837
4849
|
const [error, setError] = (0, import_react40.useState)(null);
|
|
4838
4850
|
const state = controller.getState();
|
|
4839
|
-
const { brush, foreground, background, mixer, mixerLoad } = state.paint;
|
|
4851
|
+
const { brush, foreground, background, mixer, mixerLoad, retouch, cloneSource } = state.paint;
|
|
4852
|
+
const tool = state.activeTool;
|
|
4840
4853
|
const attempt = (fn) => {
|
|
4841
4854
|
try {
|
|
4842
4855
|
setError(null);
|
|
@@ -4846,12 +4859,12 @@ var BrushOptionsBar = ({ controller, className }) => {
|
|
|
4846
4859
|
}
|
|
4847
4860
|
};
|
|
4848
4861
|
return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: `flex flex-col gap-2 text-xs text-slate-200 ${className ?? ""}`, "data-testid": "brush-options", children: [
|
|
4849
|
-
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "flex gap-1", role: "toolbar", "aria-label": "Paint tools", children: import_image_editor8.PAINT_TOOLS.map((t) => /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
4862
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "flex flex-wrap gap-1", role: "toolbar", "aria-label": "Paint tools", children: import_image_editor8.PAINT_TOOLS.map((t) => /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
4850
4863
|
"button",
|
|
4851
4864
|
{
|
|
4852
4865
|
type: "button",
|
|
4853
4866
|
"aria-pressed": state.activeTool === t.id,
|
|
4854
|
-
title: `${t.label} (${t.shortcut})
|
|
4867
|
+
title: t.shortcut ? `${t.label} (${t.shortcut})` : t.label,
|
|
4855
4868
|
className: chip(state.activeTool === t.id),
|
|
4856
4869
|
onClick: () => controller.setTool(t.id),
|
|
4857
4870
|
children: t.label
|
|
@@ -4953,6 +4966,41 @@ var BrushOptionsBar = ({ controller, className }) => {
|
|
|
4953
4966
|
] })
|
|
4954
4967
|
] })
|
|
4955
4968
|
] }),
|
|
4969
|
+
(0, import_image_editor8.isRetouchPaintTool)(tool) && /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("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: [
|
|
4970
|
+
(tool === "clone" || tool === "heal") && /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
4971
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "text-slate-400", "data-testid": "clone-source", children: (0, import_image_editor8.cloneSourceLabel)(controller) }),
|
|
4972
|
+
cloneSource && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("button", { type: "button", title: "Forget the source point", className: chip(false), onClick: () => controller.setCloneSource(null), children: "Clear source" })
|
|
4973
|
+
] }),
|
|
4974
|
+
import_image_editor8.RETOUCH_CHOICES.filter((c) => c.tools.includes(tool)).map((choice) => /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex flex-wrap items-center gap-1", role: "group", "aria-label": choice.label, children: [
|
|
4975
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "text-slate-400", children: choice.label }),
|
|
4976
|
+
choice.options.map((o) => /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
4977
|
+
"button",
|
|
4978
|
+
{
|
|
4979
|
+
type: "button",
|
|
4980
|
+
"aria-pressed": retouch[choice.id] === o.id,
|
|
4981
|
+
title: o.title,
|
|
4982
|
+
className: chip(retouch[choice.id] === o.id),
|
|
4983
|
+
onClick: () => (0, import_image_editor8.setRetouchChoice)(controller, choice.id, o.id),
|
|
4984
|
+
children: o.label
|
|
4985
|
+
},
|
|
4986
|
+
o.id
|
|
4987
|
+
))
|
|
4988
|
+
] }, choice.id)),
|
|
4989
|
+
import_image_editor8.RETOUCH_OPTION_CONTROLS.filter((c) => c.tools.includes(tool)).map((spec) => /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(ControlSlider, { spec, value: retouch[spec.id], onChange: (v) => controller.setPaintOptions({ retouch: { [spec.id]: v } }) }, spec.id)),
|
|
4990
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "flex flex-wrap gap-3 text-slate-300", children: import_image_editor8.RETOUCH_TOGGLES.filter((t) => t.tools.includes(tool)).map((t) => /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("label", { className: "flex items-center gap-1.5", children: [
|
|
4991
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
4992
|
+
"input",
|
|
4993
|
+
{
|
|
4994
|
+
type: "checkbox",
|
|
4995
|
+
"aria-label": t.label,
|
|
4996
|
+
checked: retouch[t.id],
|
|
4997
|
+
onChange: (e) => controller.setPaintOptions({ retouch: { [t.id]: e.target.checked } }),
|
|
4998
|
+
className: "accent-indigo-500"
|
|
4999
|
+
}
|
|
5000
|
+
),
|
|
5001
|
+
t.label
|
|
5002
|
+
] }, t.id)) })
|
|
5003
|
+
] }),
|
|
4956
5004
|
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex flex-wrap gap-3 text-slate-300", role: "group", "aria-label": "Pressure", children: [
|
|
4957
5005
|
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("label", { className: "flex items-center gap-1.5", children: [
|
|
4958
5006
|
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
@@ -4989,10 +5037,90 @@ var BrushOptionsBar = ({ controller, className }) => {
|
|
|
4989
5037
|
] });
|
|
4990
5038
|
};
|
|
4991
5039
|
|
|
4992
|
-
// src/image-editor/
|
|
5040
|
+
// src/image-editor/ColorProfilePanel.tsx
|
|
4993
5041
|
var import_react41 = require("react");
|
|
4994
5042
|
var import_image_editor9 = require("@pixerate/editor/image-editor");
|
|
4995
5043
|
var import_jsx_runtime24 = require("react/jsx-runtime");
|
|
5044
|
+
var chip2 = "px-2 py-1 rounded text-[11px] bg-slate-800 text-slate-300 hover:text-white";
|
|
5045
|
+
var select = "rounded bg-slate-800 px-1 py-0.5 text-[11px] text-slate-200";
|
|
5046
|
+
var ColorProfilePanel = ({ controller, className }) => {
|
|
5047
|
+
const [, setTick] = (0, import_react41.useState)(0);
|
|
5048
|
+
(0, import_react41.useEffect)(() => controller.subscribe(() => setTick((n) => n + 1)), [controller]);
|
|
5049
|
+
const [target, setTarget] = (0, import_react41.useState)("display-p3");
|
|
5050
|
+
const [intent, setIntent] = (0, import_react41.useState)("relative");
|
|
5051
|
+
const [bpc, setBpc] = (0, import_react41.useState)(true);
|
|
5052
|
+
const [error, setError] = (0, import_react41.useState)(null);
|
|
5053
|
+
const view = (0, import_image_editor9.colorPanelView)(controller);
|
|
5054
|
+
const attempt = (fn) => {
|
|
5055
|
+
try {
|
|
5056
|
+
setError(null);
|
|
5057
|
+
fn();
|
|
5058
|
+
} catch (err) {
|
|
5059
|
+
setError(err instanceof Error ? err.message : String(err));
|
|
5060
|
+
}
|
|
5061
|
+
};
|
|
5062
|
+
const proofWith = (patch) => {
|
|
5063
|
+
const cur = view.proof;
|
|
5064
|
+
const id = patch.id ?? cur?.id ?? "coated-cmyk";
|
|
5065
|
+
attempt(
|
|
5066
|
+
() => controller.setProofSetup({
|
|
5067
|
+
profile: id,
|
|
5068
|
+
intent: patch.intent ?? cur?.intent ?? "relative",
|
|
5069
|
+
simulatePaper: patch.simulatePaper ?? cur?.simulatePaper ?? false,
|
|
5070
|
+
gamutWarning: patch.gamutWarning ?? cur?.gamutWarning ?? false
|
|
5071
|
+
})
|
|
5072
|
+
);
|
|
5073
|
+
};
|
|
5074
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: `flex flex-col gap-2 text-xs text-slate-200 ${className ?? ""}`, "data-testid": "color-profile-panel", children: [
|
|
5075
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
5076
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { className: "text-slate-400", children: "Profile" }),
|
|
5077
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { "data-testid": "color-profile-name", children: view.profileName })
|
|
5078
|
+
] }),
|
|
5079
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "flex flex-wrap items-center gap-1", role: "group", "aria-label": "Assign or convert", children: [
|
|
5080
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)("select", { "aria-label": "Target profile", className: select, value: target, onChange: (e) => setTarget(e.target.value), children: import_image_editor9.WORKING_SPACE_OPTIONS.map((o) => /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("option", { value: o.id, children: o.label }, o.id)) }),
|
|
5081
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)("select", { "aria-label": "Rendering intent", className: select, value: intent, onChange: (e) => setIntent(e.target.value), children: import_image_editor9.INTENT_OPTIONS.map((o) => /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("option", { value: o.id, title: o.title, children: o.label }, o.id)) }),
|
|
5082
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("label", { className: "flex items-center gap-1", children: [
|
|
5083
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)("input", { type: "checkbox", "aria-label": "Black point compensation", checked: bpc, onChange: (e) => setBpc(e.target.checked), className: "accent-indigo-500" }),
|
|
5084
|
+
"BPC"
|
|
5085
|
+
] }),
|
|
5086
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)("button", { type: "button", className: chip2, title: "Edit \u203A Assign Profile: keep the numbers", onClick: () => attempt(() => controller.assignProfile(target)), children: "Assign" }),
|
|
5087
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)("button", { type: "button", className: chip2, title: "Edit \u203A Convert to Profile: keep the look", onClick: () => attempt(() => controller.convertToProfile(target, { intent, bpc })), children: "Convert" })
|
|
5088
|
+
] }),
|
|
5089
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "flex flex-wrap items-center gap-1", role: "group", "aria-label": "Proof setup", children: [
|
|
5090
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { className: "text-slate-400", children: "Proof" }),
|
|
5091
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(
|
|
5092
|
+
"select",
|
|
5093
|
+
{
|
|
5094
|
+
"aria-label": "Proof profile",
|
|
5095
|
+
className: select,
|
|
5096
|
+
value: view.proof?.id ?? "",
|
|
5097
|
+
onChange: (e) => e.target.value ? proofWith({ id: e.target.value }) : attempt(() => controller.setProofSetup(null)),
|
|
5098
|
+
children: [
|
|
5099
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)("option", { value: "", children: "Off" }),
|
|
5100
|
+
import_image_editor9.PROOF_PROFILE_OPTIONS.map((o) => /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("option", { value: o.id, children: o.label }, o.id))
|
|
5101
|
+
]
|
|
5102
|
+
}
|
|
5103
|
+
),
|
|
5104
|
+
view.proof && /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(import_jsx_runtime24.Fragment, { children: [
|
|
5105
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)("select", { "aria-label": "Proof intent", className: select, value: view.proof.intent, onChange: (e) => proofWith({ intent: e.target.value }), children: import_image_editor9.INTENT_OPTIONS.map((o) => /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("option", { value: o.id, children: o.label }, o.id)) }),
|
|
5106
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("label", { className: "flex items-center gap-1", children: [
|
|
5107
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)("input", { type: "checkbox", "aria-label": "Simulate paper colour", checked: view.proof.simulatePaper, onChange: (e) => proofWith({ simulatePaper: e.target.checked }), className: "accent-indigo-500" }),
|
|
5108
|
+
"Paper"
|
|
5109
|
+
] }),
|
|
5110
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("label", { className: "flex items-center gap-1", children: [
|
|
5111
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)("input", { type: "checkbox", "aria-label": "Gamut warning", checked: view.proof.gamutWarning, onChange: (e) => proofWith({ gamutWarning: e.target.checked }), className: "accent-indigo-500" }),
|
|
5112
|
+
"Gamut warning"
|
|
5113
|
+
] })
|
|
5114
|
+
] })
|
|
5115
|
+
] }),
|
|
5116
|
+
error && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("p", { role: "alert", className: "text-rose-400", children: error })
|
|
5117
|
+
] });
|
|
5118
|
+
};
|
|
5119
|
+
|
|
5120
|
+
// src/image-editor/SelectionOptionsBar.tsx
|
|
5121
|
+
var import_react42 = require("react");
|
|
5122
|
+
var import_image_editor10 = require("@pixerate/editor/image-editor");
|
|
5123
|
+
var import_jsx_runtime25 = require("react/jsx-runtime");
|
|
4996
5124
|
var MODIFY_OPS = [
|
|
4997
5125
|
{ op: "grow", label: "Grow" },
|
|
4998
5126
|
{ op: "shrink", label: "Shrink" },
|
|
@@ -5009,20 +5137,20 @@ var SelectionOptionsBar = ({
|
|
|
5009
5137
|
quickMask,
|
|
5010
5138
|
className = ""
|
|
5011
5139
|
}) => {
|
|
5012
|
-
const [radius, setRadius] = (0,
|
|
5140
|
+
const [radius, setRadius] = (0, import_react42.useState)(2);
|
|
5013
5141
|
const set = (patch) => onOptionsChange({ ...options, ...patch });
|
|
5014
5142
|
const sel = selection === void 0 ? controller.getSelection() : selection;
|
|
5015
5143
|
const qm = quickMask ?? Boolean(controller.getState().quickMask);
|
|
5016
|
-
return /* @__PURE__ */ (0,
|
|
5017
|
-
/* @__PURE__ */ (0,
|
|
5018
|
-
/* @__PURE__ */ (0,
|
|
5019
|
-
options.tool === "wand" && /* @__PURE__ */ (0,
|
|
5020
|
-
/* @__PURE__ */ (0,
|
|
5021
|
-
/* @__PURE__ */ (0,
|
|
5022
|
-
/* @__PURE__ */ (0,
|
|
5023
|
-
/* @__PURE__ */ (0,
|
|
5144
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { "data-testid": "selection-options-bar", className: `flex flex-col gap-3 text-xs ${className}`, children: [
|
|
5145
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { role: "group", "aria-label": "Selection tool", className: "flex flex-wrap gap-1", children: import_image_editor10.SELECTION_TOOLS.map((t) => /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("button", { type: "button", "aria-pressed": options.tool === t.id, className: btn(options.tool === t.id), onClick: () => set({ tool: t.id }), children: t.label }, t.id)) }),
|
|
5146
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { role: "group", "aria-label": "Selection mode", className: "flex flex-wrap gap-1", children: import_image_editor10.SELECTION_MODES.map((m) => /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("button", { type: "button", "aria-pressed": options.mode === m, className: btn(options.mode === m), onClick: () => set({ mode: m }), children: import_image_editor10.SELECTION_MODE_LABELS[m] }, m)) }),
|
|
5147
|
+
options.tool === "wand" && /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "flex flex-col gap-2", children: [
|
|
5148
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("label", { className: "flex flex-col gap-1", children: [
|
|
5149
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("span", { className: "flex justify-between text-slate-400", children: [
|
|
5150
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { children: "Tolerance" }),
|
|
5151
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: "font-mono", children: options.tolerance })
|
|
5024
5152
|
] }),
|
|
5025
|
-
/* @__PURE__ */ (0,
|
|
5153
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
5026
5154
|
"input",
|
|
5027
5155
|
{
|
|
5028
5156
|
type: "range",
|
|
@@ -5036,17 +5164,17 @@ var SelectionOptionsBar = ({
|
|
|
5036
5164
|
}
|
|
5037
5165
|
)
|
|
5038
5166
|
] }),
|
|
5039
|
-
/* @__PURE__ */ (0,
|
|
5040
|
-
/* @__PURE__ */ (0,
|
|
5167
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("label", { className: "flex items-center gap-2 text-slate-300", children: [
|
|
5168
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("input", { type: "checkbox", checked: options.contiguous, onChange: (e) => set({ contiguous: e.target.checked }) }),
|
|
5041
5169
|
"Contiguous"
|
|
5042
5170
|
] }),
|
|
5043
|
-
/* @__PURE__ */ (0,
|
|
5044
|
-
/* @__PURE__ */ (0,
|
|
5171
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("label", { className: "flex items-center gap-2 text-slate-300", children: [
|
|
5172
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("input", { type: "checkbox", checked: options.sampleMerged, onChange: (e) => set({ sampleMerged: e.target.checked }) }),
|
|
5045
5173
|
"Sample adjusted image"
|
|
5046
5174
|
] }),
|
|
5047
|
-
/* @__PURE__ */ (0,
|
|
5175
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("label", { className: "flex items-center gap-2 text-slate-300", children: [
|
|
5048
5176
|
"Sample",
|
|
5049
|
-
/* @__PURE__ */ (0,
|
|
5177
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(
|
|
5050
5178
|
"select",
|
|
5051
5179
|
{
|
|
5052
5180
|
"aria-label": "Sample from",
|
|
@@ -5054,27 +5182,27 @@ var SelectionOptionsBar = ({
|
|
|
5054
5182
|
onChange: (e) => set({ sample: e.target.value }),
|
|
5055
5183
|
className: "bg-slate-800 border border-slate-700 rounded px-1 py-0.5",
|
|
5056
5184
|
children: [
|
|
5057
|
-
/* @__PURE__ */ (0,
|
|
5058
|
-
/* @__PURE__ */ (0,
|
|
5185
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("option", { value: "composite", children: "All layers" }),
|
|
5186
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("option", { value: "active-layer", children: "Active layer" })
|
|
5059
5187
|
]
|
|
5060
5188
|
}
|
|
5061
5189
|
)
|
|
5062
5190
|
] })
|
|
5063
5191
|
] }),
|
|
5064
|
-
/* @__PURE__ */ (0,
|
|
5065
|
-
/* @__PURE__ */ (0,
|
|
5192
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("label", { className: "flex items-center gap-2 text-slate-300", children: [
|
|
5193
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("input", { type: "checkbox", checked: options.antiAlias, onChange: (e) => set({ antiAlias: e.target.checked }) }),
|
|
5066
5194
|
"Anti-alias"
|
|
5067
5195
|
] }),
|
|
5068
|
-
/* @__PURE__ */ (0,
|
|
5069
|
-
/* @__PURE__ */ (0,
|
|
5070
|
-
/* @__PURE__ */ (0,
|
|
5071
|
-
/* @__PURE__ */ (0,
|
|
5072
|
-
/* @__PURE__ */ (0,
|
|
5196
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "flex flex-wrap gap-1", children: [
|
|
5197
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("button", { type: "button", className: btn(false), onClick: () => controller.selectAll(), children: "Select All" }),
|
|
5198
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("button", { type: "button", className: btn(false), disabled: !sel, onClick: () => controller.deselect(), children: "Deselect" }),
|
|
5199
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("button", { type: "button", className: btn(false), onClick: () => controller.invertSelection(), children: "Inverse" }),
|
|
5200
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("button", { type: "button", "aria-pressed": qm, className: btn(qm), onClick: () => controller.setQuickMask(!qm), children: "Quick Mask" })
|
|
5073
5201
|
] }),
|
|
5074
|
-
/* @__PURE__ */ (0,
|
|
5075
|
-
/* @__PURE__ */ (0,
|
|
5202
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "flex flex-wrap items-center gap-1", children: [
|
|
5203
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("label", { className: "flex items-center gap-1 text-slate-400", children: [
|
|
5076
5204
|
"Radius",
|
|
5077
|
-
/* @__PURE__ */ (0,
|
|
5205
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
5078
5206
|
"input",
|
|
5079
5207
|
{
|
|
5080
5208
|
type: "number",
|
|
@@ -5088,24 +5216,24 @@ var SelectionOptionsBar = ({
|
|
|
5088
5216
|
}
|
|
5089
5217
|
)
|
|
5090
5218
|
] }),
|
|
5091
|
-
MODIFY_OPS.map(({ op, label }) => /* @__PURE__ */ (0,
|
|
5219
|
+
MODIFY_OPS.map(({ op, label }) => /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("button", { type: "button", className: btn(false), disabled: !sel, onClick: () => controller.modifySelection(op, radius), children: label }, op))
|
|
5092
5220
|
] }),
|
|
5093
|
-
/* @__PURE__ */ (0,
|
|
5221
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("p", { "data-testid": "selection-status", className: "text-slate-400", children: (0, import_image_editor10.describeSelection)(sel) })
|
|
5094
5222
|
] });
|
|
5095
5223
|
};
|
|
5096
5224
|
|
|
5097
5225
|
// src/image-editor/RefineEdgePanel.tsx
|
|
5098
|
-
var
|
|
5099
|
-
var
|
|
5100
|
-
var
|
|
5226
|
+
var import_react43 = require("react");
|
|
5227
|
+
var import_image_editor11 = require("@pixerate/editor/image-editor");
|
|
5228
|
+
var import_jsx_runtime26 = require("react/jsx-runtime");
|
|
5101
5229
|
var DEFAULT_PARAMS = { radius: 8, smartRadius: false, smooth: 0, feather: 0, contrast: 0, shiftEdge: 0 };
|
|
5102
5230
|
var button2 = "px-2 py-1 rounded-md border border-slate-800 bg-slate-950 text-[11px] text-slate-200 hover:text-white disabled:opacity-40";
|
|
5103
5231
|
var RefineEdgePanel = ({ controller, selection, layers, className = "" }) => {
|
|
5104
|
-
const [params, setParams] = (0,
|
|
5105
|
-
const [busy, setBusy] = (0,
|
|
5106
|
-
const [error, setError] = (0,
|
|
5107
|
-
const [layerId, setLayerId] = (0,
|
|
5108
|
-
const [newKind, setNewKind] = (0,
|
|
5232
|
+
const [params, setParams] = (0, import_react43.useState)(DEFAULT_PARAMS);
|
|
5233
|
+
const [busy, setBusy] = (0, import_react43.useState)(false);
|
|
5234
|
+
const [error, setError] = (0, import_react43.useState)(null);
|
|
5235
|
+
const [layerId, setLayerId] = (0, import_react43.useState)("");
|
|
5236
|
+
const [newKind, setNewKind] = (0, import_react43.useState)("hueSaturation");
|
|
5109
5237
|
const sel = selection === void 0 ? controller.getSelection() : selection;
|
|
5110
5238
|
const list = layers ?? controller.getAdjustmentLayers();
|
|
5111
5239
|
const target = list.find((l) => l.id === layerId) ?? list[list.length - 1];
|
|
@@ -5120,17 +5248,17 @@ var RefineEdgePanel = ({ controller, selection, layers, className = "" }) => {
|
|
|
5120
5248
|
setBusy(false);
|
|
5121
5249
|
}
|
|
5122
5250
|
};
|
|
5123
|
-
return /* @__PURE__ */ (0,
|
|
5124
|
-
/* @__PURE__ */ (0,
|
|
5125
|
-
|
|
5126
|
-
/* @__PURE__ */ (0,
|
|
5127
|
-
/* @__PURE__ */ (0,
|
|
5128
|
-
/* @__PURE__ */ (0,
|
|
5251
|
+
return /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { "data-testid": "refine-edge-panel", className: `flex flex-col gap-3 text-xs ${className}`, children: [
|
|
5252
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Refine Edge" }),
|
|
5253
|
+
import_image_editor11.REFINE_EDGE_CONTROLS.map((c) => /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("label", { className: "flex flex-col gap-1", children: [
|
|
5254
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("span", { className: "flex justify-between text-slate-400", children: [
|
|
5255
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { children: c.label }),
|
|
5256
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("span", { className: "font-mono", children: [
|
|
5129
5257
|
params[c.id],
|
|
5130
5258
|
c.unit
|
|
5131
5259
|
] })
|
|
5132
5260
|
] }),
|
|
5133
|
-
/* @__PURE__ */ (0,
|
|
5261
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
5134
5262
|
"input",
|
|
5135
5263
|
{
|
|
5136
5264
|
type: "range",
|
|
@@ -5144,67 +5272,67 @@ var RefineEdgePanel = ({ controller, selection, layers, className = "" }) => {
|
|
|
5144
5272
|
}
|
|
5145
5273
|
)
|
|
5146
5274
|
] }, c.id)),
|
|
5147
|
-
/* @__PURE__ */ (0,
|
|
5148
|
-
/* @__PURE__ */ (0,
|
|
5275
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("label", { className: "flex items-center gap-2 text-slate-300", children: [
|
|
5276
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("input", { type: "checkbox", checked: params.smartRadius, onChange: (e) => setParams({ ...params, smartRadius: e.target.checked }) }),
|
|
5149
5277
|
"Smart Radius"
|
|
5150
5278
|
] }),
|
|
5151
|
-
/* @__PURE__ */ (0,
|
|
5152
|
-
/* @__PURE__ */ (0,
|
|
5153
|
-
/* @__PURE__ */ (0,
|
|
5279
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "flex gap-1", children: [
|
|
5280
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("button", { type: "button", className: button2, disabled: !sel || busy, onClick: refine, children: "Refine Edge" }),
|
|
5281
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("button", { type: "button", className: button2, onClick: () => setParams(DEFAULT_PARAMS), children: "Reset" })
|
|
5154
5282
|
] }),
|
|
5155
|
-
error && /* @__PURE__ */ (0,
|
|
5156
|
-
/* @__PURE__ */ (0,
|
|
5157
|
-
/* @__PURE__ */ (0,
|
|
5158
|
-
/* @__PURE__ */ (0,
|
|
5283
|
+
error && /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("p", { role: "alert", className: "text-rose-400", children: error }),
|
|
5284
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px] mt-2", children: "Layer Mask" }),
|
|
5285
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "flex gap-1 items-center", children: [
|
|
5286
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
5159
5287
|
"select",
|
|
5160
5288
|
{
|
|
5161
5289
|
"aria-label": "New masked layer kind",
|
|
5162
5290
|
value: newKind,
|
|
5163
5291
|
onChange: (e) => setNewKind(e.target.value),
|
|
5164
5292
|
className: "flex-1 bg-slate-950 border border-slate-800 rounded px-1 py-1 text-slate-200",
|
|
5165
|
-
children:
|
|
5293
|
+
children: import_image_editor11.ADJUSTMENT_KINDS.map((k) => /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("option", { value: k.kind, children: k.label }, k.kind))
|
|
5166
5294
|
}
|
|
5167
5295
|
),
|
|
5168
|
-
/* @__PURE__ */ (0,
|
|
5296
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
5169
5297
|
"button",
|
|
5170
5298
|
{
|
|
5171
5299
|
type: "button",
|
|
5172
5300
|
className: button2,
|
|
5173
5301
|
disabled: !sel,
|
|
5174
|
-
onClick: () => sel && setLayerId(controller.addAdjustmentLayer({ kind: newKind, mask: (0,
|
|
5302
|
+
onClick: () => sel && setLayerId(controller.addAdjustmentLayer({ kind: newKind, mask: (0, import_image_editor11.layerMaskFromSelection)(sel) })),
|
|
5175
5303
|
children: "New Masked Layer"
|
|
5176
5304
|
}
|
|
5177
5305
|
)
|
|
5178
5306
|
] }),
|
|
5179
|
-
list.length > 0 && target && /* @__PURE__ */ (0,
|
|
5180
|
-
/* @__PURE__ */ (0,
|
|
5307
|
+
list.length > 0 && target && /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "flex flex-col gap-2", children: [
|
|
5308
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
5181
5309
|
"select",
|
|
5182
5310
|
{
|
|
5183
5311
|
"aria-label": "Mask layer",
|
|
5184
5312
|
value: target.id,
|
|
5185
5313
|
onChange: (e) => setLayerId(e.target.value),
|
|
5186
5314
|
className: "bg-slate-950 border border-slate-800 rounded px-1 py-1 text-slate-200",
|
|
5187
|
-
children: list.map((l) => /* @__PURE__ */ (0,
|
|
5188
|
-
l.name || (0,
|
|
5315
|
+
children: list.map((l) => /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("option", { value: l.id, children: [
|
|
5316
|
+
l.name || (0, import_image_editor11.adjustmentKindLabel)(l.kind),
|
|
5189
5317
|
l.mask ? " (masked)" : ""
|
|
5190
5318
|
] }, l.id))
|
|
5191
5319
|
}
|
|
5192
5320
|
),
|
|
5193
|
-
/* @__PURE__ */ (0,
|
|
5194
|
-
/* @__PURE__ */ (0,
|
|
5195
|
-
/* @__PURE__ */ (0,
|
|
5196
|
-
/* @__PURE__ */ (0,
|
|
5321
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "flex flex-wrap gap-1", children: [
|
|
5322
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("button", { type: "button", className: button2, disabled: !sel, onClick: () => controller.applySelectionAsLayerMask(target.id), children: "Mask with Selection" }),
|
|
5323
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("button", { type: "button", className: button2, disabled: !target.mask, onClick: () => controller.selectionFromLayerMask(target.id), children: "Load as Selection" }),
|
|
5324
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("button", { type: "button", className: button2, disabled: !target.mask, onClick: () => controller.setAdjustmentLayerMask(target.id, null), children: "Remove Mask" })
|
|
5197
5325
|
] }),
|
|
5198
|
-
target.mask && /* @__PURE__ */ (0,
|
|
5199
|
-
/* @__PURE__ */ (0,
|
|
5200
|
-
/* @__PURE__ */ (0,
|
|
5201
|
-
/* @__PURE__ */ (0,
|
|
5202
|
-
/* @__PURE__ */ (0,
|
|
5326
|
+
target.mask && /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(import_jsx_runtime26.Fragment, { children: [
|
|
5327
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("label", { className: "flex flex-col gap-1", children: [
|
|
5328
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("span", { className: "flex justify-between text-slate-400", children: [
|
|
5329
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { children: "Density" }),
|
|
5330
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("span", { className: "font-mono", children: [
|
|
5203
5331
|
Math.round((target.mask.density ?? 1) * 100),
|
|
5204
5332
|
"%"
|
|
5205
5333
|
] })
|
|
5206
5334
|
] }),
|
|
5207
|
-
/* @__PURE__ */ (0,
|
|
5335
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
5208
5336
|
"input",
|
|
5209
5337
|
{
|
|
5210
5338
|
type: "range",
|
|
@@ -5218,15 +5346,15 @@ var RefineEdgePanel = ({ controller, selection, layers, className = "" }) => {
|
|
|
5218
5346
|
}
|
|
5219
5347
|
)
|
|
5220
5348
|
] }),
|
|
5221
|
-
/* @__PURE__ */ (0,
|
|
5222
|
-
/* @__PURE__ */ (0,
|
|
5223
|
-
/* @__PURE__ */ (0,
|
|
5224
|
-
/* @__PURE__ */ (0,
|
|
5349
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("label", { className: "flex flex-col gap-1", children: [
|
|
5350
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("span", { className: "flex justify-between text-slate-400", children: [
|
|
5351
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { children: "Mask Feather" }),
|
|
5352
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("span", { className: "font-mono", children: [
|
|
5225
5353
|
target.mask.feather ?? 0,
|
|
5226
5354
|
"px"
|
|
5227
5355
|
] })
|
|
5228
5356
|
] }),
|
|
5229
|
-
/* @__PURE__ */ (0,
|
|
5357
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
5230
5358
|
"input",
|
|
5231
5359
|
{
|
|
5232
5360
|
type: "range",
|
|
@@ -5246,14 +5374,14 @@ var RefineEdgePanel = ({ controller, selection, layers, className = "" }) => {
|
|
|
5246
5374
|
};
|
|
5247
5375
|
|
|
5248
5376
|
// src/image-editor/FreeTransformOptionsBar.tsx
|
|
5249
|
-
var
|
|
5250
|
-
var
|
|
5251
|
-
var
|
|
5252
|
-
var
|
|
5377
|
+
var import_react44 = require("react");
|
|
5378
|
+
var import_image_editor12 = require("@pixerate/editor/image-editor");
|
|
5379
|
+
var import_jsx_runtime27 = require("react/jsx-runtime");
|
|
5380
|
+
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"}`;
|
|
5253
5381
|
var round = (v, unit) => unit === "px" ? Math.round(v * 10) / 10 : Math.round(v * 100) / 100;
|
|
5254
5382
|
var FreeTransformOptionsBar = ({ tool, className }) => {
|
|
5255
|
-
const [, setTick] = (0,
|
|
5256
|
-
(0,
|
|
5383
|
+
const [, setTick] = (0, import_react44.useState)(0);
|
|
5384
|
+
(0, import_react44.useEffect)(() => tool.subscribe(() => setTick((n) => n + 1)), [tool]);
|
|
5257
5385
|
const bar = tool.bar();
|
|
5258
5386
|
if (!tool.active || !bar) return null;
|
|
5259
5387
|
const warp = tool.warpBar();
|
|
@@ -5265,17 +5393,17 @@ var FreeTransformOptionsBar = ({ tool, className }) => {
|
|
|
5265
5393
|
const v = Number(raw);
|
|
5266
5394
|
if (raw.trim() !== "" && Number.isFinite(v) && Math.abs(v - bar[field]) > 1e-9) tool.setField(field, v);
|
|
5267
5395
|
};
|
|
5268
|
-
return /* @__PURE__ */ (0,
|
|
5269
|
-
/* @__PURE__ */ (0,
|
|
5270
|
-
/* @__PURE__ */ (0,
|
|
5271
|
-
tool.mode === "warp" && /* @__PURE__ */ (0,
|
|
5272
|
-
/* @__PURE__ */ (0,
|
|
5273
|
-
/* @__PURE__ */ (0,
|
|
5274
|
-
/* @__PURE__ */ (0,
|
|
5396
|
+
return /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: `flex flex-wrap items-center gap-2 text-xs text-slate-200 ${className ?? ""}`, "data-testid": "free-transform-options", role: "toolbar", "aria-label": "Free Transform options", children: [
|
|
5397
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: "flex gap-1", role: "group", "aria-label": "Transform mode", children: import_image_editor12.FREE_TRANSFORM_MODE_OPTIONS.map((m) => /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("button", { type: "button", title: m.title, "aria-pressed": tool.mode === m.id, className: chip3(tool.mode === m.id), onClick: () => tool.setMode(m.id), children: m.label }, m.id)) }),
|
|
5398
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: "grid grid-cols-3 gap-px", role: "group", "aria-label": "Reference point", children: import_image_editor12.TRANSFORM_ANCHORS.map((a) => /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("button", { type: "button", "aria-label": `Reference point ${a}`, title: `Reference point: ${a}`, className: "h-2.5 w-2.5 rounded-sm bg-slate-700 hover:bg-indigo-500", onClick: () => tool.setReference(a) }, a)) }),
|
|
5399
|
+
tool.mode === "warp" && /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "flex flex-wrap items-center gap-2", role: "group", "aria-label": "Warp options", children: [
|
|
5400
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("label", { className: "flex items-center gap-1", children: [
|
|
5401
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: "text-slate-400", children: "Warp" }),
|
|
5402
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("select", { "aria-label": "Warp style", value: warp.style, onChange: (e) => tool.setWarp({ style: e.target.value }), className: "rounded border border-slate-700 bg-slate-900 px-1 py-0.5", children: import_image_editor12.WARP_STYLE_OPTIONS.map((o) => /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("option", { value: o.id, children: o.label }, o.id)) })
|
|
5275
5403
|
] }),
|
|
5276
|
-
["bend", "horizontal", "vertical"].map((k) => /* @__PURE__ */ (0,
|
|
5277
|
-
/* @__PURE__ */ (0,
|
|
5278
|
-
/* @__PURE__ */ (0,
|
|
5404
|
+
["bend", "horizontal", "vertical"].map((k) => /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("label", { className: "flex items-center gap-1", children: [
|
|
5405
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: "text-slate-400", children: k === "bend" ? "Bend" : k === "horizontal" ? "H" : "V" }),
|
|
5406
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
5279
5407
|
"input",
|
|
5280
5408
|
{
|
|
5281
5409
|
type: "number",
|
|
@@ -5296,40 +5424,40 @@ var FreeTransformOptionsBar = ({ tool, className }) => {
|
|
|
5296
5424
|
},
|
|
5297
5425
|
`${k}:${warp[k]}`
|
|
5298
5426
|
),
|
|
5299
|
-
/* @__PURE__ */ (0,
|
|
5427
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: "text-slate-500", children: "%" })
|
|
5300
5428
|
] }, k)),
|
|
5301
|
-
/* @__PURE__ */ (0,
|
|
5429
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
5302
5430
|
"button",
|
|
5303
5431
|
{
|
|
5304
5432
|
type: "button",
|
|
5305
5433
|
title: "Bend along the vertical axis",
|
|
5306
5434
|
"aria-pressed": warp.orientation === "vertical",
|
|
5307
5435
|
disabled: warp.style === "custom",
|
|
5308
|
-
className:
|
|
5436
|
+
className: chip3(warp.orientation === "vertical"),
|
|
5309
5437
|
onClick: () => tool.setWarp({ orientation: warp.orientation === "vertical" ? "horizontal" : "vertical" }),
|
|
5310
5438
|
children: "Vertical"
|
|
5311
5439
|
}
|
|
5312
5440
|
),
|
|
5313
|
-
/* @__PURE__ */ (0,
|
|
5314
|
-
/* @__PURE__ */ (0,
|
|
5315
|
-
/* @__PURE__ */ (0,
|
|
5441
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("label", { className: "flex items-center gap-1", children: [
|
|
5442
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: "text-slate-400", children: "Grid" }),
|
|
5443
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
5316
5444
|
"select",
|
|
5317
5445
|
{
|
|
5318
5446
|
"aria-label": "Warp grid",
|
|
5319
|
-
value:
|
|
5447
|
+
value: import_image_editor12.WARP_GRID_OPTIONS.find((g) => g.columns === warp.columns && g.rows === warp.rows)?.id ?? "1x1",
|
|
5320
5448
|
onChange: (e) => {
|
|
5321
|
-
const g =
|
|
5449
|
+
const g = import_image_editor12.WARP_GRID_OPTIONS.find((o) => o.id === e.target.value);
|
|
5322
5450
|
tool.setWarp({ columns: g.columns, rows: g.rows });
|
|
5323
5451
|
},
|
|
5324
5452
|
className: "rounded border border-slate-700 bg-slate-900 px-1 py-0.5",
|
|
5325
|
-
children:
|
|
5453
|
+
children: import_image_editor12.WARP_GRID_OPTIONS.map((g) => /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("option", { value: g.id, children: g.label }, g.id))
|
|
5326
5454
|
}
|
|
5327
5455
|
)
|
|
5328
5456
|
] })
|
|
5329
5457
|
] }),
|
|
5330
|
-
tool.mode !== "warp" &&
|
|
5331
|
-
/* @__PURE__ */ (0,
|
|
5332
|
-
/* @__PURE__ */ (0,
|
|
5458
|
+
tool.mode !== "warp" && import_image_editor12.FREE_TRANSFORM_FIELDS.map((f) => /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("label", { className: "flex items-center gap-1", title: f.title, children: [
|
|
5459
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: "text-slate-400", children: f.label }),
|
|
5460
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
5333
5461
|
"input",
|
|
5334
5462
|
{
|
|
5335
5463
|
type: "number",
|
|
@@ -5349,14 +5477,14 @@ var FreeTransformOptionsBar = ({ tool, className }) => {
|
|
|
5349
5477
|
},
|
|
5350
5478
|
`${f.id}:${round(bar[f.id], f.unit)}`
|
|
5351
5479
|
),
|
|
5352
|
-
/* @__PURE__ */ (0,
|
|
5353
|
-
f.id === "scaleX" && /* @__PURE__ */ (0,
|
|
5480
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: "text-slate-500", children: f.unit }),
|
|
5481
|
+
f.id === "scaleX" && /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
5354
5482
|
"button",
|
|
5355
5483
|
{
|
|
5356
5484
|
type: "button",
|
|
5357
5485
|
"aria-label": "Keep width and height proportional",
|
|
5358
5486
|
"aria-pressed": tool.proportional,
|
|
5359
|
-
className:
|
|
5487
|
+
className: chip3(tool.proportional),
|
|
5360
5488
|
onClick: () => {
|
|
5361
5489
|
tool.proportional = !tool.proportional;
|
|
5362
5490
|
setTick((n) => n + 1);
|
|
@@ -5365,34 +5493,34 @@ var FreeTransformOptionsBar = ({ tool, className }) => {
|
|
|
5365
5493
|
}
|
|
5366
5494
|
)
|
|
5367
5495
|
] }, f.id)),
|
|
5368
|
-
/* @__PURE__ */ (0,
|
|
5369
|
-
/* @__PURE__ */ (0,
|
|
5370
|
-
/* @__PURE__ */ (0,
|
|
5496
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("label", { className: "flex items-center gap-1", children: [
|
|
5497
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: "text-slate-400", children: "Interpolation" }),
|
|
5498
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
5371
5499
|
"select",
|
|
5372
5500
|
{
|
|
5373
5501
|
"aria-label": "Interpolation",
|
|
5374
5502
|
value: tool.interpolation,
|
|
5375
5503
|
onChange: (e) => tool.setInterpolation(e.target.value),
|
|
5376
5504
|
className: "rounded border border-slate-700 bg-slate-900 px-1 py-0.5",
|
|
5377
|
-
children:
|
|
5505
|
+
children: import_image_editor12.INTERPOLATIONS.map((i) => /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("option", { value: i, children: i[0].toUpperCase() + i.slice(1) }, i))
|
|
5378
5506
|
}
|
|
5379
5507
|
)
|
|
5380
5508
|
] }),
|
|
5381
|
-
/* @__PURE__ */ (0,
|
|
5382
|
-
/* @__PURE__ */ (0,
|
|
5383
|
-
tool.error && /* @__PURE__ */ (0,
|
|
5509
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("button", { type: "button", title: "Commit (Enter)", className: "px-2 py-1 rounded bg-emerald-600 text-white hover:bg-emerald-500", onClick: () => tool.commit(), children: "Commit" }),
|
|
5510
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("button", { type: "button", title: "Cancel (Esc)", className: chip3(false), onClick: () => tool.cancel(), children: "Cancel" }),
|
|
5511
|
+
tool.error && /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { role: "alert", className: "text-rose-400", children: tool.error })
|
|
5384
5512
|
] });
|
|
5385
5513
|
};
|
|
5386
5514
|
|
|
5387
5515
|
// src/image-editor/ShapeOptionsBar.tsx
|
|
5388
|
-
var
|
|
5389
|
-
var
|
|
5390
|
-
var
|
|
5391
|
-
var
|
|
5516
|
+
var import_react45 = require("react");
|
|
5517
|
+
var import_image_editor13 = require("@pixerate/editor/image-editor");
|
|
5518
|
+
var import_jsx_runtime28 = require("react/jsx-runtime");
|
|
5519
|
+
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"}`;
|
|
5392
5520
|
var ShapeOptionsBar = ({ controller, options, onChange, className }) => {
|
|
5393
|
-
const [, setTick] = (0,
|
|
5394
|
-
(0,
|
|
5395
|
-
const [error, setError] = (0,
|
|
5521
|
+
const [, setTick] = (0, import_react45.useState)(0);
|
|
5522
|
+
(0, import_react45.useEffect)(() => controller.subscribe(() => setTick((n) => n + 1)), [controller]);
|
|
5523
|
+
const [error, setError] = (0, import_react45.useState)(null);
|
|
5396
5524
|
const active = controller.getActiveLayer();
|
|
5397
5525
|
const shapeId = active?.type === "shape" ? active.id : null;
|
|
5398
5526
|
const set = (change) => {
|
|
@@ -5400,19 +5528,19 @@ var ShapeOptionsBar = ({ controller, options, onChange, className }) => {
|
|
|
5400
5528
|
if (!shapeId) return;
|
|
5401
5529
|
try {
|
|
5402
5530
|
setError(null);
|
|
5403
|
-
(0,
|
|
5531
|
+
(0, import_image_editor13.applyShapeOptions)(controller, shapeId, change);
|
|
5404
5532
|
} catch (e) {
|
|
5405
5533
|
setError(e instanceof Error ? e.message : String(e));
|
|
5406
5534
|
}
|
|
5407
5535
|
};
|
|
5408
5536
|
const num = (v, min, max) => Math.max(min, Math.min(max, Number(v) || min));
|
|
5409
|
-
return /* @__PURE__ */ (0,
|
|
5410
|
-
/* @__PURE__ */ (0,
|
|
5411
|
-
/* @__PURE__ */ (0,
|
|
5412
|
-
/* @__PURE__ */ (0,
|
|
5413
|
-
/* @__PURE__ */ (0,
|
|
5537
|
+
return /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: `flex flex-col gap-2 text-xs text-slate-200 ${className ?? ""}`, "data-testid": "shape-options", children: [
|
|
5538
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { className: "flex flex-wrap gap-1", role: "toolbar", "aria-label": "Shape kind", children: import_image_editor13.LIVE_SHAPE_KINDS.map((k) => /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("button", { type: "button", "aria-pressed": options.kind === k, className: chip4(options.kind === k), onClick: () => onChange({ ...options, kind: k }), children: import_image_editor13.SHAPE_KIND_LABELS[k] }, k)) }),
|
|
5539
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: "flex flex-wrap items-center gap-3", children: [
|
|
5540
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("label", { className: "flex items-center gap-1", children: [
|
|
5541
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)("input", { type: "checkbox", "aria-label": "Fill", checked: options.fill !== null, onChange: (e) => set({ fill: e.target.checked ? "#4f46e5" : null }) }),
|
|
5414
5542
|
"Fill",
|
|
5415
|
-
/* @__PURE__ */ (0,
|
|
5543
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
5416
5544
|
"input",
|
|
5417
5545
|
{
|
|
5418
5546
|
type: "color",
|
|
@@ -5424,10 +5552,10 @@ var ShapeOptionsBar = ({ controller, options, onChange, className }) => {
|
|
|
5424
5552
|
}
|
|
5425
5553
|
)
|
|
5426
5554
|
] }),
|
|
5427
|
-
/* @__PURE__ */ (0,
|
|
5428
|
-
/* @__PURE__ */ (0,
|
|
5555
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("label", { className: "flex items-center gap-1", children: [
|
|
5556
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)("input", { type: "checkbox", "aria-label": "Stroke", checked: options.stroke !== null, onChange: (e) => set({ stroke: e.target.checked ? "#000000" : null }) }),
|
|
5429
5557
|
"Stroke",
|
|
5430
|
-
/* @__PURE__ */ (0,
|
|
5558
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
5431
5559
|
"input",
|
|
5432
5560
|
{
|
|
5433
5561
|
type: "color",
|
|
@@ -5439,9 +5567,9 @@ var ShapeOptionsBar = ({ controller, options, onChange, className }) => {
|
|
|
5439
5567
|
}
|
|
5440
5568
|
)
|
|
5441
5569
|
] }),
|
|
5442
|
-
/* @__PURE__ */ (0,
|
|
5570
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("label", { className: "flex items-center gap-1", children: [
|
|
5443
5571
|
"Width",
|
|
5444
|
-
/* @__PURE__ */ (0,
|
|
5572
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
5445
5573
|
"input",
|
|
5446
5574
|
{
|
|
5447
5575
|
type: "number",
|
|
@@ -5455,23 +5583,23 @@ var ShapeOptionsBar = ({ controller, options, onChange, className }) => {
|
|
|
5455
5583
|
)
|
|
5456
5584
|
] })
|
|
5457
5585
|
] }),
|
|
5458
|
-
/* @__PURE__ */ (0,
|
|
5459
|
-
options.kind === "rect" && /* @__PURE__ */ (0,
|
|
5586
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: "flex flex-wrap items-center gap-3", children: [
|
|
5587
|
+
options.kind === "rect" && /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("label", { className: "flex items-center gap-1", children: [
|
|
5460
5588
|
"Radius",
|
|
5461
|
-
/* @__PURE__ */ (0,
|
|
5589
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)("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" })
|
|
5462
5590
|
] }),
|
|
5463
|
-
options.kind === "polygon" && /* @__PURE__ */ (0,
|
|
5591
|
+
options.kind === "polygon" && /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("label", { className: "flex items-center gap-1", children: [
|
|
5464
5592
|
"Sides",
|
|
5465
|
-
/* @__PURE__ */ (0,
|
|
5593
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)("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" })
|
|
5466
5594
|
] }),
|
|
5467
|
-
options.kind === "star" && /* @__PURE__ */ (0,
|
|
5468
|
-
/* @__PURE__ */ (0,
|
|
5595
|
+
options.kind === "star" && /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(import_jsx_runtime28.Fragment, { children: [
|
|
5596
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("label", { className: "flex items-center gap-1", children: [
|
|
5469
5597
|
"Points",
|
|
5470
|
-
/* @__PURE__ */ (0,
|
|
5598
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)("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" })
|
|
5471
5599
|
] }),
|
|
5472
|
-
/* @__PURE__ */ (0,
|
|
5600
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("label", { className: "flex items-center gap-1", children: [
|
|
5473
5601
|
"Inner",
|
|
5474
|
-
/* @__PURE__ */ (0,
|
|
5602
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
5475
5603
|
"input",
|
|
5476
5604
|
{
|
|
5477
5605
|
type: "range",
|
|
@@ -5486,33 +5614,33 @@ var ShapeOptionsBar = ({ controller, options, onChange, className }) => {
|
|
|
5486
5614
|
)
|
|
5487
5615
|
] })
|
|
5488
5616
|
] }),
|
|
5489
|
-
options.kind === "line" && /* @__PURE__ */ (0,
|
|
5490
|
-
/* @__PURE__ */ (0,
|
|
5617
|
+
options.kind === "line" && /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(import_jsx_runtime28.Fragment, { children: [
|
|
5618
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("label", { className: "flex items-center gap-1", children: [
|
|
5491
5619
|
"Weight",
|
|
5492
|
-
/* @__PURE__ */ (0,
|
|
5620
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)("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" })
|
|
5493
5621
|
] }),
|
|
5494
|
-
/* @__PURE__ */ (0,
|
|
5495
|
-
/* @__PURE__ */ (0,
|
|
5622
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("label", { className: "flex items-center gap-1", children: [
|
|
5623
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)("input", { type: "checkbox", "aria-label": "Arrowhead", checked: options.arrow, onChange: (e) => set({ arrow: e.target.checked }) }),
|
|
5496
5624
|
"Arrowhead"
|
|
5497
5625
|
] })
|
|
5498
5626
|
] })
|
|
5499
5627
|
] }),
|
|
5500
|
-
/* @__PURE__ */ (0,
|
|
5501
|
-
error && /* @__PURE__ */ (0,
|
|
5628
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)("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." }),
|
|
5629
|
+
error && /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("p", { role: "alert", className: "text-rose-400", children: error })
|
|
5502
5630
|
] });
|
|
5503
5631
|
};
|
|
5504
5632
|
|
|
5505
5633
|
// src/image-editor/TypeOptionsBar.tsx
|
|
5506
|
-
var
|
|
5507
|
-
var
|
|
5508
|
-
var
|
|
5509
|
-
var
|
|
5634
|
+
var import_react46 = require("react");
|
|
5635
|
+
var import_image_editor14 = require("@pixerate/editor/image-editor");
|
|
5636
|
+
var import_jsx_runtime29 = require("react/jsx-runtime");
|
|
5637
|
+
var chip5 = (on) => `px-2 py-1 rounded text-[11px] ${on ? "bg-indigo-600 text-white" : "bg-slate-800 text-slate-300 hover:text-white"}`;
|
|
5510
5638
|
var ALIGN_LABELS = { left: "Left", center: "Centre", right: "Right", justify: "Justify" };
|
|
5511
5639
|
var TypeOptionsBar = ({ controller, options, onChange, session, className }) => {
|
|
5512
|
-
const [, setTick] = (0,
|
|
5513
|
-
(0,
|
|
5514
|
-
(0,
|
|
5515
|
-
const [error, setError] = (0,
|
|
5640
|
+
const [, setTick] = (0, import_react46.useState)(0);
|
|
5641
|
+
(0, import_react46.useEffect)(() => controller.subscribe(() => setTick((n) => n + 1)), [controller]);
|
|
5642
|
+
(0, import_react46.useEffect)(() => session?.subscribe(() => setTick((n) => n + 1)), [session]);
|
|
5643
|
+
const [error, setError] = (0, import_react46.useState)(null);
|
|
5516
5644
|
const active = controller.getActiveLayer();
|
|
5517
5645
|
const typeId = !session && active?.type === "type" ? active.id : null;
|
|
5518
5646
|
const here = session?.alive ? session.styleHere() : {};
|
|
@@ -5544,11 +5672,11 @@ var TypeOptionsBar = ({ controller, options, onChange, session, className }) =>
|
|
|
5544
5672
|
setError(e instanceof Error ? e.message : String(e));
|
|
5545
5673
|
}
|
|
5546
5674
|
};
|
|
5547
|
-
return /* @__PURE__ */ (0,
|
|
5548
|
-
/* @__PURE__ */ (0,
|
|
5549
|
-
/* @__PURE__ */ (0,
|
|
5675
|
+
return /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: `flex flex-col gap-2 text-xs text-slate-200 ${className ?? ""}`, "data-testid": "type-options", children: [
|
|
5676
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "flex flex-wrap items-center gap-2", children: [
|
|
5677
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("label", { className: "flex items-center gap-1", children: [
|
|
5550
5678
|
"Font",
|
|
5551
|
-
/* @__PURE__ */ (0,
|
|
5679
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
5552
5680
|
"input",
|
|
5553
5681
|
{
|
|
5554
5682
|
list: "pixerate-type-fonts",
|
|
@@ -5558,11 +5686,11 @@ var TypeOptionsBar = ({ controller, options, onChange, session, className }) =>
|
|
|
5558
5686
|
className: "w-32 rounded border border-slate-700 bg-slate-950 px-1 py-0.5"
|
|
5559
5687
|
}
|
|
5560
5688
|
),
|
|
5561
|
-
/* @__PURE__ */ (0,
|
|
5689
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)("datalist", { id: "pixerate-type-fonts", children: fonts.map((f) => /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("option", { value: f }, f)) })
|
|
5562
5690
|
] }),
|
|
5563
|
-
/* @__PURE__ */ (0,
|
|
5691
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("label", { className: "flex items-center gap-1", children: [
|
|
5564
5692
|
"Size",
|
|
5565
|
-
/* @__PURE__ */ (0,
|
|
5693
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
5566
5694
|
"input",
|
|
5567
5695
|
{
|
|
5568
5696
|
type: "number",
|
|
@@ -5575,24 +5703,24 @@ var TypeOptionsBar = ({ controller, options, onChange, session, className }) =>
|
|
|
5575
5703
|
}
|
|
5576
5704
|
)
|
|
5577
5705
|
] }),
|
|
5578
|
-
/* @__PURE__ */ (0,
|
|
5579
|
-
/* @__PURE__ */ (0,
|
|
5580
|
-
/* @__PURE__ */ (0,
|
|
5706
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)("button", { type: "button", "aria-pressed": shown.fontWeight >= 600, className: `${chip5(shown.fontWeight >= 600)} font-bold`, onClick: () => style({ fontWeight: shown.fontWeight >= 600 ? 400 : 700 }), children: "B" }),
|
|
5707
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)("button", { type: "button", "aria-pressed": shown.italic, className: `${chip5(shown.italic)} italic`, onClick: () => style({ italic: !shown.italic }), children: "I" }),
|
|
5708
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)("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" })
|
|
5581
5709
|
] }),
|
|
5582
|
-
/* @__PURE__ */ (0,
|
|
5583
|
-
/* @__PURE__ */ (0,
|
|
5584
|
-
missing.length > 0 && /* @__PURE__ */ (0,
|
|
5710
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: "flex gap-1", role: "toolbar", "aria-label": "Alignment", children: import_image_editor14.TEXT_ALIGNS.map((a) => /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("button", { type: "button", "aria-pressed": options.align === a, className: chip5(options.align === a), onClick: () => style({ align: a }), children: ALIGN_LABELS[a] }, a)) }),
|
|
5711
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)("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." }),
|
|
5712
|
+
missing.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("p", { role: "status", className: "text-amber-400", "data-testid": "type-missing-fonts", children: [
|
|
5585
5713
|
"Missing ",
|
|
5586
5714
|
missing.length === 1 ? "font" : "fonts",
|
|
5587
5715
|
": ",
|
|
5588
5716
|
missing.join(", ")
|
|
5589
5717
|
] }),
|
|
5590
|
-
error && /* @__PURE__ */ (0,
|
|
5718
|
+
error && /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("p", { role: "alert", className: "text-rose-400", children: error })
|
|
5591
5719
|
] });
|
|
5592
5720
|
};
|
|
5593
5721
|
|
|
5594
5722
|
// src/image-editor/ImageEditor.tsx
|
|
5595
|
-
var
|
|
5723
|
+
var import_jsx_runtime30 = require("react/jsx-runtime");
|
|
5596
5724
|
var ImageEditor = ({
|
|
5597
5725
|
editor: externalEditor,
|
|
5598
5726
|
src,
|
|
@@ -5607,65 +5735,65 @@ var ImageEditor = ({
|
|
|
5607
5735
|
const internalEditor = useImageEditor({ image: src });
|
|
5608
5736
|
const editor = externalEditor || internalEditor;
|
|
5609
5737
|
const { state, controller } = editor;
|
|
5610
|
-
const legacyProcess = (0,
|
|
5611
|
-
const canvasRef = (0,
|
|
5612
|
-
const containerRef = (0,
|
|
5613
|
-
const [activeTab, setActiveTab] = (0,
|
|
5614
|
-
const [activeCropRatio, setActiveCropRatio] = (0,
|
|
5615
|
-
const [selectionOptions, setSelectionOptions] = (0,
|
|
5616
|
-
const selectionOptionsRef = (0,
|
|
5738
|
+
const legacyProcess = (0, import_image_editor15.normalizeProcessVersion)(state.adjustments.process) < import_image_editor15.LATEST_PROCESS_VERSION;
|
|
5739
|
+
const canvasRef = (0, import_react47.useRef)(null);
|
|
5740
|
+
const containerRef = (0, import_react47.useRef)(null);
|
|
5741
|
+
const [activeTab, setActiveTab] = (0, import_react47.useState)("crop");
|
|
5742
|
+
const [activeCropRatio, setActiveCropRatio] = (0, import_react47.useState)(null);
|
|
5743
|
+
const [selectionOptions, setSelectionOptions] = (0, import_react47.useState)(import_image_editor15.DEFAULT_SELECTION_TOOL_OPTIONS);
|
|
5744
|
+
const selectionOptionsRef = (0, import_react47.useRef)(selectionOptions);
|
|
5617
5745
|
selectionOptionsRef.current = selectionOptions;
|
|
5618
|
-
const selectionGestureRef = (0,
|
|
5746
|
+
const selectionGestureRef = (0, import_react47.useRef)(null);
|
|
5619
5747
|
if (!selectionGestureRef.current || selectionGestureRef.current.controller !== controller) {
|
|
5620
|
-
selectionGestureRef.current = new
|
|
5748
|
+
selectionGestureRef.current = new import_image_editor15.SelectionGesture(controller, () => selectionOptionsRef.current);
|
|
5621
5749
|
}
|
|
5622
|
-
const selectionDraftRef = (0,
|
|
5623
|
-
const [selectionError, setSelectionError] = (0,
|
|
5624
|
-
const paintGestureRef = (0,
|
|
5625
|
-
const paintControllerRef = (0,
|
|
5750
|
+
const selectionDraftRef = (0, import_react47.useRef)(null);
|
|
5751
|
+
const [selectionError, setSelectionError] = (0, import_react47.useState)(null);
|
|
5752
|
+
const paintGestureRef = (0, import_react47.useRef)(null);
|
|
5753
|
+
const paintControllerRef = (0, import_react47.useRef)(controller);
|
|
5626
5754
|
if (!paintGestureRef.current || paintControllerRef.current !== controller) {
|
|
5627
|
-
paintGestureRef.current = new
|
|
5755
|
+
paintGestureRef.current = new import_image_editor15.PaintGesture(controller);
|
|
5628
5756
|
paintControllerRef.current = controller;
|
|
5629
5757
|
}
|
|
5630
|
-
const brushCursorRef = (0,
|
|
5631
|
-
const [paintError, setPaintError] = (0,
|
|
5632
|
-
const transformToolRef = (0,
|
|
5633
|
-
const transformControllerRef = (0,
|
|
5758
|
+
const brushCursorRef = (0, import_react47.useRef)(null);
|
|
5759
|
+
const [paintError, setPaintError] = (0, import_react47.useState)(null);
|
|
5760
|
+
const transformToolRef = (0, import_react47.useRef)(null);
|
|
5761
|
+
const transformControllerRef = (0, import_react47.useRef)(controller);
|
|
5634
5762
|
if (!transformToolRef.current || transformControllerRef.current !== controller) {
|
|
5635
5763
|
transformToolRef.current?.cancel();
|
|
5636
|
-
transformToolRef.current = new
|
|
5764
|
+
transformToolRef.current = new import_image_editor15.FreeTransformTool(controller, {
|
|
5637
5765
|
schedule: (run) => typeof requestAnimationFrame !== "undefined" ? requestAnimationFrame(run) : run()
|
|
5638
5766
|
});
|
|
5639
5767
|
transformControllerRef.current = controller;
|
|
5640
5768
|
}
|
|
5641
5769
|
const transformTool = transformToolRef.current;
|
|
5642
|
-
const [, setTransformTick] = (0,
|
|
5643
|
-
const [transformCursor, setTransformCursor] = (0,
|
|
5644
|
-
const [shapeOptions, setShapeOptions] = (0,
|
|
5645
|
-
const shapeOptionsRef = (0,
|
|
5770
|
+
const [, setTransformTick] = (0, import_react47.useState)(0);
|
|
5771
|
+
const [transformCursor, setTransformCursor] = (0, import_react47.useState)("default");
|
|
5772
|
+
const [shapeOptions, setShapeOptions] = (0, import_react47.useState)(import_image_editor15.DEFAULT_SHAPE_TOOL_OPTIONS);
|
|
5773
|
+
const shapeOptionsRef = (0, import_react47.useRef)(shapeOptions);
|
|
5646
5774
|
shapeOptionsRef.current = shapeOptions;
|
|
5647
|
-
const [typeOptions, setTypeOptions] = (0,
|
|
5648
|
-
const typeOptionsRef = (0,
|
|
5775
|
+
const [typeOptions, setTypeOptions] = (0, import_react47.useState)(import_image_editor15.DEFAULT_TYPE_TOOL_OPTIONS);
|
|
5776
|
+
const typeOptionsRef = (0, import_react47.useRef)(typeOptions);
|
|
5649
5777
|
typeOptionsRef.current = typeOptions;
|
|
5650
|
-
const shapeGestureRef = (0,
|
|
5651
|
-
const typeToolRef = (0,
|
|
5652
|
-
const shapeTypeControllerRef = (0,
|
|
5778
|
+
const shapeGestureRef = (0, import_react47.useRef)(null);
|
|
5779
|
+
const typeToolRef = (0, import_react47.useRef)(null);
|
|
5780
|
+
const shapeTypeControllerRef = (0, import_react47.useRef)(controller);
|
|
5653
5781
|
if (!shapeGestureRef.current || !typeToolRef.current || shapeTypeControllerRef.current !== controller) {
|
|
5654
5782
|
typeToolRef.current?.finish();
|
|
5655
|
-
shapeGestureRef.current = new
|
|
5656
|
-
typeToolRef.current = new
|
|
5783
|
+
shapeGestureRef.current = new import_image_editor15.ShapeDrawGesture(controller, () => shapeOptionsRef.current);
|
|
5784
|
+
typeToolRef.current = new import_image_editor15.TypeToolGesture(controller, () => typeOptionsRef.current);
|
|
5657
5785
|
shapeTypeControllerRef.current = controller;
|
|
5658
5786
|
}
|
|
5659
|
-
const typeInputRef = (0,
|
|
5660
|
-
const [typeSession, setTypeSession] = (0,
|
|
5661
|
-
const [shapeTypeError, setShapeTypeError] = (0,
|
|
5662
|
-
const [inpaintPrompt, setInpaintPrompt] = (0,
|
|
5663
|
-
const [inpaintMaskMode, setInpaintMaskMode] = (0,
|
|
5664
|
-
const [isRemovingBg, setIsRemovingBg] = (0,
|
|
5665
|
-
const [isInpainting, setIsInpainting] = (0,
|
|
5666
|
-
const [aiError, setAiError] = (0,
|
|
5667
|
-
const [aiSuccess, setAiSuccess] = (0,
|
|
5668
|
-
const [aiTarget, setAiTarget] = (0,
|
|
5787
|
+
const typeInputRef = (0, import_react47.useRef)(null);
|
|
5788
|
+
const [typeSession, setTypeSession] = (0, import_react47.useState)(typeToolRef.current.session);
|
|
5789
|
+
const [shapeTypeError, setShapeTypeError] = (0, import_react47.useState)(null);
|
|
5790
|
+
const [inpaintPrompt, setInpaintPrompt] = (0, import_react47.useState)("");
|
|
5791
|
+
const [inpaintMaskMode, setInpaintMaskMode] = (0, import_react47.useState)("annotations");
|
|
5792
|
+
const [isRemovingBg, setIsRemovingBg] = (0, import_react47.useState)(false);
|
|
5793
|
+
const [isInpainting, setIsInpainting] = (0, import_react47.useState)(false);
|
|
5794
|
+
const [aiError, setAiError] = (0, import_react47.useState)(null);
|
|
5795
|
+
const [aiSuccess, setAiSuccess] = (0, import_react47.useState)(null);
|
|
5796
|
+
const [aiTarget, setAiTarget] = (0, import_react47.useState)("auto");
|
|
5669
5797
|
const aiOptions = aiTarget === "auto" ? {} : { target: aiTarget };
|
|
5670
5798
|
const effectiveOnInpaint = onInpaint || aiHooks?.onInpaint;
|
|
5671
5799
|
const effectiveOnRemoveBg = onRemoveBackground || aiHooks?.onRemoveBackground;
|
|
@@ -5728,18 +5856,18 @@ var ImageEditor = ({
|
|
|
5728
5856
|
setIsInpainting(false);
|
|
5729
5857
|
}
|
|
5730
5858
|
};
|
|
5731
|
-
const [activeColor, setActiveColor] = (0,
|
|
5732
|
-
const [strokeWidth, setStrokeWidth] = (0,
|
|
5733
|
-
const [fontSize, setFontSize] = (0,
|
|
5734
|
-
const [textInput, setTextInput] = (0,
|
|
5735
|
-
const draftAnnotationRef = (0,
|
|
5736
|
-
const draftCropRef = (0,
|
|
5737
|
-
const cropDragInfoRef = (0,
|
|
5738
|
-
const annotationDragInfoRef = (0,
|
|
5739
|
-
const isDrawingRef = (0,
|
|
5740
|
-
const currentPathRef = (0,
|
|
5741
|
-
const dragStartPointRef = (0,
|
|
5742
|
-
const renderCanvas = (0,
|
|
5859
|
+
const [activeColor, setActiveColor] = (0, import_react47.useState)("#ef4444");
|
|
5860
|
+
const [strokeWidth, setStrokeWidth] = (0, import_react47.useState)(3);
|
|
5861
|
+
const [fontSize, setFontSize] = (0, import_react47.useState)(24);
|
|
5862
|
+
const [textInput, setTextInput] = (0, import_react47.useState)("");
|
|
5863
|
+
const draftAnnotationRef = (0, import_react47.useRef)(null);
|
|
5864
|
+
const draftCropRef = (0, import_react47.useRef)(null);
|
|
5865
|
+
const cropDragInfoRef = (0, import_react47.useRef)(null);
|
|
5866
|
+
const annotationDragInfoRef = (0, import_react47.useRef)(null);
|
|
5867
|
+
const isDrawingRef = (0, import_react47.useRef)(false);
|
|
5868
|
+
const currentPathRef = (0, import_react47.useRef)([]);
|
|
5869
|
+
const dragStartPointRef = (0, import_react47.useRef)(null);
|
|
5870
|
+
const renderCanvas = (0, import_react47.useCallback)(
|
|
5743
5871
|
async (draftAnnotation, draftCrop) => {
|
|
5744
5872
|
const canvas = canvasRef.current;
|
|
5745
5873
|
const container = containerRef.current;
|
|
@@ -5762,8 +5890,8 @@ var ImageEditor = ({
|
|
|
5762
5890
|
},
|
|
5763
5891
|
[controller, activeTab, transformTool]
|
|
5764
5892
|
);
|
|
5765
|
-
(0,
|
|
5766
|
-
(0,
|
|
5893
|
+
(0, import_react47.useEffect)(() => typeSession?.subscribe(() => void renderCanvas()), [typeSession, renderCanvas]);
|
|
5894
|
+
(0, import_react47.useEffect)(() => {
|
|
5767
5895
|
if (activeTab === "annotate" && state.activeTool === "type") return;
|
|
5768
5896
|
if (typeToolRef.current?.session) {
|
|
5769
5897
|
typeToolRef.current.finish();
|
|
@@ -5798,7 +5926,7 @@ var ImageEditor = ({
|
|
|
5798
5926
|
el.value = "";
|
|
5799
5927
|
}
|
|
5800
5928
|
};
|
|
5801
|
-
(0,
|
|
5929
|
+
(0, import_react47.useEffect)(() => transformTool.subscribe(() => {
|
|
5802
5930
|
setTransformTick((n) => n + 1);
|
|
5803
5931
|
void renderCanvas();
|
|
5804
5932
|
}), [transformTool, renderCanvas]);
|
|
@@ -5809,8 +5937,8 @@ var ImageEditor = ({
|
|
|
5809
5937
|
const sy = rect.height > 0 ? canvas.height / rect.height : 1;
|
|
5810
5938
|
const s = controller.getState();
|
|
5811
5939
|
const cropping = activeTab === "crop";
|
|
5812
|
-
const projection = (0,
|
|
5813
|
-
const pt = (0,
|
|
5940
|
+
const projection = (0, import_image_editor15.getViewportProjection)(s, canvas.width, canvas.height, cropping);
|
|
5941
|
+
const pt = (0, import_image_editor15.canvasToImagePoint)({ x: (e.clientX - rect.left) * sx, y: (e.clientY - rect.top) * sy }, s, canvas.width, canvas.height, cropping);
|
|
5814
5942
|
transformTool.setView(projection.scale);
|
|
5815
5943
|
return { pt, tolerance: 6 / (projection.scale || 1) };
|
|
5816
5944
|
};
|
|
@@ -5841,7 +5969,7 @@ var ImageEditor = ({
|
|
|
5841
5969
|
transformTool.up();
|
|
5842
5970
|
return true;
|
|
5843
5971
|
};
|
|
5844
|
-
(0,
|
|
5972
|
+
(0, import_react47.useEffect)(() => {
|
|
5845
5973
|
if (typeof window === "undefined") return;
|
|
5846
5974
|
const onKey = (e) => {
|
|
5847
5975
|
if (transformTool.key(e)) e.preventDefault();
|
|
@@ -5849,7 +5977,7 @@ var ImageEditor = ({
|
|
|
5849
5977
|
window.addEventListener("keydown", onKey);
|
|
5850
5978
|
return () => window.removeEventListener("keydown", onKey);
|
|
5851
5979
|
}, [transformTool]);
|
|
5852
|
-
(0,
|
|
5980
|
+
(0, import_react47.useEffect)(() => {
|
|
5853
5981
|
const raf = typeof requestAnimationFrame !== "undefined" ? requestAnimationFrame : (cb) => setTimeout(cb, 0);
|
|
5854
5982
|
const caf = typeof cancelAnimationFrame !== "undefined" ? cancelAnimationFrame : (id) => clearTimeout(id);
|
|
5855
5983
|
const animId = raf(() => {
|
|
@@ -5857,12 +5985,12 @@ var ImageEditor = ({
|
|
|
5857
5985
|
});
|
|
5858
5986
|
return () => caf(animId);
|
|
5859
5987
|
}, [renderCanvas, state]);
|
|
5860
|
-
(0,
|
|
5988
|
+
(0, import_react47.useEffect)(() => {
|
|
5861
5989
|
if (activeTab === "crop" && editor.state.activeTool !== "crop") {
|
|
5862
5990
|
editor.setTool("crop");
|
|
5863
5991
|
}
|
|
5864
5992
|
}, [activeTab, editor]);
|
|
5865
|
-
(0,
|
|
5993
|
+
(0, import_react47.useEffect)(() => {
|
|
5866
5994
|
const container = containerRef.current;
|
|
5867
5995
|
if (!container) return;
|
|
5868
5996
|
if (typeof ResizeObserver !== "undefined") {
|
|
@@ -5898,8 +6026,8 @@ var ImageEditor = ({
|
|
|
5898
6026
|
const sy = rect.height > 0 ? canvas.height / rect.height : 1;
|
|
5899
6027
|
const s = controller.getState();
|
|
5900
6028
|
return list.map((ev) => ({
|
|
5901
|
-
...(0,
|
|
5902
|
-
pressure: (0,
|
|
6029
|
+
...(0, import_image_editor15.canvasToImagePoint)({ x: (ev.clientX - rect.left) * sx, y: (ev.clientY - rect.top) * sy }, s, canvas.width, canvas.height, false),
|
|
6030
|
+
pressure: (0, import_image_editor15.pointerPressure)(ev)
|
|
5903
6031
|
}));
|
|
5904
6032
|
};
|
|
5905
6033
|
const handlePaintPointerDown = (e) => {
|
|
@@ -5911,7 +6039,7 @@ var ImageEditor = ({
|
|
|
5911
6039
|
} catch {
|
|
5912
6040
|
}
|
|
5913
6041
|
const [first] = paintSamples(e);
|
|
5914
|
-
setPaintError(paintGestureRef.current.down(first));
|
|
6042
|
+
setPaintError(paintGestureRef.current.down({ ...first, altKey: e.altKey }));
|
|
5915
6043
|
};
|
|
5916
6044
|
const handlePaintPointerMove = (e) => {
|
|
5917
6045
|
if (handleTransformPointerMove(e)) return;
|
|
@@ -5930,10 +6058,10 @@ var ImageEditor = ({
|
|
|
5930
6058
|
if (g.error) setPaintError(g.error);
|
|
5931
6059
|
}
|
|
5932
6060
|
};
|
|
5933
|
-
(0,
|
|
6061
|
+
(0, import_react47.useEffect)(() => {
|
|
5934
6062
|
if (activeTab !== "paint" || typeof window === "undefined") return;
|
|
5935
6063
|
const onKey = (e) => {
|
|
5936
|
-
if ((0,
|
|
6064
|
+
if ((0, import_image_editor15.handlePaintShortcut)(controller, e)) e.preventDefault();
|
|
5937
6065
|
};
|
|
5938
6066
|
window.addEventListener("keydown", onKey);
|
|
5939
6067
|
return () => window.removeEventListener("keydown", onKey);
|
|
@@ -5944,7 +6072,7 @@ var ImageEditor = ({
|
|
|
5944
6072
|
const canvasPt = getCanvasEventPoint(e);
|
|
5945
6073
|
if (activeTab === "select") {
|
|
5946
6074
|
const gesture = selectionGestureRef.current;
|
|
5947
|
-
const imgPt = (0,
|
|
6075
|
+
const imgPt = (0, import_image_editor15.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false);
|
|
5948
6076
|
void gesture.begin(imgPt, e).then(() => setSelectionError(gesture.error));
|
|
5949
6077
|
return;
|
|
5950
6078
|
}
|
|
@@ -5955,8 +6083,8 @@ var ImageEditor = ({
|
|
|
5955
6083
|
width: state.imageDimensions.width,
|
|
5956
6084
|
height: state.imageDimensions.height
|
|
5957
6085
|
};
|
|
5958
|
-
const handle = (0,
|
|
5959
|
-
const startImgPt = (0,
|
|
6086
|
+
const handle = (0, import_image_editor15.hitTestCrop)(canvasPt, state, canvas.width, canvas.height, 14, activeCrop);
|
|
6087
|
+
const startImgPt = (0, import_image_editor15.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, true);
|
|
5960
6088
|
if (handle) {
|
|
5961
6089
|
cropDragInfoRef.current = {
|
|
5962
6090
|
handle,
|
|
@@ -5975,7 +6103,7 @@ var ImageEditor = ({
|
|
|
5975
6103
|
return;
|
|
5976
6104
|
}
|
|
5977
6105
|
if (activeTab === "annotate" && (state.activeTool === "shape" || state.activeTool === "type")) {
|
|
5978
|
-
const imgPt = (0,
|
|
6106
|
+
const imgPt = (0, import_image_editor15.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false);
|
|
5979
6107
|
setShapeTypeError(null);
|
|
5980
6108
|
if (state.activeTool === "shape") shapeGestureRef.current.down(imgPt);
|
|
5981
6109
|
else {
|
|
@@ -5986,12 +6114,12 @@ var ImageEditor = ({
|
|
|
5986
6114
|
return;
|
|
5987
6115
|
}
|
|
5988
6116
|
if (activeTab === "annotate") {
|
|
5989
|
-
const imgPt = (0,
|
|
6117
|
+
const imgPt = (0, import_image_editor15.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false);
|
|
5990
6118
|
dragStartPointRef.current = imgPt;
|
|
5991
6119
|
if (state.activeTool === "select") {
|
|
5992
6120
|
for (let i = state.annotations.length - 1; i >= 0; i--) {
|
|
5993
6121
|
const ann = state.annotations[i];
|
|
5994
|
-
if ((0,
|
|
6122
|
+
if ((0, import_image_editor15.hitTestAnnotation)(imgPt, ann)) {
|
|
5995
6123
|
editor.selectAnnotation(ann.id);
|
|
5996
6124
|
annotationDragInfoRef.current = {
|
|
5997
6125
|
annId: ann.id,
|
|
@@ -6027,7 +6155,7 @@ var ImageEditor = ({
|
|
|
6027
6155
|
const canvasPt = getCanvasEventPoint(e);
|
|
6028
6156
|
if (activeTab === "select") {
|
|
6029
6157
|
const gesture = selectionGestureRef.current;
|
|
6030
|
-
if (gesture.active && gesture.move((0,
|
|
6158
|
+
if (gesture.active && gesture.move((0, import_image_editor15.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false))) {
|
|
6031
6159
|
selectionDraftRef.current = gesture.draftPath;
|
|
6032
6160
|
renderCanvas();
|
|
6033
6161
|
}
|
|
@@ -6036,7 +6164,7 @@ var ImageEditor = ({
|
|
|
6036
6164
|
if (activeTab === "crop") {
|
|
6037
6165
|
const drag = cropDragInfoRef.current;
|
|
6038
6166
|
if (drag) {
|
|
6039
|
-
const currentImgPt = (0,
|
|
6167
|
+
const currentImgPt = (0, import_image_editor15.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, true);
|
|
6040
6168
|
let newCrop;
|
|
6041
6169
|
if (drag.handle === "new") {
|
|
6042
6170
|
const minX = Math.max(0, Math.min(drag.startImgPt.x, currentImgPt.x));
|
|
@@ -6050,7 +6178,7 @@ var ImageEditor = ({
|
|
|
6050
6178
|
height: Math.round(Math.max(20, maxY - minY))
|
|
6051
6179
|
};
|
|
6052
6180
|
} else {
|
|
6053
|
-
newCrop = (0,
|
|
6181
|
+
newCrop = (0, import_image_editor15.calculateCropDrag)(
|
|
6054
6182
|
drag.startCrop,
|
|
6055
6183
|
drag.handle,
|
|
6056
6184
|
drag.startImgPt,
|
|
@@ -6070,15 +6198,15 @@ var ImageEditor = ({
|
|
|
6070
6198
|
width: state.imageDimensions.width,
|
|
6071
6199
|
height: state.imageDimensions.height
|
|
6072
6200
|
};
|
|
6073
|
-
const handle = (0,
|
|
6074
|
-
canvas.style.cursor = (0,
|
|
6201
|
+
const handle = (0, import_image_editor15.hitTestCrop)(canvasPt, state, canvas.width, canvas.height, 14, activeCrop);
|
|
6202
|
+
canvas.style.cursor = (0, import_image_editor15.getCropCursor)(handle, state.transform);
|
|
6075
6203
|
}
|
|
6076
6204
|
return;
|
|
6077
6205
|
}
|
|
6078
6206
|
if (activeTab === "annotate" && state.activeTool === "shape") {
|
|
6079
6207
|
const g = shapeGestureRef.current;
|
|
6080
6208
|
if (g.active) {
|
|
6081
|
-
g.move((0,
|
|
6209
|
+
g.move((0, import_image_editor15.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false), { shift: e.shiftKey, alt: e.altKey });
|
|
6082
6210
|
if (g.error) setShapeTypeError(g.error);
|
|
6083
6211
|
}
|
|
6084
6212
|
return;
|
|
@@ -6086,7 +6214,7 @@ var ImageEditor = ({
|
|
|
6086
6214
|
if (activeTab === "annotate") {
|
|
6087
6215
|
if (annotationDragInfoRef.current) {
|
|
6088
6216
|
const drag = annotationDragInfoRef.current;
|
|
6089
|
-
const currentImgPt2 = (0,
|
|
6217
|
+
const currentImgPt2 = (0, import_image_editor15.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false);
|
|
6090
6218
|
const dx = currentImgPt2.x - drag.startImgPt.x;
|
|
6091
6219
|
const dy = currentImgPt2.y - drag.startImgPt.y;
|
|
6092
6220
|
editor.updateAnnotation(drag.annId, {
|
|
@@ -6098,10 +6226,10 @@ var ImageEditor = ({
|
|
|
6098
6226
|
const startPt = dragStartPointRef.current;
|
|
6099
6227
|
if (!startPt) {
|
|
6100
6228
|
if (state.activeTool === "select") {
|
|
6101
|
-
const imgPt = (0,
|
|
6229
|
+
const imgPt = (0, import_image_editor15.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false);
|
|
6102
6230
|
let hovered = false;
|
|
6103
6231
|
for (let i = state.annotations.length - 1; i >= 0; i--) {
|
|
6104
|
-
if ((0,
|
|
6232
|
+
if ((0, import_image_editor15.hitTestAnnotation)(imgPt, state.annotations[i])) {
|
|
6105
6233
|
hovered = true;
|
|
6106
6234
|
break;
|
|
6107
6235
|
}
|
|
@@ -6112,7 +6240,7 @@ var ImageEditor = ({
|
|
|
6112
6240
|
}
|
|
6113
6241
|
return;
|
|
6114
6242
|
}
|
|
6115
|
-
const currentImgPt = (0,
|
|
6243
|
+
const currentImgPt = (0, import_image_editor15.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false);
|
|
6116
6244
|
if (state.activeTool === "pen" && isDrawingRef.current) {
|
|
6117
6245
|
currentPathRef.current.push(currentImgPt);
|
|
6118
6246
|
const draft = {
|
|
@@ -6192,7 +6320,7 @@ var ImageEditor = ({
|
|
|
6192
6320
|
if (activeTab === "select") {
|
|
6193
6321
|
const gesture = selectionGestureRef.current;
|
|
6194
6322
|
if (gesture.active) {
|
|
6195
|
-
gesture.end((0,
|
|
6323
|
+
gesture.end((0, import_image_editor15.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false), e);
|
|
6196
6324
|
selectionDraftRef.current = null;
|
|
6197
6325
|
renderCanvas();
|
|
6198
6326
|
}
|
|
@@ -6215,7 +6343,7 @@ var ImageEditor = ({
|
|
|
6215
6343
|
}
|
|
6216
6344
|
if (activeTab === "annotate" && state.activeTool === "type") {
|
|
6217
6345
|
const tool = typeToolRef.current;
|
|
6218
|
-
tool.up((0,
|
|
6346
|
+
tool.up((0, import_image_editor15.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false));
|
|
6219
6347
|
setTypeSession(tool.session);
|
|
6220
6348
|
if (tool.error) setShapeTypeError(tool.error);
|
|
6221
6349
|
void renderCanvas();
|
|
@@ -6229,7 +6357,7 @@ var ImageEditor = ({
|
|
|
6229
6357
|
}
|
|
6230
6358
|
const startPt = dragStartPointRef.current;
|
|
6231
6359
|
if (startPt) {
|
|
6232
|
-
const currentImgPt = (0,
|
|
6360
|
+
const currentImgPt = (0, import_image_editor15.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false);
|
|
6233
6361
|
if (state.activeTool === "pen" && isDrawingRef.current) {
|
|
6234
6362
|
if (currentPathRef.current.length > 1) {
|
|
6235
6363
|
editor.addAnnotation({
|
|
@@ -6325,15 +6453,15 @@ var ImageEditor = ({
|
|
|
6325
6453
|
link.click();
|
|
6326
6454
|
}
|
|
6327
6455
|
};
|
|
6328
|
-
return /* @__PURE__ */ (0,
|
|
6456
|
+
return /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(
|
|
6329
6457
|
"div",
|
|
6330
6458
|
{
|
|
6331
6459
|
className: `flex flex-col bg-slate-900 border border-slate-800 rounded-xl overflow-hidden shadow-2xl text-slate-100 ${className}`,
|
|
6332
6460
|
style,
|
|
6333
6461
|
children: [
|
|
6334
|
-
/* @__PURE__ */ (0,
|
|
6335
|
-
/* @__PURE__ */ (0,
|
|
6336
|
-
/* @__PURE__ */ (0,
|
|
6462
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("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: [
|
|
6463
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "flex items-center gap-1 bg-slate-900 p-1 rounded-lg border border-slate-800 text-xs", children: [
|
|
6464
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
6337
6465
|
"button",
|
|
6338
6466
|
{
|
|
6339
6467
|
type: "button",
|
|
@@ -6345,7 +6473,7 @@ var ImageEditor = ({
|
|
|
6345
6473
|
children: "Transform & Crop"
|
|
6346
6474
|
}
|
|
6347
6475
|
),
|
|
6348
|
-
/* @__PURE__ */ (0,
|
|
6476
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
6349
6477
|
"button",
|
|
6350
6478
|
{
|
|
6351
6479
|
type: "button",
|
|
@@ -6357,7 +6485,7 @@ var ImageEditor = ({
|
|
|
6357
6485
|
children: "Adjustments"
|
|
6358
6486
|
}
|
|
6359
6487
|
),
|
|
6360
|
-
/* @__PURE__ */ (0,
|
|
6488
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
6361
6489
|
"button",
|
|
6362
6490
|
{
|
|
6363
6491
|
type: "button",
|
|
@@ -6369,7 +6497,7 @@ var ImageEditor = ({
|
|
|
6369
6497
|
children: "Layers"
|
|
6370
6498
|
}
|
|
6371
6499
|
),
|
|
6372
|
-
/* @__PURE__ */ (0,
|
|
6500
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
6373
6501
|
"button",
|
|
6374
6502
|
{
|
|
6375
6503
|
type: "button",
|
|
@@ -6381,7 +6509,7 @@ var ImageEditor = ({
|
|
|
6381
6509
|
children: "Paint"
|
|
6382
6510
|
}
|
|
6383
6511
|
),
|
|
6384
|
-
/* @__PURE__ */ (0,
|
|
6512
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
6385
6513
|
"button",
|
|
6386
6514
|
{
|
|
6387
6515
|
type: "button",
|
|
@@ -6393,7 +6521,7 @@ var ImageEditor = ({
|
|
|
6393
6521
|
children: "Select & Mask"
|
|
6394
6522
|
}
|
|
6395
6523
|
),
|
|
6396
|
-
/* @__PURE__ */ (0,
|
|
6524
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
6397
6525
|
"button",
|
|
6398
6526
|
{
|
|
6399
6527
|
type: "button",
|
|
@@ -6405,7 +6533,7 @@ var ImageEditor = ({
|
|
|
6405
6533
|
children: "Annotations"
|
|
6406
6534
|
}
|
|
6407
6535
|
),
|
|
6408
|
-
/* @__PURE__ */ (0,
|
|
6536
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
6409
6537
|
"button",
|
|
6410
6538
|
{
|
|
6411
6539
|
type: "button",
|
|
@@ -6417,7 +6545,7 @@ var ImageEditor = ({
|
|
|
6417
6545
|
children: "Depth Mask"
|
|
6418
6546
|
}
|
|
6419
6547
|
),
|
|
6420
|
-
/* @__PURE__ */ (0,
|
|
6548
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(
|
|
6421
6549
|
"button",
|
|
6422
6550
|
{
|
|
6423
6551
|
type: "button",
|
|
@@ -6427,14 +6555,14 @@ var ImageEditor = ({
|
|
|
6427
6555
|
},
|
|
6428
6556
|
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"}`,
|
|
6429
6557
|
children: [
|
|
6430
|
-
/* @__PURE__ */ (0,
|
|
6558
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("svg", { className: "w-3.5 h-3.5", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("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" }) }),
|
|
6431
6559
|
"AI Tools"
|
|
6432
6560
|
]
|
|
6433
6561
|
}
|
|
6434
6562
|
)
|
|
6435
6563
|
] }),
|
|
6436
|
-
/* @__PURE__ */ (0,
|
|
6437
|
-
/* @__PURE__ */ (0,
|
|
6564
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "flex items-center gap-2 text-xs", children: [
|
|
6565
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
6438
6566
|
"button",
|
|
6439
6567
|
{
|
|
6440
6568
|
type: "button",
|
|
@@ -6445,7 +6573,7 @@ var ImageEditor = ({
|
|
|
6445
6573
|
children: "\u21A9"
|
|
6446
6574
|
}
|
|
6447
6575
|
),
|
|
6448
|
-
/* @__PURE__ */ (0,
|
|
6576
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
6449
6577
|
"button",
|
|
6450
6578
|
{
|
|
6451
6579
|
type: "button",
|
|
@@ -6456,7 +6584,7 @@ var ImageEditor = ({
|
|
|
6456
6584
|
children: "\u21AA"
|
|
6457
6585
|
}
|
|
6458
6586
|
),
|
|
6459
|
-
/* @__PURE__ */ (0,
|
|
6587
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
6460
6588
|
"button",
|
|
6461
6589
|
{
|
|
6462
6590
|
type: "button",
|
|
@@ -6465,8 +6593,8 @@ var ImageEditor = ({
|
|
|
6465
6593
|
children: "Reset"
|
|
6466
6594
|
}
|
|
6467
6595
|
),
|
|
6468
|
-
/* @__PURE__ */ (0,
|
|
6469
|
-
/* @__PURE__ */ (0,
|
|
6596
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("div", { className: "h-4 w-px bg-slate-800 mx-1" }),
|
|
6597
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
6470
6598
|
"button",
|
|
6471
6599
|
{
|
|
6472
6600
|
type: "button",
|
|
@@ -6476,11 +6604,11 @@ var ImageEditor = ({
|
|
|
6476
6604
|
children: "-"
|
|
6477
6605
|
}
|
|
6478
6606
|
),
|
|
6479
|
-
/* @__PURE__ */ (0,
|
|
6607
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("span", { className: "font-mono text-slate-400 w-10 text-center", children: [
|
|
6480
6608
|
Math.round(state.zoom * 100),
|
|
6481
6609
|
"%"
|
|
6482
6610
|
] }),
|
|
6483
|
-
/* @__PURE__ */ (0,
|
|
6611
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
6484
6612
|
"button",
|
|
6485
6613
|
{
|
|
6486
6614
|
type: "button",
|
|
@@ -6490,8 +6618,8 @@ var ImageEditor = ({
|
|
|
6490
6618
|
children: "+"
|
|
6491
6619
|
}
|
|
6492
6620
|
),
|
|
6493
|
-
/* @__PURE__ */ (0,
|
|
6494
|
-
/* @__PURE__ */ (0,
|
|
6621
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("div", { className: "h-4 w-px bg-slate-800 mx-1" }),
|
|
6622
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
6495
6623
|
"button",
|
|
6496
6624
|
{
|
|
6497
6625
|
type: "button",
|
|
@@ -6502,7 +6630,7 @@ var ImageEditor = ({
|
|
|
6502
6630
|
children: "Hold Compare"
|
|
6503
6631
|
}
|
|
6504
6632
|
),
|
|
6505
|
-
/* @__PURE__ */ (0,
|
|
6633
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
6506
6634
|
"button",
|
|
6507
6635
|
{
|
|
6508
6636
|
type: "button",
|
|
@@ -6513,16 +6641,16 @@ var ImageEditor = ({
|
|
|
6513
6641
|
)
|
|
6514
6642
|
] })
|
|
6515
6643
|
] }),
|
|
6516
|
-
transformTool.active && /* @__PURE__ */ (0,
|
|
6517
|
-
!transformTool.active && transformTool.error && /* @__PURE__ */ (0,
|
|
6518
|
-
/* @__PURE__ */ (0,
|
|
6519
|
-
/* @__PURE__ */ (0,
|
|
6644
|
+
transformTool.active && /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(FreeTransformOptionsBar, { tool: transformTool, className: "border-b border-slate-800 bg-slate-900/95 px-4 py-2" }),
|
|
6645
|
+
!transformTool.active && transformTool.error && /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("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 }),
|
|
6646
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "flex flex-col md:flex-row flex-1 min-h-[520px] md:h-[560px]", children: [
|
|
6647
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(
|
|
6520
6648
|
"div",
|
|
6521
6649
|
{
|
|
6522
6650
|
ref: containerRef,
|
|
6523
6651
|
className: "relative flex-1 h-[360px] md:h-full min-h-[320px] bg-slate-950 overflow-hidden select-none",
|
|
6524
6652
|
children: [
|
|
6525
|
-
/* @__PURE__ */ (0,
|
|
6653
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
6526
6654
|
"canvas",
|
|
6527
6655
|
{
|
|
6528
6656
|
ref: canvasRef,
|
|
@@ -6539,7 +6667,7 @@ var ImageEditor = ({
|
|
|
6539
6667
|
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" : ""}`
|
|
6540
6668
|
}
|
|
6541
6669
|
),
|
|
6542
|
-
typeSession && /* @__PURE__ */ (0,
|
|
6670
|
+
typeSession && /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
6543
6671
|
"textarea",
|
|
6544
6672
|
{
|
|
6545
6673
|
ref: typeInputRef,
|
|
@@ -6561,11 +6689,11 @@ var ImageEditor = ({
|
|
|
6561
6689
|
]
|
|
6562
6690
|
}
|
|
6563
6691
|
),
|
|
6564
|
-
/* @__PURE__ */ (0,
|
|
6565
|
-
activeTab === "crop" && /* @__PURE__ */ (0,
|
|
6566
|
-
/* @__PURE__ */ (0,
|
|
6567
|
-
/* @__PURE__ */ (0,
|
|
6568
|
-
/* @__PURE__ */ (0,
|
|
6692
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("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: [
|
|
6693
|
+
activeTab === "crop" && /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "flex flex-col gap-4 text-xs", children: [
|
|
6694
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Aspect Ratio Presets" }),
|
|
6695
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "grid grid-cols-3 gap-2", children: [
|
|
6696
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
6569
6697
|
"button",
|
|
6570
6698
|
{
|
|
6571
6699
|
type: "button",
|
|
@@ -6577,7 +6705,7 @@ var ImageEditor = ({
|
|
|
6577
6705
|
children: "Freeform"
|
|
6578
6706
|
}
|
|
6579
6707
|
),
|
|
6580
|
-
/* @__PURE__ */ (0,
|
|
6708
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
6581
6709
|
"button",
|
|
6582
6710
|
{
|
|
6583
6711
|
type: "button",
|
|
@@ -6589,7 +6717,7 @@ var ImageEditor = ({
|
|
|
6589
6717
|
children: "1:1 Square"
|
|
6590
6718
|
}
|
|
6591
6719
|
),
|
|
6592
|
-
/* @__PURE__ */ (0,
|
|
6720
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
6593
6721
|
"button",
|
|
6594
6722
|
{
|
|
6595
6723
|
type: "button",
|
|
@@ -6601,7 +6729,7 @@ var ImageEditor = ({
|
|
|
6601
6729
|
children: "4:3 Standard"
|
|
6602
6730
|
}
|
|
6603
6731
|
),
|
|
6604
|
-
/* @__PURE__ */ (0,
|
|
6732
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
6605
6733
|
"button",
|
|
6606
6734
|
{
|
|
6607
6735
|
type: "button",
|
|
@@ -6613,7 +6741,7 @@ var ImageEditor = ({
|
|
|
6613
6741
|
children: "16:9 Wide"
|
|
6614
6742
|
}
|
|
6615
6743
|
),
|
|
6616
|
-
/* @__PURE__ */ (0,
|
|
6744
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
6617
6745
|
"button",
|
|
6618
6746
|
{
|
|
6619
6747
|
type: "button",
|
|
@@ -6625,7 +6753,7 @@ var ImageEditor = ({
|
|
|
6625
6753
|
children: "3:2 Photo"
|
|
6626
6754
|
}
|
|
6627
6755
|
),
|
|
6628
|
-
/* @__PURE__ */ (0,
|
|
6756
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
6629
6757
|
"button",
|
|
6630
6758
|
{
|
|
6631
6759
|
type: "button",
|
|
@@ -6638,10 +6766,10 @@ var ImageEditor = ({
|
|
|
6638
6766
|
}
|
|
6639
6767
|
)
|
|
6640
6768
|
] }),
|
|
6641
|
-
/* @__PURE__ */ (0,
|
|
6642
|
-
/* @__PURE__ */ (0,
|
|
6643
|
-
/* @__PURE__ */ (0,
|
|
6644
|
-
/* @__PURE__ */ (0,
|
|
6769
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("div", { className: "h-px bg-slate-800 my-1" }),
|
|
6770
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Orientation & Flips" }),
|
|
6771
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "grid grid-cols-2 gap-2", children: [
|
|
6772
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
6645
6773
|
"button",
|
|
6646
6774
|
{
|
|
6647
6775
|
type: "button",
|
|
@@ -6650,7 +6778,7 @@ var ImageEditor = ({
|
|
|
6650
6778
|
children: "Rotate -90\xB0"
|
|
6651
6779
|
}
|
|
6652
6780
|
),
|
|
6653
|
-
/* @__PURE__ */ (0,
|
|
6781
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
6654
6782
|
"button",
|
|
6655
6783
|
{
|
|
6656
6784
|
type: "button",
|
|
@@ -6659,7 +6787,7 @@ var ImageEditor = ({
|
|
|
6659
6787
|
children: "Rotate +90\xB0"
|
|
6660
6788
|
}
|
|
6661
6789
|
),
|
|
6662
|
-
/* @__PURE__ */ (0,
|
|
6790
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
6663
6791
|
"button",
|
|
6664
6792
|
{
|
|
6665
6793
|
type: "button",
|
|
@@ -6668,7 +6796,7 @@ var ImageEditor = ({
|
|
|
6668
6796
|
children: "Flip Horizontal"
|
|
6669
6797
|
}
|
|
6670
6798
|
),
|
|
6671
|
-
/* @__PURE__ */ (0,
|
|
6799
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
6672
6800
|
"button",
|
|
6673
6801
|
{
|
|
6674
6802
|
type: "button",
|
|
@@ -6679,10 +6807,10 @@ var ImageEditor = ({
|
|
|
6679
6807
|
)
|
|
6680
6808
|
] })
|
|
6681
6809
|
] }),
|
|
6682
|
-
activeTab === "adjust" && /* @__PURE__ */ (0,
|
|
6683
|
-
/* @__PURE__ */ (0,
|
|
6684
|
-
/* @__PURE__ */ (0,
|
|
6685
|
-
/* @__PURE__ */ (0,
|
|
6810
|
+
activeTab === "adjust" && /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "flex flex-col gap-3 text-xs", children: [
|
|
6811
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "flex items-center justify-between", children: [
|
|
6812
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Color Adjustments" }),
|
|
6813
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
6686
6814
|
"button",
|
|
6687
6815
|
{
|
|
6688
6816
|
type: "button",
|
|
@@ -6692,25 +6820,25 @@ var ImageEditor = ({
|
|
|
6692
6820
|
}
|
|
6693
6821
|
)
|
|
6694
6822
|
] }),
|
|
6695
|
-
/* @__PURE__ */ (0,
|
|
6696
|
-
|
|
6697
|
-
/* @__PURE__ */ (0,
|
|
6823
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(Histogram, { histogram: editor.histogram }),
|
|
6824
|
+
import_image_editor15.IMAGE_ADJUSTMENT_CONTROLS.map((spec) => /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(import_react47.default.Fragment, { children: [
|
|
6825
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
6698
6826
|
ControlSlider,
|
|
6699
6827
|
{
|
|
6700
6828
|
spec,
|
|
6701
|
-
value: (0,
|
|
6829
|
+
value: (0, import_image_editor15.readAdjustmentControls)(state.adjustments)[spec.id],
|
|
6702
6830
|
disabled: spec.requiresProcess !== void 0 && legacyProcess,
|
|
6703
6831
|
onChange: (v) => editor.setAdjustments({ [spec.id]: v })
|
|
6704
6832
|
}
|
|
6705
6833
|
),
|
|
6706
|
-
spec.id === "tint" && legacyProcess && /* @__PURE__ */ (0,
|
|
6834
|
+
spec.id === "tint" && legacyProcess && /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(
|
|
6707
6835
|
"div",
|
|
6708
6836
|
{
|
|
6709
6837
|
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",
|
|
6710
6838
|
"data-testid": "image-editor-process-notice",
|
|
6711
6839
|
children: [
|
|
6712
|
-
/* @__PURE__ */ (0,
|
|
6713
|
-
/* @__PURE__ */ (0,
|
|
6840
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", { children: "Legacy rendering (process 1). Tint needs the current process." }),
|
|
6841
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
6714
6842
|
"button",
|
|
6715
6843
|
{
|
|
6716
6844
|
type: "button",
|
|
@@ -6723,7 +6851,7 @@ var ImageEditor = ({
|
|
|
6723
6851
|
}
|
|
6724
6852
|
)
|
|
6725
6853
|
] }, spec.id)),
|
|
6726
|
-
/* @__PURE__ */ (0,
|
|
6854
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("div", { className: "border-t border-slate-700/60 pt-3", children: /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
6727
6855
|
AdjustmentLayersPanel,
|
|
6728
6856
|
{
|
|
6729
6857
|
controller,
|
|
@@ -6732,9 +6860,9 @@ var ImageEditor = ({
|
|
|
6732
6860
|
}
|
|
6733
6861
|
) })
|
|
6734
6862
|
] }),
|
|
6735
|
-
activeTab === "layers" && /* @__PURE__ */ (0,
|
|
6736
|
-
/* @__PURE__ */ (0,
|
|
6737
|
-
/* @__PURE__ */ (0,
|
|
6863
|
+
activeTab === "layers" && /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "flex flex-col gap-3 text-xs", children: [
|
|
6864
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Layers" }),
|
|
6865
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
6738
6866
|
"button",
|
|
6739
6867
|
{
|
|
6740
6868
|
type: "button",
|
|
@@ -6745,12 +6873,14 @@ var ImageEditor = ({
|
|
|
6745
6873
|
children: "Free Transform"
|
|
6746
6874
|
}
|
|
6747
6875
|
),
|
|
6748
|
-
/* @__PURE__ */ (0,
|
|
6876
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(LayersPanel, { controller }),
|
|
6877
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Colour" }),
|
|
6878
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(ColorProfilePanel, { controller })
|
|
6749
6879
|
] }),
|
|
6750
|
-
activeTab === "paint" && /* @__PURE__ */ (0,
|
|
6751
|
-
/* @__PURE__ */ (0,
|
|
6752
|
-
/* @__PURE__ */ (0,
|
|
6753
|
-
/* @__PURE__ */ (0,
|
|
6880
|
+
activeTab === "paint" && /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "flex flex-col gap-3 text-xs", children: [
|
|
6881
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Paint" }),
|
|
6882
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(BrushOptionsBar, { controller }),
|
|
6883
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
6754
6884
|
"button",
|
|
6755
6885
|
{
|
|
6756
6886
|
type: "button",
|
|
@@ -6761,12 +6891,12 @@ var ImageEditor = ({
|
|
|
6761
6891
|
children: "Free Transform"
|
|
6762
6892
|
}
|
|
6763
6893
|
),
|
|
6764
|
-
paintError && /* @__PURE__ */ (0,
|
|
6765
|
-
/* @__PURE__ */ (0,
|
|
6894
|
+
paintError && /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("p", { role: "alert", className: "text-rose-400", "data-testid": "paint-error", children: paintError }),
|
|
6895
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("div", { className: "border-t border-slate-700/60 pt-3", children: /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(LayersPanel, { controller }) })
|
|
6766
6896
|
] }),
|
|
6767
|
-
activeTab === "annotate" && /* @__PURE__ */ (0,
|
|
6768
|
-
/* @__PURE__ */ (0,
|
|
6769
|
-
/* @__PURE__ */ (0,
|
|
6897
|
+
activeTab === "annotate" && /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "flex flex-col gap-3 text-xs", children: [
|
|
6898
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Shape & Type Layers" }),
|
|
6899
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("div", { className: "grid grid-cols-2 gap-1.5", children: ["shape", "type"].map((t) => /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
6770
6900
|
"button",
|
|
6771
6901
|
{
|
|
6772
6902
|
type: "button",
|
|
@@ -6777,13 +6907,13 @@ var ImageEditor = ({
|
|
|
6777
6907
|
},
|
|
6778
6908
|
t
|
|
6779
6909
|
)) }),
|
|
6780
|
-
state.activeTool === "shape" && /* @__PURE__ */ (0,
|
|
6781
|
-
state.activeTool === "type" && /* @__PURE__ */ (0,
|
|
6782
|
-
state.activeTool === "type" && typeSession && /* @__PURE__ */ (0,
|
|
6783
|
-
shapeTypeError && /* @__PURE__ */ (0,
|
|
6784
|
-
/* @__PURE__ */ (0,
|
|
6785
|
-
/* @__PURE__ */ (0,
|
|
6786
|
-
/* @__PURE__ */ (0,
|
|
6910
|
+
state.activeTool === "shape" && /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(ShapeOptionsBar, { controller, options: shapeOptions, onChange: setShapeOptions }),
|
|
6911
|
+
state.activeTool === "type" && /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(TypeOptionsBar, { controller, options: typeOptions, onChange: setTypeOptions, session: typeSession }),
|
|
6912
|
+
state.activeTool === "type" && typeSession && /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("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" }),
|
|
6913
|
+
shapeTypeError && /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("p", { role: "alert", className: "text-rose-400", "data-testid": "shape-type-error", children: shapeTypeError }),
|
|
6914
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("div", { className: "h-px bg-slate-800 my-1" }),
|
|
6915
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Draw & Annotate" }),
|
|
6916
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("div", { className: "grid grid-cols-3 gap-1.5", children: ["pen", "rect", "circle", "arrow", "line"].map((t) => /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
6787
6917
|
"button",
|
|
6788
6918
|
{
|
|
6789
6919
|
type: "button",
|
|
@@ -6793,9 +6923,9 @@ var ImageEditor = ({
|
|
|
6793
6923
|
},
|
|
6794
6924
|
t
|
|
6795
6925
|
)) }),
|
|
6796
|
-
/* @__PURE__ */ (0,
|
|
6797
|
-
/* @__PURE__ */ (0,
|
|
6798
|
-
/* @__PURE__ */ (0,
|
|
6926
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "flex items-center gap-2 mt-2", children: [
|
|
6927
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("label", { className: "text-slate-400", children: "Color:" }),
|
|
6928
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
6799
6929
|
"input",
|
|
6800
6930
|
{
|
|
6801
6931
|
type: "color",
|
|
@@ -6804,15 +6934,15 @@ var ImageEditor = ({
|
|
|
6804
6934
|
className: "w-8 h-8 rounded border border-slate-700 cursor-pointer bg-transparent"
|
|
6805
6935
|
}
|
|
6806
6936
|
),
|
|
6807
|
-
/* @__PURE__ */ (0,
|
|
6808
|
-
/* @__PURE__ */ (0,
|
|
6809
|
-
/* @__PURE__ */ (0,
|
|
6810
|
-
/* @__PURE__ */ (0,
|
|
6937
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "flex-1 ml-2", children: [
|
|
6938
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "flex justify-between text-slate-400 mb-0.5", children: [
|
|
6939
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", { children: "Width:" }),
|
|
6940
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("span", { className: "font-mono", children: [
|
|
6811
6941
|
strokeWidth,
|
|
6812
6942
|
"px"
|
|
6813
6943
|
] })
|
|
6814
6944
|
] }),
|
|
6815
|
-
/* @__PURE__ */ (0,
|
|
6945
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
6816
6946
|
"input",
|
|
6817
6947
|
{
|
|
6818
6948
|
type: "range",
|
|
@@ -6825,10 +6955,10 @@ var ImageEditor = ({
|
|
|
6825
6955
|
)
|
|
6826
6956
|
] })
|
|
6827
6957
|
] }),
|
|
6828
|
-
/* @__PURE__ */ (0,
|
|
6829
|
-
/* @__PURE__ */ (0,
|
|
6830
|
-
/* @__PURE__ */ (0,
|
|
6831
|
-
/* @__PURE__ */ (0,
|
|
6958
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("div", { className: "h-px bg-slate-800 my-1" }),
|
|
6959
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Add Text" }),
|
|
6960
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "flex gap-2", children: [
|
|
6961
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
6832
6962
|
"input",
|
|
6833
6963
|
{
|
|
6834
6964
|
type: "text",
|
|
@@ -6839,7 +6969,7 @@ var ImageEditor = ({
|
|
|
6839
6969
|
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"
|
|
6840
6970
|
}
|
|
6841
6971
|
),
|
|
6842
|
-
/* @__PURE__ */ (0,
|
|
6972
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
6843
6973
|
"button",
|
|
6844
6974
|
{
|
|
6845
6975
|
type: "button",
|
|
@@ -6849,14 +6979,14 @@ var ImageEditor = ({
|
|
|
6849
6979
|
}
|
|
6850
6980
|
)
|
|
6851
6981
|
] }),
|
|
6852
|
-
/* @__PURE__ */ (0,
|
|
6853
|
-
/* @__PURE__ */ (0,
|
|
6854
|
-
/* @__PURE__ */ (0,
|
|
6982
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "flex items-center justify-between text-slate-400", children: [
|
|
6983
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", { children: "Font Size:" }),
|
|
6984
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("span", { className: "font-mono", children: [
|
|
6855
6985
|
fontSize,
|
|
6856
6986
|
"px"
|
|
6857
6987
|
] })
|
|
6858
6988
|
] }),
|
|
6859
|
-
/* @__PURE__ */ (0,
|
|
6989
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
6860
6990
|
"input",
|
|
6861
6991
|
{
|
|
6862
6992
|
type: "range",
|
|
@@ -6867,14 +6997,14 @@ var ImageEditor = ({
|
|
|
6867
6997
|
className: "w-full accent-indigo-500"
|
|
6868
6998
|
}
|
|
6869
6999
|
),
|
|
6870
|
-
/* @__PURE__ */ (0,
|
|
6871
|
-
/* @__PURE__ */ (0,
|
|
6872
|
-
/* @__PURE__ */ (0,
|
|
7000
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("div", { className: "h-px bg-slate-800 my-1" }),
|
|
7001
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "flex items-center justify-between", children: [
|
|
7002
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("span", { className: "text-slate-400", children: [
|
|
6873
7003
|
"Layers (",
|
|
6874
7004
|
state.annotations.length,
|
|
6875
7005
|
")"
|
|
6876
7006
|
] }),
|
|
6877
|
-
state.selectedAnnotationId && /* @__PURE__ */ (0,
|
|
7007
|
+
state.selectedAnnotationId && /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
6878
7008
|
"button",
|
|
6879
7009
|
{
|
|
6880
7010
|
type: "button",
|
|
@@ -6883,7 +7013,7 @@ var ImageEditor = ({
|
|
|
6883
7013
|
children: "Delete Selected"
|
|
6884
7014
|
}
|
|
6885
7015
|
),
|
|
6886
|
-
state.annotations.length > 0 && /* @__PURE__ */ (0,
|
|
7016
|
+
state.annotations.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
6887
7017
|
"button",
|
|
6888
7018
|
{
|
|
6889
7019
|
type: "button",
|
|
@@ -6894,10 +7024,10 @@ var ImageEditor = ({
|
|
|
6894
7024
|
)
|
|
6895
7025
|
] })
|
|
6896
7026
|
] }),
|
|
6897
|
-
activeTab === "depth" && /* @__PURE__ */ (0,
|
|
6898
|
-
/* @__PURE__ */ (0,
|
|
6899
|
-
/* @__PURE__ */ (0,
|
|
6900
|
-
/* @__PURE__ */ (0,
|
|
7027
|
+
activeTab === "depth" && /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "flex flex-col gap-3 text-xs", children: [
|
|
7028
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "flex items-center justify-between", children: [
|
|
7029
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Depth Masking" }),
|
|
7030
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
6901
7031
|
"button",
|
|
6902
7032
|
{
|
|
6903
7033
|
type: "button",
|
|
@@ -6907,8 +7037,8 @@ var ImageEditor = ({
|
|
|
6907
7037
|
}
|
|
6908
7038
|
)
|
|
6909
7039
|
] }),
|
|
6910
|
-
/* @__PURE__ */ (0,
|
|
6911
|
-
/* @__PURE__ */ (0,
|
|
7040
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("label", { className: "flex items-center gap-2 cursor-pointer text-slate-300", children: [
|
|
7041
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
6912
7042
|
"input",
|
|
6913
7043
|
{
|
|
6914
7044
|
type: "checkbox",
|
|
@@ -6917,12 +7047,12 @@ var ImageEditor = ({
|
|
|
6917
7047
|
className: "rounded accent-indigo-500"
|
|
6918
7048
|
}
|
|
6919
7049
|
),
|
|
6920
|
-
/* @__PURE__ */ (0,
|
|
7050
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", { children: "Enable Depth / Alpha Mask" })
|
|
6921
7051
|
] }),
|
|
6922
|
-
state.depthMask.enabled && /* @__PURE__ */ (0,
|
|
6923
|
-
/* @__PURE__ */ (0,
|
|
6924
|
-
/* @__PURE__ */ (0,
|
|
6925
|
-
/* @__PURE__ */ (0,
|
|
7052
|
+
state.depthMask.enabled && /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(import_jsx_runtime30.Fragment, { children: [
|
|
7053
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { children: [
|
|
7054
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("label", { className: "text-slate-400 block mb-1", children: "Mask Image URL:" }),
|
|
7055
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
6926
7056
|
"input",
|
|
6927
7057
|
{
|
|
6928
7058
|
type: "text",
|
|
@@ -6933,8 +7063,8 @@ var ImageEditor = ({
|
|
|
6933
7063
|
}
|
|
6934
7064
|
)
|
|
6935
7065
|
] }),
|
|
6936
|
-
/* @__PURE__ */ (0,
|
|
6937
|
-
/* @__PURE__ */ (0,
|
|
7066
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "flex gap-2", children: [
|
|
7067
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
6938
7068
|
"button",
|
|
6939
7069
|
{
|
|
6940
7070
|
type: "button",
|
|
@@ -6943,7 +7073,7 @@ var ImageEditor = ({
|
|
|
6943
7073
|
children: "Threshold Mode"
|
|
6944
7074
|
}
|
|
6945
7075
|
),
|
|
6946
|
-
/* @__PURE__ */ (0,
|
|
7076
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
6947
7077
|
"button",
|
|
6948
7078
|
{
|
|
6949
7079
|
type: "button",
|
|
@@ -6953,12 +7083,12 @@ var ImageEditor = ({
|
|
|
6953
7083
|
}
|
|
6954
7084
|
)
|
|
6955
7085
|
] }),
|
|
6956
|
-
/* @__PURE__ */ (0,
|
|
6957
|
-
/* @__PURE__ */ (0,
|
|
6958
|
-
/* @__PURE__ */ (0,
|
|
6959
|
-
/* @__PURE__ */ (0,
|
|
7086
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { children: [
|
|
7087
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "flex justify-between text-slate-400 mb-1", children: [
|
|
7088
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", { children: "Depth Start (Lower):" }),
|
|
7089
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", { className: "font-mono", children: state.depthMask.depthRange[0] })
|
|
6960
7090
|
] }),
|
|
6961
|
-
/* @__PURE__ */ (0,
|
|
7091
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
6962
7092
|
"input",
|
|
6963
7093
|
{
|
|
6964
7094
|
type: "range",
|
|
@@ -6972,12 +7102,12 @@ var ImageEditor = ({
|
|
|
6972
7102
|
}
|
|
6973
7103
|
)
|
|
6974
7104
|
] }),
|
|
6975
|
-
/* @__PURE__ */ (0,
|
|
6976
|
-
/* @__PURE__ */ (0,
|
|
6977
|
-
/* @__PURE__ */ (0,
|
|
6978
|
-
/* @__PURE__ */ (0,
|
|
7105
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { children: [
|
|
7106
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "flex justify-between text-slate-400 mb-1", children: [
|
|
7107
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", { children: "Depth Stop (Upper):" }),
|
|
7108
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", { className: "font-mono", children: state.depthMask.depthRange[1] })
|
|
6979
7109
|
] }),
|
|
6980
|
-
/* @__PURE__ */ (0,
|
|
7110
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
6981
7111
|
"input",
|
|
6982
7112
|
{
|
|
6983
7113
|
type: "range",
|
|
@@ -6991,12 +7121,12 @@ var ImageEditor = ({
|
|
|
6991
7121
|
}
|
|
6992
7122
|
)
|
|
6993
7123
|
] }),
|
|
6994
|
-
/* @__PURE__ */ (0,
|
|
6995
|
-
/* @__PURE__ */ (0,
|
|
6996
|
-
/* @__PURE__ */ (0,
|
|
6997
|
-
/* @__PURE__ */ (0,
|
|
7124
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { children: [
|
|
7125
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "flex justify-between text-slate-400 mb-1", children: [
|
|
7126
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", { children: "Softness:" }),
|
|
7127
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", { className: "font-mono", children: state.depthMask.softness })
|
|
6998
7128
|
] }),
|
|
6999
|
-
/* @__PURE__ */ (0,
|
|
7129
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
7000
7130
|
"input",
|
|
7001
7131
|
{
|
|
7002
7132
|
type: "range",
|
|
@@ -7008,8 +7138,8 @@ var ImageEditor = ({
|
|
|
7008
7138
|
}
|
|
7009
7139
|
)
|
|
7010
7140
|
] }),
|
|
7011
|
-
/* @__PURE__ */ (0,
|
|
7012
|
-
/* @__PURE__ */ (0,
|
|
7141
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("label", { className: "flex items-center gap-2 cursor-pointer text-slate-300 mt-1", children: [
|
|
7142
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
7013
7143
|
"input",
|
|
7014
7144
|
{
|
|
7015
7145
|
type: "checkbox",
|
|
@@ -7018,12 +7148,12 @@ var ImageEditor = ({
|
|
|
7018
7148
|
className: "rounded accent-indigo-500"
|
|
7019
7149
|
}
|
|
7020
7150
|
),
|
|
7021
|
-
/* @__PURE__ */ (0,
|
|
7151
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", { children: "Invert Mask" })
|
|
7022
7152
|
] })
|
|
7023
7153
|
] })
|
|
7024
7154
|
] }),
|
|
7025
|
-
activeTab === "select" && /* @__PURE__ */ (0,
|
|
7026
|
-
/* @__PURE__ */ (0,
|
|
7155
|
+
activeTab === "select" && /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "flex flex-col gap-4 text-xs", children: [
|
|
7156
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
7027
7157
|
SelectionOptionsBar,
|
|
7028
7158
|
{
|
|
7029
7159
|
controller,
|
|
@@ -7033,9 +7163,9 @@ var ImageEditor = ({
|
|
|
7033
7163
|
quickMask: Boolean(state.quickMask)
|
|
7034
7164
|
}
|
|
7035
7165
|
),
|
|
7036
|
-
selectionError && /* @__PURE__ */ (0,
|
|
7037
|
-
/* @__PURE__ */ (0,
|
|
7038
|
-
/* @__PURE__ */ (0,
|
|
7166
|
+
selectionError && /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("p", { role: "alert", className: "text-rose-400", children: selectionError }),
|
|
7167
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "flex gap-1", children: [
|
|
7168
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
7039
7169
|
"button",
|
|
7040
7170
|
{
|
|
7041
7171
|
type: "button",
|
|
@@ -7046,7 +7176,7 @@ var ImageEditor = ({
|
|
|
7046
7176
|
children: "Transform Selection"
|
|
7047
7177
|
}
|
|
7048
7178
|
),
|
|
7049
|
-
/* @__PURE__ */ (0,
|
|
7179
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
7050
7180
|
"button",
|
|
7051
7181
|
{
|
|
7052
7182
|
type: "button",
|
|
@@ -7058,12 +7188,12 @@ var ImageEditor = ({
|
|
|
7058
7188
|
}
|
|
7059
7189
|
)
|
|
7060
7190
|
] }),
|
|
7061
|
-
/* @__PURE__ */ (0,
|
|
7191
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(RefineEdgePanel, { controller, selection: state.selection ?? null, layers: state.adjustments.layers })
|
|
7062
7192
|
] }),
|
|
7063
|
-
activeTab === "ai" && /* @__PURE__ */ (0,
|
|
7064
|
-
/* @__PURE__ */ (0,
|
|
7065
|
-
/* @__PURE__ */ (0,
|
|
7066
|
-
/* @__PURE__ */ (0,
|
|
7193
|
+
activeTab === "ai" && /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "flex flex-col gap-4 text-xs", children: [
|
|
7194
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("label", { className: "flex items-center justify-between gap-2 text-slate-300", children: [
|
|
7195
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", { children: "Results go to" }),
|
|
7196
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(
|
|
7067
7197
|
"select",
|
|
7068
7198
|
{
|
|
7069
7199
|
"aria-label": "AI result target",
|
|
@@ -7071,54 +7201,54 @@ var ImageEditor = ({
|
|
|
7071
7201
|
onChange: (e) => setAiTarget(e.target.value),
|
|
7072
7202
|
className: "bg-slate-800 border border-slate-700 rounded px-1.5 py-1",
|
|
7073
7203
|
children: [
|
|
7074
|
-
/* @__PURE__ */ (0,
|
|
7075
|
-
/* @__PURE__ */ (0,
|
|
7076
|
-
/* @__PURE__ */ (0,
|
|
7204
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("option", { value: "auto", children: controller.isMultiLayer ? "Auto (new layer)" : "Auto (replace image)" }),
|
|
7205
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("option", { value: "new-layer", children: "New layer / mask" }),
|
|
7206
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("option", { value: "replace", children: "Replace image" })
|
|
7077
7207
|
]
|
|
7078
7208
|
}
|
|
7079
7209
|
)
|
|
7080
7210
|
] }),
|
|
7081
|
-
/* @__PURE__ */ (0,
|
|
7082
|
-
/* @__PURE__ */ (0,
|
|
7083
|
-
/* @__PURE__ */ (0,
|
|
7084
|
-
/* @__PURE__ */ (0,
|
|
7211
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "p-3 rounded-lg bg-slate-950/60 border border-slate-800 flex flex-col gap-2.5", children: [
|
|
7212
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "flex items-center justify-between", children: [
|
|
7213
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px] flex items-center gap-1.5", children: [
|
|
7214
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("svg", { className: "w-3.5 h-3.5 text-indigo-400", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("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" }) }),
|
|
7085
7215
|
"Background Removal"
|
|
7086
7216
|
] }),
|
|
7087
|
-
isRemovingBg && /* @__PURE__ */ (0,
|
|
7217
|
+
isRemovingBg && /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("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..." })
|
|
7088
7218
|
] }),
|
|
7089
|
-
/* @__PURE__ */ (0,
|
|
7090
|
-
/* @__PURE__ */ (0,
|
|
7219
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("p", { className: "text-slate-400 text-[11px] leading-relaxed", children: "Isolate foreground subject with AI alpha transparency segmentation." }),
|
|
7220
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
7091
7221
|
"button",
|
|
7092
7222
|
{
|
|
7093
7223
|
type: "button",
|
|
7094
7224
|
onClick: handleRemoveBackground,
|
|
7095
7225
|
disabled: isRemovingBg || isInpainting,
|
|
7096
7226
|
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",
|
|
7097
|
-
children: isRemovingBg ? /* @__PURE__ */ (0,
|
|
7098
|
-
/* @__PURE__ */ (0,
|
|
7227
|
+
children: isRemovingBg ? /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(import_jsx_runtime30.Fragment, { children: [
|
|
7228
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("div", { className: "w-3.5 h-3.5 border-2 border-white/30 border-t-white rounded-full animate-spin" }),
|
|
7099
7229
|
"Removing Background..."
|
|
7100
|
-
] }) : /* @__PURE__ */ (0,
|
|
7101
|
-
/* @__PURE__ */ (0,
|
|
7230
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(import_jsx_runtime30.Fragment, { children: [
|
|
7231
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("svg", { className: "w-3.5 h-3.5", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("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" }) }),
|
|
7102
7232
|
"Remove Background"
|
|
7103
7233
|
] })
|
|
7104
7234
|
}
|
|
7105
7235
|
)
|
|
7106
7236
|
] }),
|
|
7107
|
-
/* @__PURE__ */ (0,
|
|
7108
|
-
/* @__PURE__ */ (0,
|
|
7109
|
-
/* @__PURE__ */ (0,
|
|
7110
|
-
/* @__PURE__ */ (0,
|
|
7111
|
-
/* @__PURE__ */ (0,
|
|
7112
|
-
/* @__PURE__ */ (0,
|
|
7237
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "p-3 rounded-lg bg-slate-950/60 border border-slate-800 flex flex-col gap-2.5", children: [
|
|
7238
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "flex items-center justify-between", children: [
|
|
7239
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px] flex items-center gap-1.5", children: [
|
|
7240
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("svg", { className: "w-3.5 h-3.5 text-purple-400", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: [
|
|
7241
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("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" }),
|
|
7242
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("path", { d: "m14 7 3 3" })
|
|
7113
7243
|
] }),
|
|
7114
7244
|
"Generative Inpainting"
|
|
7115
7245
|
] }),
|
|
7116
|
-
isInpainting && /* @__PURE__ */ (0,
|
|
7246
|
+
isInpainting && /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("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..." })
|
|
7117
7247
|
] }),
|
|
7118
|
-
/* @__PURE__ */ (0,
|
|
7119
|
-
/* @__PURE__ */ (0,
|
|
7120
|
-
/* @__PURE__ */ (0,
|
|
7121
|
-
/* @__PURE__ */ (0,
|
|
7248
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("p", { className: "text-slate-400 text-[11px] leading-relaxed", children: "Replace, modify, or fill selected regions using prompt-guided generative inpainting." }),
|
|
7249
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "flex flex-col gap-1", children: [
|
|
7250
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("label", { htmlFor: "ai-inpaint-prompt-react", className: "text-slate-300 text-[11px] font-medium", children: "Prompt" }),
|
|
7251
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
7122
7252
|
"textarea",
|
|
7123
7253
|
{
|
|
7124
7254
|
id: "ai-inpaint-prompt-react",
|
|
@@ -7130,10 +7260,10 @@ var ImageEditor = ({
|
|
|
7130
7260
|
}
|
|
7131
7261
|
)
|
|
7132
7262
|
] }),
|
|
7133
|
-
/* @__PURE__ */ (0,
|
|
7134
|
-
/* @__PURE__ */ (0,
|
|
7135
|
-
/* @__PURE__ */ (0,
|
|
7136
|
-
/* @__PURE__ */ (0,
|
|
7263
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "flex flex-col gap-1", children: [
|
|
7264
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", { className: "text-slate-300 text-[11px] font-medium", children: "Target Mask Region" }),
|
|
7265
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "grid grid-cols-2 gap-1.5", children: [
|
|
7266
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(
|
|
7137
7267
|
"button",
|
|
7138
7268
|
{
|
|
7139
7269
|
type: "button",
|
|
@@ -7146,7 +7276,7 @@ var ImageEditor = ({
|
|
|
7146
7276
|
]
|
|
7147
7277
|
}
|
|
7148
7278
|
),
|
|
7149
|
-
/* @__PURE__ */ (0,
|
|
7279
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(
|
|
7150
7280
|
"button",
|
|
7151
7281
|
{
|
|
7152
7282
|
type: "button",
|
|
@@ -7161,25 +7291,25 @@ var ImageEditor = ({
|
|
|
7161
7291
|
)
|
|
7162
7292
|
] })
|
|
7163
7293
|
] }),
|
|
7164
|
-
/* @__PURE__ */ (0,
|
|
7294
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
7165
7295
|
"button",
|
|
7166
7296
|
{
|
|
7167
7297
|
type: "button",
|
|
7168
7298
|
onClick: handleInpaint,
|
|
7169
7299
|
disabled: isInpainting || isRemovingBg || !inpaintPrompt.trim(),
|
|
7170
7300
|
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",
|
|
7171
|
-
children: isInpainting ? /* @__PURE__ */ (0,
|
|
7172
|
-
/* @__PURE__ */ (0,
|
|
7301
|
+
children: isInpainting ? /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(import_jsx_runtime30.Fragment, { children: [
|
|
7302
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("div", { className: "w-3.5 h-3.5 border-2 border-white/30 border-t-white rounded-full animate-spin" }),
|
|
7173
7303
|
"Generating Inpaint..."
|
|
7174
|
-
] }) : /* @__PURE__ */ (0,
|
|
7175
|
-
/* @__PURE__ */ (0,
|
|
7304
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(import_jsx_runtime30.Fragment, { children: [
|
|
7305
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("svg", { className: "w-3.5 h-3.5", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("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" }) }),
|
|
7176
7306
|
"Apply Inpainting"
|
|
7177
7307
|
] })
|
|
7178
7308
|
}
|
|
7179
7309
|
)
|
|
7180
7310
|
] }),
|
|
7181
|
-
aiError && /* @__PURE__ */ (0,
|
|
7182
|
-
aiSuccess && /* @__PURE__ */ (0,
|
|
7311
|
+
aiError && /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("div", { className: "p-2.5 rounded-lg bg-rose-950/60 border border-rose-800 text-rose-300 text-[11px]", children: aiError }),
|
|
7312
|
+
aiSuccess && /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("div", { className: "p-2.5 rounded-lg bg-emerald-950/60 border border-emerald-800 text-emerald-300 text-[11px]", children: aiSuccess })
|
|
7183
7313
|
] })
|
|
7184
7314
|
] })
|
|
7185
7315
|
] })
|
|
@@ -7189,7 +7319,7 @@ var ImageEditor = ({
|
|
|
7189
7319
|
};
|
|
7190
7320
|
|
|
7191
7321
|
// src/review/useReview.ts
|
|
7192
|
-
var
|
|
7322
|
+
var import_react48 = require("react");
|
|
7193
7323
|
var import_editor12 = require("@pixerate/editor");
|
|
7194
7324
|
var EMPTY_COMMENTS = Object.freeze({
|
|
7195
7325
|
threads: [],
|
|
@@ -7208,23 +7338,23 @@ function isCommentStore(value) {
|
|
|
7208
7338
|
}
|
|
7209
7339
|
function useComments(source) {
|
|
7210
7340
|
const store = isCommentStore(source) ? source : (0, import_editor12.getCommentStore)(source);
|
|
7211
|
-
const subscribe = (0,
|
|
7341
|
+
const subscribe = (0, import_react48.useCallback)(
|
|
7212
7342
|
(onChange) => store ? store.subscribe(() => onChange()) : noopUnsubscribe,
|
|
7213
7343
|
[store]
|
|
7214
7344
|
);
|
|
7215
7345
|
const getSnapshot = () => store?.getSnapshot() ?? EMPTY_COMMENTS;
|
|
7216
|
-
const snapshot = (0,
|
|
7217
|
-
return (0,
|
|
7346
|
+
const snapshot = (0, import_react48.useSyncExternalStore)(subscribe, getSnapshot, getSnapshot);
|
|
7347
|
+
return (0, import_react48.useMemo)(() => ({ ...snapshot, store }), [snapshot, store]);
|
|
7218
7348
|
}
|
|
7219
7349
|
function useTrackChanges(editor) {
|
|
7220
7350
|
const store = (0, import_editor12.getTrackChangesStore)(editor ?? null);
|
|
7221
|
-
const subscribe = (0,
|
|
7351
|
+
const subscribe = (0, import_react48.useCallback)(
|
|
7222
7352
|
(onChange) => store ? store.subscribe(() => onChange()) : noopUnsubscribe,
|
|
7223
7353
|
[store]
|
|
7224
7354
|
);
|
|
7225
7355
|
const getSnapshot = () => store?.getSnapshot() ?? EMPTY_TRACK_CHANGES;
|
|
7226
|
-
const snapshot = (0,
|
|
7227
|
-
return (0,
|
|
7356
|
+
const snapshot = (0, import_react48.useSyncExternalStore)(subscribe, getSnapshot, getSnapshot);
|
|
7357
|
+
return (0, import_react48.useMemo)(() => {
|
|
7228
7358
|
const run = (fn) => () => {
|
|
7229
7359
|
if (editor && !editor.isDestroyed) fn(editor);
|
|
7230
7360
|
};
|
|
@@ -7247,9 +7377,9 @@ function useTrackChanges(editor) {
|
|
|
7247
7377
|
}
|
|
7248
7378
|
|
|
7249
7379
|
// src/review/CommentsPanel.tsx
|
|
7250
|
-
var
|
|
7380
|
+
var import_react49 = require("react");
|
|
7251
7381
|
var import_editor13 = require("@pixerate/editor");
|
|
7252
|
-
var
|
|
7382
|
+
var import_jsx_runtime31 = require("react/jsx-runtime");
|
|
7253
7383
|
var buttonClass2 = "rounded px-2 py-1 text-xs text-muted-foreground hover:bg-muted hover:text-foreground disabled:opacity-50";
|
|
7254
7384
|
var primaryButtonClass = "rounded px-2 py-1 text-xs bg-primary/10 text-primary hover:bg-primary/20 disabled:opacity-50";
|
|
7255
7385
|
var textareaClass = "w-full resize-y rounded-md border border-input bg-background p-2 text-sm text-foreground focus:outline-none focus:ring-2 focus:ring-primary";
|
|
@@ -7263,18 +7393,18 @@ var CommentsPanel = ({
|
|
|
7263
7393
|
emptyMessage = "No comments yet. Select text and add a comment."
|
|
7264
7394
|
}) => {
|
|
7265
7395
|
const { threads, activeThreadId, store } = useComments(storeProp ?? editor);
|
|
7266
|
-
const [showResolved, setShowResolved] = (0,
|
|
7396
|
+
const [showResolved, setShowResolved] = (0, import_react49.useState)(showResolvedInitial);
|
|
7267
7397
|
const author = authorProp ?? (0, import_editor13.getCommentAuthor)(editor) ?? { id: "anonymous", name: "Anonymous" };
|
|
7268
7398
|
const visible = threads.filter((t) => showResolved || !t.resolved);
|
|
7269
7399
|
const resolvedCount = threads.filter((t) => t.resolved).length;
|
|
7270
|
-
return /* @__PURE__ */ (0,
|
|
7271
|
-
/* @__PURE__ */ (0,
|
|
7272
|
-
/* @__PURE__ */ (0,
|
|
7400
|
+
return /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("aside", { className, "aria-label": "Comments", children: [
|
|
7401
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("div", { className: "flex items-center justify-between gap-2", children: [
|
|
7402
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("span", { className: "text-xs font-medium text-muted-foreground", children: [
|
|
7273
7403
|
threads.length - resolvedCount,
|
|
7274
7404
|
" open",
|
|
7275
7405
|
resolvedCount > 0 ? ` \xB7 ${resolvedCount} resolved` : ""
|
|
7276
7406
|
] }),
|
|
7277
|
-
resolvedCount > 0 && /* @__PURE__ */ (0,
|
|
7407
|
+
resolvedCount > 0 && /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
|
|
7278
7408
|
"button",
|
|
7279
7409
|
{
|
|
7280
7410
|
type: "button",
|
|
@@ -7285,7 +7415,7 @@ var CommentsPanel = ({
|
|
|
7285
7415
|
}
|
|
7286
7416
|
)
|
|
7287
7417
|
] }),
|
|
7288
|
-
visible.length === 0 ? /* @__PURE__ */ (0,
|
|
7418
|
+
visible.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("p", { className: "text-xs text-muted-foreground", children: emptyMessage }) : /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("ul", { className: "flex flex-col gap-2", role: "list", children: visible.map((thread) => /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
|
|
7289
7419
|
CommentThreadCard,
|
|
7290
7420
|
{
|
|
7291
7421
|
thread,
|
|
@@ -7307,7 +7437,7 @@ var CommentThreadCard = ({
|
|
|
7307
7437
|
author,
|
|
7308
7438
|
formatTime
|
|
7309
7439
|
}) => {
|
|
7310
|
-
const [draft, setDraft] = (0,
|
|
7440
|
+
const [draft, setDraft] = (0, import_react49.useState)("");
|
|
7311
7441
|
const isDraft = thread.body === "";
|
|
7312
7442
|
const quote = thread.anchor?.quote ?? thread.lastQuote ?? "";
|
|
7313
7443
|
const live = editor && !editor.isDestroyed ? editor : null;
|
|
@@ -7333,7 +7463,7 @@ var CommentThreadCard = ({
|
|
|
7333
7463
|
setDraft("");
|
|
7334
7464
|
};
|
|
7335
7465
|
const stop = (e) => e.stopPropagation();
|
|
7336
|
-
return /* @__PURE__ */ (0,
|
|
7466
|
+
return /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(
|
|
7337
7467
|
"li",
|
|
7338
7468
|
{
|
|
7339
7469
|
className: `flex flex-col gap-2 rounded-md border bg-background p-3 cursor-pointer ${active ? "border-primary ring-1 ring-primary" : "border-border"} ${thread.resolved ? "opacity-70" : ""}`,
|
|
@@ -7349,24 +7479,24 @@ var CommentThreadCard = ({
|
|
|
7349
7479
|
}
|
|
7350
7480
|
},
|
|
7351
7481
|
children: [
|
|
7352
|
-
/* @__PURE__ */ (0,
|
|
7353
|
-
/* @__PURE__ */ (0,
|
|
7354
|
-
/* @__PURE__ */ (0,
|
|
7482
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("div", { className: "flex items-baseline justify-between gap-2", children: [
|
|
7483
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)("span", { className: "font-medium", children: thread.author.name }),
|
|
7484
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)("span", { className: "text-xs text-muted-foreground", children: formatTime(thread.createdAt) })
|
|
7355
7485
|
] }),
|
|
7356
|
-
quote && /* @__PURE__ */ (0,
|
|
7357
|
-
thread.orphaned && /* @__PURE__ */ (0,
|
|
7358
|
-
thread.resolved && /* @__PURE__ */ (0,
|
|
7359
|
-
!isDraft && /* @__PURE__ */ (0,
|
|
7360
|
-
thread.replies.length > 0 && /* @__PURE__ */ (0,
|
|
7361
|
-
/* @__PURE__ */ (0,
|
|
7362
|
-
/* @__PURE__ */ (0,
|
|
7486
|
+
quote && /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("blockquote", { className: "border-l-2 border-border pl-2 text-xs text-muted-foreground line-clamp-2", children: quote }),
|
|
7487
|
+
thread.orphaned && /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("span", { className: "text-xs text-destructive", children: "The commented text was deleted." }),
|
|
7488
|
+
thread.resolved && /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("span", { className: "text-xs text-muted-foreground", children: "Resolved" }),
|
|
7489
|
+
!isDraft && /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("p", { className: "whitespace-pre-wrap break-words", children: thread.body }),
|
|
7490
|
+
thread.replies.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("ul", { className: "flex flex-col gap-2 border-l border-border pl-3", role: "list", children: thread.replies.map((reply) => /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("li", { className: "flex flex-col gap-0.5", "data-reply-id": reply.id, children: [
|
|
7491
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("span", { className: "text-xs", children: [
|
|
7492
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)("span", { className: "font-medium", children: reply.author.name }),
|
|
7363
7493
|
" ",
|
|
7364
|
-
/* @__PURE__ */ (0,
|
|
7494
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)("span", { className: "text-muted-foreground", children: formatTime(reply.createdAt) })
|
|
7365
7495
|
] }),
|
|
7366
|
-
/* @__PURE__ */ (0,
|
|
7496
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)("p", { className: "whitespace-pre-wrap break-words", children: reply.body })
|
|
7367
7497
|
] }, reply.id)) }),
|
|
7368
|
-
(active || isDraft) && !thread.resolved && /* @__PURE__ */ (0,
|
|
7369
|
-
/* @__PURE__ */ (0,
|
|
7498
|
+
(active || isDraft) && !thread.resolved && /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("div", { className: "flex flex-col gap-1", onClick: stop, children: [
|
|
7499
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
|
|
7370
7500
|
"textarea",
|
|
7371
7501
|
{
|
|
7372
7502
|
className: textareaClass,
|
|
@@ -7384,9 +7514,9 @@ var CommentThreadCard = ({
|
|
|
7384
7514
|
}
|
|
7385
7515
|
}
|
|
7386
7516
|
),
|
|
7387
|
-
/* @__PURE__ */ (0,
|
|
7388
|
-
isDraft && /* @__PURE__ */ (0,
|
|
7389
|
-
/* @__PURE__ */ (0,
|
|
7517
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("div", { className: "flex justify-end gap-1", children: [
|
|
7518
|
+
isDraft && /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("button", { type: "button", className: buttonClass2, onClick: remove, children: "Cancel" }),
|
|
7519
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
|
|
7390
7520
|
"button",
|
|
7391
7521
|
{
|
|
7392
7522
|
type: "button",
|
|
@@ -7398,9 +7528,9 @@ var CommentThreadCard = ({
|
|
|
7398
7528
|
)
|
|
7399
7529
|
] })
|
|
7400
7530
|
] }),
|
|
7401
|
-
!isDraft && /* @__PURE__ */ (0,
|
|
7402
|
-
/* @__PURE__ */ (0,
|
|
7403
|
-
/* @__PURE__ */ (0,
|
|
7531
|
+
!isDraft && /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("div", { className: "flex justify-end gap-1", onClick: stop, children: [
|
|
7532
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)("button", { type: "button", className: buttonClass2, onClick: () => setResolved(!thread.resolved), children: thread.resolved ? "Reopen" : "Resolve" }),
|
|
7533
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
|
|
7404
7534
|
"button",
|
|
7405
7535
|
{
|
|
7406
7536
|
type: "button",
|
|
@@ -7416,7 +7546,7 @@ var CommentThreadCard = ({
|
|
|
7416
7546
|
};
|
|
7417
7547
|
|
|
7418
7548
|
// src/review/ReviewToolbar.tsx
|
|
7419
|
-
var
|
|
7549
|
+
var import_jsx_runtime32 = require("react/jsx-runtime");
|
|
7420
7550
|
var defaultDescriptionClass = "max-w-[16rem] truncate px-1 text-xs text-muted-foreground";
|
|
7421
7551
|
var buttonClass3 = "rounded px-2 py-1 text-xs text-foreground hover:bg-muted disabled:opacity-40 disabled:hover:bg-transparent";
|
|
7422
7552
|
var ReviewToolbar = ({
|
|
@@ -7429,8 +7559,8 @@ var ReviewToolbar = ({
|
|
|
7429
7559
|
const count = review.changes.length;
|
|
7430
7560
|
const current = review.currentChange;
|
|
7431
7561
|
const index = current ? review.changes.findIndex((c) => c.id === current.id) + 1 : 0;
|
|
7432
|
-
return /* @__PURE__ */ (0,
|
|
7433
|
-
/* @__PURE__ */ (0,
|
|
7562
|
+
return /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { className, role: "toolbar", "aria-label": "Review", children: [
|
|
7563
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
7434
7564
|
"button",
|
|
7435
7565
|
{
|
|
7436
7566
|
type: "button",
|
|
@@ -7441,8 +7571,8 @@ var ReviewToolbar = ({
|
|
|
7441
7571
|
children: review.enabled ? "Tracking on" : "Track changes"
|
|
7442
7572
|
}
|
|
7443
7573
|
),
|
|
7444
|
-
/* @__PURE__ */ (0,
|
|
7445
|
-
/* @__PURE__ */ (0,
|
|
7574
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)("span", { className: "mx-1 h-4 w-px bg-border", "aria-hidden": "true" }),
|
|
7575
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
7446
7576
|
"button",
|
|
7447
7577
|
{
|
|
7448
7578
|
type: "button",
|
|
@@ -7453,8 +7583,8 @@ var ReviewToolbar = ({
|
|
|
7453
7583
|
children: "\u2039"
|
|
7454
7584
|
}
|
|
7455
7585
|
),
|
|
7456
|
-
/* @__PURE__ */ (0,
|
|
7457
|
-
/* @__PURE__ */ (0,
|
|
7586
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)("span", { className: "min-w-[4rem] text-center text-xs text-muted-foreground", "aria-live": "polite", children: count === 0 ? "No changes" : current ? `${index} of ${count}` : `${count} changes` }),
|
|
7587
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
7458
7588
|
"button",
|
|
7459
7589
|
{
|
|
7460
7590
|
type: "button",
|
|
@@ -7465,7 +7595,7 @@ var ReviewToolbar = ({
|
|
|
7465
7595
|
children: "\u203A"
|
|
7466
7596
|
}
|
|
7467
7597
|
),
|
|
7468
|
-
showDescription && current && /* @__PURE__ */ (0,
|
|
7598
|
+
showDescription && current && /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(
|
|
7469
7599
|
"span",
|
|
7470
7600
|
{
|
|
7471
7601
|
className: descriptionClassName,
|
|
@@ -7477,8 +7607,8 @@ var ReviewToolbar = ({
|
|
|
7477
7607
|
]
|
|
7478
7608
|
}
|
|
7479
7609
|
),
|
|
7480
|
-
/* @__PURE__ */ (0,
|
|
7481
|
-
/* @__PURE__ */ (0,
|
|
7610
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)("span", { className: "mx-1 h-4 w-px bg-border", "aria-hidden": "true" }),
|
|
7611
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
7482
7612
|
"button",
|
|
7483
7613
|
{
|
|
7484
7614
|
type: "button",
|
|
@@ -7488,7 +7618,7 @@ var ReviewToolbar = ({
|
|
|
7488
7618
|
children: "Accept"
|
|
7489
7619
|
}
|
|
7490
7620
|
),
|
|
7491
|
-
/* @__PURE__ */ (0,
|
|
7621
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
7492
7622
|
"button",
|
|
7493
7623
|
{
|
|
7494
7624
|
type: "button",
|
|
@@ -7498,18 +7628,18 @@ var ReviewToolbar = ({
|
|
|
7498
7628
|
children: "Reject"
|
|
7499
7629
|
}
|
|
7500
7630
|
),
|
|
7501
|
-
/* @__PURE__ */ (0,
|
|
7502
|
-
/* @__PURE__ */ (0,
|
|
7631
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)("button", { type: "button", className: buttonClass3, disabled: count === 0, onClick: review.acceptAll, children: "Accept all" }),
|
|
7632
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)("button", { type: "button", className: buttonClass3, disabled: count === 0, onClick: review.rejectAll, children: "Reject all" })
|
|
7503
7633
|
] });
|
|
7504
7634
|
};
|
|
7505
7635
|
|
|
7506
7636
|
// src/review/CommentButton.tsx
|
|
7507
|
-
var
|
|
7637
|
+
var import_jsx_runtime33 = require("react/jsx-runtime");
|
|
7508
7638
|
var CommentButton = ({
|
|
7509
7639
|
editor,
|
|
7510
7640
|
className = "rounded px-2 py-1 text-xs text-popover-foreground hover:bg-muted",
|
|
7511
7641
|
children = "Comment"
|
|
7512
|
-
}) => /* @__PURE__ */ (0,
|
|
7642
|
+
}) => /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
|
|
7513
7643
|
"button",
|
|
7514
7644
|
{
|
|
7515
7645
|
type: "button",
|
|
@@ -7521,13 +7651,13 @@ var CommentButton = ({
|
|
|
7521
7651
|
);
|
|
7522
7652
|
|
|
7523
7653
|
// src/review/useDocumentCompare.ts
|
|
7524
|
-
var
|
|
7654
|
+
var import_react50 = require("react");
|
|
7525
7655
|
var import_editor14 = require("@pixerate/editor");
|
|
7526
7656
|
function useDocumentCompare(editor, options) {
|
|
7527
|
-
const [summary, setSummary] = (0,
|
|
7528
|
-
const defaults = (0,
|
|
7657
|
+
const [summary, setSummary] = (0, import_react50.useState)(null);
|
|
7658
|
+
const defaults = (0, import_react50.useRef)(options);
|
|
7529
7659
|
defaults.current = options;
|
|
7530
|
-
const compare = (0,
|
|
7660
|
+
const compare = (0, import_react50.useCallback)(
|
|
7531
7661
|
(original, revised, overrides) => {
|
|
7532
7662
|
if (!editor || editor.isDestroyed) return null;
|
|
7533
7663
|
const result = (0, import_editor14.applyDocumentComparison)(editor, original, revised, {
|
|
@@ -7539,13 +7669,13 @@ function useDocumentCompare(editor, options) {
|
|
|
7539
7669
|
},
|
|
7540
7670
|
[editor]
|
|
7541
7671
|
);
|
|
7542
|
-
const clear = (0,
|
|
7543
|
-
return (0,
|
|
7672
|
+
const clear = (0, import_react50.useCallback)(() => setSummary(null), []);
|
|
7673
|
+
return (0, import_react50.useMemo)(() => ({ summary, compare, clear }), [summary, compare, clear]);
|
|
7544
7674
|
}
|
|
7545
7675
|
|
|
7546
7676
|
// src/review/TrackedChangesList.tsx
|
|
7547
7677
|
var import_editor15 = require("@pixerate/editor");
|
|
7548
|
-
var
|
|
7678
|
+
var import_jsx_runtime34 = require("react/jsx-runtime");
|
|
7549
7679
|
var buttonClass4 = "rounded px-1.5 py-0.5 text-xs text-foreground hover:bg-muted disabled:opacity-40";
|
|
7550
7680
|
var TrackedChangesList = ({
|
|
7551
7681
|
editor,
|
|
@@ -7556,18 +7686,18 @@ var TrackedChangesList = ({
|
|
|
7556
7686
|
}) => {
|
|
7557
7687
|
const review = useTrackChanges(editor);
|
|
7558
7688
|
if (review.changes.length === 0) {
|
|
7559
|
-
return /* @__PURE__ */ (0,
|
|
7689
|
+
return /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("div", { className, "data-tracked-changes-list": "", children: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("div", { className: "pixerate-changes-empty text-xs text-muted-foreground", children: emptyState }) });
|
|
7560
7690
|
}
|
|
7561
|
-
return /* @__PURE__ */ (0,
|
|
7691
|
+
return /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("ul", { className, role: "list", "aria-label": "Tracked changes", "data-tracked-changes-list": "", children: review.changes.map((change) => {
|
|
7562
7692
|
const active = change.id === review.currentChangeId;
|
|
7563
|
-
return /* @__PURE__ */ (0,
|
|
7693
|
+
return /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(
|
|
7564
7694
|
"li",
|
|
7565
7695
|
{
|
|
7566
7696
|
className: active ? `${itemClassName} ${activeItemClassName}` : itemClassName,
|
|
7567
7697
|
"data-change-type": change.type,
|
|
7568
7698
|
"data-change-id": change.id,
|
|
7569
7699
|
children: [
|
|
7570
|
-
/* @__PURE__ */ (0,
|
|
7700
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(
|
|
7571
7701
|
"button",
|
|
7572
7702
|
{
|
|
7573
7703
|
type: "button",
|
|
@@ -7575,14 +7705,14 @@ var TrackedChangesList = ({
|
|
|
7575
7705
|
title: `${change.author.name}: ${change.description}`,
|
|
7576
7706
|
onClick: () => review.select(change.id),
|
|
7577
7707
|
children: [
|
|
7578
|
-
/* @__PURE__ */ (0,
|
|
7708
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)("span", { className: "font-medium", children: (0, import_editor15.trackedChangeLabel)(change) }),
|
|
7579
7709
|
change.author.name ? ` \xB7 ${change.author.name}` : "",
|
|
7580
|
-
/* @__PURE__ */ (0,
|
|
7710
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)("span", { className: "block truncate text-muted-foreground", children: change.description })
|
|
7581
7711
|
]
|
|
7582
7712
|
}
|
|
7583
7713
|
),
|
|
7584
|
-
/* @__PURE__ */ (0,
|
|
7585
|
-
/* @__PURE__ */ (0,
|
|
7714
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)("button", { type: "button", className: buttonClass4, onClick: () => review.accept(change.id), children: "Accept" }),
|
|
7715
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)("button", { type: "button", className: buttonClass4, onClick: () => review.reject(change.id), children: "Reject" })
|
|
7586
7716
|
]
|
|
7587
7717
|
},
|
|
7588
7718
|
`${change.type}:${change.id}`
|
|
@@ -7591,12 +7721,12 @@ var TrackedChangesList = ({
|
|
|
7591
7721
|
};
|
|
7592
7722
|
|
|
7593
7723
|
// src/commands/useCommandPalette.ts
|
|
7594
|
-
var
|
|
7724
|
+
var import_react51 = require("react");
|
|
7595
7725
|
var import_commands2 = require("@pixerate/editor/commands");
|
|
7596
7726
|
function useCommandPalette(registry, options = {}) {
|
|
7597
|
-
const optionsRef = (0,
|
|
7727
|
+
const optionsRef = (0, import_react51.useRef)(options);
|
|
7598
7728
|
optionsRef.current = options;
|
|
7599
|
-
const controller = (0,
|
|
7729
|
+
const controller = (0, import_react51.useMemo)(
|
|
7600
7730
|
() => (0, import_commands2.createCommandPaletteController)(registry, {
|
|
7601
7731
|
context: () => {
|
|
7602
7732
|
const c = optionsRef.current.context;
|
|
@@ -7617,9 +7747,9 @@ function useCommandPalette(registry, options = {}) {
|
|
|
7617
7747
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
7618
7748
|
[registry]
|
|
7619
7749
|
);
|
|
7620
|
-
const state = (0,
|
|
7750
|
+
const state = (0, import_react51.useSyncExternalStore)(controller.subscribe, controller.getState, controller.getState);
|
|
7621
7751
|
const { hotkey, hotkeyTarget } = options;
|
|
7622
|
-
(0,
|
|
7752
|
+
(0, import_react51.useEffect)(() => {
|
|
7623
7753
|
if (!hotkey) return;
|
|
7624
7754
|
const target = hotkeyTarget ?? (typeof window !== "undefined" ? window : null);
|
|
7625
7755
|
if (!target) return;
|
|
@@ -7647,13 +7777,13 @@ function useCommandPalette(registry, options = {}) {
|
|
|
7647
7777
|
}
|
|
7648
7778
|
|
|
7649
7779
|
// src/commands/CommandPalette.tsx
|
|
7650
|
-
var
|
|
7651
|
-
var
|
|
7780
|
+
var import_react52 = __toESM(require("react"), 1);
|
|
7781
|
+
var import_jsx_runtime35 = require("react/jsx-runtime");
|
|
7652
7782
|
function HighlightedLabel({ item }) {
|
|
7653
|
-
if (item.labelIndices.length === 0) return /* @__PURE__ */ (0,
|
|
7783
|
+
if (item.labelIndices.length === 0) return /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(import_jsx_runtime35.Fragment, { children: item.label });
|
|
7654
7784
|
const marked = new Set(item.labelIndices);
|
|
7655
|
-
return /* @__PURE__ */ (0,
|
|
7656
|
-
(ch, i) => marked.has(i) ? /* @__PURE__ */ (0,
|
|
7785
|
+
return /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(import_jsx_runtime35.Fragment, { children: Array.from(item.label).map(
|
|
7786
|
+
(ch, i) => marked.has(i) ? /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("span", { className: "font-semibold text-foreground", "data-match": "", children: ch }, i) : /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(import_react52.default.Fragment, { children: ch }, i)
|
|
7657
7787
|
) });
|
|
7658
7788
|
}
|
|
7659
7789
|
var CommandPalette = ({
|
|
@@ -7662,22 +7792,22 @@ var CommandPalette = ({
|
|
|
7662
7792
|
emptyMessage = "No matching commands",
|
|
7663
7793
|
className = ""
|
|
7664
7794
|
}) => {
|
|
7665
|
-
const inputRef = (0,
|
|
7666
|
-
const listRef = (0,
|
|
7667
|
-
const baseId = (0,
|
|
7795
|
+
const inputRef = (0, import_react52.useRef)(null);
|
|
7796
|
+
const listRef = (0, import_react52.useRef)(null);
|
|
7797
|
+
const baseId = (0, import_react52.useId)();
|
|
7668
7798
|
const listId = `${baseId}-list`;
|
|
7669
7799
|
const optionId = (index) => `${baseId}-option-${index}`;
|
|
7670
7800
|
const { open, query, items, activeIndex } = palette;
|
|
7671
|
-
(0,
|
|
7801
|
+
(0, import_react52.useEffect)(() => {
|
|
7672
7802
|
if (open) inputRef.current?.focus();
|
|
7673
7803
|
}, [open]);
|
|
7674
|
-
(0,
|
|
7804
|
+
(0, import_react52.useEffect)(() => {
|
|
7675
7805
|
if (!open) return;
|
|
7676
7806
|
const active = listRef.current?.querySelector('[aria-selected="true"]');
|
|
7677
7807
|
active?.scrollIntoView?.({ block: "nearest" });
|
|
7678
7808
|
}, [open, activeIndex]);
|
|
7679
7809
|
if (!open) return null;
|
|
7680
|
-
return /* @__PURE__ */ (0,
|
|
7810
|
+
return /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
|
|
7681
7811
|
"div",
|
|
7682
7812
|
{
|
|
7683
7813
|
className: "fixed inset-0 z-50 flex items-start justify-center bg-black/30 px-4 pt-[15vh]",
|
|
@@ -7685,7 +7815,7 @@ var CommandPalette = ({
|
|
|
7685
7815
|
onMouseDown: (e) => {
|
|
7686
7816
|
if (e.target === e.currentTarget) palette.setOpen(false);
|
|
7687
7817
|
},
|
|
7688
|
-
children: /* @__PURE__ */ (0,
|
|
7818
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)(
|
|
7689
7819
|
"div",
|
|
7690
7820
|
{
|
|
7691
7821
|
role: "dialog",
|
|
@@ -7694,7 +7824,7 @@ var CommandPalette = ({
|
|
|
7694
7824
|
className: `w-full max-w-lg overflow-hidden rounded-lg border border-border bg-popover text-popover-foreground shadow-xl ${className}`,
|
|
7695
7825
|
style: { background: "var(--popover, var(--background, #fff))" },
|
|
7696
7826
|
children: [
|
|
7697
|
-
/* @__PURE__ */ (0,
|
|
7827
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
|
|
7698
7828
|
"input",
|
|
7699
7829
|
{
|
|
7700
7830
|
ref: inputRef,
|
|
@@ -7714,7 +7844,7 @@ var CommandPalette = ({
|
|
|
7714
7844
|
className: "w-full border-b border-border bg-transparent px-3 py-2 text-sm outline-none placeholder:text-muted-foreground"
|
|
7715
7845
|
}
|
|
7716
7846
|
),
|
|
7717
|
-
items.length === 0 ? /* @__PURE__ */ (0,
|
|
7847
|
+
items.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("div", { className: "px-3 py-6 text-center text-sm text-muted-foreground", children: emptyMessage }) : /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("ul", { ref: listRef, id: listId, role: "listbox", "aria-label": "Commands", className: "max-h-80 overflow-y-auto py-1", children: items.map((item, index) => /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)(
|
|
7718
7848
|
"li",
|
|
7719
7849
|
{
|
|
7720
7850
|
id: optionId(index),
|
|
@@ -7729,12 +7859,12 @@ var CommandPalette = ({
|
|
|
7729
7859
|
onClick: () => palette.run(item.id),
|
|
7730
7860
|
className: `flex cursor-pointer items-center gap-2 px-3 py-1.5 text-sm ${index === activeIndex ? "bg-muted" : ""} ${item.enabled ? "" : "cursor-default opacity-50"}`,
|
|
7731
7861
|
children: [
|
|
7732
|
-
/* @__PURE__ */ (0,
|
|
7733
|
-
/* @__PURE__ */ (0,
|
|
7734
|
-
item.disabledReason && /* @__PURE__ */ (0,
|
|
7862
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("span", { className: "min-w-0 flex-1 truncate", children: [
|
|
7863
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsx)(HighlightedLabel, { item }),
|
|
7864
|
+
item.disabledReason && /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("span", { className: "ml-2 text-xs text-muted-foreground", "data-disabled-reason": "", children: item.disabledReason })
|
|
7735
7865
|
] }),
|
|
7736
|
-
item.group && /* @__PURE__ */ (0,
|
|
7737
|
-
item.shortcut && /* @__PURE__ */ (0,
|
|
7866
|
+
item.group && /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("span", { className: "shrink-0 text-xs text-muted-foreground", children: item.group }),
|
|
7867
|
+
item.shortcut && /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("kbd", { className: "shrink-0 rounded border border-border px-1.5 font-mono text-[10px] text-muted-foreground", children: item.shortcut })
|
|
7738
7868
|
]
|
|
7739
7869
|
},
|
|
7740
7870
|
item.id
|
|
@@ -7747,12 +7877,12 @@ var CommandPalette = ({
|
|
|
7747
7877
|
};
|
|
7748
7878
|
|
|
7749
7879
|
// src/commands/useCommandShortcuts.ts
|
|
7750
|
-
var
|
|
7880
|
+
var import_react53 = require("react");
|
|
7751
7881
|
function useCommandShortcuts(registry, options = {}) {
|
|
7752
|
-
const optionsRef = (0,
|
|
7882
|
+
const optionsRef = (0, import_react53.useRef)(options);
|
|
7753
7883
|
optionsRef.current = options;
|
|
7754
7884
|
const { enabled = true, target } = options;
|
|
7755
|
-
(0,
|
|
7885
|
+
(0, import_react53.useEffect)(() => {
|
|
7756
7886
|
if (!registry || !enabled) return;
|
|
7757
7887
|
const eventTarget = target ?? (typeof window !== "undefined" ? window : null);
|
|
7758
7888
|
if (!eventTarget) return;
|
|
@@ -7770,14 +7900,14 @@ function useCommandShortcuts(registry, options = {}) {
|
|
|
7770
7900
|
}, [registry, enabled, target]);
|
|
7771
7901
|
}
|
|
7772
7902
|
function useRegisterCommands(registry, specs) {
|
|
7773
|
-
(0,
|
|
7903
|
+
(0, import_react53.useEffect)(() => {
|
|
7774
7904
|
if (!registry || !specs || specs.length === 0) return;
|
|
7775
7905
|
return registry.register(specs);
|
|
7776
7906
|
}, [registry, specs]);
|
|
7777
7907
|
}
|
|
7778
7908
|
|
|
7779
7909
|
// src/persistence/useAutosave.ts
|
|
7780
|
-
var
|
|
7910
|
+
var import_react54 = require("react");
|
|
7781
7911
|
var import_persistence = require("@pixerate/editor/persistence");
|
|
7782
7912
|
var IDLE = {
|
|
7783
7913
|
status: "idle",
|
|
@@ -7788,18 +7918,18 @@ var IDLE = {
|
|
|
7788
7918
|
ready: false
|
|
7789
7919
|
};
|
|
7790
7920
|
function useAutosave(options) {
|
|
7791
|
-
const optionsRef = (0,
|
|
7921
|
+
const optionsRef = (0, import_react54.useRef)(options);
|
|
7792
7922
|
optionsRef.current = options;
|
|
7793
7923
|
const { storage, key, history, dirty } = options;
|
|
7794
7924
|
const recover = options.recover !== false;
|
|
7795
7925
|
const flushOnHide = options.flushOnHide !== false;
|
|
7796
7926
|
const ready = options.ready !== false;
|
|
7797
|
-
const [controller, setController] = (0,
|
|
7798
|
-
const [status, setStatus] = (0,
|
|
7799
|
-
const [recovery, setRecovery] = (0,
|
|
7800
|
-
const [pendingRecovery, setPendingRecovery] = (0,
|
|
7801
|
-
const revisionsRef = (0,
|
|
7802
|
-
(0,
|
|
7927
|
+
const [controller, setController] = (0, import_react54.useState)(null);
|
|
7928
|
+
const [status, setStatus] = (0, import_react54.useState)(IDLE);
|
|
7929
|
+
const [recovery, setRecovery] = (0, import_react54.useState)(null);
|
|
7930
|
+
const [pendingRecovery, setPendingRecovery] = (0, import_react54.useState)(recover);
|
|
7931
|
+
const revisionsRef = (0, import_react54.useRef)(null);
|
|
7932
|
+
(0, import_react54.useEffect)(() => {
|
|
7803
7933
|
const revisions = (0, import_persistence.createRevisionTracker)({ history, dirty });
|
|
7804
7934
|
const o = optionsRef.current;
|
|
7805
7935
|
const instance = (0, import_persistence.createAutosaveController)({
|
|
@@ -7842,10 +7972,10 @@ function useAutosave(options) {
|
|
|
7842
7972
|
if (revisionsRef.current === revisions) revisionsRef.current = null;
|
|
7843
7973
|
};
|
|
7844
7974
|
}, [storage, key, history, dirty, recover]);
|
|
7845
|
-
(0,
|
|
7975
|
+
(0, import_react54.useEffect)(() => {
|
|
7846
7976
|
if (controller && ready && !pendingRecovery) controller.ready();
|
|
7847
7977
|
}, [controller, ready, pendingRecovery]);
|
|
7848
|
-
(0,
|
|
7978
|
+
(0, import_react54.useEffect)(() => {
|
|
7849
7979
|
if (!controller || !flushOnHide || typeof window === "undefined") return;
|
|
7850
7980
|
const flush = () => void controller.flushNow();
|
|
7851
7981
|
const onVisibility = () => {
|
|
@@ -7858,31 +7988,31 @@ function useAutosave(options) {
|
|
|
7858
7988
|
document.removeEventListener("visibilitychange", onVisibility);
|
|
7859
7989
|
};
|
|
7860
7990
|
}, [controller, flushOnHide]);
|
|
7861
|
-
const restore = (0,
|
|
7991
|
+
const restore = (0, import_react54.useCallback)(() => {
|
|
7862
7992
|
const snapshot = recovery?.snapshot;
|
|
7863
7993
|
setRecovery(null);
|
|
7864
7994
|
setPendingRecovery(false);
|
|
7865
7995
|
return snapshot;
|
|
7866
7996
|
}, [recovery]);
|
|
7867
|
-
const discard = (0,
|
|
7997
|
+
const discard = (0, import_react54.useCallback)(async () => {
|
|
7868
7998
|
if (controller) await controller.discardRecovery();
|
|
7869
7999
|
setRecovery(null);
|
|
7870
8000
|
setPendingRecovery(false);
|
|
7871
8001
|
}, [controller]);
|
|
7872
|
-
const flushNow = (0,
|
|
8002
|
+
const flushNow = (0, import_react54.useCallback)(async () => {
|
|
7873
8003
|
await controller?.flushNow();
|
|
7874
8004
|
}, [controller]);
|
|
7875
|
-
const markClean = (0,
|
|
8005
|
+
const markClean = (0, import_react54.useCallback)(async () => {
|
|
7876
8006
|
revisionsRef.current?.markSaved();
|
|
7877
8007
|
await controller?.markClean();
|
|
7878
8008
|
}, [controller]);
|
|
7879
|
-
const notifyChange = (0,
|
|
8009
|
+
const notifyChange = (0, import_react54.useCallback)(() => revisionsRef.current?.bump(), []);
|
|
7880
8010
|
return { status, recovery, pendingRecovery, restore, discard, flushNow, markClean, notifyChange, controller };
|
|
7881
8011
|
}
|
|
7882
8012
|
|
|
7883
8013
|
// src/persistence/RecoveryPrompt.tsx
|
|
7884
8014
|
var import_persistence2 = require("@pixerate/editor/persistence");
|
|
7885
|
-
var
|
|
8015
|
+
var import_jsx_runtime36 = require("react/jsx-runtime");
|
|
7886
8016
|
var RecoveryPrompt = ({
|
|
7887
8017
|
recovery,
|
|
7888
8018
|
onRestore,
|
|
@@ -7894,7 +8024,7 @@ var RecoveryPrompt = ({
|
|
|
7894
8024
|
}) => {
|
|
7895
8025
|
if (!recovery) return null;
|
|
7896
8026
|
const { name } = recovery.meta;
|
|
7897
|
-
return /* @__PURE__ */ (0,
|
|
8027
|
+
return /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(
|
|
7898
8028
|
"div",
|
|
7899
8029
|
{
|
|
7900
8030
|
role: "alertdialog",
|
|
@@ -7902,15 +8032,15 @@ var RecoveryPrompt = ({
|
|
|
7902
8032
|
"data-recovery-prompt": "",
|
|
7903
8033
|
className: `flex flex-wrap items-center gap-3 rounded-md border border-border bg-background px-3 py-2 text-sm text-foreground shadow-sm ${className}`,
|
|
7904
8034
|
children: [
|
|
7905
|
-
/* @__PURE__ */ (0,
|
|
8035
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("span", { className: "min-w-0 flex-1", children: [
|
|
7906
8036
|
(0, import_persistence2.formatRecoveryMessage)(recovery.meta, formatTime),
|
|
7907
|
-
name ? /* @__PURE__ */ (0,
|
|
8037
|
+
name ? /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("span", { className: "ml-1 text-xs text-muted-foreground", children: [
|
|
7908
8038
|
"(",
|
|
7909
8039
|
name,
|
|
7910
8040
|
")"
|
|
7911
8041
|
] }) : null
|
|
7912
8042
|
] }),
|
|
7913
|
-
/* @__PURE__ */ (0,
|
|
8043
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
7914
8044
|
"button",
|
|
7915
8045
|
{
|
|
7916
8046
|
type: "button",
|
|
@@ -7920,7 +8050,7 @@ var RecoveryPrompt = ({
|
|
|
7920
8050
|
children: restoreLabel
|
|
7921
8051
|
}
|
|
7922
8052
|
),
|
|
7923
|
-
/* @__PURE__ */ (0,
|
|
8053
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
7924
8054
|
"button",
|
|
7925
8055
|
{
|
|
7926
8056
|
type: "button",
|
|
@@ -7936,17 +8066,17 @@ var RecoveryPrompt = ({
|
|
|
7936
8066
|
};
|
|
7937
8067
|
|
|
7938
8068
|
// src/generation/useGenerationPlan.ts
|
|
7939
|
-
var
|
|
8069
|
+
var import_react55 = require("react");
|
|
7940
8070
|
var import_generation = require("@pixerate/editor/generation");
|
|
7941
8071
|
function useGenerationPlan(request, capabilities, options = {}) {
|
|
7942
8072
|
const key = JSON.stringify([request, capabilities, options]);
|
|
7943
|
-
return (0,
|
|
8073
|
+
return (0, import_react55.useMemo)(() => (0, import_generation.planGenerationRequest)(request, capabilities, options), [key]);
|
|
7944
8074
|
}
|
|
7945
8075
|
function useJobProgress(options) {
|
|
7946
8076
|
const { startedAt, expectedMs, done, now, intervalMs = 1e3 } = options;
|
|
7947
|
-
const [tick, setTick] = (0,
|
|
8077
|
+
const [tick, setTick] = (0, import_react55.useState)(() => Date.now());
|
|
7948
8078
|
const ticking = !done && now === void 0;
|
|
7949
|
-
(0,
|
|
8079
|
+
(0, import_react55.useEffect)(() => {
|
|
7950
8080
|
if (!ticking) return;
|
|
7951
8081
|
setTick(Date.now());
|
|
7952
8082
|
const id = setInterval(() => setTick(Date.now()), Math.max(16, intervalMs));
|
|
@@ -7956,9 +8086,9 @@ function useJobProgress(options) {
|
|
|
7956
8086
|
}
|
|
7957
8087
|
|
|
7958
8088
|
// src/generation/GenerationSettings.tsx
|
|
7959
|
-
var
|
|
8089
|
+
var import_react56 = require("react");
|
|
7960
8090
|
var import_generation2 = require("@pixerate/editor/generation");
|
|
7961
|
-
var
|
|
8091
|
+
var import_jsx_runtime37 = require("react/jsx-runtime");
|
|
7962
8092
|
var inputClass2 = "w-full rounded-md border border-border bg-background px-2 py-1 text-sm outline-none focus:ring-1 focus:ring-ring";
|
|
7963
8093
|
function Control({
|
|
7964
8094
|
control,
|
|
@@ -7968,7 +8098,7 @@ function Control({
|
|
|
7968
8098
|
}) {
|
|
7969
8099
|
const shown = value ?? control.defaultValue;
|
|
7970
8100
|
if (control.kind === "checkbox") {
|
|
7971
|
-
return /* @__PURE__ */ (0,
|
|
8101
|
+
return /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
|
|
7972
8102
|
"input",
|
|
7973
8103
|
{
|
|
7974
8104
|
id,
|
|
@@ -7980,7 +8110,7 @@ function Control({
|
|
|
7980
8110
|
);
|
|
7981
8111
|
}
|
|
7982
8112
|
if (control.kind === "select") {
|
|
7983
|
-
return /* @__PURE__ */ (0,
|
|
8113
|
+
return /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)(
|
|
7984
8114
|
"select",
|
|
7985
8115
|
{
|
|
7986
8116
|
id,
|
|
@@ -7989,14 +8119,14 @@ function Control({
|
|
|
7989
8119
|
value: shown === void 0 ? "" : String(shown),
|
|
7990
8120
|
onChange: (e) => onValue((0, import_generation2.parseControlValue)(control, e.target.value)),
|
|
7991
8121
|
children: [
|
|
7992
|
-
shown === void 0 && /* @__PURE__ */ (0,
|
|
7993
|
-
control.options.map((option) => /* @__PURE__ */ (0,
|
|
8122
|
+
shown === void 0 && /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("option", { value: "", children: "Default" }),
|
|
8123
|
+
control.options.map((option) => /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("option", { value: String(option.value), children: option.label }, String(option.value)))
|
|
7994
8124
|
]
|
|
7995
8125
|
}
|
|
7996
8126
|
);
|
|
7997
8127
|
}
|
|
7998
8128
|
if (control.kind === "textarea") {
|
|
7999
|
-
return /* @__PURE__ */ (0,
|
|
8129
|
+
return /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
|
|
8000
8130
|
"textarea",
|
|
8001
8131
|
{
|
|
8002
8132
|
id,
|
|
@@ -8010,8 +8140,8 @@ function Control({
|
|
|
8010
8140
|
);
|
|
8011
8141
|
}
|
|
8012
8142
|
const numeric = typeof shown === "number" ? shown : void 0;
|
|
8013
|
-
return /* @__PURE__ */ (0,
|
|
8014
|
-
/* @__PURE__ */ (0,
|
|
8143
|
+
return /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
8144
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
|
|
8015
8145
|
"input",
|
|
8016
8146
|
{
|
|
8017
8147
|
id,
|
|
@@ -8025,7 +8155,7 @@ function Control({
|
|
|
8025
8155
|
onChange: (e) => onValue((0, import_generation2.parseControlValue)(control, e.target.value))
|
|
8026
8156
|
}
|
|
8027
8157
|
),
|
|
8028
|
-
control.kind === "range" && /* @__PURE__ */ (0,
|
|
8158
|
+
control.kind === "range" && /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("span", { className: "w-10 text-right tabular-nums text-muted-foreground", "data-field-value": "", children: numeric ?? "\u2013" })
|
|
8029
8159
|
] });
|
|
8030
8160
|
}
|
|
8031
8161
|
var GenerationSettings = ({
|
|
@@ -8039,17 +8169,17 @@ var GenerationSettings = ({
|
|
|
8039
8169
|
renderReference,
|
|
8040
8170
|
className = ""
|
|
8041
8171
|
}) => {
|
|
8042
|
-
const baseId = (0,
|
|
8043
|
-
const controls = (0,
|
|
8172
|
+
const baseId = (0, import_react56.useId)();
|
|
8173
|
+
const controls = (0, import_react56.useMemo)(() => (0, import_generation2.getGenerationControls)(capabilities), [capabilities]);
|
|
8044
8174
|
const computed = useGenerationPlan(value, capabilities, { strategy });
|
|
8045
8175
|
const plan = planProp ?? computed;
|
|
8046
8176
|
const slots = (0, import_generation2.getReferenceSlots)(capabilities, value);
|
|
8047
|
-
return /* @__PURE__ */ (0,
|
|
8177
|
+
return /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("div", { className: `flex flex-col gap-3 text-sm ${className}`, "data-generation-settings": "", "data-model": capabilities.id, children: [
|
|
8048
8178
|
controls.map((control) => {
|
|
8049
8179
|
const id = `${baseId}-${control.key}`;
|
|
8050
|
-
return /* @__PURE__ */ (0,
|
|
8051
|
-
/* @__PURE__ */ (0,
|
|
8052
|
-
/* @__PURE__ */ (0,
|
|
8180
|
+
return /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("div", { className: "flex flex-col gap-1", "data-control": control.key, children: [
|
|
8181
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsx)("label", { htmlFor: id, className: "text-xs font-medium text-muted-foreground", title: control.description, children: control.label }),
|
|
8182
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
|
|
8053
8183
|
Control,
|
|
8054
8184
|
{
|
|
8055
8185
|
control,
|
|
@@ -8060,23 +8190,23 @@ var GenerationSettings = ({
|
|
|
8060
8190
|
)
|
|
8061
8191
|
] }, control.key);
|
|
8062
8192
|
}),
|
|
8063
|
-
slots.map((slot) => /* @__PURE__ */ (0,
|
|
8064
|
-
/* @__PURE__ */ (0,
|
|
8193
|
+
slots.map((slot) => /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("fieldset", { className: "flex flex-col gap-1", "data-reference-role": slot.role, children: [
|
|
8194
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("legend", { className: "text-xs font-medium text-muted-foreground", title: slot.description, children: [
|
|
8065
8195
|
slot.label,
|
|
8066
8196
|
" ",
|
|
8067
|
-
/* @__PURE__ */ (0,
|
|
8197
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("span", { className: "tabular-nums", "data-reference-count": "", children: [
|
|
8068
8198
|
"(",
|
|
8069
8199
|
slot.references.length,
|
|
8070
8200
|
"/",
|
|
8071
8201
|
slot.max,
|
|
8072
8202
|
")"
|
|
8073
8203
|
] }),
|
|
8074
|
-
slot.min > 0 && /* @__PURE__ */ (0,
|
|
8204
|
+
slot.min > 0 && /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("span", { className: "text-destructive", children: " *" })
|
|
8075
8205
|
] }),
|
|
8076
|
-
/* @__PURE__ */ (0,
|
|
8077
|
-
slot.references.map((ref) => /* @__PURE__ */ (0,
|
|
8078
|
-
renderReference ? renderReference(ref) : /* @__PURE__ */ (0,
|
|
8079
|
-
/* @__PURE__ */ (0,
|
|
8206
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("ul", { className: "flex flex-wrap gap-1", children: [
|
|
8207
|
+
slot.references.map((ref) => /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("li", { className: "flex items-center gap-1 rounded border border-border px-1.5 py-0.5", "data-reference-id": ref.id, children: [
|
|
8208
|
+
renderReference ? renderReference(ref) : /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("span", { className: "max-w-[10rem] truncate", children: ref.id }),
|
|
8209
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
|
|
8080
8210
|
"button",
|
|
8081
8211
|
{
|
|
8082
8212
|
type: "button",
|
|
@@ -8087,7 +8217,7 @@ var GenerationSettings = ({
|
|
|
8087
8217
|
}
|
|
8088
8218
|
)
|
|
8089
8219
|
] }, ref.id)),
|
|
8090
|
-
onAddReference && slot.canAdd && /* @__PURE__ */ (0,
|
|
8220
|
+
onAddReference && slot.canAdd && /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("li", { children: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
|
|
8091
8221
|
"button",
|
|
8092
8222
|
{
|
|
8093
8223
|
type: "button",
|
|
@@ -8098,21 +8228,21 @@ var GenerationSettings = ({
|
|
|
8098
8228
|
) })
|
|
8099
8229
|
] })
|
|
8100
8230
|
] }, slot.role)),
|
|
8101
|
-
showAdjustments && plan.adjustments.length > 0 && /* @__PURE__ */ (0,
|
|
8102
|
-
showAdjustments && plan.errors.length > 0 && /* @__PURE__ */ (0,
|
|
8231
|
+
showAdjustments && plan.adjustments.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("ul", { role: "status", className: "flex flex-col gap-0.5 text-xs text-muted-foreground", "data-generation-adjustments": "", children: plan.adjustments.map((adjustment, index) => /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("li", { "data-adjustment-field": adjustment.field, "data-adjustment-kind": adjustment.kind, children: adjustment.reason }, index)) }),
|
|
8232
|
+
showAdjustments && plan.errors.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("ul", { role: "alert", className: "flex flex-col gap-0.5 text-xs text-destructive", "data-generation-errors": "", children: plan.errors.map((error, index) => /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("li", { "data-error-field": error.field, children: error.message }, index)) })
|
|
8103
8233
|
] });
|
|
8104
8234
|
};
|
|
8105
8235
|
|
|
8106
8236
|
// src/generation/JobProgress.tsx
|
|
8107
|
-
var
|
|
8237
|
+
var import_jsx_runtime38 = require("react/jsx-runtime");
|
|
8108
8238
|
var JobProgress = ({ title, className = "", ...options }) => {
|
|
8109
8239
|
const progress = useJobProgress(options);
|
|
8110
|
-
return /* @__PURE__ */ (0,
|
|
8111
|
-
/* @__PURE__ */ (0,
|
|
8112
|
-
title && /* @__PURE__ */ (0,
|
|
8113
|
-
/* @__PURE__ */ (0,
|
|
8240
|
+
return /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)("div", { className: `flex flex-col gap-1 text-sm ${className}`, "data-job-progress": "", "data-done": options.done ? "" : void 0, children: [
|
|
8241
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsxs)("div", { className: "flex items-center justify-between gap-2 text-muted-foreground", children: [
|
|
8242
|
+
title && /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("span", { className: "truncate text-foreground", children: title }),
|
|
8243
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)("span", { "data-job-progress-label": "", "aria-live": "polite", children: progress.label })
|
|
8114
8244
|
] }),
|
|
8115
|
-
/* @__PURE__ */ (0,
|
|
8245
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
|
|
8116
8246
|
"div",
|
|
8117
8247
|
{
|
|
8118
8248
|
role: "progressbar",
|
|
@@ -8122,7 +8252,7 @@ var JobProgress = ({ title, className = "", ...options }) => {
|
|
|
8122
8252
|
"aria-valuenow": progress.percent,
|
|
8123
8253
|
"aria-valuetext": `${progress.percent}%, ${progress.label}`,
|
|
8124
8254
|
className: "h-1.5 w-full overflow-hidden rounded-full bg-muted",
|
|
8125
|
-
children: /* @__PURE__ */ (0,
|
|
8255
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
|
|
8126
8256
|
"div",
|
|
8127
8257
|
{
|
|
8128
8258
|
className: "h-full rounded-full bg-primary transition-[width] duration-500",
|
|
@@ -8135,9 +8265,9 @@ var JobProgress = ({ title, className = "", ...options }) => {
|
|
|
8135
8265
|
};
|
|
8136
8266
|
|
|
8137
8267
|
// src/generation/AssetMentionChips.tsx
|
|
8138
|
-
var
|
|
8268
|
+
var import_react57 = require("react");
|
|
8139
8269
|
var import_generation3 = require("@pixerate/editor/generation");
|
|
8140
|
-
var
|
|
8270
|
+
var import_jsx_runtime39 = require("react/jsx-runtime");
|
|
8141
8271
|
var AssetMentionChips = ({
|
|
8142
8272
|
content,
|
|
8143
8273
|
onChange,
|
|
@@ -8147,14 +8277,14 @@ var AssetMentionChips = ({
|
|
|
8147
8277
|
renderAsset,
|
|
8148
8278
|
className = ""
|
|
8149
8279
|
}) => {
|
|
8150
|
-
const [open, setOpen] = (0,
|
|
8151
|
-
const rootRef = (0,
|
|
8152
|
-
const chips = (0,
|
|
8280
|
+
const [open, setOpen] = (0, import_react57.useState)(null);
|
|
8281
|
+
const rootRef = (0, import_react57.useRef)(null);
|
|
8282
|
+
const chips = (0, import_react57.useMemo)(
|
|
8153
8283
|
() => (0, import_generation3.describeAssetMentions)((0, import_generation3.findTextMentions)(content), assets, capabilities),
|
|
8154
8284
|
[content, assets, capabilities]
|
|
8155
8285
|
);
|
|
8156
8286
|
const options = roles ?? (capabilities ? (0, import_generation3.getAssetRoleOptions)(capabilities) : (0, import_generation3.defaultAssetRoleOptions)());
|
|
8157
|
-
(0,
|
|
8287
|
+
(0, import_react57.useEffect)(() => {
|
|
8158
8288
|
if (open === null) return;
|
|
8159
8289
|
const onPointer = (event) => {
|
|
8160
8290
|
if (!rootRef.current?.contains(event.target)) setOpen(null);
|
|
@@ -8162,19 +8292,19 @@ var AssetMentionChips = ({
|
|
|
8162
8292
|
document.addEventListener("mousedown", onPointer);
|
|
8163
8293
|
return () => document.removeEventListener("mousedown", onPointer);
|
|
8164
8294
|
}, [open]);
|
|
8165
|
-
const pick = (
|
|
8295
|
+
const pick = (chip6, role) => {
|
|
8166
8296
|
setOpen(null);
|
|
8167
|
-
if (
|
|
8168
|
-
onChange((0, import_generation3.setMentionRoleInText)(content,
|
|
8297
|
+
if (chip6.start === void 0) return;
|
|
8298
|
+
onChange((0, import_generation3.setMentionRoleInText)(content, chip6.start, role));
|
|
8169
8299
|
};
|
|
8170
8300
|
if (chips.length === 0) return null;
|
|
8171
|
-
return /* @__PURE__ */ (0,
|
|
8172
|
-
const error =
|
|
8173
|
-
const warning =
|
|
8301
|
+
return /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("div", { ref: rootRef, className: `flex flex-wrap gap-1.5 ${className}`, "data-asset-mention-chips": "", children: chips.map((chip6) => {
|
|
8302
|
+
const error = chip6.issues.find((issue) => issue.severity === "error");
|
|
8303
|
+
const warning = chip6.issues.find((issue) => issue.severity === "warning");
|
|
8174
8304
|
const problem = error ?? warning;
|
|
8175
|
-
const isOpen = open ===
|
|
8176
|
-
return /* @__PURE__ */ (0,
|
|
8177
|
-
/* @__PURE__ */ (0,
|
|
8305
|
+
const isOpen = open === chip6.index;
|
|
8306
|
+
return /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("span", { className: "relative inline-flex", "data-asset-chip": chip6.asset.id, children: [
|
|
8307
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsxs)(
|
|
8178
8308
|
"button",
|
|
8179
8309
|
{
|
|
8180
8310
|
type: "button",
|
|
@@ -8182,82 +8312,82 @@ var AssetMentionChips = ({
|
|
|
8182
8312
|
"aria-expanded": isOpen,
|
|
8183
8313
|
title: problem?.message,
|
|
8184
8314
|
"data-issue": problem?.code,
|
|
8185
|
-
onClick: () => setOpen(isOpen ? null :
|
|
8315
|
+
onClick: () => setOpen(isOpen ? null : chip6.index),
|
|
8186
8316
|
onKeyDown: (e) => {
|
|
8187
8317
|
if (e.key === "Escape") setOpen(null);
|
|
8188
8318
|
},
|
|
8189
8319
|
className: `inline-flex items-center gap-1 rounded-full border px-2 py-0.5 text-xs ${error ? "border-red-500/60" : warning ? "border-amber-500/60" : "border-border"} bg-muted/40 hover:bg-muted`,
|
|
8190
8320
|
children: [
|
|
8191
|
-
/* @__PURE__ */ (0,
|
|
8192
|
-
/* @__PURE__ */ (0,
|
|
8321
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsx)("span", { children: renderAsset ? renderAsset(chip6) : `@${chip6.asset.label ?? chip6.handle}` }),
|
|
8322
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
|
|
8193
8323
|
"span",
|
|
8194
8324
|
{
|
|
8195
|
-
className: `rounded px-1 text-[10px] uppercase tracking-wide ${
|
|
8196
|
-
"data-role-badge":
|
|
8197
|
-
children:
|
|
8325
|
+
className: `rounded px-1 text-[10px] uppercase tracking-wide ${chip6.role ? "bg-primary/15" : "opacity-60"}`,
|
|
8326
|
+
"data-role-badge": chip6.role ?? "",
|
|
8327
|
+
children: chip6.roleLabel ?? "No role"
|
|
8198
8328
|
}
|
|
8199
8329
|
)
|
|
8200
8330
|
]
|
|
8201
8331
|
}
|
|
8202
8332
|
),
|
|
8203
|
-
isOpen && /* @__PURE__ */ (0,
|
|
8333
|
+
isOpen && /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)(
|
|
8204
8334
|
"div",
|
|
8205
8335
|
{
|
|
8206
8336
|
role: "listbox",
|
|
8207
|
-
"aria-label": `Role for ${
|
|
8337
|
+
"aria-label": `Role for ${chip6.asset.label ?? chip6.handle}`,
|
|
8208
8338
|
className: "absolute left-0 top-full z-50 mt-1 flex min-w-[12rem] flex-col rounded-md border border-border bg-background p-1 text-xs shadow-lg",
|
|
8209
8339
|
"data-role-picker": "",
|
|
8210
8340
|
onKeyDown: (e) => {
|
|
8211
8341
|
if (e.key === "Escape") setOpen(null);
|
|
8212
8342
|
},
|
|
8213
8343
|
children: [
|
|
8214
|
-
options.map((option) => /* @__PURE__ */ (0,
|
|
8344
|
+
options.map((option) => /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)(
|
|
8215
8345
|
"button",
|
|
8216
8346
|
{
|
|
8217
8347
|
type: "button",
|
|
8218
8348
|
role: "option",
|
|
8219
|
-
"aria-selected":
|
|
8349
|
+
"aria-selected": chip6.role === option.role,
|
|
8220
8350
|
"data-role-option": option.role,
|
|
8221
8351
|
title: option.description,
|
|
8222
|
-
onClick: () => pick(
|
|
8352
|
+
onClick: () => pick(chip6, option.role),
|
|
8223
8353
|
className: "flex items-center justify-between gap-2 rounded px-2 py-1 text-left hover:bg-muted",
|
|
8224
8354
|
children: [
|
|
8225
|
-
/* @__PURE__ */ (0,
|
|
8226
|
-
option.accepts?.length ? /* @__PURE__ */ (0,
|
|
8355
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsx)("span", { children: option.label }),
|
|
8356
|
+
option.accepts?.length ? /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("span", { className: "text-[10px] opacity-60", children: option.accepts.join(", ") }) : null
|
|
8227
8357
|
]
|
|
8228
8358
|
},
|
|
8229
8359
|
option.role
|
|
8230
8360
|
)),
|
|
8231
|
-
/* @__PURE__ */ (0,
|
|
8361
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
|
|
8232
8362
|
"button",
|
|
8233
8363
|
{
|
|
8234
8364
|
type: "button",
|
|
8235
8365
|
role: "option",
|
|
8236
|
-
"aria-selected": !
|
|
8366
|
+
"aria-selected": !chip6.role,
|
|
8237
8367
|
"data-role-option": "",
|
|
8238
|
-
onClick: () => pick(
|
|
8368
|
+
onClick: () => pick(chip6, null),
|
|
8239
8369
|
className: "rounded px-2 py-1 text-left opacity-70 hover:bg-muted",
|
|
8240
8370
|
children: "No role"
|
|
8241
8371
|
}
|
|
8242
8372
|
),
|
|
8243
|
-
|
|
8373
|
+
chip6.issues.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("ul", { className: "mt-1 border-t border-border px-2 pt-1 text-[10px]", "data-chip-issues": "", children: chip6.issues.map((issue, i) => /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("li", { className: issue.severity === "error" ? "text-red-500" : "text-amber-500", children: issue.message }, i)) })
|
|
8244
8374
|
]
|
|
8245
8375
|
}
|
|
8246
8376
|
)
|
|
8247
|
-
] }, `${
|
|
8377
|
+
] }, `${chip6.start}-${chip6.index}`);
|
|
8248
8378
|
}) });
|
|
8249
8379
|
};
|
|
8250
8380
|
|
|
8251
8381
|
// src/generation/GenerationHistory.tsx
|
|
8252
|
-
var
|
|
8382
|
+
var import_react58 = require("react");
|
|
8253
8383
|
var import_generation4 = require("@pixerate/editor/generation");
|
|
8254
|
-
var
|
|
8384
|
+
var import_jsx_runtime40 = require("react/jsx-runtime");
|
|
8255
8385
|
function useGenerationRecords(store, filter) {
|
|
8256
|
-
const [records, setRecords] = (0,
|
|
8257
|
-
const [loading, setLoading] = (0,
|
|
8258
|
-
const [error, setError] = (0,
|
|
8386
|
+
const [records, setRecords] = (0, import_react58.useState)([]);
|
|
8387
|
+
const [loading, setLoading] = (0, import_react58.useState)(!!store);
|
|
8388
|
+
const [error, setError] = (0, import_react58.useState)(null);
|
|
8259
8389
|
const filterKey = (0, import_generation4.stableStringify)(filter ?? {});
|
|
8260
|
-
const refresh = (0,
|
|
8390
|
+
const refresh = (0, import_react58.useCallback)(async () => {
|
|
8261
8391
|
if (!store) {
|
|
8262
8392
|
setRecords([]);
|
|
8263
8393
|
setLoading(false);
|
|
@@ -8274,7 +8404,7 @@ function useGenerationRecords(store, filter) {
|
|
|
8274
8404
|
setLoading(false);
|
|
8275
8405
|
}
|
|
8276
8406
|
}, [store, filterKey]);
|
|
8277
|
-
(0,
|
|
8407
|
+
(0, import_react58.useEffect)(() => {
|
|
8278
8408
|
void refresh();
|
|
8279
8409
|
if (!store) return;
|
|
8280
8410
|
return store.subscribe(() => void refresh());
|
|
@@ -8300,21 +8430,21 @@ var GenerationHistory = ({
|
|
|
8300
8430
|
emptyText = "No generations yet.",
|
|
8301
8431
|
className = ""
|
|
8302
8432
|
}) => {
|
|
8303
|
-
const [innerMode, setInnerMode] = (0,
|
|
8433
|
+
const [innerMode, setInnerMode] = (0, import_react58.useState)("exact");
|
|
8304
8434
|
const mode = modeProp ?? innerMode;
|
|
8305
8435
|
const setMode = (next) => {
|
|
8306
8436
|
if (modeProp === void 0) setInnerMode(next);
|
|
8307
8437
|
onModeChange?.(next);
|
|
8308
8438
|
};
|
|
8309
|
-
const options = (0,
|
|
8310
|
-
const results = (0,
|
|
8311
|
-
const models = (0,
|
|
8439
|
+
const options = (0, import_react58.useMemo)(() => ({ templates, capabilities, assets, mode }), [templates, capabilities, assets, mode]);
|
|
8440
|
+
const results = (0, import_react58.useMemo)(() => records.map((record) => (0, import_generation4.recreateRequest)(record, options)), [records, options]);
|
|
8441
|
+
const models = (0, import_react58.useMemo)(
|
|
8312
8442
|
() => capabilities ? Array.isArray(capabilities) ? capabilities : [capabilities] : [],
|
|
8313
8443
|
[capabilities]
|
|
8314
8444
|
);
|
|
8315
|
-
return /* @__PURE__ */ (0,
|
|
8316
|
-
/* @__PURE__ */ (0,
|
|
8317
|
-
/* @__PURE__ */ (0,
|
|
8445
|
+
return /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)("div", { className: `flex flex-col gap-2 text-sm ${className}`, "data-generation-history": "", children: [
|
|
8446
|
+
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)("div", { className: "flex items-center gap-2 text-xs", role: "radiogroup", "aria-label": "Recreate mode", children: ["exact", "latest"].map((value) => /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)("label", { className: "inline-flex items-center gap-1", children: [
|
|
8447
|
+
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
|
|
8318
8448
|
"input",
|
|
8319
8449
|
{
|
|
8320
8450
|
type: "radio",
|
|
@@ -8327,34 +8457,34 @@ var GenerationHistory = ({
|
|
|
8327
8457
|
),
|
|
8328
8458
|
value === "exact" ? "Exact (recorded versions)" : "Latest templates & settings"
|
|
8329
8459
|
] }, value)) }),
|
|
8330
|
-
records.length === 0 && /* @__PURE__ */ (0,
|
|
8331
|
-
/* @__PURE__ */ (0,
|
|
8460
|
+
records.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("p", { className: "text-xs text-muted-foreground", children: emptyText }),
|
|
8461
|
+
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)("ul", { className: "flex flex-col gap-2", children: records.map((record, i) => {
|
|
8332
8462
|
const result = results[i];
|
|
8333
8463
|
const model = models.find((m) => m.id === record.provenance.modelId);
|
|
8334
8464
|
const blocked = !result.ok;
|
|
8335
|
-
return /* @__PURE__ */ (0,
|
|
8465
|
+
return /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(
|
|
8336
8466
|
"li",
|
|
8337
8467
|
{
|
|
8338
8468
|
className: "rounded-md border border-border p-2",
|
|
8339
8469
|
"data-record": record.id,
|
|
8340
8470
|
"data-drift": result.drift.length,
|
|
8341
8471
|
children: [
|
|
8342
|
-
/* @__PURE__ */ (0,
|
|
8343
|
-
/* @__PURE__ */ (0,
|
|
8344
|
-
/* @__PURE__ */ (0,
|
|
8345
|
-
record.kind !== "generate" && /* @__PURE__ */ (0,
|
|
8472
|
+
/* @__PURE__ */ (0, import_jsx_runtime40.jsxs)("div", { className: "flex flex-wrap items-center justify-between gap-2 text-xs", children: [
|
|
8473
|
+
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)("span", { className: "font-medium", children: model?.name ?? record.provenance.modelId }),
|
|
8474
|
+
/* @__PURE__ */ (0, import_jsx_runtime40.jsxs)("span", { className: "text-muted-foreground", children: [
|
|
8475
|
+
record.kind !== "generate" && /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)("span", { "data-kind": "", children: [
|
|
8346
8476
|
record.kind,
|
|
8347
8477
|
" \xB7 "
|
|
8348
8478
|
] }),
|
|
8349
|
-
/* @__PURE__ */ (0,
|
|
8350
|
-
record.seed !== void 0 && /* @__PURE__ */ (0,
|
|
8479
|
+
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)("time", { dateTime: record.createdAt, children: record.createdAt.replace("T", " ").slice(0, 16) }),
|
|
8480
|
+
record.seed !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(import_jsx_runtime40.Fragment, { children: [
|
|
8351
8481
|
" \xB7 seed ",
|
|
8352
8482
|
record.seed
|
|
8353
8483
|
] })
|
|
8354
8484
|
] })
|
|
8355
8485
|
] }),
|
|
8356
|
-
/* @__PURE__ */ (0,
|
|
8357
|
-
record.assets.length > 0 && /* @__PURE__ */ (0,
|
|
8486
|
+
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)("p", { className: "mt-1 line-clamp-3 break-words text-xs", "data-record-prompt": "", children: record.provenance.resolvedPrompt }),
|
|
8487
|
+
record.assets.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("div", { className: "mt-1 flex flex-wrap gap-1", children: record.assets.map((asset) => /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(
|
|
8358
8488
|
"span",
|
|
8359
8489
|
{
|
|
8360
8490
|
className: "rounded-full bg-muted px-2 py-0.5 text-[10px]",
|
|
@@ -8368,16 +8498,16 @@ var GenerationHistory = ({
|
|
|
8368
8498
|
`${asset.role}:${asset.id}`
|
|
8369
8499
|
)) }),
|
|
8370
8500
|
renderPreview?.(record),
|
|
8371
|
-
result.drift.length > 0 && /* @__PURE__ */ (0,
|
|
8372
|
-
/* @__PURE__ */ (0,
|
|
8501
|
+
result.drift.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("ul", { className: "mt-1 flex flex-col gap-0.5 text-[11px]", "data-drift-report": "", children: result.drift.map((item, j) => /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)("li", { className: severityClass[item.severity], "data-drift-type": item.type, children: [
|
|
8502
|
+
/* @__PURE__ */ (0, import_jsx_runtime40.jsxs)("strong", { children: [
|
|
8373
8503
|
import_generation4.DRIFT_TYPE_LABELS[item.type],
|
|
8374
8504
|
":"
|
|
8375
8505
|
] }),
|
|
8376
8506
|
" ",
|
|
8377
8507
|
item.message
|
|
8378
8508
|
] }, j)) }),
|
|
8379
|
-
/* @__PURE__ */ (0,
|
|
8380
|
-
onRecreate && /* @__PURE__ */ (0,
|
|
8509
|
+
/* @__PURE__ */ (0, import_jsx_runtime40.jsxs)("div", { className: "mt-2 flex gap-2", children: [
|
|
8510
|
+
onRecreate && /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
|
|
8381
8511
|
"button",
|
|
8382
8512
|
{
|
|
8383
8513
|
type: "button",
|
|
@@ -8389,7 +8519,7 @@ var GenerationHistory = ({
|
|
|
8389
8519
|
children: "Recreate"
|
|
8390
8520
|
}
|
|
8391
8521
|
),
|
|
8392
|
-
onVariation && /* @__PURE__ */ (0,
|
|
8522
|
+
onVariation && /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
|
|
8393
8523
|
"button",
|
|
8394
8524
|
{
|
|
8395
8525
|
type: "button",
|
|
@@ -8399,7 +8529,7 @@ var GenerationHistory = ({
|
|
|
8399
8529
|
children: "Variation"
|
|
8400
8530
|
}
|
|
8401
8531
|
),
|
|
8402
|
-
onRemove && /* @__PURE__ */ (0,
|
|
8532
|
+
onRemove && /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
|
|
8403
8533
|
"button",
|
|
8404
8534
|
{
|
|
8405
8535
|
type: "button",
|
|
@@ -8419,19 +8549,19 @@ var GenerationHistory = ({
|
|
|
8419
8549
|
};
|
|
8420
8550
|
|
|
8421
8551
|
// src/find-replace/useFindReplace.ts
|
|
8422
|
-
var
|
|
8552
|
+
var import_react59 = require("react");
|
|
8423
8553
|
var import_editor16 = require("@pixerate/editor");
|
|
8424
8554
|
var noopUnsubscribe2 = () => {
|
|
8425
8555
|
};
|
|
8426
8556
|
function useFindReplace(editor) {
|
|
8427
8557
|
const store = (0, import_editor16.getFindReplaceStore)(editor ?? null);
|
|
8428
|
-
const subscribe = (0,
|
|
8558
|
+
const subscribe = (0, import_react59.useCallback)(
|
|
8429
8559
|
(onChange) => store ? store.subscribe(() => onChange()) : noopUnsubscribe2,
|
|
8430
8560
|
[store]
|
|
8431
8561
|
);
|
|
8432
8562
|
const getSnapshot = () => store?.getSnapshot() ?? import_editor16.EMPTY_FIND_REPLACE_SNAPSHOT;
|
|
8433
|
-
const snapshot = (0,
|
|
8434
|
-
return (0,
|
|
8563
|
+
const snapshot = (0, import_react59.useSyncExternalStore)(subscribe, getSnapshot, getSnapshot);
|
|
8564
|
+
return (0, import_react59.useMemo)(() => {
|
|
8435
8565
|
const run = (fn) => {
|
|
8436
8566
|
if (editor && !editor.isDestroyed && store) fn(editor);
|
|
8437
8567
|
};
|
|
@@ -8455,9 +8585,9 @@ function useFindReplace(editor) {
|
|
|
8455
8585
|
}
|
|
8456
8586
|
|
|
8457
8587
|
// src/find-replace/FindReplaceBar.tsx
|
|
8458
|
-
var
|
|
8588
|
+
var import_react60 = require("react");
|
|
8459
8589
|
var import_editor17 = require("@pixerate/editor");
|
|
8460
|
-
var
|
|
8590
|
+
var import_jsx_runtime41 = require("react/jsx-runtime");
|
|
8461
8591
|
var inputClass3 = "min-w-0 flex-1 rounded border border-input bg-background px-2 py-1 text-xs text-foreground focus:outline-none focus:ring-1 focus:ring-ring";
|
|
8462
8592
|
var buttonClass5 = "rounded px-2 py-1 text-xs text-foreground hover:bg-muted disabled:opacity-40 disabled:hover:bg-transparent";
|
|
8463
8593
|
var toggleClass = (on) => `${buttonClass5} font-mono ${on ? "bg-primary/10 text-primary" : "text-muted-foreground"}`;
|
|
@@ -8470,10 +8600,10 @@ var FindReplaceBar = ({
|
|
|
8470
8600
|
onClose
|
|
8471
8601
|
}) => {
|
|
8472
8602
|
const find = useFindReplace(editor);
|
|
8473
|
-
const findInput = (0,
|
|
8474
|
-
const [moreOpen, setMoreOpen] = (0,
|
|
8603
|
+
const findInput = (0, import_react60.useRef)(null);
|
|
8604
|
+
const [moreOpen, setMoreOpen] = (0, import_react60.useState)(false);
|
|
8475
8605
|
const visible = find.available && (alwaysOpen || find.open);
|
|
8476
|
-
(0,
|
|
8606
|
+
(0, import_react60.useEffect)(() => {
|
|
8477
8607
|
if (!visible || find.focusRequest === 0) return;
|
|
8478
8608
|
findInput.current?.focus();
|
|
8479
8609
|
findInput.current?.select();
|
|
@@ -8511,9 +8641,9 @@ var FindReplaceBar = ({
|
|
|
8511
8641
|
if (isMod(e)) find.replaceAll();
|
|
8512
8642
|
else find.replace();
|
|
8513
8643
|
};
|
|
8514
|
-
return /* @__PURE__ */ (0,
|
|
8515
|
-
/* @__PURE__ */ (0,
|
|
8516
|
-
/* @__PURE__ */ (0,
|
|
8644
|
+
return /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("div", { className, role: "search", "aria-label": "Find and replace", onKeyDown: onBarKeyDown, children: [
|
|
8645
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("div", { className: "flex items-center gap-1", children: [
|
|
8646
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
|
|
8517
8647
|
"button",
|
|
8518
8648
|
{
|
|
8519
8649
|
type: "button",
|
|
@@ -8524,7 +8654,7 @@ var FindReplaceBar = ({
|
|
|
8524
8654
|
children: showReplace ? "\u25BE" : "\u25B8"
|
|
8525
8655
|
}
|
|
8526
8656
|
),
|
|
8527
|
-
/* @__PURE__ */ (0,
|
|
8657
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
|
|
8528
8658
|
"input",
|
|
8529
8659
|
{
|
|
8530
8660
|
ref: findInput,
|
|
@@ -8538,7 +8668,7 @@ var FindReplaceBar = ({
|
|
|
8538
8668
|
onKeyDown: onFindKeyDown
|
|
8539
8669
|
}
|
|
8540
8670
|
),
|
|
8541
|
-
import_editor17.FIND_OPTION_TOGGLES.filter((t) => !t.advanced).map((t) => /* @__PURE__ */ (0,
|
|
8671
|
+
import_editor17.FIND_OPTION_TOGGLES.filter((t) => !t.advanced).map((t) => /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
|
|
8542
8672
|
"button",
|
|
8543
8673
|
{
|
|
8544
8674
|
type: "button",
|
|
@@ -8551,7 +8681,7 @@ var FindReplaceBar = ({
|
|
|
8551
8681
|
},
|
|
8552
8682
|
t.key
|
|
8553
8683
|
)),
|
|
8554
|
-
/* @__PURE__ */ (0,
|
|
8684
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
|
|
8555
8685
|
"span",
|
|
8556
8686
|
{
|
|
8557
8687
|
className: `min-w-[5rem] px-1 text-center text-xs ${find.error ? "text-destructive" : "text-muted-foreground"}`,
|
|
@@ -8561,9 +8691,9 @@ var FindReplaceBar = ({
|
|
|
8561
8691
|
children: status
|
|
8562
8692
|
}
|
|
8563
8693
|
),
|
|
8564
|
-
/* @__PURE__ */ (0,
|
|
8565
|
-
/* @__PURE__ */ (0,
|
|
8566
|
-
showMoreOptions && /* @__PURE__ */ (0,
|
|
8694
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)("button", { type: "button", className: buttonClass5, "aria-label": "Previous match", disabled: !hasMatches, onClick: find.previous, children: "\u2191" }),
|
|
8695
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)("button", { type: "button", className: buttonClass5, "aria-label": "Next match", disabled: !hasMatches, onClick: find.next, children: "\u2193" }),
|
|
8696
|
+
showMoreOptions && /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
|
|
8567
8697
|
"button",
|
|
8568
8698
|
{
|
|
8569
8699
|
type: "button",
|
|
@@ -8574,10 +8704,10 @@ var FindReplaceBar = ({
|
|
|
8574
8704
|
children: "\u2026"
|
|
8575
8705
|
}
|
|
8576
8706
|
),
|
|
8577
|
-
/* @__PURE__ */ (0,
|
|
8707
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)("button", { type: "button", className: buttonClass5, "aria-label": "Close find", onClick: close, children: "\xD7" })
|
|
8578
8708
|
] }),
|
|
8579
|
-
showReplace && /* @__PURE__ */ (0,
|
|
8580
|
-
/* @__PURE__ */ (0,
|
|
8709
|
+
showReplace && /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("div", { className: "flex items-center gap-1 pl-7", children: [
|
|
8710
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
|
|
8581
8711
|
"input",
|
|
8582
8712
|
{
|
|
8583
8713
|
type: "text",
|
|
@@ -8589,7 +8719,7 @@ var FindReplaceBar = ({
|
|
|
8589
8719
|
onKeyDown: onReplaceKeyDown
|
|
8590
8720
|
}
|
|
8591
8721
|
),
|
|
8592
|
-
/* @__PURE__ */ (0,
|
|
8722
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
|
|
8593
8723
|
"button",
|
|
8594
8724
|
{
|
|
8595
8725
|
type: "button",
|
|
@@ -8599,11 +8729,11 @@ var FindReplaceBar = ({
|
|
|
8599
8729
|
children: "Replace"
|
|
8600
8730
|
}
|
|
8601
8731
|
),
|
|
8602
|
-
/* @__PURE__ */ (0,
|
|
8603
|
-
find.lastReplaceCount !== null && /* @__PURE__ */ (0,
|
|
8732
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)("button", { type: "button", className: buttonClass5, disabled: !hasMatches, onClick: find.replaceAll, children: "Replace all" }),
|
|
8733
|
+
find.lastReplaceCount !== null && /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("span", { className: "px-1 text-xs text-muted-foreground", "aria-live": "polite", children: find.lastReplaceCount === 1 ? "1 replaced" : `${find.lastReplaceCount} replaced` })
|
|
8604
8734
|
] }),
|
|
8605
|
-
showMoreOptions && moreOpen && /* @__PURE__ */ (0,
|
|
8606
|
-
/* @__PURE__ */ (0,
|
|
8735
|
+
showMoreOptions && moreOpen && /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("div", { className: "flex flex-wrap items-center gap-x-3 gap-y-1 pl-7 text-xs text-muted-foreground", children: import_editor17.FIND_OPTION_TOGGLES.filter((t) => t.advanced).map((t) => /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("label", { className: "flex items-center gap-1", children: [
|
|
8736
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
|
|
8607
8737
|
"input",
|
|
8608
8738
|
{
|
|
8609
8739
|
type: "checkbox",
|
|
@@ -8617,12 +8747,12 @@ var FindReplaceBar = ({
|
|
|
8617
8747
|
};
|
|
8618
8748
|
|
|
8619
8749
|
// src/tables/useTableMenu.ts
|
|
8620
|
-
var
|
|
8750
|
+
var import_react61 = require("react");
|
|
8621
8751
|
var import_editor18 = require("@pixerate/editor");
|
|
8622
8752
|
function useTableMenu(editor) {
|
|
8623
|
-
const store = (0,
|
|
8624
|
-
const snapshot = (0,
|
|
8625
|
-
return (0,
|
|
8753
|
+
const store = (0, import_react61.useMemo)(() => (0, import_editor18.createTableStore)(editor), [editor]);
|
|
8754
|
+
const snapshot = (0, import_react61.useSyncExternalStore)(store.subscribe, store.getSnapshot, store.getSnapshot);
|
|
8755
|
+
return (0, import_react61.useMemo)(
|
|
8626
8756
|
() => ({
|
|
8627
8757
|
...snapshot,
|
|
8628
8758
|
run: (action, params) => (0, import_editor18.runTableAction)(editor, action, params, { focus: true }),
|
|
@@ -8633,9 +8763,9 @@ function useTableMenu(editor) {
|
|
|
8633
8763
|
}
|
|
8634
8764
|
|
|
8635
8765
|
// src/tables/TableToolbar.tsx
|
|
8636
|
-
var
|
|
8766
|
+
var import_react62 = __toESM(require("react"), 1);
|
|
8637
8767
|
var import_editor19 = require("@pixerate/editor");
|
|
8638
|
-
var
|
|
8768
|
+
var import_jsx_runtime42 = require("react/jsx-runtime");
|
|
8639
8769
|
var keepSelection2 = (event) => event.preventDefault();
|
|
8640
8770
|
var TableToolbar = ({
|
|
8641
8771
|
editor,
|
|
@@ -8649,14 +8779,14 @@ var TableToolbar = ({
|
|
|
8649
8779
|
}) => {
|
|
8650
8780
|
const table = useTableMenu(editor);
|
|
8651
8781
|
if (!editor || !table.inTable && !showWhenOutside) return null;
|
|
8652
|
-
return /* @__PURE__ */ (0,
|
|
8782
|
+
return /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("div", { className, role: "toolbar", "aria-label": "Table", "data-table-toolbar": "", children: items.map((item, index) => {
|
|
8653
8783
|
const status = table.check(item.action, item.params);
|
|
8654
8784
|
const enabled = status === true;
|
|
8655
8785
|
const active = item.active?.(table);
|
|
8656
8786
|
const separator = index > 0 && items[index - 1].group !== item.group;
|
|
8657
|
-
return /* @__PURE__ */ (0,
|
|
8658
|
-
separator && /* @__PURE__ */ (0,
|
|
8659
|
-
/* @__PURE__ */ (0,
|
|
8787
|
+
return /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)(import_react62.default.Fragment, { children: [
|
|
8788
|
+
separator && /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("span", { className: separatorClassName, "aria-hidden": "true" }),
|
|
8789
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
|
|
8660
8790
|
"button",
|
|
8661
8791
|
{
|
|
8662
8792
|
type: "button",
|
|
@@ -8678,8 +8808,8 @@ var TableToolbar = ({
|
|
|
8678
8808
|
};
|
|
8679
8809
|
|
|
8680
8810
|
// src/tables/InsertTableGrid.tsx
|
|
8681
|
-
var
|
|
8682
|
-
var
|
|
8811
|
+
var import_react63 = require("react");
|
|
8812
|
+
var import_jsx_runtime43 = require("react/jsx-runtime");
|
|
8683
8813
|
var keepSelection3 = (event) => event.preventDefault();
|
|
8684
8814
|
var InsertTableGrid = ({
|
|
8685
8815
|
editor,
|
|
@@ -8692,14 +8822,14 @@ var InsertTableGrid = ({
|
|
|
8692
8822
|
onInsert
|
|
8693
8823
|
}) => {
|
|
8694
8824
|
const table = useTableMenu(editor);
|
|
8695
|
-
const [hover, setHover] = (0,
|
|
8825
|
+
const [hover, setHover] = (0, import_react63.useState)(null);
|
|
8696
8826
|
const status = table.actions.insertTable;
|
|
8697
8827
|
const disabled = !editor || !status.enabled;
|
|
8698
8828
|
const insert = (size) => {
|
|
8699
8829
|
if (table.run("insertTable", { ...size, withHeaderRow })) onInsert?.(size);
|
|
8700
8830
|
setHover(null);
|
|
8701
8831
|
};
|
|
8702
|
-
return /* @__PURE__ */ (0,
|
|
8832
|
+
return /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)(
|
|
8703
8833
|
"div",
|
|
8704
8834
|
{
|
|
8705
8835
|
className,
|
|
@@ -8709,7 +8839,7 @@ var InsertTableGrid = ({
|
|
|
8709
8839
|
"data-insert-table-grid": "",
|
|
8710
8840
|
onMouseLeave: () => setHover(null),
|
|
8711
8841
|
children: [
|
|
8712
|
-
/* @__PURE__ */ (0,
|
|
8842
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
|
|
8713
8843
|
"div",
|
|
8714
8844
|
{
|
|
8715
8845
|
role: "grid",
|
|
@@ -8718,7 +8848,7 @@ var InsertTableGrid = ({
|
|
|
8718
8848
|
children: Array.from({ length: rows * cols }, (_, i) => {
|
|
8719
8849
|
const size = { rows: Math.floor(i / cols) + 1, cols: i % cols + 1 };
|
|
8720
8850
|
const active = !!hover && size.rows <= hover.rows && size.cols <= hover.cols;
|
|
8721
|
-
return /* @__PURE__ */ (0,
|
|
8851
|
+
return /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
|
|
8722
8852
|
"button",
|
|
8723
8853
|
{
|
|
8724
8854
|
type: "button",
|
|
@@ -8738,7 +8868,7 @@ var InsertTableGrid = ({
|
|
|
8738
8868
|
})
|
|
8739
8869
|
}
|
|
8740
8870
|
),
|
|
8741
|
-
/* @__PURE__ */ (0,
|
|
8871
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)("div", { "aria-live": "polite", "data-testid": "insert-table-size", children: disabled ? status.reason : hover ? `${hover.rows} \xD7 ${hover.cols}` : "Insert table" })
|
|
8742
8872
|
]
|
|
8743
8873
|
}
|
|
8744
8874
|
);
|
|
@@ -8746,31 +8876,31 @@ var InsertTableGrid = ({
|
|
|
8746
8876
|
|
|
8747
8877
|
// src/tables/TableBubbleMenu.tsx
|
|
8748
8878
|
var import_editor20 = require("@pixerate/editor");
|
|
8749
|
-
var
|
|
8879
|
+
var import_jsx_runtime44 = require("react/jsx-runtime");
|
|
8750
8880
|
var TableBubbleMenu = ({
|
|
8751
8881
|
editor,
|
|
8752
8882
|
children,
|
|
8753
8883
|
toolbarProps,
|
|
8754
8884
|
pluginKey = "tableBubbleMenu",
|
|
8755
8885
|
...rest
|
|
8756
|
-
}) => /* @__PURE__ */ (0,
|
|
8886
|
+
}) => /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(BubbleMenu, { editor, pluginKey, shouldShow: import_editor20.shouldShowTableBubbleMenu, ...rest, children: children ?? /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(TableToolbar, { editor, ...toolbarProps }) });
|
|
8757
8887
|
|
|
8758
8888
|
// src/chart-node/ChartNodeView.tsx
|
|
8759
8889
|
var import_client = require("react-dom/client");
|
|
8760
8890
|
|
|
8761
8891
|
// src/chart/ChartCanvas.tsx
|
|
8762
|
-
var
|
|
8892
|
+
var import_react65 = require("react");
|
|
8763
8893
|
var import_chart2 = require("@pixerate/editor/chart");
|
|
8764
8894
|
|
|
8765
8895
|
// src/chart/useChartEditor.ts
|
|
8766
|
-
var
|
|
8896
|
+
var import_react64 = require("react");
|
|
8767
8897
|
var import_chart = require("@pixerate/editor/chart");
|
|
8768
8898
|
function useChartState(controller) {
|
|
8769
|
-
return (0,
|
|
8899
|
+
return (0, import_react64.useSyncExternalStore)(controller.subscribe, controller.getState, controller.getState);
|
|
8770
8900
|
}
|
|
8771
8901
|
|
|
8772
8902
|
// src/chart/ChartCanvas.tsx
|
|
8773
|
-
var
|
|
8903
|
+
var import_jsx_runtime45 = require("react/jsx-runtime");
|
|
8774
8904
|
function renderChartMark(mark, fontFamily, interactive) {
|
|
8775
8905
|
const common = {
|
|
8776
8906
|
"data-role": mark.role,
|
|
@@ -8782,9 +8912,9 @@ function renderChartMark(mark, fontFamily, interactive) {
|
|
|
8782
8912
|
};
|
|
8783
8913
|
switch (mark.kind) {
|
|
8784
8914
|
case "rect":
|
|
8785
|
-
return /* @__PURE__ */ (0,
|
|
8915
|
+
return /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("rect", { ...common, x: mark.x, y: mark.y, width: mark.width, height: mark.height, rx: mark.radius, style: { fill: mark.fill, stroke: mark.stroke, strokeWidth: mark.strokeWidth } }, mark.key);
|
|
8786
8916
|
case "path":
|
|
8787
|
-
return /* @__PURE__ */ (0,
|
|
8917
|
+
return /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
|
|
8788
8918
|
"path",
|
|
8789
8919
|
{
|
|
8790
8920
|
...common,
|
|
@@ -8797,11 +8927,11 @@ function renderChartMark(mark, fontFamily, interactive) {
|
|
|
8797
8927
|
mark.key
|
|
8798
8928
|
);
|
|
8799
8929
|
case "circle":
|
|
8800
|
-
return /* @__PURE__ */ (0,
|
|
8930
|
+
return /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("circle", { ...common, cx: mark.cx, cy: mark.cy, r: mark.r, style: { fill: mark.fill, stroke: mark.stroke, strokeWidth: mark.strokeWidth } }, mark.key);
|
|
8801
8931
|
case "line":
|
|
8802
|
-
return /* @__PURE__ */ (0,
|
|
8932
|
+
return /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("line", { ...common, x1: mark.x1, y1: mark.y1, x2: mark.x2, y2: mark.y2, strokeDasharray: mark.dash, style: { stroke: mark.stroke, strokeWidth: mark.strokeWidth } }, mark.key);
|
|
8803
8933
|
case "text":
|
|
8804
|
-
return /* @__PURE__ */ (0,
|
|
8934
|
+
return /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
|
|
8805
8935
|
"text",
|
|
8806
8936
|
{
|
|
8807
8937
|
...common,
|
|
@@ -8818,23 +8948,23 @@ function renderChartMark(mark, fontFamily, interactive) {
|
|
|
8818
8948
|
}
|
|
8819
8949
|
}
|
|
8820
8950
|
function ChartPresenceLayer({ presence }) {
|
|
8821
|
-
const { actors } = (0,
|
|
8822
|
-
return /* @__PURE__ */ (0,
|
|
8823
|
-
/* @__PURE__ */ (0,
|
|
8824
|
-
/* @__PURE__ */ (0,
|
|
8825
|
-
/* @__PURE__ */ (0,
|
|
8826
|
-
/* @__PURE__ */ (0,
|
|
8951
|
+
const { actors } = (0, import_react65.useSyncExternalStore)(presence.subscribe, presence.getState, presence.getState);
|
|
8952
|
+
return /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("g", { "data-chart-presence": "", pointerEvents: "none", children: actors.map((a) => /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("g", { transform: `translate(${a.x} ${a.y})`, "data-actor": a.id, children: [
|
|
8953
|
+
/* @__PURE__ */ (0, import_jsx_runtime45.jsx)("path", { d: "M0,0 L0,14 L4,10.5 L7,17 L9.5,16 L6.5,9.5 L11.5,9.5 Z", style: { fill: a.color, stroke: "#ffffff", strokeWidth: 1 }, transform: a.pressed ? "scale(0.9)" : void 0 }),
|
|
8954
|
+
/* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("g", { transform: "translate(13 16)", children: [
|
|
8955
|
+
/* @__PURE__ */ (0, import_jsx_runtime45.jsx)("rect", { x: 0, y: 0, rx: 4, height: 18, width: Math.max(28, (a.message ?? a.name).length * 6.4 + 12), style: { fill: a.color } }),
|
|
8956
|
+
/* @__PURE__ */ (0, import_jsx_runtime45.jsx)("text", { x: 6, y: 9, dominantBaseline: "central", style: { fill: "#ffffff", fontSize: 11, fontWeight: 600, fontFamily: "inherit" }, children: a.message ?? a.name })
|
|
8827
8957
|
] })
|
|
8828
8958
|
] }, a.id)) });
|
|
8829
8959
|
}
|
|
8830
8960
|
function ChartCanvas({ controller, width = 640, height = 400, responsive = true, theme, editable = true, measureText, emptyMessage, className, presence, sceneRef }) {
|
|
8831
8961
|
const state = useChartState(controller);
|
|
8832
|
-
const wrapper = (0,
|
|
8833
|
-
const svg = (0,
|
|
8834
|
-
const drag = (0,
|
|
8835
|
-
const [measured, setMeasured] = (0,
|
|
8836
|
-
const [frozen, setFrozen] = (0,
|
|
8837
|
-
(0,
|
|
8962
|
+
const wrapper = (0, import_react65.useRef)(null);
|
|
8963
|
+
const svg = (0, import_react65.useRef)(null);
|
|
8964
|
+
const drag = (0, import_react65.useRef)(null);
|
|
8965
|
+
const [measured, setMeasured] = (0, import_react65.useState)(null);
|
|
8966
|
+
const [frozen, setFrozen] = (0, import_react65.useState)(null);
|
|
8967
|
+
(0, import_react65.useEffect)(() => {
|
|
8838
8968
|
const el = wrapper.current;
|
|
8839
8969
|
if (!responsive || !el || typeof ResizeObserver === "undefined") return;
|
|
8840
8970
|
const observer = new ResizeObserver(([entry]) => {
|
|
@@ -8845,8 +8975,8 @@ function ChartCanvas({ controller, width = 640, height = 400, responsive = true,
|
|
|
8845
8975
|
return () => observer.disconnect();
|
|
8846
8976
|
}, [responsive]);
|
|
8847
8977
|
const sceneWidth = responsive && measured || width;
|
|
8848
|
-
const fullTheme = (0,
|
|
8849
|
-
const scene = (0,
|
|
8978
|
+
const fullTheme = (0, import_react65.useMemo)(() => ({ ...import_chart2.CSS_VARIABLE_CHART_THEME, ...theme }), [theme]);
|
|
8979
|
+
const scene = (0, import_react65.useMemo)(
|
|
8850
8980
|
() => (0, import_chart2.layoutChart)(state.spec, {
|
|
8851
8981
|
width: sceneWidth,
|
|
8852
8982
|
height,
|
|
@@ -8862,8 +8992,8 @@ function ChartCanvas({ controller, width = 640, height = 400, responsive = true,
|
|
|
8862
8992
|
[state.spec, state.selection, sceneWidth, height, fullTheme, editable, measureText, emptyMessage, frozen]
|
|
8863
8993
|
);
|
|
8864
8994
|
if (sceneRef) sceneRef.current = scene;
|
|
8865
|
-
const byKey = (0,
|
|
8866
|
-
(0,
|
|
8995
|
+
const byKey = (0, import_react65.useMemo)(() => new Map(scene.marks.map((m) => [m.key, m])), [scene]);
|
|
8996
|
+
(0, import_react65.useEffect)(() => () => drag.current?.end(), []);
|
|
8867
8997
|
const scenePoint = (e) => (0, import_chart2.chartClientToScene)(scene, svg.current.getBoundingClientRect(), e.clientX, e.clientY);
|
|
8868
8998
|
const onPointerDown = (e) => {
|
|
8869
8999
|
if (!editable || e.button !== 0) return;
|
|
@@ -8896,7 +9026,7 @@ function ChartCanvas({ controller, width = 640, height = 400, responsive = true,
|
|
|
8896
9026
|
if (editable && (0, import_chart2.handleChartKey)(controller, scene, e)) e.preventDefault();
|
|
8897
9027
|
};
|
|
8898
9028
|
const label = state.spec.title || "Chart";
|
|
8899
|
-
return /* @__PURE__ */ (0,
|
|
9029
|
+
return /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("div", { ref: wrapper, className: `w-full ${className ?? ""}`, "data-chart-canvas": "", children: /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)(
|
|
8900
9030
|
"svg",
|
|
8901
9031
|
{
|
|
8902
9032
|
ref: svg,
|
|
@@ -8914,14 +9044,14 @@ function ChartCanvas({ controller, width = 640, height = 400, responsive = true,
|
|
|
8914
9044
|
onKeyDown,
|
|
8915
9045
|
children: [
|
|
8916
9046
|
scene.marks.map((m) => renderChartMark(m, scene.theme.fontFamily, editable)),
|
|
8917
|
-
presence && /* @__PURE__ */ (0,
|
|
9047
|
+
presence && /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(ChartPresenceLayer, { presence })
|
|
8918
9048
|
]
|
|
8919
9049
|
}
|
|
8920
9050
|
) });
|
|
8921
9051
|
}
|
|
8922
9052
|
|
|
8923
9053
|
// src/chart/ChartDataGrid.tsx
|
|
8924
|
-
var
|
|
9054
|
+
var import_react66 = require("react");
|
|
8925
9055
|
var import_chart3 = require("@pixerate/editor/chart");
|
|
8926
9056
|
|
|
8927
9057
|
// src/chart/styles.ts
|
|
@@ -8934,11 +9064,11 @@ var chartSectionClass = "space-y-2 border-b border-border pb-3 last:border-b-0";
|
|
|
8934
9064
|
var chartCellClass = "h-7 w-full min-w-[4.5rem] bg-transparent px-2 text-right text-xs tabular-nums text-foreground focus-visible:bg-background focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-inset focus-visible:ring-primary";
|
|
8935
9065
|
|
|
8936
9066
|
// src/chart/ChartDataGrid.tsx
|
|
8937
|
-
var
|
|
9067
|
+
var import_jsx_runtime46 = require("react/jsx-runtime");
|
|
8938
9068
|
function ChartCommitInput({ value, onCommit, onKeyDown, onBlur, ...rest }) {
|
|
8939
|
-
const [draft, setDraft] = (0,
|
|
8940
|
-
const typing = (0,
|
|
8941
|
-
(0,
|
|
9069
|
+
const [draft, setDraft] = (0, import_react66.useState)(value);
|
|
9070
|
+
const typing = (0, import_react66.useRef)(false);
|
|
9071
|
+
(0, import_react66.useEffect)(() => {
|
|
8942
9072
|
if (!typing.current) setDraft(value);
|
|
8943
9073
|
}, [value]);
|
|
8944
9074
|
const commit = () => {
|
|
@@ -8947,7 +9077,7 @@ function ChartCommitInput({ value, onCommit, onKeyDown, onBlur, ...rest }) {
|
|
|
8947
9077
|
if (draft === value) return;
|
|
8948
9078
|
if (onCommit(draft) === false) setDraft(value);
|
|
8949
9079
|
};
|
|
8950
|
-
return /* @__PURE__ */ (0,
|
|
9080
|
+
return /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
|
|
8951
9081
|
"input",
|
|
8952
9082
|
{
|
|
8953
9083
|
...rest,
|
|
@@ -8982,15 +9112,15 @@ function ChartDataGrid({ controller, categoryHeader = "Category", readOnly = fal
|
|
|
8982
9112
|
e.preventDefault();
|
|
8983
9113
|
controller.pasteCells(row, column, text);
|
|
8984
9114
|
};
|
|
8985
|
-
return /* @__PURE__ */ (0,
|
|
8986
|
-
/* @__PURE__ */ (0,
|
|
8987
|
-
/* @__PURE__ */ (0,
|
|
8988
|
-
/* @__PURE__ */ (0,
|
|
9115
|
+
return /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("div", { className: `overflow-auto rounded-md border border-border ${className ?? ""}`, "data-chart-grid": "", children: [
|
|
9116
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("table", { className: "w-full border-collapse text-xs", children: [
|
|
9117
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsx)("thead", { className: "bg-muted/50", children: /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("tr", { children: [
|
|
9118
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsx)("th", { className: "border-b border-r border-border px-2 py-1 text-left font-medium text-muted-foreground", children: categoryHeader }),
|
|
8989
9119
|
spec.series.map((s, si) => {
|
|
8990
9120
|
const color = (0, import_chart3.chartSeriesColor)(spec, si);
|
|
8991
9121
|
const selected = selection?.kind === "series" && selection.seriesId === s.id;
|
|
8992
|
-
return /* @__PURE__ */ (0,
|
|
8993
|
-
/* @__PURE__ */ (0,
|
|
9122
|
+
return /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("th", { "data-series-id": s.id, className: `border-b border-r border-border px-1 py-1 font-medium ${selected ? "bg-primary/10" : ""}`, children: /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("div", { className: "flex items-center gap-1", children: [
|
|
9123
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
|
|
8994
9124
|
"input",
|
|
8995
9125
|
{
|
|
8996
9126
|
type: "color",
|
|
@@ -9003,7 +9133,7 @@ function ChartDataGrid({ controller, categoryHeader = "Category", readOnly = fal
|
|
|
9003
9133
|
className: "h-5 w-5 shrink-0 cursor-pointer rounded border-0 bg-transparent p-0"
|
|
9004
9134
|
}
|
|
9005
9135
|
),
|
|
9006
|
-
/* @__PURE__ */ (0,
|
|
9136
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
|
|
9007
9137
|
ChartCommitInput,
|
|
9008
9138
|
{
|
|
9009
9139
|
value: s.name,
|
|
@@ -9013,8 +9143,8 @@ function ChartDataGrid({ controller, categoryHeader = "Category", readOnly = fal
|
|
|
9013
9143
|
className: `${chartInputClass} h-6 min-w-[5rem] border-transparent bg-transparent font-medium ${s.hidden ? "text-muted-foreground line-through" : ""}`
|
|
9014
9144
|
}
|
|
9015
9145
|
),
|
|
9016
|
-
!readOnly && /* @__PURE__ */ (0,
|
|
9017
|
-
/* @__PURE__ */ (0,
|
|
9146
|
+
!readOnly && /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)(import_jsx_runtime46.Fragment, { children: [
|
|
9147
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
|
|
9018
9148
|
"button",
|
|
9019
9149
|
{
|
|
9020
9150
|
type: "button",
|
|
@@ -9027,16 +9157,16 @@ function ChartDataGrid({ controller, categoryHeader = "Category", readOnly = fal
|
|
|
9027
9157
|
children: s.hidden ? "\u25CB" : "\u25CF"
|
|
9028
9158
|
}
|
|
9029
9159
|
),
|
|
9030
|
-
/* @__PURE__ */ (0,
|
|
9160
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsx)("button", { type: "button", className: chartIconButtonClass, title: "Delete series", "aria-label": `Delete ${s.name}`, "data-action": "remove-series", onClick: () => controller.removeSeries(s.id), children: "\xD7" })
|
|
9031
9161
|
] })
|
|
9032
9162
|
] }) }, s.id);
|
|
9033
9163
|
}),
|
|
9034
|
-
!readOnly && /* @__PURE__ */ (0,
|
|
9164
|
+
!readOnly && /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("th", { className: "w-8 border-b border-border px-1", children: /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("button", { type: "button", className: chartIconButtonClass, title: "Add series", "aria-label": "Add series", "data-action": "add-series", onClick: () => controller.addSeries(), children: "+" }) })
|
|
9035
9165
|
] }) }),
|
|
9036
|
-
/* @__PURE__ */ (0,
|
|
9166
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsx)("tbody", { children: spec.categories.map((category, i) => {
|
|
9037
9167
|
const rowSelected = selection?.kind === "category" && selection.index === i;
|
|
9038
|
-
return /* @__PURE__ */ (0,
|
|
9039
|
-
/* @__PURE__ */ (0,
|
|
9168
|
+
return /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("tr", { "data-category-index": i, className: rowSelected ? "bg-primary/10" : void 0, children: [
|
|
9169
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsx)("th", { className: "border-b border-r border-border p-0 text-left font-normal", children: /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
|
|
9040
9170
|
ChartCommitInput,
|
|
9041
9171
|
{
|
|
9042
9172
|
value: category,
|
|
@@ -9050,7 +9180,7 @@ function ChartDataGrid({ controller, categoryHeader = "Category", readOnly = fal
|
|
|
9050
9180
|
spec.series.map((s) => {
|
|
9051
9181
|
const value = s.values[i];
|
|
9052
9182
|
const selected = selection?.kind === "point" && selection.seriesId === s.id && selection.index === i;
|
|
9053
|
-
return /* @__PURE__ */ (0,
|
|
9183
|
+
return /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("td", { className: `border-b border-r border-border p-0 ${selected ? "bg-primary/10" : ""}`, children: /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
|
|
9054
9184
|
ChartCommitInput,
|
|
9055
9185
|
{
|
|
9056
9186
|
value: value === null || value === void 0 ? "" : String(value),
|
|
@@ -9065,38 +9195,38 @@ function ChartDataGrid({ controller, categoryHeader = "Category", readOnly = fal
|
|
|
9065
9195
|
}
|
|
9066
9196
|
) }, s.id);
|
|
9067
9197
|
}),
|
|
9068
|
-
!readOnly && /* @__PURE__ */ (0,
|
|
9198
|
+
!readOnly && /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("td", { className: "border-b border-border px-1", children: /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("button", { type: "button", className: chartIconButtonClass, title: "Delete category", "aria-label": `Delete ${category}`, "data-action": "remove-category", onClick: () => controller.removeCategory(i), children: "\xD7" }) })
|
|
9069
9199
|
] }, i);
|
|
9070
9200
|
}) })
|
|
9071
9201
|
] }),
|
|
9072
|
-
!readOnly && /* @__PURE__ */ (0,
|
|
9202
|
+
!readOnly && /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("div", { className: "p-1", children: /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("button", { type: "button", className: `${chartButtonClass} h-6 border-dashed`, "data-action": "add-category", onClick: () => controller.addCategory(), children: "+ Add category" }) })
|
|
9073
9203
|
] });
|
|
9074
9204
|
}
|
|
9075
9205
|
|
|
9076
9206
|
// src/chart/ChartInspector.tsx
|
|
9077
|
-
var
|
|
9207
|
+
var import_react67 = require("react");
|
|
9078
9208
|
var import_chart4 = require("@pixerate/editor/chart");
|
|
9079
|
-
var
|
|
9209
|
+
var import_jsx_runtime47 = require("react/jsx-runtime");
|
|
9080
9210
|
var cap = (s) => s.charAt(0).toUpperCase() + s.slice(1);
|
|
9081
9211
|
function Field({ label, htmlFor, children }) {
|
|
9082
|
-
return /* @__PURE__ */ (0,
|
|
9083
|
-
/* @__PURE__ */ (0,
|
|
9084
|
-
/* @__PURE__ */ (0,
|
|
9212
|
+
return /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
9213
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)("label", { htmlFor, className: `${chartLabelClass} w-20 shrink-0`, children: label }),
|
|
9214
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)("div", { className: "min-w-0 flex-1", children })
|
|
9085
9215
|
] });
|
|
9086
9216
|
}
|
|
9087
9217
|
function Toggle({ label, checked, onChange, name }) {
|
|
9088
|
-
return /* @__PURE__ */ (0,
|
|
9089
|
-
/* @__PURE__ */ (0,
|
|
9218
|
+
return /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("label", { className: "flex cursor-pointer items-center gap-2 text-xs text-foreground", children: [
|
|
9219
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)("input", { type: "checkbox", className: "h-3.5 w-3.5 accent-primary", checked, "data-option": name, onChange: (e) => onChange(e.currentTarget.checked) }),
|
|
9090
9220
|
label
|
|
9091
9221
|
] });
|
|
9092
9222
|
}
|
|
9093
9223
|
function Select({ id, value, options, onChange, name, labels }) {
|
|
9094
|
-
return /* @__PURE__ */ (0,
|
|
9224
|
+
return /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("select", { id, className: chartInputClass, value, "data-option": name, onChange: (e) => onChange(e.currentTarget.value), children: options.map((o) => /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("option", { value: o, children: labels?.[o] ?? cap(o) }, o)) });
|
|
9095
9225
|
}
|
|
9096
9226
|
function AxisSection({ controller, axis, value, idBase, horizontal, numeric = false, scales = false }) {
|
|
9097
9227
|
const set = (patch) => controller.setAxis(axis, patch);
|
|
9098
9228
|
const setFormat = (patch) => set({ format: { ...value.format, ...patch } });
|
|
9099
|
-
const bound = (key2) => /* @__PURE__ */ (0,
|
|
9229
|
+
const bound = (key2) => /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
|
|
9100
9230
|
ChartCommitInput,
|
|
9101
9231
|
{
|
|
9102
9232
|
id: `${idBase}-${axis}-${key2}`,
|
|
@@ -9111,26 +9241,26 @@ function AxisSection({ controller, axis, value, idBase, horizontal, numeric = fa
|
|
|
9111
9241
|
const name = axis === "x" ? numeric ? "X axis" : "Category axis" : axis === "y" ? "Value axis" : "Secondary axis";
|
|
9112
9242
|
const valueAxis = axis !== "x" || numeric;
|
|
9113
9243
|
const key = axis === "y2" ? "yAxis2" : `${axis}Axis`;
|
|
9114
|
-
return /* @__PURE__ */ (0,
|
|
9115
|
-
/* @__PURE__ */ (0,
|
|
9116
|
-
/* @__PURE__ */ (0,
|
|
9244
|
+
return /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: chartSectionClass, "data-section": `axis-${axis}`, children: [
|
|
9245
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: "flex items-center justify-between", children: [
|
|
9246
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("h4", { className: "text-xs font-semibold text-foreground", children: [
|
|
9117
9247
|
name,
|
|
9118
|
-
/* @__PURE__ */ (0,
|
|
9248
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("span", { className: "ml-1 font-normal text-muted-foreground", children: [
|
|
9119
9249
|
"(",
|
|
9120
9250
|
axis === "x" ? horizontal ? "left" : "bottom" : axis === "y2" ? horizontal ? "top" : "right" : horizontal ? "bottom" : "left",
|
|
9121
9251
|
")"
|
|
9122
9252
|
] })
|
|
9123
9253
|
] }),
|
|
9124
|
-
/* @__PURE__ */ (0,
|
|
9254
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)(Toggle, { label: "Show", name: `${axis}Axis.show`, checked: value.show, onChange: (show) => set({ show }) })
|
|
9125
9255
|
] }),
|
|
9126
|
-
/* @__PURE__ */ (0,
|
|
9127
|
-
/* @__PURE__ */ (0,
|
|
9128
|
-
/* @__PURE__ */ (0,
|
|
9129
|
-
axis === "x" && !numeric && /* @__PURE__ */ (0,
|
|
9130
|
-
scales && /* @__PURE__ */ (0,
|
|
9131
|
-
scales && valueAxis && /* @__PURE__ */ (0,
|
|
9256
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)(Field, { label: "Title", htmlFor: `${idBase}-${axis}-title`, children: /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(ChartCommitInput, { id: `${idBase}-${axis}-title`, value: value.title, "data-option": `${axis}Axis.title`, className: chartInputClass, onCommit: (title) => void set({ title }) }) }),
|
|
9257
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: "flex flex-wrap gap-x-4 gap-y-1", children: [
|
|
9258
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)(Toggle, { label: "Grid lines", name: `${key}.gridlines`, checked: value.gridlines, onChange: (gridlines) => set({ gridlines }) }),
|
|
9259
|
+
axis === "x" && !numeric && /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(Toggle, { label: "Dates", name: "xAxis.kind", checked: value.kind === "date", onChange: (dates) => set({ kind: dates ? "date" : void 0 }) }),
|
|
9260
|
+
scales && /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(Toggle, { label: "Reverse", name: `${key}.reverse`, checked: !!value.reverse, onChange: (reverse) => set({ reverse }) }),
|
|
9261
|
+
scales && valueAxis && /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(Toggle, { label: "Log scale", name: `${key}.scale`, checked: value.scale === "log", onChange: (log) => set({ scale: log ? "log" : "linear" }) })
|
|
9132
9262
|
] }),
|
|
9133
|
-
scales && valueAxis && value.scale === "log" && /* @__PURE__ */ (0,
|
|
9263
|
+
scales && valueAxis && value.scale === "log" && /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(Field, { label: "Log base", htmlFor: `${idBase}-${axis}-log-base`, children: /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
|
|
9134
9264
|
ChartCommitInput,
|
|
9135
9265
|
{
|
|
9136
9266
|
id: `${idBase}-${axis}-log-base`,
|
|
@@ -9141,7 +9271,7 @@ function AxisSection({ controller, axis, value, idBase, horizontal, numeric = fa
|
|
|
9141
9271
|
onCommit: (text) => set({ logBase: text.trim() === "" ? void 0 : Number(text) }).ok
|
|
9142
9272
|
}
|
|
9143
9273
|
) }),
|
|
9144
|
-
valueAxis && value.scale !== "log" && /* @__PURE__ */ (0,
|
|
9274
|
+
valueAxis && value.scale !== "log" && /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(Field, { label: "Step", htmlFor: `${idBase}-${axis}-step`, children: /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
|
|
9145
9275
|
ChartCommitInput,
|
|
9146
9276
|
{
|
|
9147
9277
|
id: `${idBase}-${axis}-step`,
|
|
@@ -9153,14 +9283,14 @@ function AxisSection({ controller, axis, value, idBase, horizontal, numeric = fa
|
|
|
9153
9283
|
onCommit: (text) => set({ step: text.trim() === "" ? null : Number(text) }).ok
|
|
9154
9284
|
}
|
|
9155
9285
|
) }),
|
|
9156
|
-
valueAxis && /* @__PURE__ */ (0,
|
|
9157
|
-
/* @__PURE__ */ (0,
|
|
9286
|
+
valueAxis && /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)(import_jsx_runtime47.Fragment, { children: [
|
|
9287
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)(Field, { label: "Min / max", children: /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: "flex gap-1", children: [
|
|
9158
9288
|
bound("min"),
|
|
9159
9289
|
bound("max")
|
|
9160
9290
|
] }) }),
|
|
9161
|
-
/* @__PURE__ */ (0,
|
|
9162
|
-
/* @__PURE__ */ (0,
|
|
9163
|
-
/* @__PURE__ */ (0,
|
|
9291
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)(Field, { label: "Format", htmlFor: `${idBase}-${axis}-format`, children: /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: "flex gap-1", children: [
|
|
9292
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)(Select, { id: `${idBase}-${axis}-format`, name: `${key}.format.style`, value: value.format.style ?? "number", options: import_chart4.CHART_NUMBER_STYLES, onChange: (style) => setFormat({ style }) }),
|
|
9293
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
|
|
9164
9294
|
ChartCommitInput,
|
|
9165
9295
|
{
|
|
9166
9296
|
value: value.format.decimals === void 0 ? "" : String(value.format.decimals),
|
|
@@ -9179,8 +9309,8 @@ function AxisSection({ controller, axis, value, idBase, horizontal, numeric = fa
|
|
|
9179
9309
|
}
|
|
9180
9310
|
)
|
|
9181
9311
|
] }) }),
|
|
9182
|
-
value.format.style === "currency" && /* @__PURE__ */ (0,
|
|
9183
|
-
/* @__PURE__ */ (0,
|
|
9312
|
+
value.format.style === "currency" && /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(Field, { label: "Currency", htmlFor: `${idBase}-${axis}-currency`, children: /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(ChartCommitInput, { id: `${idBase}-${axis}-currency`, value: value.format.currency ?? "USD", "data-option": `${key}.format.currency`, className: chartInputClass, onCommit: (currency) => void setFormat({ currency: currency.toUpperCase() }) }) }),
|
|
9313
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)(Field, { label: "Code", htmlFor: `${idBase}-${axis}-code`, children: /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
|
|
9184
9314
|
ChartCommitInput,
|
|
9185
9315
|
{
|
|
9186
9316
|
id: `${idBase}-${axis}-code`,
|
|
@@ -9206,15 +9336,15 @@ function ErrorBarFields({ controller, series, which, idBase }) {
|
|
|
9206
9336
|
const values = which === "xErrorBars" ? series.x ?? [] : series.values;
|
|
9207
9337
|
const set = (next) => controller.updateSeries(series.id, { [which]: next });
|
|
9208
9338
|
const patch = (p) => bars && set({ ...bars, ...p });
|
|
9209
|
-
return /* @__PURE__ */ (0,
|
|
9210
|
-
/* @__PURE__ */ (0,
|
|
9211
|
-
/* @__PURE__ */ (0,
|
|
9212
|
-
import_chart4.CHART_ERROR_BAR_TYPES.map((t) => /* @__PURE__ */ (0,
|
|
9339
|
+
return /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: "space-y-1.5", "data-section": which === "errorBars" ? "error-bars" : "x-error-bars", children: [
|
|
9340
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)(Field, { label: which === "errorBars" ? "Error bars" : "X error bars", htmlFor: `${id}-type`, children: /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("select", { id: `${id}-type`, className: chartInputClass, value: bars?.type ?? "", "data-option": `${key}.type`, onChange: (e) => set((0, import_chart4.chartErrorBarsOfType)(e.currentTarget.value, bars, values)), children: [
|
|
9341
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)("option", { value: "", children: "None" }),
|
|
9342
|
+
import_chart4.CHART_ERROR_BAR_TYPES.map((t) => /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("option", { value: t, children: import_chart4.CHART_ERROR_BAR_LABELS[t] }, t))
|
|
9213
9343
|
] }) }),
|
|
9214
|
-
bars && (bars.type === "fixed" || bars.type === "percent" || bars.type === "stddev") && /* @__PURE__ */ (0,
|
|
9215
|
-
bars?.type === "custom" && /* @__PURE__ */ (0,
|
|
9216
|
-
/* @__PURE__ */ (0,
|
|
9217
|
-
/* @__PURE__ */ (0,
|
|
9344
|
+
bars && (bars.type === "fixed" || bars.type === "percent" || bars.type === "stddev") && /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(Field, { label: bars.type === "percent" ? "Percent" : bars.type === "stddev" ? "Deviations" : "Amount", htmlFor: `${id}-value`, children: /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(ChartCommitInput, { id: `${id}-value`, value: String(bars.value ?? (0, import_chart4.defaultChartErrorBarValue)(bars.type)), inputMode: "decimal", "data-option": `${key}.value`, className: chartInputClass, onCommit: (text) => !!patch({ value: text.trim() === "" ? void 0 : Number(text) })?.ok }) }),
|
|
9345
|
+
bars?.type === "custom" && /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)(import_jsx_runtime47.Fragment, { children: [
|
|
9346
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)(Field, { label: "Plus", htmlFor: `${id}-plus`, children: /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(ChartCommitInput, { id: `${id}-plus`, value: (0, import_chart4.formatChartAmountList)(bars.plus), placeholder: "1, 2, -, 0.5", "data-option": `${key}.plus`, className: chartInputClass, onCommit: (text) => !!patch({ plus: (0, import_chart4.parseChartAmountList)(text) })?.ok }) }),
|
|
9347
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)(Field, { label: "Minus", htmlFor: `${id}-minus`, children: /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
|
|
9218
9348
|
ChartCommitInput,
|
|
9219
9349
|
{
|
|
9220
9350
|
id: `${id}-minus`,
|
|
@@ -9231,15 +9361,15 @@ function ErrorBarFields({ controller, series, which, idBase }) {
|
|
|
9231
9361
|
}
|
|
9232
9362
|
) })
|
|
9233
9363
|
] }),
|
|
9234
|
-
bars && /* @__PURE__ */ (0,
|
|
9235
|
-
/* @__PURE__ */ (0,
|
|
9236
|
-
/* @__PURE__ */ (0,
|
|
9364
|
+
bars && /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
9365
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)("select", { className: `${chartInputClass} flex-1`, "aria-label": "Error bar direction", value: bars.direction ?? "both", "data-option": `${key}.direction`, onChange: (e) => patch({ direction: e.currentTarget.value }), children: import_chart4.CHART_ERROR_BAR_DIRECTIONS.map((d) => /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("option", { value: d, children: d === "both" ? "Both ways" : d === "plus" ? "Plus only" : "Minus only" }, d)) }),
|
|
9366
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)(Toggle, { label: "Caps", name: `${key}.cap`, checked: bars.cap !== false, onChange: (cap2) => patch({ cap: cap2 }) })
|
|
9237
9367
|
] })
|
|
9238
9368
|
] });
|
|
9239
9369
|
}
|
|
9240
9370
|
function ChartInspector({ controller, sections, className }) {
|
|
9241
9371
|
const { spec, selectedSeries } = useChartState(controller);
|
|
9242
|
-
const idBase = (0,
|
|
9372
|
+
const idBase = (0, import_react67.useId)();
|
|
9243
9373
|
const show = (section) => !sections || sections.includes(section);
|
|
9244
9374
|
const cartesian = (0, import_chart4.isCartesianChart)(spec.type);
|
|
9245
9375
|
const family = (0, import_chart4.chartFamily)(spec);
|
|
@@ -9251,29 +9381,29 @@ function ChartInspector({ controller, sections, className }) {
|
|
|
9251
9381
|
const hasLines = cartesian && types.some((t) => t === "line" || t === "area");
|
|
9252
9382
|
const seriesIndex = selectedSeries ? spec.series.findIndex((s) => s.id === selectedSeries.id) : -1;
|
|
9253
9383
|
const scales = family === "cartesian" || family === "xy";
|
|
9254
|
-
return /* @__PURE__ */ (0,
|
|
9255
|
-
show("type") && /* @__PURE__ */ (0,
|
|
9256
|
-
show("style") && /* @__PURE__ */ (0,
|
|
9257
|
-
/* @__PURE__ */ (0,
|
|
9258
|
-
/* @__PURE__ */ (0,
|
|
9259
|
-
import_chart4.CHART_LAYOUT_PRESETS.map((p) => /* @__PURE__ */ (0,
|
|
9384
|
+
return /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: `space-y-3 text-xs ${className ?? ""}`, "data-chart-inspector": "", children: [
|
|
9385
|
+
show("type") && /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("div", { className: chartSectionClass, "data-section": "type", children: /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("div", { className: "grid grid-cols-3 gap-0.5 rounded-md bg-muted p-0.5", role: "radiogroup", "aria-label": "Chart type", children: import_chart4.CHART_TYPES.map((type) => /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("button", { type: "button", role: "radio", "aria-checked": spec.type === type, "data-chart-type": type, className: chartSegmentClass(spec.type === type), onClick: () => controller.setType(type), children: import_chart4.CHART_TYPE_LABELS[type] }, type)) }) }),
|
|
9386
|
+
show("style") && /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: chartSectionClass, "data-section": "style", children: [
|
|
9387
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)(Field, { label: "Layout", htmlFor: `${idBase}-layout`, children: /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("select", { id: `${idBase}-layout`, className: chartInputClass, value: "", "data-option": "preset.layout", onChange: (e) => e.currentTarget.value && controller.applyPreset({ layout: e.currentTarget.value }), children: [
|
|
9388
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)("option", { value: "", children: "Quick layout\u2026" }),
|
|
9389
|
+
import_chart4.CHART_LAYOUT_PRESETS.map((p) => /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("option", { value: p.id, title: p.description, children: p.label }, p.id))
|
|
9260
9390
|
] }) }),
|
|
9261
|
-
/* @__PURE__ */ (0,
|
|
9262
|
-
/* @__PURE__ */ (0,
|
|
9263
|
-
import_chart4.CHART_COLOR_SCHEMES.map((c) => /* @__PURE__ */ (0,
|
|
9391
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)(Field, { label: "Colours", htmlFor: `${idBase}-colors`, children: /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("select", { id: `${idBase}-colors`, className: chartInputClass, value: import_chart4.CHART_COLOR_SCHEMES.find((c) => c.palette.join() === spec.palette.join())?.id ?? "", "data-option": "preset.colors", onChange: (e) => e.currentTarget.value && controller.applyPreset({ colors: e.currentTarget.value }), children: [
|
|
9392
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)("option", { value: "", children: "Custom" }),
|
|
9393
|
+
import_chart4.CHART_COLOR_SCHEMES.map((c) => /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("option", { value: c.id, title: c.description, children: c.label }, c.id))
|
|
9264
9394
|
] }) }),
|
|
9265
|
-
!colorCheck.ok && /* @__PURE__ */ (0,
|
|
9266
|
-
/* @__PURE__ */ (0,
|
|
9395
|
+
!colorCheck.ok && /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("p", { className: "text-[11px] leading-snug text-amber-600 dark:text-amber-400", "data-chart-color-warning": "", children: colorCheck.issues[0] }),
|
|
9396
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)("button", { type: "button", className: chartButtonClass, "data-action": "transpose", onClick: () => controller.transpose(), children: "Switch rows and columns" })
|
|
9267
9397
|
] }),
|
|
9268
|
-
show("titles") && /* @__PURE__ */ (0,
|
|
9269
|
-
/* @__PURE__ */ (0,
|
|
9270
|
-
/* @__PURE__ */ (0,
|
|
9398
|
+
show("titles") && /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: chartSectionClass, "data-section": "titles", children: [
|
|
9399
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)(Field, { label: "Title", htmlFor: `${idBase}-title`, children: /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(ChartCommitInput, { id: `${idBase}-title`, value: spec.title, "data-option": "title", className: chartInputClass, onCommit: (title) => void controller.setTitle(title) }) }),
|
|
9400
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)(Field, { label: "Subtitle", htmlFor: `${idBase}-subtitle`, children: /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(ChartCommitInput, { id: `${idBase}-subtitle`, value: spec.subtitle, "data-option": "subtitle", className: chartInputClass, onCommit: (subtitle) => void controller.setSubtitle(subtitle) }) })
|
|
9271
9401
|
] }),
|
|
9272
|
-
show("options") && /* @__PURE__ */ (0,
|
|
9273
|
-
cartesian && /* @__PURE__ */ (0,
|
|
9274
|
-
hasBars && /* @__PURE__ */ (0,
|
|
9275
|
-
hasLines && /* @__PURE__ */ (0,
|
|
9276
|
-
spec.type === "donut" && /* @__PURE__ */ (0,
|
|
9402
|
+
show("options") && /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: chartSectionClass, "data-section": "options", children: [
|
|
9403
|
+
cartesian && /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(Field, { label: "Stacking", htmlFor: `${idBase}-stacking`, children: /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(Select, { id: `${idBase}-stacking`, name: "stacking", value: spec.stacking, options: import_chart4.CHART_STACKINGS, labels: { none: "None", stacked: "Stacked", percent: "100%" }, onChange: (stacking) => controller.update({ stacking }) }) }),
|
|
9404
|
+
hasBars && /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(Field, { label: "Bars", children: /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("div", { className: "flex gap-0.5 rounded-md bg-muted p-0.5", children: ["vertical", "horizontal"].map((o) => /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("button", { type: "button", "aria-pressed": spec.orientation === o, "data-option": `orientation.${o}`, className: chartSegmentClass(spec.orientation === o), onClick: () => controller.update({ orientation: o }), children: cap(o) }, o)) }) }),
|
|
9405
|
+
hasLines && /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(Field, { label: "Lines", htmlFor: `${idBase}-curve`, children: /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(Select, { id: `${idBase}-curve`, name: "curve", value: spec.curve, options: import_chart4.CHART_CURVES, onChange: (curve) => controller.update({ curve }) }) }),
|
|
9406
|
+
spec.type === "donut" && /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(Field, { label: "Hole", htmlFor: `${idBase}-hole`, children: /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
|
|
9277
9407
|
"input",
|
|
9278
9408
|
{
|
|
9279
9409
|
id: `${idBase}-hole`,
|
|
@@ -9289,7 +9419,7 @@ function ChartInspector({ controller, sections, className }) {
|
|
|
9289
9419
|
onChange: (e) => controller.update({ innerRadius: Number(e.currentTarget.value) })
|
|
9290
9420
|
}
|
|
9291
9421
|
) }),
|
|
9292
|
-
hasBars && /* @__PURE__ */ (0,
|
|
9422
|
+
hasBars && /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(Field, { label: "Spacing", htmlFor: `${idBase}-gap`, children: /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
|
|
9293
9423
|
"input",
|
|
9294
9424
|
{
|
|
9295
9425
|
id: `${idBase}-gap`,
|
|
@@ -9305,31 +9435,31 @@ function ChartInspector({ controller, sections, className }) {
|
|
|
9305
9435
|
onChange: (e) => controller.update({ gapWidth: Number(e.currentTarget.value) })
|
|
9306
9436
|
}
|
|
9307
9437
|
) }),
|
|
9308
|
-
spec.dataLabels && hasBars && /* @__PURE__ */ (0,
|
|
9309
|
-
spec.type === "histogram" && /* @__PURE__ */ (0,
|
|
9310
|
-
/* @__PURE__ */ (0,
|
|
9311
|
-
spec.type === "waterfall" && /* @__PURE__ */ (0,
|
|
9312
|
-
hasLines && /* @__PURE__ */ (0,
|
|
9313
|
-
/* @__PURE__ */ (0,
|
|
9438
|
+
spec.dataLabels && hasBars && /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(Field, { label: "Labels", htmlFor: `${idBase}-label-position`, children: /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(Select, { id: `${idBase}-label-position`, name: "labelPosition", value: spec.labelPosition, options: import_chart4.CHART_LABEL_POSITIONS, onChange: (labelPosition) => controller.update({ labelPosition }) }) }),
|
|
9439
|
+
spec.type === "histogram" && /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(Field, { label: "Bins", htmlFor: `${idBase}-bins`, children: /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(ChartCommitInput, { id: `${idBase}-bins`, value: spec.bins === null ? "" : String(spec.bins), placeholder: "Auto", inputMode: "numeric", "data-option": "bins", className: chartInputClass, onCommit: (text) => controller.update({ bins: text.trim() === "" ? null : Number(text) }).ok }) }),
|
|
9440
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: "flex flex-wrap gap-x-4 gap-y-1", children: [
|
|
9441
|
+
spec.type === "waterfall" && /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(Toggle, { label: "Total bar", name: "showTotal", checked: spec.showTotal, onChange: (showTotal) => controller.update({ showTotal }) }),
|
|
9442
|
+
hasLines && /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(Toggle, { label: "Points", name: "points", checked: spec.points, onChange: (points) => controller.update({ points }) }),
|
|
9443
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)(Toggle, { label: "Data labels", name: "dataLabels", checked: spec.dataLabels, onChange: (dataLabels) => controller.update({ dataLabels }) })
|
|
9314
9444
|
] })
|
|
9315
9445
|
] }),
|
|
9316
|
-
show("legend") && /* @__PURE__ */ (0,
|
|
9317
|
-
/* @__PURE__ */ (0,
|
|
9318
|
-
/* @__PURE__ */ (0,
|
|
9319
|
-
/* @__PURE__ */ (0,
|
|
9446
|
+
show("legend") && /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: chartSectionClass, "data-section": "legend", children: [
|
|
9447
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: "flex items-center justify-between", children: [
|
|
9448
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)("h4", { className: "text-xs font-semibold text-foreground", children: "Legend" }),
|
|
9449
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)(Toggle, { label: "Show", name: "legend.show", checked: spec.legend.show, onChange: (v) => controller.setLegend({ show: v }) })
|
|
9320
9450
|
] }),
|
|
9321
|
-
spec.legend.show && /* @__PURE__ */ (0,
|
|
9451
|
+
spec.legend.show && /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("div", { className: "flex gap-0.5 rounded-md bg-muted p-0.5", children: import_chart4.CHART_LEGEND_POSITIONS.map((p) => /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("button", { type: "button", "aria-pressed": spec.legend.position === p, "data-option": `legend.${p}`, className: chartSegmentClass(spec.legend.position === p), onClick: () => controller.setLegend({ position: p }), children: cap(p) }, p)) })
|
|
9322
9452
|
] }),
|
|
9323
|
-
show("axes") && hasAxes && /* @__PURE__ */ (0,
|
|
9324
|
-
family !== "box" && family !== "histogram" && /* @__PURE__ */ (0,
|
|
9325
|
-
/* @__PURE__ */ (0,
|
|
9326
|
-
usesSecondary && /* @__PURE__ */ (0,
|
|
9453
|
+
show("axes") && hasAxes && /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)(import_jsx_runtime47.Fragment, { children: [
|
|
9454
|
+
family !== "box" && family !== "histogram" && /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(AxisSection, { controller, axis: "x", value: spec.xAxis, idBase, horizontal: spec.orientation === "horizontal", numeric: family === "xy", scales }),
|
|
9455
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)(AxisSection, { controller, axis: "y", value: spec.yAxis, idBase, horizontal: spec.orientation === "horizontal", scales }),
|
|
9456
|
+
usesSecondary && /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(AxisSection, { controller, axis: "y2", value: spec.yAxis2, idBase, horizontal: spec.orientation === "horizontal", scales })
|
|
9327
9457
|
] }),
|
|
9328
|
-
show("series") && selectedSeries && /* @__PURE__ */ (0,
|
|
9329
|
-
/* @__PURE__ */ (0,
|
|
9330
|
-
/* @__PURE__ */ (0,
|
|
9331
|
-
/* @__PURE__ */ (0,
|
|
9332
|
-
/* @__PURE__ */ (0,
|
|
9458
|
+
show("series") && selectedSeries && /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: chartSectionClass, "data-section": "series", "data-series-id": selectedSeries.id, children: [
|
|
9459
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)("h4", { className: "text-xs font-semibold text-foreground", children: "Series" }),
|
|
9460
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)(Field, { label: "Name", htmlFor: `${idBase}-series-name`, children: /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(ChartCommitInput, { id: `${idBase}-series-name`, value: selectedSeries.name, "data-option": "series.name", className: chartInputClass, onCommit: (name) => void controller.updateSeries(selectedSeries.id, { name }) }) }),
|
|
9461
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)(Field, { label: "Colour", htmlFor: `${idBase}-series-color`, children: /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: "flex items-center gap-1", children: [
|
|
9462
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
|
|
9333
9463
|
"input",
|
|
9334
9464
|
{
|
|
9335
9465
|
id: `${idBase}-series-color`,
|
|
@@ -9342,9 +9472,9 @@ function ChartInspector({ controller, sections, className }) {
|
|
|
9342
9472
|
onChange: (e) => controller.updateSeries(selectedSeries.id, { color: e.currentTarget.value })
|
|
9343
9473
|
}
|
|
9344
9474
|
),
|
|
9345
|
-
selectedSeries.color && /* @__PURE__ */ (0,
|
|
9475
|
+
selectedSeries.color && /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("button", { type: "button", className: chartButtonClass, "data-action": "reset-color", onClick: () => controller.updateSeries(selectedSeries.id, { color: null }), children: "Palette" })
|
|
9346
9476
|
] }) }),
|
|
9347
|
-
cartesian && /* @__PURE__ */ (0,
|
|
9477
|
+
cartesian && /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(Field, { label: "Draw as", htmlFor: `${idBase}-series-type`, children: /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)(
|
|
9348
9478
|
"select",
|
|
9349
9479
|
{
|
|
9350
9480
|
id: `${idBase}-series-type`,
|
|
@@ -9353,12 +9483,12 @@ function ChartInspector({ controller, sections, className }) {
|
|
|
9353
9483
|
"data-option": "series.type",
|
|
9354
9484
|
onChange: (e) => controller.updateSeries(selectedSeries.id, { type: e.currentTarget.value || null }),
|
|
9355
9485
|
children: [
|
|
9356
|
-
/* @__PURE__ */ (0,
|
|
9357
|
-
import_chart4.CHART_SERIES_TYPES.map((t) => /* @__PURE__ */ (0,
|
|
9486
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)("option", { value: "", children: "Chart type" }),
|
|
9487
|
+
import_chart4.CHART_SERIES_TYPES.map((t) => /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("option", { value: t, children: import_chart4.CHART_TYPE_LABELS[t] }, t))
|
|
9358
9488
|
]
|
|
9359
9489
|
}
|
|
9360
9490
|
) }),
|
|
9361
|
-
(cartesian || family === "xy") && ["line", "area", "scatter"].includes((0, import_chart4.chartSeriesType)(spec, selectedSeries)) && /* @__PURE__ */ (0,
|
|
9491
|
+
(cartesian || family === "xy") && ["line", "area", "scatter"].includes((0, import_chart4.chartSeriesType)(spec, selectedSeries)) && /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(Field, { label: "Marker", htmlFor: `${idBase}-series-marker`, children: /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)(
|
|
9362
9492
|
"select",
|
|
9363
9493
|
{
|
|
9364
9494
|
id: `${idBase}-series-marker`,
|
|
@@ -9367,20 +9497,20 @@ function ChartInspector({ controller, sections, className }) {
|
|
|
9367
9497
|
"data-option": "series.marker",
|
|
9368
9498
|
onChange: (e) => controller.updateSeries(selectedSeries.id, { marker: e.currentTarget.value || null }),
|
|
9369
9499
|
children: [
|
|
9370
|
-
/* @__PURE__ */ (0,
|
|
9371
|
-
import_chart4.CHART_MARKERS.map((m) => /* @__PURE__ */ (0,
|
|
9500
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)("option", { value: "", children: "Default" }),
|
|
9501
|
+
import_chart4.CHART_MARKERS.map((m) => /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("option", { value: m, children: cap(m) }, m))
|
|
9372
9502
|
]
|
|
9373
9503
|
}
|
|
9374
9504
|
) }),
|
|
9375
|
-
scales && /* @__PURE__ */ (0,
|
|
9376
|
-
family === "xy" && /* @__PURE__ */ (0,
|
|
9377
|
-
(0, import_chart4.chartSupportsTrendlines)(spec.type, spec.stacking) && /* @__PURE__ */ (0,
|
|
9378
|
-
(selectedSeries.trendlines ?? []).map((t, i) => /* @__PURE__ */ (0,
|
|
9379
|
-
/* @__PURE__ */ (0,
|
|
9380
|
-
/* @__PURE__ */ (0,
|
|
9381
|
-
/* @__PURE__ */ (0,
|
|
9505
|
+
scales && /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(ErrorBarFields, { controller, series: selectedSeries, which: "errorBars", idBase }),
|
|
9506
|
+
family === "xy" && /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(ErrorBarFields, { controller, series: selectedSeries, which: "xErrorBars", idBase }),
|
|
9507
|
+
(0, import_chart4.chartSupportsTrendlines)(spec.type, spec.stacking) && /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: "space-y-1", "data-section": "trendlines", children: [
|
|
9508
|
+
(selectedSeries.trendlines ?? []).map((t, i) => /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: "flex items-center gap-1", "data-trendline": i, children: [
|
|
9509
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)("span", { className: "flex-1 truncate text-muted-foreground", children: (0, import_chart4.chartTrendlineName)(t, selectedSeries.name) }),
|
|
9510
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)(Toggle, { label: "R\xB2", name: `trendline.${i}.showR2`, checked: !!t.showR2, onChange: (showR2) => controller.updateTrendline(selectedSeries.id, i, { showR2 }) }),
|
|
9511
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)("button", { type: "button", className: chartButtonClass, "aria-label": "Delete trendline", "data-action": "trendline-delete", onClick: () => controller.removeTrendline(selectedSeries.id, i), children: "\xD7" })
|
|
9382
9512
|
] }, i)),
|
|
9383
|
-
/* @__PURE__ */ (0,
|
|
9513
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsxs)(
|
|
9384
9514
|
"select",
|
|
9385
9515
|
{
|
|
9386
9516
|
className: chartInputClass,
|
|
@@ -9389,32 +9519,32 @@ function ChartInspector({ controller, sections, className }) {
|
|
|
9389
9519
|
"data-option": "trendline.add",
|
|
9390
9520
|
onChange: (e) => e.currentTarget.value && controller.addTrendline(selectedSeries.id, { type: e.currentTarget.value }),
|
|
9391
9521
|
children: [
|
|
9392
|
-
/* @__PURE__ */ (0,
|
|
9393
|
-
import_chart4.CHART_TRENDLINE_TYPES.map((t) => /* @__PURE__ */ (0,
|
|
9522
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)("option", { value: "", children: "Add trendline\u2026" }),
|
|
9523
|
+
import_chart4.CHART_TRENDLINE_TYPES.map((t) => /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("option", { value: t, children: cap(t.replace("-", " ")) }, t))
|
|
9394
9524
|
]
|
|
9395
9525
|
}
|
|
9396
9526
|
)
|
|
9397
9527
|
] }),
|
|
9398
|
-
/* @__PURE__ */ (0,
|
|
9399
|
-
/* @__PURE__ */ (0,
|
|
9400
|
-
family === "cartesian" && /* @__PURE__ */ (0,
|
|
9401
|
-
/* @__PURE__ */ (0,
|
|
9402
|
-
/* @__PURE__ */ (0,
|
|
9403
|
-
/* @__PURE__ */ (0,
|
|
9404
|
-
/* @__PURE__ */ (0,
|
|
9528
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: "flex flex-wrap items-center gap-1", children: [
|
|
9529
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)(Toggle, { label: "Hidden", name: "series.hidden", checked: !!selectedSeries.hidden, onChange: (hidden) => controller.updateSeries(selectedSeries.id, { hidden }) }),
|
|
9530
|
+
family === "cartesian" && /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(Toggle, { label: "Secondary axis", name: "series.axis", checked: selectedSeries.axis === "secondary", onChange: (secondary) => controller.updateSeries(selectedSeries.id, { axis: secondary ? "secondary" : null }) }),
|
|
9531
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)("span", { className: "flex-1" }),
|
|
9532
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)("button", { type: "button", className: chartButtonClass, disabled: seriesIndex <= 0, "aria-label": "Move series earlier", "data-action": "series-up", onClick: () => controller.moveSeries(selectedSeries.id, seriesIndex - 1), children: "\u2191" }),
|
|
9533
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)("button", { type: "button", className: chartButtonClass, disabled: seriesIndex >= spec.series.length - 1, "aria-label": "Move series later", "data-action": "series-down", onClick: () => controller.moveSeries(selectedSeries.id, seriesIndex + 1), children: "\u2193" }),
|
|
9534
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)("button", { type: "button", className: `${chartButtonClass} text-destructive`, "data-action": "series-delete", onClick: () => controller.removeSeries(selectedSeries.id), children: "Delete" })
|
|
9405
9535
|
] })
|
|
9406
9536
|
] })
|
|
9407
9537
|
] });
|
|
9408
9538
|
}
|
|
9409
9539
|
|
|
9410
9540
|
// src/chart-node/ChartNodeView.tsx
|
|
9411
|
-
var
|
|
9541
|
+
var import_jsx_runtime48 = require("react/jsx-runtime");
|
|
9412
9542
|
function ChartNodeView({ state, theme, showDataGrid = true }) {
|
|
9413
9543
|
const { controller, editing, editable, selected, width, height, setEditing } = state;
|
|
9414
9544
|
const open = () => {
|
|
9415
9545
|
if (editable && !editing) setEditing(true);
|
|
9416
9546
|
};
|
|
9417
|
-
return /* @__PURE__ */ (0,
|
|
9547
|
+
return /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)(
|
|
9418
9548
|
"div",
|
|
9419
9549
|
{
|
|
9420
9550
|
className: `not-prose my-2 rounded-md border bg-background p-1 ${selected ? "border-primary ring-1 ring-primary" : "border-border"}`,
|
|
@@ -9427,24 +9557,24 @@ function ChartNodeView({ state, theme, showDataGrid = true }) {
|
|
|
9427
9557
|
}
|
|
9428
9558
|
},
|
|
9429
9559
|
children: [
|
|
9430
|
-
editing && /* @__PURE__ */ (0,
|
|
9431
|
-
/* @__PURE__ */ (0,
|
|
9432
|
-
/* @__PURE__ */ (0,
|
|
9560
|
+
editing && /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)("div", { className: "mb-1 flex items-center justify-between gap-2 px-1", "data-chart-node-toolbar": "", children: [
|
|
9561
|
+
/* @__PURE__ */ (0, import_jsx_runtime48.jsx)("span", { className: "text-xs text-muted-foreground", children: "Editing chart" }),
|
|
9562
|
+
/* @__PURE__ */ (0, import_jsx_runtime48.jsx)("button", { type: "button", className: chartButtonClass, "data-action": "done", onClick: () => setEditing(false), children: "Done" })
|
|
9433
9563
|
] }),
|
|
9434
|
-
/* @__PURE__ */ (0,
|
|
9564
|
+
/* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
|
|
9435
9565
|
"div",
|
|
9436
9566
|
{
|
|
9437
9567
|
className: editable && !editing ? "cursor-pointer" : void 0,
|
|
9438
9568
|
onClick: open,
|
|
9439
9569
|
title: editable && !editing ? "Click to edit the chart" : void 0,
|
|
9440
9570
|
"data-chart-node-canvas": "",
|
|
9441
|
-
children: /* @__PURE__ */ (0,
|
|
9571
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(ChartCanvas, { controller, width: width ?? 640, height, responsive: width === null, editable: editing, theme })
|
|
9442
9572
|
}
|
|
9443
9573
|
),
|
|
9444
9574
|
editing && // Wraps by the document's width, not the viewport's: side by side when there is room.
|
|
9445
|
-
/* @__PURE__ */ (0,
|
|
9446
|
-
showDataGrid && /* @__PURE__ */ (0,
|
|
9447
|
-
/* @__PURE__ */ (0,
|
|
9575
|
+
/* @__PURE__ */ (0, import_jsx_runtime48.jsxs)("div", { className: "mt-2 flex flex-wrap items-start gap-2", "data-chart-node-panel": "", children: [
|
|
9576
|
+
showDataGrid && /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("div", { className: "min-w-0 flex-[1_1_20rem] overflow-x-auto", children: /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(ChartDataGrid, { controller }) }),
|
|
9577
|
+
/* @__PURE__ */ (0, import_jsx_runtime48.jsx)(ChartInspector, { controller, className: "max-h-96 min-w-0 flex-[1_1_16rem] overflow-y-auto rounded-md border border-border p-3" })
|
|
9448
9578
|
] })
|
|
9449
9579
|
]
|
|
9450
9580
|
}
|
|
@@ -9462,7 +9592,7 @@ function createReactChartNodeView(options = {}) {
|
|
|
9462
9592
|
scheduled = true;
|
|
9463
9593
|
queueMicrotask(() => {
|
|
9464
9594
|
scheduled = false;
|
|
9465
|
-
if (!destroyed) root.render(/* @__PURE__ */ (0,
|
|
9595
|
+
if (!destroyed) root.render(/* @__PURE__ */ (0, import_jsx_runtime48.jsx)(Component, { ...props, state: latest }));
|
|
9466
9596
|
});
|
|
9467
9597
|
};
|
|
9468
9598
|
schedule();
|
|
@@ -9485,6 +9615,7 @@ function createReactChartNodeView(options = {}) {
|
|
|
9485
9615
|
BrushOptionsBar,
|
|
9486
9616
|
BubbleMenu,
|
|
9487
9617
|
ChartNodeView,
|
|
9618
|
+
ColorProfilePanel,
|
|
9488
9619
|
CommandPalette,
|
|
9489
9620
|
CommentButton,
|
|
9490
9621
|
CommentsPanel,
|