@pixerate/editor-react 0.72.0 → 0.74.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-YAFNCBDA.js → chunk-LWMUV5TC.js} +477 -377
- package/dist/chunk-LWMUV5TC.js.map +1 -0
- package/dist/image-editor/index.cjs +540 -440
- package/dist/image-editor/index.cjs.map +1 -1
- package/dist/image-editor/index.d.cts +12 -1
- package/dist/image-editor/index.d.ts +12 -1
- package/dist/image-editor/index.js +3 -1
- package/dist/index.cjs +969 -869
- 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-YAFNCBDA.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" }),
|
|
@@ -5025,10 +5037,95 @@ var BrushOptionsBar = ({ controller, className }) => {
|
|
|
5025
5037
|
] });
|
|
5026
5038
|
};
|
|
5027
5039
|
|
|
5028
|
-
// src/image-editor/
|
|
5040
|
+
// src/image-editor/ColorProfilePanel.tsx
|
|
5029
5041
|
var import_react41 = require("react");
|
|
5030
5042
|
var import_image_editor9 = require("@pixerate/editor/image-editor");
|
|
5031
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": "Colour mode", children: [
|
|
5080
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { className: "text-slate-400", children: "Mode" }),
|
|
5081
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)("select", { "aria-label": "Colour mode", className: select, value: view.mode, onChange: (e) => attempt(() => controller.setColorMode(e.target.value)), children: import_image_editor9.COLOR_MODE_OPTIONS.map((o) => /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("option", { value: o.id, title: o.title, children: o.label }, o.id)) }),
|
|
5082
|
+
view.cmykProfileName && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { className: "text-slate-400", children: view.cmykProfileName })
|
|
5083
|
+
] }),
|
|
5084
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "flex flex-wrap items-center gap-1", role: "group", "aria-label": "Assign or convert", children: [
|
|
5085
|
+
/* @__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)) }),
|
|
5086
|
+
/* @__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)) }),
|
|
5087
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("label", { className: "flex items-center gap-1", children: [
|
|
5088
|
+
/* @__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" }),
|
|
5089
|
+
"BPC"
|
|
5090
|
+
] }),
|
|
5091
|
+
/* @__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" }),
|
|
5092
|
+
/* @__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" })
|
|
5093
|
+
] }),
|
|
5094
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "flex flex-wrap items-center gap-1", role: "group", "aria-label": "Proof setup", children: [
|
|
5095
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { className: "text-slate-400", children: "Proof" }),
|
|
5096
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(
|
|
5097
|
+
"select",
|
|
5098
|
+
{
|
|
5099
|
+
"aria-label": "Proof profile",
|
|
5100
|
+
className: select,
|
|
5101
|
+
value: view.proof?.id ?? "",
|
|
5102
|
+
onChange: (e) => e.target.value ? proofWith({ id: e.target.value }) : attempt(() => controller.setProofSetup(null)),
|
|
5103
|
+
children: [
|
|
5104
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)("option", { value: "", children: "Off" }),
|
|
5105
|
+
import_image_editor9.PROOF_PROFILE_OPTIONS.map((o) => /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("option", { value: o.id, children: o.label }, o.id))
|
|
5106
|
+
]
|
|
5107
|
+
}
|
|
5108
|
+
),
|
|
5109
|
+
view.proof && /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(import_jsx_runtime24.Fragment, { children: [
|
|
5110
|
+
/* @__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)) }),
|
|
5111
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("label", { className: "flex items-center gap-1", children: [
|
|
5112
|
+
/* @__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" }),
|
|
5113
|
+
"Paper"
|
|
5114
|
+
] }),
|
|
5115
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("label", { className: "flex items-center gap-1", children: [
|
|
5116
|
+
/* @__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" }),
|
|
5117
|
+
"Gamut warning"
|
|
5118
|
+
] })
|
|
5119
|
+
] })
|
|
5120
|
+
] }),
|
|
5121
|
+
error && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("p", { role: "alert", className: "text-rose-400", children: error })
|
|
5122
|
+
] });
|
|
5123
|
+
};
|
|
5124
|
+
|
|
5125
|
+
// src/image-editor/SelectionOptionsBar.tsx
|
|
5126
|
+
var import_react42 = require("react");
|
|
5127
|
+
var import_image_editor10 = require("@pixerate/editor/image-editor");
|
|
5128
|
+
var import_jsx_runtime25 = require("react/jsx-runtime");
|
|
5032
5129
|
var MODIFY_OPS = [
|
|
5033
5130
|
{ op: "grow", label: "Grow" },
|
|
5034
5131
|
{ op: "shrink", label: "Shrink" },
|
|
@@ -5045,20 +5142,20 @@ var SelectionOptionsBar = ({
|
|
|
5045
5142
|
quickMask,
|
|
5046
5143
|
className = ""
|
|
5047
5144
|
}) => {
|
|
5048
|
-
const [radius, setRadius] = (0,
|
|
5145
|
+
const [radius, setRadius] = (0, import_react42.useState)(2);
|
|
5049
5146
|
const set = (patch) => onOptionsChange({ ...options, ...patch });
|
|
5050
5147
|
const sel = selection === void 0 ? controller.getSelection() : selection;
|
|
5051
5148
|
const qm = quickMask ?? Boolean(controller.getState().quickMask);
|
|
5052
|
-
return /* @__PURE__ */ (0,
|
|
5053
|
-
/* @__PURE__ */ (0,
|
|
5054
|
-
/* @__PURE__ */ (0,
|
|
5055
|
-
options.tool === "wand" && /* @__PURE__ */ (0,
|
|
5056
|
-
/* @__PURE__ */ (0,
|
|
5057
|
-
/* @__PURE__ */ (0,
|
|
5058
|
-
/* @__PURE__ */ (0,
|
|
5059
|
-
/* @__PURE__ */ (0,
|
|
5149
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { "data-testid": "selection-options-bar", className: `flex flex-col gap-3 text-xs ${className}`, children: [
|
|
5150
|
+
/* @__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)) }),
|
|
5151
|
+
/* @__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)) }),
|
|
5152
|
+
options.tool === "wand" && /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "flex flex-col gap-2", children: [
|
|
5153
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("label", { className: "flex flex-col gap-1", children: [
|
|
5154
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("span", { className: "flex justify-between text-slate-400", children: [
|
|
5155
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { children: "Tolerance" }),
|
|
5156
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: "font-mono", children: options.tolerance })
|
|
5060
5157
|
] }),
|
|
5061
|
-
/* @__PURE__ */ (0,
|
|
5158
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
5062
5159
|
"input",
|
|
5063
5160
|
{
|
|
5064
5161
|
type: "range",
|
|
@@ -5072,17 +5169,17 @@ var SelectionOptionsBar = ({
|
|
|
5072
5169
|
}
|
|
5073
5170
|
)
|
|
5074
5171
|
] }),
|
|
5075
|
-
/* @__PURE__ */ (0,
|
|
5076
|
-
/* @__PURE__ */ (0,
|
|
5172
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("label", { className: "flex items-center gap-2 text-slate-300", children: [
|
|
5173
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("input", { type: "checkbox", checked: options.contiguous, onChange: (e) => set({ contiguous: e.target.checked }) }),
|
|
5077
5174
|
"Contiguous"
|
|
5078
5175
|
] }),
|
|
5079
|
-
/* @__PURE__ */ (0,
|
|
5080
|
-
/* @__PURE__ */ (0,
|
|
5176
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("label", { className: "flex items-center gap-2 text-slate-300", children: [
|
|
5177
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("input", { type: "checkbox", checked: options.sampleMerged, onChange: (e) => set({ sampleMerged: e.target.checked }) }),
|
|
5081
5178
|
"Sample adjusted image"
|
|
5082
5179
|
] }),
|
|
5083
|
-
/* @__PURE__ */ (0,
|
|
5180
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("label", { className: "flex items-center gap-2 text-slate-300", children: [
|
|
5084
5181
|
"Sample",
|
|
5085
|
-
/* @__PURE__ */ (0,
|
|
5182
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(
|
|
5086
5183
|
"select",
|
|
5087
5184
|
{
|
|
5088
5185
|
"aria-label": "Sample from",
|
|
@@ -5090,27 +5187,27 @@ var SelectionOptionsBar = ({
|
|
|
5090
5187
|
onChange: (e) => set({ sample: e.target.value }),
|
|
5091
5188
|
className: "bg-slate-800 border border-slate-700 rounded px-1 py-0.5",
|
|
5092
5189
|
children: [
|
|
5093
|
-
/* @__PURE__ */ (0,
|
|
5094
|
-
/* @__PURE__ */ (0,
|
|
5190
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("option", { value: "composite", children: "All layers" }),
|
|
5191
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("option", { value: "active-layer", children: "Active layer" })
|
|
5095
5192
|
]
|
|
5096
5193
|
}
|
|
5097
5194
|
)
|
|
5098
5195
|
] })
|
|
5099
5196
|
] }),
|
|
5100
|
-
/* @__PURE__ */ (0,
|
|
5101
|
-
/* @__PURE__ */ (0,
|
|
5197
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("label", { className: "flex items-center gap-2 text-slate-300", children: [
|
|
5198
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("input", { type: "checkbox", checked: options.antiAlias, onChange: (e) => set({ antiAlias: e.target.checked }) }),
|
|
5102
5199
|
"Anti-alias"
|
|
5103
5200
|
] }),
|
|
5104
|
-
/* @__PURE__ */ (0,
|
|
5105
|
-
/* @__PURE__ */ (0,
|
|
5106
|
-
/* @__PURE__ */ (0,
|
|
5107
|
-
/* @__PURE__ */ (0,
|
|
5108
|
-
/* @__PURE__ */ (0,
|
|
5201
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "flex flex-wrap gap-1", children: [
|
|
5202
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("button", { type: "button", className: btn(false), onClick: () => controller.selectAll(), children: "Select All" }),
|
|
5203
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("button", { type: "button", className: btn(false), disabled: !sel, onClick: () => controller.deselect(), children: "Deselect" }),
|
|
5204
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("button", { type: "button", className: btn(false), onClick: () => controller.invertSelection(), children: "Inverse" }),
|
|
5205
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("button", { type: "button", "aria-pressed": qm, className: btn(qm), onClick: () => controller.setQuickMask(!qm), children: "Quick Mask" })
|
|
5109
5206
|
] }),
|
|
5110
|
-
/* @__PURE__ */ (0,
|
|
5111
|
-
/* @__PURE__ */ (0,
|
|
5207
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "flex flex-wrap items-center gap-1", children: [
|
|
5208
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("label", { className: "flex items-center gap-1 text-slate-400", children: [
|
|
5112
5209
|
"Radius",
|
|
5113
|
-
/* @__PURE__ */ (0,
|
|
5210
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
5114
5211
|
"input",
|
|
5115
5212
|
{
|
|
5116
5213
|
type: "number",
|
|
@@ -5124,24 +5221,24 @@ var SelectionOptionsBar = ({
|
|
|
5124
5221
|
}
|
|
5125
5222
|
)
|
|
5126
5223
|
] }),
|
|
5127
|
-
MODIFY_OPS.map(({ op, label }) => /* @__PURE__ */ (0,
|
|
5224
|
+
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))
|
|
5128
5225
|
] }),
|
|
5129
|
-
/* @__PURE__ */ (0,
|
|
5226
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("p", { "data-testid": "selection-status", className: "text-slate-400", children: (0, import_image_editor10.describeSelection)(sel) })
|
|
5130
5227
|
] });
|
|
5131
5228
|
};
|
|
5132
5229
|
|
|
5133
5230
|
// src/image-editor/RefineEdgePanel.tsx
|
|
5134
|
-
var
|
|
5135
|
-
var
|
|
5136
|
-
var
|
|
5231
|
+
var import_react43 = require("react");
|
|
5232
|
+
var import_image_editor11 = require("@pixerate/editor/image-editor");
|
|
5233
|
+
var import_jsx_runtime26 = require("react/jsx-runtime");
|
|
5137
5234
|
var DEFAULT_PARAMS = { radius: 8, smartRadius: false, smooth: 0, feather: 0, contrast: 0, shiftEdge: 0 };
|
|
5138
5235
|
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";
|
|
5139
5236
|
var RefineEdgePanel = ({ controller, selection, layers, className = "" }) => {
|
|
5140
|
-
const [params, setParams] = (0,
|
|
5141
|
-
const [busy, setBusy] = (0,
|
|
5142
|
-
const [error, setError] = (0,
|
|
5143
|
-
const [layerId, setLayerId] = (0,
|
|
5144
|
-
const [newKind, setNewKind] = (0,
|
|
5237
|
+
const [params, setParams] = (0, import_react43.useState)(DEFAULT_PARAMS);
|
|
5238
|
+
const [busy, setBusy] = (0, import_react43.useState)(false);
|
|
5239
|
+
const [error, setError] = (0, import_react43.useState)(null);
|
|
5240
|
+
const [layerId, setLayerId] = (0, import_react43.useState)("");
|
|
5241
|
+
const [newKind, setNewKind] = (0, import_react43.useState)("hueSaturation");
|
|
5145
5242
|
const sel = selection === void 0 ? controller.getSelection() : selection;
|
|
5146
5243
|
const list = layers ?? controller.getAdjustmentLayers();
|
|
5147
5244
|
const target = list.find((l) => l.id === layerId) ?? list[list.length - 1];
|
|
@@ -5156,17 +5253,17 @@ var RefineEdgePanel = ({ controller, selection, layers, className = "" }) => {
|
|
|
5156
5253
|
setBusy(false);
|
|
5157
5254
|
}
|
|
5158
5255
|
};
|
|
5159
|
-
return /* @__PURE__ */ (0,
|
|
5160
|
-
/* @__PURE__ */ (0,
|
|
5161
|
-
|
|
5162
|
-
/* @__PURE__ */ (0,
|
|
5163
|
-
/* @__PURE__ */ (0,
|
|
5164
|
-
/* @__PURE__ */ (0,
|
|
5256
|
+
return /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { "data-testid": "refine-edge-panel", className: `flex flex-col gap-3 text-xs ${className}`, children: [
|
|
5257
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Refine Edge" }),
|
|
5258
|
+
import_image_editor11.REFINE_EDGE_CONTROLS.map((c) => /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("label", { className: "flex flex-col gap-1", children: [
|
|
5259
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("span", { className: "flex justify-between text-slate-400", children: [
|
|
5260
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { children: c.label }),
|
|
5261
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("span", { className: "font-mono", children: [
|
|
5165
5262
|
params[c.id],
|
|
5166
5263
|
c.unit
|
|
5167
5264
|
] })
|
|
5168
5265
|
] }),
|
|
5169
|
-
/* @__PURE__ */ (0,
|
|
5266
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
5170
5267
|
"input",
|
|
5171
5268
|
{
|
|
5172
5269
|
type: "range",
|
|
@@ -5180,67 +5277,67 @@ var RefineEdgePanel = ({ controller, selection, layers, className = "" }) => {
|
|
|
5180
5277
|
}
|
|
5181
5278
|
)
|
|
5182
5279
|
] }, c.id)),
|
|
5183
|
-
/* @__PURE__ */ (0,
|
|
5184
|
-
/* @__PURE__ */ (0,
|
|
5280
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("label", { className: "flex items-center gap-2 text-slate-300", children: [
|
|
5281
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("input", { type: "checkbox", checked: params.smartRadius, onChange: (e) => setParams({ ...params, smartRadius: e.target.checked }) }),
|
|
5185
5282
|
"Smart Radius"
|
|
5186
5283
|
] }),
|
|
5187
|
-
/* @__PURE__ */ (0,
|
|
5188
|
-
/* @__PURE__ */ (0,
|
|
5189
|
-
/* @__PURE__ */ (0,
|
|
5284
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "flex gap-1", children: [
|
|
5285
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("button", { type: "button", className: button2, disabled: !sel || busy, onClick: refine, children: "Refine Edge" }),
|
|
5286
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("button", { type: "button", className: button2, onClick: () => setParams(DEFAULT_PARAMS), children: "Reset" })
|
|
5190
5287
|
] }),
|
|
5191
|
-
error && /* @__PURE__ */ (0,
|
|
5192
|
-
/* @__PURE__ */ (0,
|
|
5193
|
-
/* @__PURE__ */ (0,
|
|
5194
|
-
/* @__PURE__ */ (0,
|
|
5288
|
+
error && /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("p", { role: "alert", className: "text-rose-400", children: error }),
|
|
5289
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px] mt-2", children: "Layer Mask" }),
|
|
5290
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "flex gap-1 items-center", children: [
|
|
5291
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
5195
5292
|
"select",
|
|
5196
5293
|
{
|
|
5197
5294
|
"aria-label": "New masked layer kind",
|
|
5198
5295
|
value: newKind,
|
|
5199
5296
|
onChange: (e) => setNewKind(e.target.value),
|
|
5200
5297
|
className: "flex-1 bg-slate-950 border border-slate-800 rounded px-1 py-1 text-slate-200",
|
|
5201
|
-
children:
|
|
5298
|
+
children: import_image_editor11.ADJUSTMENT_KINDS.map((k) => /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("option", { value: k.kind, children: k.label }, k.kind))
|
|
5202
5299
|
}
|
|
5203
5300
|
),
|
|
5204
|
-
/* @__PURE__ */ (0,
|
|
5301
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
5205
5302
|
"button",
|
|
5206
5303
|
{
|
|
5207
5304
|
type: "button",
|
|
5208
5305
|
className: button2,
|
|
5209
5306
|
disabled: !sel,
|
|
5210
|
-
onClick: () => sel && setLayerId(controller.addAdjustmentLayer({ kind: newKind, mask: (0,
|
|
5307
|
+
onClick: () => sel && setLayerId(controller.addAdjustmentLayer({ kind: newKind, mask: (0, import_image_editor11.layerMaskFromSelection)(sel) })),
|
|
5211
5308
|
children: "New Masked Layer"
|
|
5212
5309
|
}
|
|
5213
5310
|
)
|
|
5214
5311
|
] }),
|
|
5215
|
-
list.length > 0 && target && /* @__PURE__ */ (0,
|
|
5216
|
-
/* @__PURE__ */ (0,
|
|
5312
|
+
list.length > 0 && target && /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "flex flex-col gap-2", children: [
|
|
5313
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
5217
5314
|
"select",
|
|
5218
5315
|
{
|
|
5219
5316
|
"aria-label": "Mask layer",
|
|
5220
5317
|
value: target.id,
|
|
5221
5318
|
onChange: (e) => setLayerId(e.target.value),
|
|
5222
5319
|
className: "bg-slate-950 border border-slate-800 rounded px-1 py-1 text-slate-200",
|
|
5223
|
-
children: list.map((l) => /* @__PURE__ */ (0,
|
|
5224
|
-
l.name || (0,
|
|
5320
|
+
children: list.map((l) => /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("option", { value: l.id, children: [
|
|
5321
|
+
l.name || (0, import_image_editor11.adjustmentKindLabel)(l.kind),
|
|
5225
5322
|
l.mask ? " (masked)" : ""
|
|
5226
5323
|
] }, l.id))
|
|
5227
5324
|
}
|
|
5228
5325
|
),
|
|
5229
|
-
/* @__PURE__ */ (0,
|
|
5230
|
-
/* @__PURE__ */ (0,
|
|
5231
|
-
/* @__PURE__ */ (0,
|
|
5232
|
-
/* @__PURE__ */ (0,
|
|
5326
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "flex flex-wrap gap-1", children: [
|
|
5327
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("button", { type: "button", className: button2, disabled: !sel, onClick: () => controller.applySelectionAsLayerMask(target.id), children: "Mask with Selection" }),
|
|
5328
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("button", { type: "button", className: button2, disabled: !target.mask, onClick: () => controller.selectionFromLayerMask(target.id), children: "Load as Selection" }),
|
|
5329
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("button", { type: "button", className: button2, disabled: !target.mask, onClick: () => controller.setAdjustmentLayerMask(target.id, null), children: "Remove Mask" })
|
|
5233
5330
|
] }),
|
|
5234
|
-
target.mask && /* @__PURE__ */ (0,
|
|
5235
|
-
/* @__PURE__ */ (0,
|
|
5236
|
-
/* @__PURE__ */ (0,
|
|
5237
|
-
/* @__PURE__ */ (0,
|
|
5238
|
-
/* @__PURE__ */ (0,
|
|
5331
|
+
target.mask && /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(import_jsx_runtime26.Fragment, { children: [
|
|
5332
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("label", { className: "flex flex-col gap-1", children: [
|
|
5333
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("span", { className: "flex justify-between text-slate-400", children: [
|
|
5334
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { children: "Density" }),
|
|
5335
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("span", { className: "font-mono", children: [
|
|
5239
5336
|
Math.round((target.mask.density ?? 1) * 100),
|
|
5240
5337
|
"%"
|
|
5241
5338
|
] })
|
|
5242
5339
|
] }),
|
|
5243
|
-
/* @__PURE__ */ (0,
|
|
5340
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
5244
5341
|
"input",
|
|
5245
5342
|
{
|
|
5246
5343
|
type: "range",
|
|
@@ -5254,15 +5351,15 @@ var RefineEdgePanel = ({ controller, selection, layers, className = "" }) => {
|
|
|
5254
5351
|
}
|
|
5255
5352
|
)
|
|
5256
5353
|
] }),
|
|
5257
|
-
/* @__PURE__ */ (0,
|
|
5258
|
-
/* @__PURE__ */ (0,
|
|
5259
|
-
/* @__PURE__ */ (0,
|
|
5260
|
-
/* @__PURE__ */ (0,
|
|
5354
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("label", { className: "flex flex-col gap-1", children: [
|
|
5355
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("span", { className: "flex justify-between text-slate-400", children: [
|
|
5356
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { children: "Mask Feather" }),
|
|
5357
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("span", { className: "font-mono", children: [
|
|
5261
5358
|
target.mask.feather ?? 0,
|
|
5262
5359
|
"px"
|
|
5263
5360
|
] })
|
|
5264
5361
|
] }),
|
|
5265
|
-
/* @__PURE__ */ (0,
|
|
5362
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
5266
5363
|
"input",
|
|
5267
5364
|
{
|
|
5268
5365
|
type: "range",
|
|
@@ -5282,14 +5379,14 @@ var RefineEdgePanel = ({ controller, selection, layers, className = "" }) => {
|
|
|
5282
5379
|
};
|
|
5283
5380
|
|
|
5284
5381
|
// src/image-editor/FreeTransformOptionsBar.tsx
|
|
5285
|
-
var
|
|
5286
|
-
var
|
|
5287
|
-
var
|
|
5288
|
-
var
|
|
5382
|
+
var import_react44 = require("react");
|
|
5383
|
+
var import_image_editor12 = require("@pixerate/editor/image-editor");
|
|
5384
|
+
var import_jsx_runtime27 = require("react/jsx-runtime");
|
|
5385
|
+
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"}`;
|
|
5289
5386
|
var round = (v, unit) => unit === "px" ? Math.round(v * 10) / 10 : Math.round(v * 100) / 100;
|
|
5290
5387
|
var FreeTransformOptionsBar = ({ tool, className }) => {
|
|
5291
|
-
const [, setTick] = (0,
|
|
5292
|
-
(0,
|
|
5388
|
+
const [, setTick] = (0, import_react44.useState)(0);
|
|
5389
|
+
(0, import_react44.useEffect)(() => tool.subscribe(() => setTick((n) => n + 1)), [tool]);
|
|
5293
5390
|
const bar = tool.bar();
|
|
5294
5391
|
if (!tool.active || !bar) return null;
|
|
5295
5392
|
const warp = tool.warpBar();
|
|
@@ -5301,17 +5398,17 @@ var FreeTransformOptionsBar = ({ tool, className }) => {
|
|
|
5301
5398
|
const v = Number(raw);
|
|
5302
5399
|
if (raw.trim() !== "" && Number.isFinite(v) && Math.abs(v - bar[field]) > 1e-9) tool.setField(field, v);
|
|
5303
5400
|
};
|
|
5304
|
-
return /* @__PURE__ */ (0,
|
|
5305
|
-
/* @__PURE__ */ (0,
|
|
5306
|
-
/* @__PURE__ */ (0,
|
|
5307
|
-
tool.mode === "warp" && /* @__PURE__ */ (0,
|
|
5308
|
-
/* @__PURE__ */ (0,
|
|
5309
|
-
/* @__PURE__ */ (0,
|
|
5310
|
-
/* @__PURE__ */ (0,
|
|
5401
|
+
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: [
|
|
5402
|
+
/* @__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)) }),
|
|
5403
|
+
/* @__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)) }),
|
|
5404
|
+
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: [
|
|
5405
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("label", { className: "flex items-center gap-1", children: [
|
|
5406
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: "text-slate-400", children: "Warp" }),
|
|
5407
|
+
/* @__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)) })
|
|
5311
5408
|
] }),
|
|
5312
|
-
["bend", "horizontal", "vertical"].map((k) => /* @__PURE__ */ (0,
|
|
5313
|
-
/* @__PURE__ */ (0,
|
|
5314
|
-
/* @__PURE__ */ (0,
|
|
5409
|
+
["bend", "horizontal", "vertical"].map((k) => /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("label", { className: "flex items-center gap-1", children: [
|
|
5410
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: "text-slate-400", children: k === "bend" ? "Bend" : k === "horizontal" ? "H" : "V" }),
|
|
5411
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
5315
5412
|
"input",
|
|
5316
5413
|
{
|
|
5317
5414
|
type: "number",
|
|
@@ -5332,40 +5429,40 @@ var FreeTransformOptionsBar = ({ tool, className }) => {
|
|
|
5332
5429
|
},
|
|
5333
5430
|
`${k}:${warp[k]}`
|
|
5334
5431
|
),
|
|
5335
|
-
/* @__PURE__ */ (0,
|
|
5432
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: "text-slate-500", children: "%" })
|
|
5336
5433
|
] }, k)),
|
|
5337
|
-
/* @__PURE__ */ (0,
|
|
5434
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
5338
5435
|
"button",
|
|
5339
5436
|
{
|
|
5340
5437
|
type: "button",
|
|
5341
5438
|
title: "Bend along the vertical axis",
|
|
5342
5439
|
"aria-pressed": warp.orientation === "vertical",
|
|
5343
5440
|
disabled: warp.style === "custom",
|
|
5344
|
-
className:
|
|
5441
|
+
className: chip3(warp.orientation === "vertical"),
|
|
5345
5442
|
onClick: () => tool.setWarp({ orientation: warp.orientation === "vertical" ? "horizontal" : "vertical" }),
|
|
5346
5443
|
children: "Vertical"
|
|
5347
5444
|
}
|
|
5348
5445
|
),
|
|
5349
|
-
/* @__PURE__ */ (0,
|
|
5350
|
-
/* @__PURE__ */ (0,
|
|
5351
|
-
/* @__PURE__ */ (0,
|
|
5446
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("label", { className: "flex items-center gap-1", children: [
|
|
5447
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: "text-slate-400", children: "Grid" }),
|
|
5448
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
5352
5449
|
"select",
|
|
5353
5450
|
{
|
|
5354
5451
|
"aria-label": "Warp grid",
|
|
5355
|
-
value:
|
|
5452
|
+
value: import_image_editor12.WARP_GRID_OPTIONS.find((g) => g.columns === warp.columns && g.rows === warp.rows)?.id ?? "1x1",
|
|
5356
5453
|
onChange: (e) => {
|
|
5357
|
-
const g =
|
|
5454
|
+
const g = import_image_editor12.WARP_GRID_OPTIONS.find((o) => o.id === e.target.value);
|
|
5358
5455
|
tool.setWarp({ columns: g.columns, rows: g.rows });
|
|
5359
5456
|
},
|
|
5360
5457
|
className: "rounded border border-slate-700 bg-slate-900 px-1 py-0.5",
|
|
5361
|
-
children:
|
|
5458
|
+
children: import_image_editor12.WARP_GRID_OPTIONS.map((g) => /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("option", { value: g.id, children: g.label }, g.id))
|
|
5362
5459
|
}
|
|
5363
5460
|
)
|
|
5364
5461
|
] })
|
|
5365
5462
|
] }),
|
|
5366
|
-
tool.mode !== "warp" &&
|
|
5367
|
-
/* @__PURE__ */ (0,
|
|
5368
|
-
/* @__PURE__ */ (0,
|
|
5463
|
+
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: [
|
|
5464
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: "text-slate-400", children: f.label }),
|
|
5465
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
5369
5466
|
"input",
|
|
5370
5467
|
{
|
|
5371
5468
|
type: "number",
|
|
@@ -5385,14 +5482,14 @@ var FreeTransformOptionsBar = ({ tool, className }) => {
|
|
|
5385
5482
|
},
|
|
5386
5483
|
`${f.id}:${round(bar[f.id], f.unit)}`
|
|
5387
5484
|
),
|
|
5388
|
-
/* @__PURE__ */ (0,
|
|
5389
|
-
f.id === "scaleX" && /* @__PURE__ */ (0,
|
|
5485
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: "text-slate-500", children: f.unit }),
|
|
5486
|
+
f.id === "scaleX" && /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
5390
5487
|
"button",
|
|
5391
5488
|
{
|
|
5392
5489
|
type: "button",
|
|
5393
5490
|
"aria-label": "Keep width and height proportional",
|
|
5394
5491
|
"aria-pressed": tool.proportional,
|
|
5395
|
-
className:
|
|
5492
|
+
className: chip3(tool.proportional),
|
|
5396
5493
|
onClick: () => {
|
|
5397
5494
|
tool.proportional = !tool.proportional;
|
|
5398
5495
|
setTick((n) => n + 1);
|
|
@@ -5401,34 +5498,34 @@ var FreeTransformOptionsBar = ({ tool, className }) => {
|
|
|
5401
5498
|
}
|
|
5402
5499
|
)
|
|
5403
5500
|
] }, f.id)),
|
|
5404
|
-
/* @__PURE__ */ (0,
|
|
5405
|
-
/* @__PURE__ */ (0,
|
|
5406
|
-
/* @__PURE__ */ (0,
|
|
5501
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("label", { className: "flex items-center gap-1", children: [
|
|
5502
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: "text-slate-400", children: "Interpolation" }),
|
|
5503
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
5407
5504
|
"select",
|
|
5408
5505
|
{
|
|
5409
5506
|
"aria-label": "Interpolation",
|
|
5410
5507
|
value: tool.interpolation,
|
|
5411
5508
|
onChange: (e) => tool.setInterpolation(e.target.value),
|
|
5412
5509
|
className: "rounded border border-slate-700 bg-slate-900 px-1 py-0.5",
|
|
5413
|
-
children:
|
|
5510
|
+
children: import_image_editor12.INTERPOLATIONS.map((i) => /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("option", { value: i, children: i[0].toUpperCase() + i.slice(1) }, i))
|
|
5414
5511
|
}
|
|
5415
5512
|
)
|
|
5416
5513
|
] }),
|
|
5417
|
-
/* @__PURE__ */ (0,
|
|
5418
|
-
/* @__PURE__ */ (0,
|
|
5419
|
-
tool.error && /* @__PURE__ */ (0,
|
|
5514
|
+
/* @__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" }),
|
|
5515
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("button", { type: "button", title: "Cancel (Esc)", className: chip3(false), onClick: () => tool.cancel(), children: "Cancel" }),
|
|
5516
|
+
tool.error && /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { role: "alert", className: "text-rose-400", children: tool.error })
|
|
5420
5517
|
] });
|
|
5421
5518
|
};
|
|
5422
5519
|
|
|
5423
5520
|
// src/image-editor/ShapeOptionsBar.tsx
|
|
5424
|
-
var
|
|
5425
|
-
var
|
|
5426
|
-
var
|
|
5427
|
-
var
|
|
5521
|
+
var import_react45 = require("react");
|
|
5522
|
+
var import_image_editor13 = require("@pixerate/editor/image-editor");
|
|
5523
|
+
var import_jsx_runtime28 = require("react/jsx-runtime");
|
|
5524
|
+
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"}`;
|
|
5428
5525
|
var ShapeOptionsBar = ({ controller, options, onChange, className }) => {
|
|
5429
|
-
const [, setTick] = (0,
|
|
5430
|
-
(0,
|
|
5431
|
-
const [error, setError] = (0,
|
|
5526
|
+
const [, setTick] = (0, import_react45.useState)(0);
|
|
5527
|
+
(0, import_react45.useEffect)(() => controller.subscribe(() => setTick((n) => n + 1)), [controller]);
|
|
5528
|
+
const [error, setError] = (0, import_react45.useState)(null);
|
|
5432
5529
|
const active = controller.getActiveLayer();
|
|
5433
5530
|
const shapeId = active?.type === "shape" ? active.id : null;
|
|
5434
5531
|
const set = (change) => {
|
|
@@ -5436,19 +5533,19 @@ var ShapeOptionsBar = ({ controller, options, onChange, className }) => {
|
|
|
5436
5533
|
if (!shapeId) return;
|
|
5437
5534
|
try {
|
|
5438
5535
|
setError(null);
|
|
5439
|
-
(0,
|
|
5536
|
+
(0, import_image_editor13.applyShapeOptions)(controller, shapeId, change);
|
|
5440
5537
|
} catch (e) {
|
|
5441
5538
|
setError(e instanceof Error ? e.message : String(e));
|
|
5442
5539
|
}
|
|
5443
5540
|
};
|
|
5444
5541
|
const num = (v, min, max) => Math.max(min, Math.min(max, Number(v) || min));
|
|
5445
|
-
return /* @__PURE__ */ (0,
|
|
5446
|
-
/* @__PURE__ */ (0,
|
|
5447
|
-
/* @__PURE__ */ (0,
|
|
5448
|
-
/* @__PURE__ */ (0,
|
|
5449
|
-
/* @__PURE__ */ (0,
|
|
5542
|
+
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: [
|
|
5543
|
+
/* @__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)) }),
|
|
5544
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: "flex flex-wrap items-center gap-3", children: [
|
|
5545
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("label", { className: "flex items-center gap-1", children: [
|
|
5546
|
+
/* @__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 }) }),
|
|
5450
5547
|
"Fill",
|
|
5451
|
-
/* @__PURE__ */ (0,
|
|
5548
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
5452
5549
|
"input",
|
|
5453
5550
|
{
|
|
5454
5551
|
type: "color",
|
|
@@ -5460,10 +5557,10 @@ var ShapeOptionsBar = ({ controller, options, onChange, className }) => {
|
|
|
5460
5557
|
}
|
|
5461
5558
|
)
|
|
5462
5559
|
] }),
|
|
5463
|
-
/* @__PURE__ */ (0,
|
|
5464
|
-
/* @__PURE__ */ (0,
|
|
5560
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("label", { className: "flex items-center gap-1", children: [
|
|
5561
|
+
/* @__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 }) }),
|
|
5465
5562
|
"Stroke",
|
|
5466
|
-
/* @__PURE__ */ (0,
|
|
5563
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
5467
5564
|
"input",
|
|
5468
5565
|
{
|
|
5469
5566
|
type: "color",
|
|
@@ -5475,9 +5572,9 @@ var ShapeOptionsBar = ({ controller, options, onChange, className }) => {
|
|
|
5475
5572
|
}
|
|
5476
5573
|
)
|
|
5477
5574
|
] }),
|
|
5478
|
-
/* @__PURE__ */ (0,
|
|
5575
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("label", { className: "flex items-center gap-1", children: [
|
|
5479
5576
|
"Width",
|
|
5480
|
-
/* @__PURE__ */ (0,
|
|
5577
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
5481
5578
|
"input",
|
|
5482
5579
|
{
|
|
5483
5580
|
type: "number",
|
|
@@ -5491,23 +5588,23 @@ var ShapeOptionsBar = ({ controller, options, onChange, className }) => {
|
|
|
5491
5588
|
)
|
|
5492
5589
|
] })
|
|
5493
5590
|
] }),
|
|
5494
|
-
/* @__PURE__ */ (0,
|
|
5495
|
-
options.kind === "rect" && /* @__PURE__ */ (0,
|
|
5591
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: "flex flex-wrap items-center gap-3", children: [
|
|
5592
|
+
options.kind === "rect" && /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("label", { className: "flex items-center gap-1", children: [
|
|
5496
5593
|
"Radius",
|
|
5497
|
-
/* @__PURE__ */ (0,
|
|
5594
|
+
/* @__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" })
|
|
5498
5595
|
] }),
|
|
5499
|
-
options.kind === "polygon" && /* @__PURE__ */ (0,
|
|
5596
|
+
options.kind === "polygon" && /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("label", { className: "flex items-center gap-1", children: [
|
|
5500
5597
|
"Sides",
|
|
5501
|
-
/* @__PURE__ */ (0,
|
|
5598
|
+
/* @__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" })
|
|
5502
5599
|
] }),
|
|
5503
|
-
options.kind === "star" && /* @__PURE__ */ (0,
|
|
5504
|
-
/* @__PURE__ */ (0,
|
|
5600
|
+
options.kind === "star" && /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(import_jsx_runtime28.Fragment, { children: [
|
|
5601
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("label", { className: "flex items-center gap-1", children: [
|
|
5505
5602
|
"Points",
|
|
5506
|
-
/* @__PURE__ */ (0,
|
|
5603
|
+
/* @__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" })
|
|
5507
5604
|
] }),
|
|
5508
|
-
/* @__PURE__ */ (0,
|
|
5605
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("label", { className: "flex items-center gap-1", children: [
|
|
5509
5606
|
"Inner",
|
|
5510
|
-
/* @__PURE__ */ (0,
|
|
5607
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
5511
5608
|
"input",
|
|
5512
5609
|
{
|
|
5513
5610
|
type: "range",
|
|
@@ -5522,33 +5619,33 @@ var ShapeOptionsBar = ({ controller, options, onChange, className }) => {
|
|
|
5522
5619
|
)
|
|
5523
5620
|
] })
|
|
5524
5621
|
] }),
|
|
5525
|
-
options.kind === "line" && /* @__PURE__ */ (0,
|
|
5526
|
-
/* @__PURE__ */ (0,
|
|
5622
|
+
options.kind === "line" && /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(import_jsx_runtime28.Fragment, { children: [
|
|
5623
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("label", { className: "flex items-center gap-1", children: [
|
|
5527
5624
|
"Weight",
|
|
5528
|
-
/* @__PURE__ */ (0,
|
|
5625
|
+
/* @__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" })
|
|
5529
5626
|
] }),
|
|
5530
|
-
/* @__PURE__ */ (0,
|
|
5531
|
-
/* @__PURE__ */ (0,
|
|
5627
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("label", { className: "flex items-center gap-1", children: [
|
|
5628
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)("input", { type: "checkbox", "aria-label": "Arrowhead", checked: options.arrow, onChange: (e) => set({ arrow: e.target.checked }) }),
|
|
5532
5629
|
"Arrowhead"
|
|
5533
5630
|
] })
|
|
5534
5631
|
] })
|
|
5535
5632
|
] }),
|
|
5536
|
-
/* @__PURE__ */ (0,
|
|
5537
|
-
error && /* @__PURE__ */ (0,
|
|
5633
|
+
/* @__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." }),
|
|
5634
|
+
error && /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("p", { role: "alert", className: "text-rose-400", children: error })
|
|
5538
5635
|
] });
|
|
5539
5636
|
};
|
|
5540
5637
|
|
|
5541
5638
|
// src/image-editor/TypeOptionsBar.tsx
|
|
5542
|
-
var
|
|
5543
|
-
var
|
|
5544
|
-
var
|
|
5545
|
-
var
|
|
5639
|
+
var import_react46 = require("react");
|
|
5640
|
+
var import_image_editor14 = require("@pixerate/editor/image-editor");
|
|
5641
|
+
var import_jsx_runtime29 = require("react/jsx-runtime");
|
|
5642
|
+
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"}`;
|
|
5546
5643
|
var ALIGN_LABELS = { left: "Left", center: "Centre", right: "Right", justify: "Justify" };
|
|
5547
5644
|
var TypeOptionsBar = ({ controller, options, onChange, session, className }) => {
|
|
5548
|
-
const [, setTick] = (0,
|
|
5549
|
-
(0,
|
|
5550
|
-
(0,
|
|
5551
|
-
const [error, setError] = (0,
|
|
5645
|
+
const [, setTick] = (0, import_react46.useState)(0);
|
|
5646
|
+
(0, import_react46.useEffect)(() => controller.subscribe(() => setTick((n) => n + 1)), [controller]);
|
|
5647
|
+
(0, import_react46.useEffect)(() => session?.subscribe(() => setTick((n) => n + 1)), [session]);
|
|
5648
|
+
const [error, setError] = (0, import_react46.useState)(null);
|
|
5552
5649
|
const active = controller.getActiveLayer();
|
|
5553
5650
|
const typeId = !session && active?.type === "type" ? active.id : null;
|
|
5554
5651
|
const here = session?.alive ? session.styleHere() : {};
|
|
@@ -5580,11 +5677,11 @@ var TypeOptionsBar = ({ controller, options, onChange, session, className }) =>
|
|
|
5580
5677
|
setError(e instanceof Error ? e.message : String(e));
|
|
5581
5678
|
}
|
|
5582
5679
|
};
|
|
5583
|
-
return /* @__PURE__ */ (0,
|
|
5584
|
-
/* @__PURE__ */ (0,
|
|
5585
|
-
/* @__PURE__ */ (0,
|
|
5680
|
+
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: [
|
|
5681
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "flex flex-wrap items-center gap-2", children: [
|
|
5682
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("label", { className: "flex items-center gap-1", children: [
|
|
5586
5683
|
"Font",
|
|
5587
|
-
/* @__PURE__ */ (0,
|
|
5684
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
5588
5685
|
"input",
|
|
5589
5686
|
{
|
|
5590
5687
|
list: "pixerate-type-fonts",
|
|
@@ -5594,11 +5691,11 @@ var TypeOptionsBar = ({ controller, options, onChange, session, className }) =>
|
|
|
5594
5691
|
className: "w-32 rounded border border-slate-700 bg-slate-950 px-1 py-0.5"
|
|
5595
5692
|
}
|
|
5596
5693
|
),
|
|
5597
|
-
/* @__PURE__ */ (0,
|
|
5694
|
+
/* @__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)) })
|
|
5598
5695
|
] }),
|
|
5599
|
-
/* @__PURE__ */ (0,
|
|
5696
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("label", { className: "flex items-center gap-1", children: [
|
|
5600
5697
|
"Size",
|
|
5601
|
-
/* @__PURE__ */ (0,
|
|
5698
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
5602
5699
|
"input",
|
|
5603
5700
|
{
|
|
5604
5701
|
type: "number",
|
|
@@ -5611,24 +5708,24 @@ var TypeOptionsBar = ({ controller, options, onChange, session, className }) =>
|
|
|
5611
5708
|
}
|
|
5612
5709
|
)
|
|
5613
5710
|
] }),
|
|
5614
|
-
/* @__PURE__ */ (0,
|
|
5615
|
-
/* @__PURE__ */ (0,
|
|
5616
|
-
/* @__PURE__ */ (0,
|
|
5711
|
+
/* @__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" }),
|
|
5712
|
+
/* @__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" }),
|
|
5713
|
+
/* @__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" })
|
|
5617
5714
|
] }),
|
|
5618
|
-
/* @__PURE__ */ (0,
|
|
5619
|
-
/* @__PURE__ */ (0,
|
|
5620
|
-
missing.length > 0 && /* @__PURE__ */ (0,
|
|
5715
|
+
/* @__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)) }),
|
|
5716
|
+
/* @__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." }),
|
|
5717
|
+
missing.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("p", { role: "status", className: "text-amber-400", "data-testid": "type-missing-fonts", children: [
|
|
5621
5718
|
"Missing ",
|
|
5622
5719
|
missing.length === 1 ? "font" : "fonts",
|
|
5623
5720
|
": ",
|
|
5624
5721
|
missing.join(", ")
|
|
5625
5722
|
] }),
|
|
5626
|
-
error && /* @__PURE__ */ (0,
|
|
5723
|
+
error && /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("p", { role: "alert", className: "text-rose-400", children: error })
|
|
5627
5724
|
] });
|
|
5628
5725
|
};
|
|
5629
5726
|
|
|
5630
5727
|
// src/image-editor/ImageEditor.tsx
|
|
5631
|
-
var
|
|
5728
|
+
var import_jsx_runtime30 = require("react/jsx-runtime");
|
|
5632
5729
|
var ImageEditor = ({
|
|
5633
5730
|
editor: externalEditor,
|
|
5634
5731
|
src,
|
|
@@ -5643,65 +5740,65 @@ var ImageEditor = ({
|
|
|
5643
5740
|
const internalEditor = useImageEditor({ image: src });
|
|
5644
5741
|
const editor = externalEditor || internalEditor;
|
|
5645
5742
|
const { state, controller } = editor;
|
|
5646
|
-
const legacyProcess = (0,
|
|
5647
|
-
const canvasRef = (0,
|
|
5648
|
-
const containerRef = (0,
|
|
5649
|
-
const [activeTab, setActiveTab] = (0,
|
|
5650
|
-
const [activeCropRatio, setActiveCropRatio] = (0,
|
|
5651
|
-
const [selectionOptions, setSelectionOptions] = (0,
|
|
5652
|
-
const selectionOptionsRef = (0,
|
|
5743
|
+
const legacyProcess = (0, import_image_editor15.normalizeProcessVersion)(state.adjustments.process) < import_image_editor15.LATEST_PROCESS_VERSION;
|
|
5744
|
+
const canvasRef = (0, import_react47.useRef)(null);
|
|
5745
|
+
const containerRef = (0, import_react47.useRef)(null);
|
|
5746
|
+
const [activeTab, setActiveTab] = (0, import_react47.useState)("crop");
|
|
5747
|
+
const [activeCropRatio, setActiveCropRatio] = (0, import_react47.useState)(null);
|
|
5748
|
+
const [selectionOptions, setSelectionOptions] = (0, import_react47.useState)(import_image_editor15.DEFAULT_SELECTION_TOOL_OPTIONS);
|
|
5749
|
+
const selectionOptionsRef = (0, import_react47.useRef)(selectionOptions);
|
|
5653
5750
|
selectionOptionsRef.current = selectionOptions;
|
|
5654
|
-
const selectionGestureRef = (0,
|
|
5751
|
+
const selectionGestureRef = (0, import_react47.useRef)(null);
|
|
5655
5752
|
if (!selectionGestureRef.current || selectionGestureRef.current.controller !== controller) {
|
|
5656
|
-
selectionGestureRef.current = new
|
|
5753
|
+
selectionGestureRef.current = new import_image_editor15.SelectionGesture(controller, () => selectionOptionsRef.current);
|
|
5657
5754
|
}
|
|
5658
|
-
const selectionDraftRef = (0,
|
|
5659
|
-
const [selectionError, setSelectionError] = (0,
|
|
5660
|
-
const paintGestureRef = (0,
|
|
5661
|
-
const paintControllerRef = (0,
|
|
5755
|
+
const selectionDraftRef = (0, import_react47.useRef)(null);
|
|
5756
|
+
const [selectionError, setSelectionError] = (0, import_react47.useState)(null);
|
|
5757
|
+
const paintGestureRef = (0, import_react47.useRef)(null);
|
|
5758
|
+
const paintControllerRef = (0, import_react47.useRef)(controller);
|
|
5662
5759
|
if (!paintGestureRef.current || paintControllerRef.current !== controller) {
|
|
5663
|
-
paintGestureRef.current = new
|
|
5760
|
+
paintGestureRef.current = new import_image_editor15.PaintGesture(controller);
|
|
5664
5761
|
paintControllerRef.current = controller;
|
|
5665
5762
|
}
|
|
5666
|
-
const brushCursorRef = (0,
|
|
5667
|
-
const [paintError, setPaintError] = (0,
|
|
5668
|
-
const transformToolRef = (0,
|
|
5669
|
-
const transformControllerRef = (0,
|
|
5763
|
+
const brushCursorRef = (0, import_react47.useRef)(null);
|
|
5764
|
+
const [paintError, setPaintError] = (0, import_react47.useState)(null);
|
|
5765
|
+
const transformToolRef = (0, import_react47.useRef)(null);
|
|
5766
|
+
const transformControllerRef = (0, import_react47.useRef)(controller);
|
|
5670
5767
|
if (!transformToolRef.current || transformControllerRef.current !== controller) {
|
|
5671
5768
|
transformToolRef.current?.cancel();
|
|
5672
|
-
transformToolRef.current = new
|
|
5769
|
+
transformToolRef.current = new import_image_editor15.FreeTransformTool(controller, {
|
|
5673
5770
|
schedule: (run) => typeof requestAnimationFrame !== "undefined" ? requestAnimationFrame(run) : run()
|
|
5674
5771
|
});
|
|
5675
5772
|
transformControllerRef.current = controller;
|
|
5676
5773
|
}
|
|
5677
5774
|
const transformTool = transformToolRef.current;
|
|
5678
|
-
const [, setTransformTick] = (0,
|
|
5679
|
-
const [transformCursor, setTransformCursor] = (0,
|
|
5680
|
-
const [shapeOptions, setShapeOptions] = (0,
|
|
5681
|
-
const shapeOptionsRef = (0,
|
|
5775
|
+
const [, setTransformTick] = (0, import_react47.useState)(0);
|
|
5776
|
+
const [transformCursor, setTransformCursor] = (0, import_react47.useState)("default");
|
|
5777
|
+
const [shapeOptions, setShapeOptions] = (0, import_react47.useState)(import_image_editor15.DEFAULT_SHAPE_TOOL_OPTIONS);
|
|
5778
|
+
const shapeOptionsRef = (0, import_react47.useRef)(shapeOptions);
|
|
5682
5779
|
shapeOptionsRef.current = shapeOptions;
|
|
5683
|
-
const [typeOptions, setTypeOptions] = (0,
|
|
5684
|
-
const typeOptionsRef = (0,
|
|
5780
|
+
const [typeOptions, setTypeOptions] = (0, import_react47.useState)(import_image_editor15.DEFAULT_TYPE_TOOL_OPTIONS);
|
|
5781
|
+
const typeOptionsRef = (0, import_react47.useRef)(typeOptions);
|
|
5685
5782
|
typeOptionsRef.current = typeOptions;
|
|
5686
|
-
const shapeGestureRef = (0,
|
|
5687
|
-
const typeToolRef = (0,
|
|
5688
|
-
const shapeTypeControllerRef = (0,
|
|
5783
|
+
const shapeGestureRef = (0, import_react47.useRef)(null);
|
|
5784
|
+
const typeToolRef = (0, import_react47.useRef)(null);
|
|
5785
|
+
const shapeTypeControllerRef = (0, import_react47.useRef)(controller);
|
|
5689
5786
|
if (!shapeGestureRef.current || !typeToolRef.current || shapeTypeControllerRef.current !== controller) {
|
|
5690
5787
|
typeToolRef.current?.finish();
|
|
5691
|
-
shapeGestureRef.current = new
|
|
5692
|
-
typeToolRef.current = new
|
|
5788
|
+
shapeGestureRef.current = new import_image_editor15.ShapeDrawGesture(controller, () => shapeOptionsRef.current);
|
|
5789
|
+
typeToolRef.current = new import_image_editor15.TypeToolGesture(controller, () => typeOptionsRef.current);
|
|
5693
5790
|
shapeTypeControllerRef.current = controller;
|
|
5694
5791
|
}
|
|
5695
|
-
const typeInputRef = (0,
|
|
5696
|
-
const [typeSession, setTypeSession] = (0,
|
|
5697
|
-
const [shapeTypeError, setShapeTypeError] = (0,
|
|
5698
|
-
const [inpaintPrompt, setInpaintPrompt] = (0,
|
|
5699
|
-
const [inpaintMaskMode, setInpaintMaskMode] = (0,
|
|
5700
|
-
const [isRemovingBg, setIsRemovingBg] = (0,
|
|
5701
|
-
const [isInpainting, setIsInpainting] = (0,
|
|
5702
|
-
const [aiError, setAiError] = (0,
|
|
5703
|
-
const [aiSuccess, setAiSuccess] = (0,
|
|
5704
|
-
const [aiTarget, setAiTarget] = (0,
|
|
5792
|
+
const typeInputRef = (0, import_react47.useRef)(null);
|
|
5793
|
+
const [typeSession, setTypeSession] = (0, import_react47.useState)(typeToolRef.current.session);
|
|
5794
|
+
const [shapeTypeError, setShapeTypeError] = (0, import_react47.useState)(null);
|
|
5795
|
+
const [inpaintPrompt, setInpaintPrompt] = (0, import_react47.useState)("");
|
|
5796
|
+
const [inpaintMaskMode, setInpaintMaskMode] = (0, import_react47.useState)("annotations");
|
|
5797
|
+
const [isRemovingBg, setIsRemovingBg] = (0, import_react47.useState)(false);
|
|
5798
|
+
const [isInpainting, setIsInpainting] = (0, import_react47.useState)(false);
|
|
5799
|
+
const [aiError, setAiError] = (0, import_react47.useState)(null);
|
|
5800
|
+
const [aiSuccess, setAiSuccess] = (0, import_react47.useState)(null);
|
|
5801
|
+
const [aiTarget, setAiTarget] = (0, import_react47.useState)("auto");
|
|
5705
5802
|
const aiOptions = aiTarget === "auto" ? {} : { target: aiTarget };
|
|
5706
5803
|
const effectiveOnInpaint = onInpaint || aiHooks?.onInpaint;
|
|
5707
5804
|
const effectiveOnRemoveBg = onRemoveBackground || aiHooks?.onRemoveBackground;
|
|
@@ -5764,18 +5861,18 @@ var ImageEditor = ({
|
|
|
5764
5861
|
setIsInpainting(false);
|
|
5765
5862
|
}
|
|
5766
5863
|
};
|
|
5767
|
-
const [activeColor, setActiveColor] = (0,
|
|
5768
|
-
const [strokeWidth, setStrokeWidth] = (0,
|
|
5769
|
-
const [fontSize, setFontSize] = (0,
|
|
5770
|
-
const [textInput, setTextInput] = (0,
|
|
5771
|
-
const draftAnnotationRef = (0,
|
|
5772
|
-
const draftCropRef = (0,
|
|
5773
|
-
const cropDragInfoRef = (0,
|
|
5774
|
-
const annotationDragInfoRef = (0,
|
|
5775
|
-
const isDrawingRef = (0,
|
|
5776
|
-
const currentPathRef = (0,
|
|
5777
|
-
const dragStartPointRef = (0,
|
|
5778
|
-
const renderCanvas = (0,
|
|
5864
|
+
const [activeColor, setActiveColor] = (0, import_react47.useState)("#ef4444");
|
|
5865
|
+
const [strokeWidth, setStrokeWidth] = (0, import_react47.useState)(3);
|
|
5866
|
+
const [fontSize, setFontSize] = (0, import_react47.useState)(24);
|
|
5867
|
+
const [textInput, setTextInput] = (0, import_react47.useState)("");
|
|
5868
|
+
const draftAnnotationRef = (0, import_react47.useRef)(null);
|
|
5869
|
+
const draftCropRef = (0, import_react47.useRef)(null);
|
|
5870
|
+
const cropDragInfoRef = (0, import_react47.useRef)(null);
|
|
5871
|
+
const annotationDragInfoRef = (0, import_react47.useRef)(null);
|
|
5872
|
+
const isDrawingRef = (0, import_react47.useRef)(false);
|
|
5873
|
+
const currentPathRef = (0, import_react47.useRef)([]);
|
|
5874
|
+
const dragStartPointRef = (0, import_react47.useRef)(null);
|
|
5875
|
+
const renderCanvas = (0, import_react47.useCallback)(
|
|
5779
5876
|
async (draftAnnotation, draftCrop) => {
|
|
5780
5877
|
const canvas = canvasRef.current;
|
|
5781
5878
|
const container = containerRef.current;
|
|
@@ -5798,8 +5895,8 @@ var ImageEditor = ({
|
|
|
5798
5895
|
},
|
|
5799
5896
|
[controller, activeTab, transformTool]
|
|
5800
5897
|
);
|
|
5801
|
-
(0,
|
|
5802
|
-
(0,
|
|
5898
|
+
(0, import_react47.useEffect)(() => typeSession?.subscribe(() => void renderCanvas()), [typeSession, renderCanvas]);
|
|
5899
|
+
(0, import_react47.useEffect)(() => {
|
|
5803
5900
|
if (activeTab === "annotate" && state.activeTool === "type") return;
|
|
5804
5901
|
if (typeToolRef.current?.session) {
|
|
5805
5902
|
typeToolRef.current.finish();
|
|
@@ -5834,7 +5931,7 @@ var ImageEditor = ({
|
|
|
5834
5931
|
el.value = "";
|
|
5835
5932
|
}
|
|
5836
5933
|
};
|
|
5837
|
-
(0,
|
|
5934
|
+
(0, import_react47.useEffect)(() => transformTool.subscribe(() => {
|
|
5838
5935
|
setTransformTick((n) => n + 1);
|
|
5839
5936
|
void renderCanvas();
|
|
5840
5937
|
}), [transformTool, renderCanvas]);
|
|
@@ -5845,8 +5942,8 @@ var ImageEditor = ({
|
|
|
5845
5942
|
const sy = rect.height > 0 ? canvas.height / rect.height : 1;
|
|
5846
5943
|
const s = controller.getState();
|
|
5847
5944
|
const cropping = activeTab === "crop";
|
|
5848
|
-
const projection = (0,
|
|
5849
|
-
const pt = (0,
|
|
5945
|
+
const projection = (0, import_image_editor15.getViewportProjection)(s, canvas.width, canvas.height, cropping);
|
|
5946
|
+
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);
|
|
5850
5947
|
transformTool.setView(projection.scale);
|
|
5851
5948
|
return { pt, tolerance: 6 / (projection.scale || 1) };
|
|
5852
5949
|
};
|
|
@@ -5877,7 +5974,7 @@ var ImageEditor = ({
|
|
|
5877
5974
|
transformTool.up();
|
|
5878
5975
|
return true;
|
|
5879
5976
|
};
|
|
5880
|
-
(0,
|
|
5977
|
+
(0, import_react47.useEffect)(() => {
|
|
5881
5978
|
if (typeof window === "undefined") return;
|
|
5882
5979
|
const onKey = (e) => {
|
|
5883
5980
|
if (transformTool.key(e)) e.preventDefault();
|
|
@@ -5885,7 +5982,7 @@ var ImageEditor = ({
|
|
|
5885
5982
|
window.addEventListener("keydown", onKey);
|
|
5886
5983
|
return () => window.removeEventListener("keydown", onKey);
|
|
5887
5984
|
}, [transformTool]);
|
|
5888
|
-
(0,
|
|
5985
|
+
(0, import_react47.useEffect)(() => {
|
|
5889
5986
|
const raf = typeof requestAnimationFrame !== "undefined" ? requestAnimationFrame : (cb) => setTimeout(cb, 0);
|
|
5890
5987
|
const caf = typeof cancelAnimationFrame !== "undefined" ? cancelAnimationFrame : (id) => clearTimeout(id);
|
|
5891
5988
|
const animId = raf(() => {
|
|
@@ -5893,12 +5990,12 @@ var ImageEditor = ({
|
|
|
5893
5990
|
});
|
|
5894
5991
|
return () => caf(animId);
|
|
5895
5992
|
}, [renderCanvas, state]);
|
|
5896
|
-
(0,
|
|
5993
|
+
(0, import_react47.useEffect)(() => {
|
|
5897
5994
|
if (activeTab === "crop" && editor.state.activeTool !== "crop") {
|
|
5898
5995
|
editor.setTool("crop");
|
|
5899
5996
|
}
|
|
5900
5997
|
}, [activeTab, editor]);
|
|
5901
|
-
(0,
|
|
5998
|
+
(0, import_react47.useEffect)(() => {
|
|
5902
5999
|
const container = containerRef.current;
|
|
5903
6000
|
if (!container) return;
|
|
5904
6001
|
if (typeof ResizeObserver !== "undefined") {
|
|
@@ -5934,8 +6031,8 @@ var ImageEditor = ({
|
|
|
5934
6031
|
const sy = rect.height > 0 ? canvas.height / rect.height : 1;
|
|
5935
6032
|
const s = controller.getState();
|
|
5936
6033
|
return list.map((ev) => ({
|
|
5937
|
-
...(0,
|
|
5938
|
-
pressure: (0,
|
|
6034
|
+
...(0, import_image_editor15.canvasToImagePoint)({ x: (ev.clientX - rect.left) * sx, y: (ev.clientY - rect.top) * sy }, s, canvas.width, canvas.height, false),
|
|
6035
|
+
pressure: (0, import_image_editor15.pointerPressure)(ev)
|
|
5939
6036
|
}));
|
|
5940
6037
|
};
|
|
5941
6038
|
const handlePaintPointerDown = (e) => {
|
|
@@ -5966,10 +6063,10 @@ var ImageEditor = ({
|
|
|
5966
6063
|
if (g.error) setPaintError(g.error);
|
|
5967
6064
|
}
|
|
5968
6065
|
};
|
|
5969
|
-
(0,
|
|
6066
|
+
(0, import_react47.useEffect)(() => {
|
|
5970
6067
|
if (activeTab !== "paint" || typeof window === "undefined") return;
|
|
5971
6068
|
const onKey = (e) => {
|
|
5972
|
-
if ((0,
|
|
6069
|
+
if ((0, import_image_editor15.handlePaintShortcut)(controller, e)) e.preventDefault();
|
|
5973
6070
|
};
|
|
5974
6071
|
window.addEventListener("keydown", onKey);
|
|
5975
6072
|
return () => window.removeEventListener("keydown", onKey);
|
|
@@ -5980,7 +6077,7 @@ var ImageEditor = ({
|
|
|
5980
6077
|
const canvasPt = getCanvasEventPoint(e);
|
|
5981
6078
|
if (activeTab === "select") {
|
|
5982
6079
|
const gesture = selectionGestureRef.current;
|
|
5983
|
-
const imgPt = (0,
|
|
6080
|
+
const imgPt = (0, import_image_editor15.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false);
|
|
5984
6081
|
void gesture.begin(imgPt, e).then(() => setSelectionError(gesture.error));
|
|
5985
6082
|
return;
|
|
5986
6083
|
}
|
|
@@ -5991,8 +6088,8 @@ var ImageEditor = ({
|
|
|
5991
6088
|
width: state.imageDimensions.width,
|
|
5992
6089
|
height: state.imageDimensions.height
|
|
5993
6090
|
};
|
|
5994
|
-
const handle = (0,
|
|
5995
|
-
const startImgPt = (0,
|
|
6091
|
+
const handle = (0, import_image_editor15.hitTestCrop)(canvasPt, state, canvas.width, canvas.height, 14, activeCrop);
|
|
6092
|
+
const startImgPt = (0, import_image_editor15.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, true);
|
|
5996
6093
|
if (handle) {
|
|
5997
6094
|
cropDragInfoRef.current = {
|
|
5998
6095
|
handle,
|
|
@@ -6011,7 +6108,7 @@ var ImageEditor = ({
|
|
|
6011
6108
|
return;
|
|
6012
6109
|
}
|
|
6013
6110
|
if (activeTab === "annotate" && (state.activeTool === "shape" || state.activeTool === "type")) {
|
|
6014
|
-
const imgPt = (0,
|
|
6111
|
+
const imgPt = (0, import_image_editor15.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false);
|
|
6015
6112
|
setShapeTypeError(null);
|
|
6016
6113
|
if (state.activeTool === "shape") shapeGestureRef.current.down(imgPt);
|
|
6017
6114
|
else {
|
|
@@ -6022,12 +6119,12 @@ var ImageEditor = ({
|
|
|
6022
6119
|
return;
|
|
6023
6120
|
}
|
|
6024
6121
|
if (activeTab === "annotate") {
|
|
6025
|
-
const imgPt = (0,
|
|
6122
|
+
const imgPt = (0, import_image_editor15.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false);
|
|
6026
6123
|
dragStartPointRef.current = imgPt;
|
|
6027
6124
|
if (state.activeTool === "select") {
|
|
6028
6125
|
for (let i = state.annotations.length - 1; i >= 0; i--) {
|
|
6029
6126
|
const ann = state.annotations[i];
|
|
6030
|
-
if ((0,
|
|
6127
|
+
if ((0, import_image_editor15.hitTestAnnotation)(imgPt, ann)) {
|
|
6031
6128
|
editor.selectAnnotation(ann.id);
|
|
6032
6129
|
annotationDragInfoRef.current = {
|
|
6033
6130
|
annId: ann.id,
|
|
@@ -6063,7 +6160,7 @@ var ImageEditor = ({
|
|
|
6063
6160
|
const canvasPt = getCanvasEventPoint(e);
|
|
6064
6161
|
if (activeTab === "select") {
|
|
6065
6162
|
const gesture = selectionGestureRef.current;
|
|
6066
|
-
if (gesture.active && gesture.move((0,
|
|
6163
|
+
if (gesture.active && gesture.move((0, import_image_editor15.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false))) {
|
|
6067
6164
|
selectionDraftRef.current = gesture.draftPath;
|
|
6068
6165
|
renderCanvas();
|
|
6069
6166
|
}
|
|
@@ -6072,7 +6169,7 @@ var ImageEditor = ({
|
|
|
6072
6169
|
if (activeTab === "crop") {
|
|
6073
6170
|
const drag = cropDragInfoRef.current;
|
|
6074
6171
|
if (drag) {
|
|
6075
|
-
const currentImgPt = (0,
|
|
6172
|
+
const currentImgPt = (0, import_image_editor15.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, true);
|
|
6076
6173
|
let newCrop;
|
|
6077
6174
|
if (drag.handle === "new") {
|
|
6078
6175
|
const minX = Math.max(0, Math.min(drag.startImgPt.x, currentImgPt.x));
|
|
@@ -6086,7 +6183,7 @@ var ImageEditor = ({
|
|
|
6086
6183
|
height: Math.round(Math.max(20, maxY - minY))
|
|
6087
6184
|
};
|
|
6088
6185
|
} else {
|
|
6089
|
-
newCrop = (0,
|
|
6186
|
+
newCrop = (0, import_image_editor15.calculateCropDrag)(
|
|
6090
6187
|
drag.startCrop,
|
|
6091
6188
|
drag.handle,
|
|
6092
6189
|
drag.startImgPt,
|
|
@@ -6106,15 +6203,15 @@ var ImageEditor = ({
|
|
|
6106
6203
|
width: state.imageDimensions.width,
|
|
6107
6204
|
height: state.imageDimensions.height
|
|
6108
6205
|
};
|
|
6109
|
-
const handle = (0,
|
|
6110
|
-
canvas.style.cursor = (0,
|
|
6206
|
+
const handle = (0, import_image_editor15.hitTestCrop)(canvasPt, state, canvas.width, canvas.height, 14, activeCrop);
|
|
6207
|
+
canvas.style.cursor = (0, import_image_editor15.getCropCursor)(handle, state.transform);
|
|
6111
6208
|
}
|
|
6112
6209
|
return;
|
|
6113
6210
|
}
|
|
6114
6211
|
if (activeTab === "annotate" && state.activeTool === "shape") {
|
|
6115
6212
|
const g = shapeGestureRef.current;
|
|
6116
6213
|
if (g.active) {
|
|
6117
|
-
g.move((0,
|
|
6214
|
+
g.move((0, import_image_editor15.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false), { shift: e.shiftKey, alt: e.altKey });
|
|
6118
6215
|
if (g.error) setShapeTypeError(g.error);
|
|
6119
6216
|
}
|
|
6120
6217
|
return;
|
|
@@ -6122,7 +6219,7 @@ var ImageEditor = ({
|
|
|
6122
6219
|
if (activeTab === "annotate") {
|
|
6123
6220
|
if (annotationDragInfoRef.current) {
|
|
6124
6221
|
const drag = annotationDragInfoRef.current;
|
|
6125
|
-
const currentImgPt2 = (0,
|
|
6222
|
+
const currentImgPt2 = (0, import_image_editor15.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false);
|
|
6126
6223
|
const dx = currentImgPt2.x - drag.startImgPt.x;
|
|
6127
6224
|
const dy = currentImgPt2.y - drag.startImgPt.y;
|
|
6128
6225
|
editor.updateAnnotation(drag.annId, {
|
|
@@ -6134,10 +6231,10 @@ var ImageEditor = ({
|
|
|
6134
6231
|
const startPt = dragStartPointRef.current;
|
|
6135
6232
|
if (!startPt) {
|
|
6136
6233
|
if (state.activeTool === "select") {
|
|
6137
|
-
const imgPt = (0,
|
|
6234
|
+
const imgPt = (0, import_image_editor15.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false);
|
|
6138
6235
|
let hovered = false;
|
|
6139
6236
|
for (let i = state.annotations.length - 1; i >= 0; i--) {
|
|
6140
|
-
if ((0,
|
|
6237
|
+
if ((0, import_image_editor15.hitTestAnnotation)(imgPt, state.annotations[i])) {
|
|
6141
6238
|
hovered = true;
|
|
6142
6239
|
break;
|
|
6143
6240
|
}
|
|
@@ -6148,7 +6245,7 @@ var ImageEditor = ({
|
|
|
6148
6245
|
}
|
|
6149
6246
|
return;
|
|
6150
6247
|
}
|
|
6151
|
-
const currentImgPt = (0,
|
|
6248
|
+
const currentImgPt = (0, import_image_editor15.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false);
|
|
6152
6249
|
if (state.activeTool === "pen" && isDrawingRef.current) {
|
|
6153
6250
|
currentPathRef.current.push(currentImgPt);
|
|
6154
6251
|
const draft = {
|
|
@@ -6228,7 +6325,7 @@ var ImageEditor = ({
|
|
|
6228
6325
|
if (activeTab === "select") {
|
|
6229
6326
|
const gesture = selectionGestureRef.current;
|
|
6230
6327
|
if (gesture.active) {
|
|
6231
|
-
gesture.end((0,
|
|
6328
|
+
gesture.end((0, import_image_editor15.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false), e);
|
|
6232
6329
|
selectionDraftRef.current = null;
|
|
6233
6330
|
renderCanvas();
|
|
6234
6331
|
}
|
|
@@ -6251,7 +6348,7 @@ var ImageEditor = ({
|
|
|
6251
6348
|
}
|
|
6252
6349
|
if (activeTab === "annotate" && state.activeTool === "type") {
|
|
6253
6350
|
const tool = typeToolRef.current;
|
|
6254
|
-
tool.up((0,
|
|
6351
|
+
tool.up((0, import_image_editor15.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false));
|
|
6255
6352
|
setTypeSession(tool.session);
|
|
6256
6353
|
if (tool.error) setShapeTypeError(tool.error);
|
|
6257
6354
|
void renderCanvas();
|
|
@@ -6265,7 +6362,7 @@ var ImageEditor = ({
|
|
|
6265
6362
|
}
|
|
6266
6363
|
const startPt = dragStartPointRef.current;
|
|
6267
6364
|
if (startPt) {
|
|
6268
|
-
const currentImgPt = (0,
|
|
6365
|
+
const currentImgPt = (0, import_image_editor15.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false);
|
|
6269
6366
|
if (state.activeTool === "pen" && isDrawingRef.current) {
|
|
6270
6367
|
if (currentPathRef.current.length > 1) {
|
|
6271
6368
|
editor.addAnnotation({
|
|
@@ -6361,15 +6458,15 @@ var ImageEditor = ({
|
|
|
6361
6458
|
link.click();
|
|
6362
6459
|
}
|
|
6363
6460
|
};
|
|
6364
|
-
return /* @__PURE__ */ (0,
|
|
6461
|
+
return /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(
|
|
6365
6462
|
"div",
|
|
6366
6463
|
{
|
|
6367
6464
|
className: `flex flex-col bg-slate-900 border border-slate-800 rounded-xl overflow-hidden shadow-2xl text-slate-100 ${className}`,
|
|
6368
6465
|
style,
|
|
6369
6466
|
children: [
|
|
6370
|
-
/* @__PURE__ */ (0,
|
|
6371
|
-
/* @__PURE__ */ (0,
|
|
6372
|
-
/* @__PURE__ */ (0,
|
|
6467
|
+
/* @__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: [
|
|
6468
|
+
/* @__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: [
|
|
6469
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
6373
6470
|
"button",
|
|
6374
6471
|
{
|
|
6375
6472
|
type: "button",
|
|
@@ -6381,7 +6478,7 @@ var ImageEditor = ({
|
|
|
6381
6478
|
children: "Transform & Crop"
|
|
6382
6479
|
}
|
|
6383
6480
|
),
|
|
6384
|
-
/* @__PURE__ */ (0,
|
|
6481
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
6385
6482
|
"button",
|
|
6386
6483
|
{
|
|
6387
6484
|
type: "button",
|
|
@@ -6393,7 +6490,7 @@ var ImageEditor = ({
|
|
|
6393
6490
|
children: "Adjustments"
|
|
6394
6491
|
}
|
|
6395
6492
|
),
|
|
6396
|
-
/* @__PURE__ */ (0,
|
|
6493
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
6397
6494
|
"button",
|
|
6398
6495
|
{
|
|
6399
6496
|
type: "button",
|
|
@@ -6405,7 +6502,7 @@ var ImageEditor = ({
|
|
|
6405
6502
|
children: "Layers"
|
|
6406
6503
|
}
|
|
6407
6504
|
),
|
|
6408
|
-
/* @__PURE__ */ (0,
|
|
6505
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
6409
6506
|
"button",
|
|
6410
6507
|
{
|
|
6411
6508
|
type: "button",
|
|
@@ -6417,7 +6514,7 @@ var ImageEditor = ({
|
|
|
6417
6514
|
children: "Paint"
|
|
6418
6515
|
}
|
|
6419
6516
|
),
|
|
6420
|
-
/* @__PURE__ */ (0,
|
|
6517
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
6421
6518
|
"button",
|
|
6422
6519
|
{
|
|
6423
6520
|
type: "button",
|
|
@@ -6429,7 +6526,7 @@ var ImageEditor = ({
|
|
|
6429
6526
|
children: "Select & Mask"
|
|
6430
6527
|
}
|
|
6431
6528
|
),
|
|
6432
|
-
/* @__PURE__ */ (0,
|
|
6529
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
6433
6530
|
"button",
|
|
6434
6531
|
{
|
|
6435
6532
|
type: "button",
|
|
@@ -6441,7 +6538,7 @@ var ImageEditor = ({
|
|
|
6441
6538
|
children: "Annotations"
|
|
6442
6539
|
}
|
|
6443
6540
|
),
|
|
6444
|
-
/* @__PURE__ */ (0,
|
|
6541
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
6445
6542
|
"button",
|
|
6446
6543
|
{
|
|
6447
6544
|
type: "button",
|
|
@@ -6453,7 +6550,7 @@ var ImageEditor = ({
|
|
|
6453
6550
|
children: "Depth Mask"
|
|
6454
6551
|
}
|
|
6455
6552
|
),
|
|
6456
|
-
/* @__PURE__ */ (0,
|
|
6553
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(
|
|
6457
6554
|
"button",
|
|
6458
6555
|
{
|
|
6459
6556
|
type: "button",
|
|
@@ -6463,14 +6560,14 @@ var ImageEditor = ({
|
|
|
6463
6560
|
},
|
|
6464
6561
|
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"}`,
|
|
6465
6562
|
children: [
|
|
6466
|
-
/* @__PURE__ */ (0,
|
|
6563
|
+
/* @__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" }) }),
|
|
6467
6564
|
"AI Tools"
|
|
6468
6565
|
]
|
|
6469
6566
|
}
|
|
6470
6567
|
)
|
|
6471
6568
|
] }),
|
|
6472
|
-
/* @__PURE__ */ (0,
|
|
6473
|
-
/* @__PURE__ */ (0,
|
|
6569
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "flex items-center gap-2 text-xs", children: [
|
|
6570
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
6474
6571
|
"button",
|
|
6475
6572
|
{
|
|
6476
6573
|
type: "button",
|
|
@@ -6481,7 +6578,7 @@ var ImageEditor = ({
|
|
|
6481
6578
|
children: "\u21A9"
|
|
6482
6579
|
}
|
|
6483
6580
|
),
|
|
6484
|
-
/* @__PURE__ */ (0,
|
|
6581
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
6485
6582
|
"button",
|
|
6486
6583
|
{
|
|
6487
6584
|
type: "button",
|
|
@@ -6492,7 +6589,7 @@ var ImageEditor = ({
|
|
|
6492
6589
|
children: "\u21AA"
|
|
6493
6590
|
}
|
|
6494
6591
|
),
|
|
6495
|
-
/* @__PURE__ */ (0,
|
|
6592
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
6496
6593
|
"button",
|
|
6497
6594
|
{
|
|
6498
6595
|
type: "button",
|
|
@@ -6501,8 +6598,8 @@ var ImageEditor = ({
|
|
|
6501
6598
|
children: "Reset"
|
|
6502
6599
|
}
|
|
6503
6600
|
),
|
|
6504
|
-
/* @__PURE__ */ (0,
|
|
6505
|
-
/* @__PURE__ */ (0,
|
|
6601
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("div", { className: "h-4 w-px bg-slate-800 mx-1" }),
|
|
6602
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
6506
6603
|
"button",
|
|
6507
6604
|
{
|
|
6508
6605
|
type: "button",
|
|
@@ -6512,11 +6609,11 @@ var ImageEditor = ({
|
|
|
6512
6609
|
children: "-"
|
|
6513
6610
|
}
|
|
6514
6611
|
),
|
|
6515
|
-
/* @__PURE__ */ (0,
|
|
6612
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("span", { className: "font-mono text-slate-400 w-10 text-center", children: [
|
|
6516
6613
|
Math.round(state.zoom * 100),
|
|
6517
6614
|
"%"
|
|
6518
6615
|
] }),
|
|
6519
|
-
/* @__PURE__ */ (0,
|
|
6616
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
6520
6617
|
"button",
|
|
6521
6618
|
{
|
|
6522
6619
|
type: "button",
|
|
@@ -6526,8 +6623,8 @@ var ImageEditor = ({
|
|
|
6526
6623
|
children: "+"
|
|
6527
6624
|
}
|
|
6528
6625
|
),
|
|
6529
|
-
/* @__PURE__ */ (0,
|
|
6530
|
-
/* @__PURE__ */ (0,
|
|
6626
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("div", { className: "h-4 w-px bg-slate-800 mx-1" }),
|
|
6627
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
6531
6628
|
"button",
|
|
6532
6629
|
{
|
|
6533
6630
|
type: "button",
|
|
@@ -6538,7 +6635,7 @@ var ImageEditor = ({
|
|
|
6538
6635
|
children: "Hold Compare"
|
|
6539
6636
|
}
|
|
6540
6637
|
),
|
|
6541
|
-
/* @__PURE__ */ (0,
|
|
6638
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
6542
6639
|
"button",
|
|
6543
6640
|
{
|
|
6544
6641
|
type: "button",
|
|
@@ -6549,16 +6646,16 @@ var ImageEditor = ({
|
|
|
6549
6646
|
)
|
|
6550
6647
|
] })
|
|
6551
6648
|
] }),
|
|
6552
|
-
transformTool.active && /* @__PURE__ */ (0,
|
|
6553
|
-
!transformTool.active && transformTool.error && /* @__PURE__ */ (0,
|
|
6554
|
-
/* @__PURE__ */ (0,
|
|
6555
|
-
/* @__PURE__ */ (0,
|
|
6649
|
+
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" }),
|
|
6650
|
+
!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 }),
|
|
6651
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "flex flex-col md:flex-row flex-1 min-h-[520px] md:h-[560px]", children: [
|
|
6652
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(
|
|
6556
6653
|
"div",
|
|
6557
6654
|
{
|
|
6558
6655
|
ref: containerRef,
|
|
6559
6656
|
className: "relative flex-1 h-[360px] md:h-full min-h-[320px] bg-slate-950 overflow-hidden select-none",
|
|
6560
6657
|
children: [
|
|
6561
|
-
/* @__PURE__ */ (0,
|
|
6658
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
6562
6659
|
"canvas",
|
|
6563
6660
|
{
|
|
6564
6661
|
ref: canvasRef,
|
|
@@ -6575,7 +6672,7 @@ var ImageEditor = ({
|
|
|
6575
6672
|
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" : ""}`
|
|
6576
6673
|
}
|
|
6577
6674
|
),
|
|
6578
|
-
typeSession && /* @__PURE__ */ (0,
|
|
6675
|
+
typeSession && /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
6579
6676
|
"textarea",
|
|
6580
6677
|
{
|
|
6581
6678
|
ref: typeInputRef,
|
|
@@ -6597,11 +6694,11 @@ var ImageEditor = ({
|
|
|
6597
6694
|
]
|
|
6598
6695
|
}
|
|
6599
6696
|
),
|
|
6600
|
-
/* @__PURE__ */ (0,
|
|
6601
|
-
activeTab === "crop" && /* @__PURE__ */ (0,
|
|
6602
|
-
/* @__PURE__ */ (0,
|
|
6603
|
-
/* @__PURE__ */ (0,
|
|
6604
|
-
/* @__PURE__ */ (0,
|
|
6697
|
+
/* @__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: [
|
|
6698
|
+
activeTab === "crop" && /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "flex flex-col gap-4 text-xs", children: [
|
|
6699
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Aspect Ratio Presets" }),
|
|
6700
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "grid grid-cols-3 gap-2", children: [
|
|
6701
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
6605
6702
|
"button",
|
|
6606
6703
|
{
|
|
6607
6704
|
type: "button",
|
|
@@ -6613,7 +6710,7 @@ var ImageEditor = ({
|
|
|
6613
6710
|
children: "Freeform"
|
|
6614
6711
|
}
|
|
6615
6712
|
),
|
|
6616
|
-
/* @__PURE__ */ (0,
|
|
6713
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
6617
6714
|
"button",
|
|
6618
6715
|
{
|
|
6619
6716
|
type: "button",
|
|
@@ -6625,7 +6722,7 @@ var ImageEditor = ({
|
|
|
6625
6722
|
children: "1:1 Square"
|
|
6626
6723
|
}
|
|
6627
6724
|
),
|
|
6628
|
-
/* @__PURE__ */ (0,
|
|
6725
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
6629
6726
|
"button",
|
|
6630
6727
|
{
|
|
6631
6728
|
type: "button",
|
|
@@ -6637,7 +6734,7 @@ var ImageEditor = ({
|
|
|
6637
6734
|
children: "4:3 Standard"
|
|
6638
6735
|
}
|
|
6639
6736
|
),
|
|
6640
|
-
/* @__PURE__ */ (0,
|
|
6737
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
6641
6738
|
"button",
|
|
6642
6739
|
{
|
|
6643
6740
|
type: "button",
|
|
@@ -6649,7 +6746,7 @@ var ImageEditor = ({
|
|
|
6649
6746
|
children: "16:9 Wide"
|
|
6650
6747
|
}
|
|
6651
6748
|
),
|
|
6652
|
-
/* @__PURE__ */ (0,
|
|
6749
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
6653
6750
|
"button",
|
|
6654
6751
|
{
|
|
6655
6752
|
type: "button",
|
|
@@ -6661,7 +6758,7 @@ var ImageEditor = ({
|
|
|
6661
6758
|
children: "3:2 Photo"
|
|
6662
6759
|
}
|
|
6663
6760
|
),
|
|
6664
|
-
/* @__PURE__ */ (0,
|
|
6761
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
6665
6762
|
"button",
|
|
6666
6763
|
{
|
|
6667
6764
|
type: "button",
|
|
@@ -6674,10 +6771,10 @@ var ImageEditor = ({
|
|
|
6674
6771
|
}
|
|
6675
6772
|
)
|
|
6676
6773
|
] }),
|
|
6677
|
-
/* @__PURE__ */ (0,
|
|
6678
|
-
/* @__PURE__ */ (0,
|
|
6679
|
-
/* @__PURE__ */ (0,
|
|
6680
|
-
/* @__PURE__ */ (0,
|
|
6774
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("div", { className: "h-px bg-slate-800 my-1" }),
|
|
6775
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Orientation & Flips" }),
|
|
6776
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "grid grid-cols-2 gap-2", children: [
|
|
6777
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
6681
6778
|
"button",
|
|
6682
6779
|
{
|
|
6683
6780
|
type: "button",
|
|
@@ -6686,7 +6783,7 @@ var ImageEditor = ({
|
|
|
6686
6783
|
children: "Rotate -90\xB0"
|
|
6687
6784
|
}
|
|
6688
6785
|
),
|
|
6689
|
-
/* @__PURE__ */ (0,
|
|
6786
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
6690
6787
|
"button",
|
|
6691
6788
|
{
|
|
6692
6789
|
type: "button",
|
|
@@ -6695,7 +6792,7 @@ var ImageEditor = ({
|
|
|
6695
6792
|
children: "Rotate +90\xB0"
|
|
6696
6793
|
}
|
|
6697
6794
|
),
|
|
6698
|
-
/* @__PURE__ */ (0,
|
|
6795
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
6699
6796
|
"button",
|
|
6700
6797
|
{
|
|
6701
6798
|
type: "button",
|
|
@@ -6704,7 +6801,7 @@ var ImageEditor = ({
|
|
|
6704
6801
|
children: "Flip Horizontal"
|
|
6705
6802
|
}
|
|
6706
6803
|
),
|
|
6707
|
-
/* @__PURE__ */ (0,
|
|
6804
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
6708
6805
|
"button",
|
|
6709
6806
|
{
|
|
6710
6807
|
type: "button",
|
|
@@ -6715,10 +6812,10 @@ var ImageEditor = ({
|
|
|
6715
6812
|
)
|
|
6716
6813
|
] })
|
|
6717
6814
|
] }),
|
|
6718
|
-
activeTab === "adjust" && /* @__PURE__ */ (0,
|
|
6719
|
-
/* @__PURE__ */ (0,
|
|
6720
|
-
/* @__PURE__ */ (0,
|
|
6721
|
-
/* @__PURE__ */ (0,
|
|
6815
|
+
activeTab === "adjust" && /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "flex flex-col gap-3 text-xs", children: [
|
|
6816
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "flex items-center justify-between", children: [
|
|
6817
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Color Adjustments" }),
|
|
6818
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
6722
6819
|
"button",
|
|
6723
6820
|
{
|
|
6724
6821
|
type: "button",
|
|
@@ -6728,25 +6825,25 @@ var ImageEditor = ({
|
|
|
6728
6825
|
}
|
|
6729
6826
|
)
|
|
6730
6827
|
] }),
|
|
6731
|
-
/* @__PURE__ */ (0,
|
|
6732
|
-
|
|
6733
|
-
/* @__PURE__ */ (0,
|
|
6828
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(Histogram, { histogram: editor.histogram }),
|
|
6829
|
+
import_image_editor15.IMAGE_ADJUSTMENT_CONTROLS.map((spec) => /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(import_react47.default.Fragment, { children: [
|
|
6830
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
6734
6831
|
ControlSlider,
|
|
6735
6832
|
{
|
|
6736
6833
|
spec,
|
|
6737
|
-
value: (0,
|
|
6834
|
+
value: (0, import_image_editor15.readAdjustmentControls)(state.adjustments)[spec.id],
|
|
6738
6835
|
disabled: spec.requiresProcess !== void 0 && legacyProcess,
|
|
6739
6836
|
onChange: (v) => editor.setAdjustments({ [spec.id]: v })
|
|
6740
6837
|
}
|
|
6741
6838
|
),
|
|
6742
|
-
spec.id === "tint" && legacyProcess && /* @__PURE__ */ (0,
|
|
6839
|
+
spec.id === "tint" && legacyProcess && /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(
|
|
6743
6840
|
"div",
|
|
6744
6841
|
{
|
|
6745
6842
|
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",
|
|
6746
6843
|
"data-testid": "image-editor-process-notice",
|
|
6747
6844
|
children: [
|
|
6748
|
-
/* @__PURE__ */ (0,
|
|
6749
|
-
/* @__PURE__ */ (0,
|
|
6845
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", { children: "Legacy rendering (process 1). Tint needs the current process." }),
|
|
6846
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
6750
6847
|
"button",
|
|
6751
6848
|
{
|
|
6752
6849
|
type: "button",
|
|
@@ -6759,7 +6856,7 @@ var ImageEditor = ({
|
|
|
6759
6856
|
}
|
|
6760
6857
|
)
|
|
6761
6858
|
] }, spec.id)),
|
|
6762
|
-
/* @__PURE__ */ (0,
|
|
6859
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("div", { className: "border-t border-slate-700/60 pt-3", children: /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
6763
6860
|
AdjustmentLayersPanel,
|
|
6764
6861
|
{
|
|
6765
6862
|
controller,
|
|
@@ -6768,9 +6865,9 @@ var ImageEditor = ({
|
|
|
6768
6865
|
}
|
|
6769
6866
|
) })
|
|
6770
6867
|
] }),
|
|
6771
|
-
activeTab === "layers" && /* @__PURE__ */ (0,
|
|
6772
|
-
/* @__PURE__ */ (0,
|
|
6773
|
-
/* @__PURE__ */ (0,
|
|
6868
|
+
activeTab === "layers" && /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "flex flex-col gap-3 text-xs", children: [
|
|
6869
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Layers" }),
|
|
6870
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
6774
6871
|
"button",
|
|
6775
6872
|
{
|
|
6776
6873
|
type: "button",
|
|
@@ -6781,12 +6878,14 @@ var ImageEditor = ({
|
|
|
6781
6878
|
children: "Free Transform"
|
|
6782
6879
|
}
|
|
6783
6880
|
),
|
|
6784
|
-
/* @__PURE__ */ (0,
|
|
6881
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(LayersPanel, { controller }),
|
|
6882
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Colour" }),
|
|
6883
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(ColorProfilePanel, { controller })
|
|
6785
6884
|
] }),
|
|
6786
|
-
activeTab === "paint" && /* @__PURE__ */ (0,
|
|
6787
|
-
/* @__PURE__ */ (0,
|
|
6788
|
-
/* @__PURE__ */ (0,
|
|
6789
|
-
/* @__PURE__ */ (0,
|
|
6885
|
+
activeTab === "paint" && /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "flex flex-col gap-3 text-xs", children: [
|
|
6886
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Paint" }),
|
|
6887
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(BrushOptionsBar, { controller }),
|
|
6888
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
6790
6889
|
"button",
|
|
6791
6890
|
{
|
|
6792
6891
|
type: "button",
|
|
@@ -6797,12 +6896,12 @@ var ImageEditor = ({
|
|
|
6797
6896
|
children: "Free Transform"
|
|
6798
6897
|
}
|
|
6799
6898
|
),
|
|
6800
|
-
paintError && /* @__PURE__ */ (0,
|
|
6801
|
-
/* @__PURE__ */ (0,
|
|
6899
|
+
paintError && /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("p", { role: "alert", className: "text-rose-400", "data-testid": "paint-error", children: paintError }),
|
|
6900
|
+
/* @__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 }) })
|
|
6802
6901
|
] }),
|
|
6803
|
-
activeTab === "annotate" && /* @__PURE__ */ (0,
|
|
6804
|
-
/* @__PURE__ */ (0,
|
|
6805
|
-
/* @__PURE__ */ (0,
|
|
6902
|
+
activeTab === "annotate" && /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "flex flex-col gap-3 text-xs", children: [
|
|
6903
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Shape & Type Layers" }),
|
|
6904
|
+
/* @__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)(
|
|
6806
6905
|
"button",
|
|
6807
6906
|
{
|
|
6808
6907
|
type: "button",
|
|
@@ -6813,13 +6912,13 @@ var ImageEditor = ({
|
|
|
6813
6912
|
},
|
|
6814
6913
|
t
|
|
6815
6914
|
)) }),
|
|
6816
|
-
state.activeTool === "shape" && /* @__PURE__ */ (0,
|
|
6817
|
-
state.activeTool === "type" && /* @__PURE__ */ (0,
|
|
6818
|
-
state.activeTool === "type" && typeSession && /* @__PURE__ */ (0,
|
|
6819
|
-
shapeTypeError && /* @__PURE__ */ (0,
|
|
6820
|
-
/* @__PURE__ */ (0,
|
|
6821
|
-
/* @__PURE__ */ (0,
|
|
6822
|
-
/* @__PURE__ */ (0,
|
|
6915
|
+
state.activeTool === "shape" && /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(ShapeOptionsBar, { controller, options: shapeOptions, onChange: setShapeOptions }),
|
|
6916
|
+
state.activeTool === "type" && /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(TypeOptionsBar, { controller, options: typeOptions, onChange: setTypeOptions, session: typeSession }),
|
|
6917
|
+
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" }),
|
|
6918
|
+
shapeTypeError && /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("p", { role: "alert", className: "text-rose-400", "data-testid": "shape-type-error", children: shapeTypeError }),
|
|
6919
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("div", { className: "h-px bg-slate-800 my-1" }),
|
|
6920
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Draw & Annotate" }),
|
|
6921
|
+
/* @__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)(
|
|
6823
6922
|
"button",
|
|
6824
6923
|
{
|
|
6825
6924
|
type: "button",
|
|
@@ -6829,9 +6928,9 @@ var ImageEditor = ({
|
|
|
6829
6928
|
},
|
|
6830
6929
|
t
|
|
6831
6930
|
)) }),
|
|
6832
|
-
/* @__PURE__ */ (0,
|
|
6833
|
-
/* @__PURE__ */ (0,
|
|
6834
|
-
/* @__PURE__ */ (0,
|
|
6931
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "flex items-center gap-2 mt-2", children: [
|
|
6932
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("label", { className: "text-slate-400", children: "Color:" }),
|
|
6933
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
6835
6934
|
"input",
|
|
6836
6935
|
{
|
|
6837
6936
|
type: "color",
|
|
@@ -6840,15 +6939,15 @@ var ImageEditor = ({
|
|
|
6840
6939
|
className: "w-8 h-8 rounded border border-slate-700 cursor-pointer bg-transparent"
|
|
6841
6940
|
}
|
|
6842
6941
|
),
|
|
6843
|
-
/* @__PURE__ */ (0,
|
|
6844
|
-
/* @__PURE__ */ (0,
|
|
6845
|
-
/* @__PURE__ */ (0,
|
|
6846
|
-
/* @__PURE__ */ (0,
|
|
6942
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "flex-1 ml-2", children: [
|
|
6943
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "flex justify-between text-slate-400 mb-0.5", children: [
|
|
6944
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", { children: "Width:" }),
|
|
6945
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("span", { className: "font-mono", children: [
|
|
6847
6946
|
strokeWidth,
|
|
6848
6947
|
"px"
|
|
6849
6948
|
] })
|
|
6850
6949
|
] }),
|
|
6851
|
-
/* @__PURE__ */ (0,
|
|
6950
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
6852
6951
|
"input",
|
|
6853
6952
|
{
|
|
6854
6953
|
type: "range",
|
|
@@ -6861,10 +6960,10 @@ var ImageEditor = ({
|
|
|
6861
6960
|
)
|
|
6862
6961
|
] })
|
|
6863
6962
|
] }),
|
|
6864
|
-
/* @__PURE__ */ (0,
|
|
6865
|
-
/* @__PURE__ */ (0,
|
|
6866
|
-
/* @__PURE__ */ (0,
|
|
6867
|
-
/* @__PURE__ */ (0,
|
|
6963
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("div", { className: "h-px bg-slate-800 my-1" }),
|
|
6964
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Add Text" }),
|
|
6965
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "flex gap-2", children: [
|
|
6966
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
6868
6967
|
"input",
|
|
6869
6968
|
{
|
|
6870
6969
|
type: "text",
|
|
@@ -6875,7 +6974,7 @@ var ImageEditor = ({
|
|
|
6875
6974
|
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"
|
|
6876
6975
|
}
|
|
6877
6976
|
),
|
|
6878
|
-
/* @__PURE__ */ (0,
|
|
6977
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
6879
6978
|
"button",
|
|
6880
6979
|
{
|
|
6881
6980
|
type: "button",
|
|
@@ -6885,14 +6984,14 @@ var ImageEditor = ({
|
|
|
6885
6984
|
}
|
|
6886
6985
|
)
|
|
6887
6986
|
] }),
|
|
6888
|
-
/* @__PURE__ */ (0,
|
|
6889
|
-
/* @__PURE__ */ (0,
|
|
6890
|
-
/* @__PURE__ */ (0,
|
|
6987
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "flex items-center justify-between text-slate-400", children: [
|
|
6988
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", { children: "Font Size:" }),
|
|
6989
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("span", { className: "font-mono", children: [
|
|
6891
6990
|
fontSize,
|
|
6892
6991
|
"px"
|
|
6893
6992
|
] })
|
|
6894
6993
|
] }),
|
|
6895
|
-
/* @__PURE__ */ (0,
|
|
6994
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
6896
6995
|
"input",
|
|
6897
6996
|
{
|
|
6898
6997
|
type: "range",
|
|
@@ -6903,14 +7002,14 @@ var ImageEditor = ({
|
|
|
6903
7002
|
className: "w-full accent-indigo-500"
|
|
6904
7003
|
}
|
|
6905
7004
|
),
|
|
6906
|
-
/* @__PURE__ */ (0,
|
|
6907
|
-
/* @__PURE__ */ (0,
|
|
6908
|
-
/* @__PURE__ */ (0,
|
|
7005
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("div", { className: "h-px bg-slate-800 my-1" }),
|
|
7006
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "flex items-center justify-between", children: [
|
|
7007
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("span", { className: "text-slate-400", children: [
|
|
6909
7008
|
"Layers (",
|
|
6910
7009
|
state.annotations.length,
|
|
6911
7010
|
")"
|
|
6912
7011
|
] }),
|
|
6913
|
-
state.selectedAnnotationId && /* @__PURE__ */ (0,
|
|
7012
|
+
state.selectedAnnotationId && /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
6914
7013
|
"button",
|
|
6915
7014
|
{
|
|
6916
7015
|
type: "button",
|
|
@@ -6919,7 +7018,7 @@ var ImageEditor = ({
|
|
|
6919
7018
|
children: "Delete Selected"
|
|
6920
7019
|
}
|
|
6921
7020
|
),
|
|
6922
|
-
state.annotations.length > 0 && /* @__PURE__ */ (0,
|
|
7021
|
+
state.annotations.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
6923
7022
|
"button",
|
|
6924
7023
|
{
|
|
6925
7024
|
type: "button",
|
|
@@ -6930,10 +7029,10 @@ var ImageEditor = ({
|
|
|
6930
7029
|
)
|
|
6931
7030
|
] })
|
|
6932
7031
|
] }),
|
|
6933
|
-
activeTab === "depth" && /* @__PURE__ */ (0,
|
|
6934
|
-
/* @__PURE__ */ (0,
|
|
6935
|
-
/* @__PURE__ */ (0,
|
|
6936
|
-
/* @__PURE__ */ (0,
|
|
7032
|
+
activeTab === "depth" && /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "flex flex-col gap-3 text-xs", children: [
|
|
7033
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "flex items-center justify-between", children: [
|
|
7034
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Depth Masking" }),
|
|
7035
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
6937
7036
|
"button",
|
|
6938
7037
|
{
|
|
6939
7038
|
type: "button",
|
|
@@ -6943,8 +7042,8 @@ var ImageEditor = ({
|
|
|
6943
7042
|
}
|
|
6944
7043
|
)
|
|
6945
7044
|
] }),
|
|
6946
|
-
/* @__PURE__ */ (0,
|
|
6947
|
-
/* @__PURE__ */ (0,
|
|
7045
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("label", { className: "flex items-center gap-2 cursor-pointer text-slate-300", children: [
|
|
7046
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
6948
7047
|
"input",
|
|
6949
7048
|
{
|
|
6950
7049
|
type: "checkbox",
|
|
@@ -6953,12 +7052,12 @@ var ImageEditor = ({
|
|
|
6953
7052
|
className: "rounded accent-indigo-500"
|
|
6954
7053
|
}
|
|
6955
7054
|
),
|
|
6956
|
-
/* @__PURE__ */ (0,
|
|
7055
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", { children: "Enable Depth / Alpha Mask" })
|
|
6957
7056
|
] }),
|
|
6958
|
-
state.depthMask.enabled && /* @__PURE__ */ (0,
|
|
6959
|
-
/* @__PURE__ */ (0,
|
|
6960
|
-
/* @__PURE__ */ (0,
|
|
6961
|
-
/* @__PURE__ */ (0,
|
|
7057
|
+
state.depthMask.enabled && /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(import_jsx_runtime30.Fragment, { children: [
|
|
7058
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { children: [
|
|
7059
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("label", { className: "text-slate-400 block mb-1", children: "Mask Image URL:" }),
|
|
7060
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
6962
7061
|
"input",
|
|
6963
7062
|
{
|
|
6964
7063
|
type: "text",
|
|
@@ -6969,8 +7068,8 @@ var ImageEditor = ({
|
|
|
6969
7068
|
}
|
|
6970
7069
|
)
|
|
6971
7070
|
] }),
|
|
6972
|
-
/* @__PURE__ */ (0,
|
|
6973
|
-
/* @__PURE__ */ (0,
|
|
7071
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "flex gap-2", children: [
|
|
7072
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
6974
7073
|
"button",
|
|
6975
7074
|
{
|
|
6976
7075
|
type: "button",
|
|
@@ -6979,7 +7078,7 @@ var ImageEditor = ({
|
|
|
6979
7078
|
children: "Threshold Mode"
|
|
6980
7079
|
}
|
|
6981
7080
|
),
|
|
6982
|
-
/* @__PURE__ */ (0,
|
|
7081
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
6983
7082
|
"button",
|
|
6984
7083
|
{
|
|
6985
7084
|
type: "button",
|
|
@@ -6989,12 +7088,12 @@ var ImageEditor = ({
|
|
|
6989
7088
|
}
|
|
6990
7089
|
)
|
|
6991
7090
|
] }),
|
|
6992
|
-
/* @__PURE__ */ (0,
|
|
6993
|
-
/* @__PURE__ */ (0,
|
|
6994
|
-
/* @__PURE__ */ (0,
|
|
6995
|
-
/* @__PURE__ */ (0,
|
|
7091
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { children: [
|
|
7092
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "flex justify-between text-slate-400 mb-1", children: [
|
|
7093
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", { children: "Depth Start (Lower):" }),
|
|
7094
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", { className: "font-mono", children: state.depthMask.depthRange[0] })
|
|
6996
7095
|
] }),
|
|
6997
|
-
/* @__PURE__ */ (0,
|
|
7096
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
6998
7097
|
"input",
|
|
6999
7098
|
{
|
|
7000
7099
|
type: "range",
|
|
@@ -7008,12 +7107,12 @@ var ImageEditor = ({
|
|
|
7008
7107
|
}
|
|
7009
7108
|
)
|
|
7010
7109
|
] }),
|
|
7011
|
-
/* @__PURE__ */ (0,
|
|
7012
|
-
/* @__PURE__ */ (0,
|
|
7013
|
-
/* @__PURE__ */ (0,
|
|
7014
|
-
/* @__PURE__ */ (0,
|
|
7110
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { children: [
|
|
7111
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "flex justify-between text-slate-400 mb-1", children: [
|
|
7112
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", { children: "Depth Stop (Upper):" }),
|
|
7113
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", { className: "font-mono", children: state.depthMask.depthRange[1] })
|
|
7015
7114
|
] }),
|
|
7016
|
-
/* @__PURE__ */ (0,
|
|
7115
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
7017
7116
|
"input",
|
|
7018
7117
|
{
|
|
7019
7118
|
type: "range",
|
|
@@ -7027,12 +7126,12 @@ var ImageEditor = ({
|
|
|
7027
7126
|
}
|
|
7028
7127
|
)
|
|
7029
7128
|
] }),
|
|
7030
|
-
/* @__PURE__ */ (0,
|
|
7031
|
-
/* @__PURE__ */ (0,
|
|
7032
|
-
/* @__PURE__ */ (0,
|
|
7033
|
-
/* @__PURE__ */ (0,
|
|
7129
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { children: [
|
|
7130
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "flex justify-between text-slate-400 mb-1", children: [
|
|
7131
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", { children: "Softness:" }),
|
|
7132
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", { className: "font-mono", children: state.depthMask.softness })
|
|
7034
7133
|
] }),
|
|
7035
|
-
/* @__PURE__ */ (0,
|
|
7134
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
7036
7135
|
"input",
|
|
7037
7136
|
{
|
|
7038
7137
|
type: "range",
|
|
@@ -7044,8 +7143,8 @@ var ImageEditor = ({
|
|
|
7044
7143
|
}
|
|
7045
7144
|
)
|
|
7046
7145
|
] }),
|
|
7047
|
-
/* @__PURE__ */ (0,
|
|
7048
|
-
/* @__PURE__ */ (0,
|
|
7146
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("label", { className: "flex items-center gap-2 cursor-pointer text-slate-300 mt-1", children: [
|
|
7147
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
7049
7148
|
"input",
|
|
7050
7149
|
{
|
|
7051
7150
|
type: "checkbox",
|
|
@@ -7054,12 +7153,12 @@ var ImageEditor = ({
|
|
|
7054
7153
|
className: "rounded accent-indigo-500"
|
|
7055
7154
|
}
|
|
7056
7155
|
),
|
|
7057
|
-
/* @__PURE__ */ (0,
|
|
7156
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", { children: "Invert Mask" })
|
|
7058
7157
|
] })
|
|
7059
7158
|
] })
|
|
7060
7159
|
] }),
|
|
7061
|
-
activeTab === "select" && /* @__PURE__ */ (0,
|
|
7062
|
-
/* @__PURE__ */ (0,
|
|
7160
|
+
activeTab === "select" && /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "flex flex-col gap-4 text-xs", children: [
|
|
7161
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
7063
7162
|
SelectionOptionsBar,
|
|
7064
7163
|
{
|
|
7065
7164
|
controller,
|
|
@@ -7069,9 +7168,9 @@ var ImageEditor = ({
|
|
|
7069
7168
|
quickMask: Boolean(state.quickMask)
|
|
7070
7169
|
}
|
|
7071
7170
|
),
|
|
7072
|
-
selectionError && /* @__PURE__ */ (0,
|
|
7073
|
-
/* @__PURE__ */ (0,
|
|
7074
|
-
/* @__PURE__ */ (0,
|
|
7171
|
+
selectionError && /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("p", { role: "alert", className: "text-rose-400", children: selectionError }),
|
|
7172
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "flex gap-1", children: [
|
|
7173
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
7075
7174
|
"button",
|
|
7076
7175
|
{
|
|
7077
7176
|
type: "button",
|
|
@@ -7082,7 +7181,7 @@ var ImageEditor = ({
|
|
|
7082
7181
|
children: "Transform Selection"
|
|
7083
7182
|
}
|
|
7084
7183
|
),
|
|
7085
|
-
/* @__PURE__ */ (0,
|
|
7184
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
7086
7185
|
"button",
|
|
7087
7186
|
{
|
|
7088
7187
|
type: "button",
|
|
@@ -7094,12 +7193,12 @@ var ImageEditor = ({
|
|
|
7094
7193
|
}
|
|
7095
7194
|
)
|
|
7096
7195
|
] }),
|
|
7097
|
-
/* @__PURE__ */ (0,
|
|
7196
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(RefineEdgePanel, { controller, selection: state.selection ?? null, layers: state.adjustments.layers })
|
|
7098
7197
|
] }),
|
|
7099
|
-
activeTab === "ai" && /* @__PURE__ */ (0,
|
|
7100
|
-
/* @__PURE__ */ (0,
|
|
7101
|
-
/* @__PURE__ */ (0,
|
|
7102
|
-
/* @__PURE__ */ (0,
|
|
7198
|
+
activeTab === "ai" && /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "flex flex-col gap-4 text-xs", children: [
|
|
7199
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("label", { className: "flex items-center justify-between gap-2 text-slate-300", children: [
|
|
7200
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", { children: "Results go to" }),
|
|
7201
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(
|
|
7103
7202
|
"select",
|
|
7104
7203
|
{
|
|
7105
7204
|
"aria-label": "AI result target",
|
|
@@ -7107,54 +7206,54 @@ var ImageEditor = ({
|
|
|
7107
7206
|
onChange: (e) => setAiTarget(e.target.value),
|
|
7108
7207
|
className: "bg-slate-800 border border-slate-700 rounded px-1.5 py-1",
|
|
7109
7208
|
children: [
|
|
7110
|
-
/* @__PURE__ */ (0,
|
|
7111
|
-
/* @__PURE__ */ (0,
|
|
7112
|
-
/* @__PURE__ */ (0,
|
|
7209
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("option", { value: "auto", children: controller.isMultiLayer ? "Auto (new layer)" : "Auto (replace image)" }),
|
|
7210
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("option", { value: "new-layer", children: "New layer / mask" }),
|
|
7211
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("option", { value: "replace", children: "Replace image" })
|
|
7113
7212
|
]
|
|
7114
7213
|
}
|
|
7115
7214
|
)
|
|
7116
7215
|
] }),
|
|
7117
|
-
/* @__PURE__ */ (0,
|
|
7118
|
-
/* @__PURE__ */ (0,
|
|
7119
|
-
/* @__PURE__ */ (0,
|
|
7120
|
-
/* @__PURE__ */ (0,
|
|
7216
|
+
/* @__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: [
|
|
7217
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "flex items-center justify-between", children: [
|
|
7218
|
+
/* @__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: [
|
|
7219
|
+
/* @__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" }) }),
|
|
7121
7220
|
"Background Removal"
|
|
7122
7221
|
] }),
|
|
7123
|
-
isRemovingBg && /* @__PURE__ */ (0,
|
|
7222
|
+
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..." })
|
|
7124
7223
|
] }),
|
|
7125
|
-
/* @__PURE__ */ (0,
|
|
7126
|
-
/* @__PURE__ */ (0,
|
|
7224
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("p", { className: "text-slate-400 text-[11px] leading-relaxed", children: "Isolate foreground subject with AI alpha transparency segmentation." }),
|
|
7225
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
7127
7226
|
"button",
|
|
7128
7227
|
{
|
|
7129
7228
|
type: "button",
|
|
7130
7229
|
onClick: handleRemoveBackground,
|
|
7131
7230
|
disabled: isRemovingBg || isInpainting,
|
|
7132
7231
|
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",
|
|
7133
|
-
children: isRemovingBg ? /* @__PURE__ */ (0,
|
|
7134
|
-
/* @__PURE__ */ (0,
|
|
7232
|
+
children: isRemovingBg ? /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(import_jsx_runtime30.Fragment, { children: [
|
|
7233
|
+
/* @__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" }),
|
|
7135
7234
|
"Removing Background..."
|
|
7136
|
-
] }) : /* @__PURE__ */ (0,
|
|
7137
|
-
/* @__PURE__ */ (0,
|
|
7235
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(import_jsx_runtime30.Fragment, { children: [
|
|
7236
|
+
/* @__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" }) }),
|
|
7138
7237
|
"Remove Background"
|
|
7139
7238
|
] })
|
|
7140
7239
|
}
|
|
7141
7240
|
)
|
|
7142
7241
|
] }),
|
|
7143
|
-
/* @__PURE__ */ (0,
|
|
7144
|
-
/* @__PURE__ */ (0,
|
|
7145
|
-
/* @__PURE__ */ (0,
|
|
7146
|
-
/* @__PURE__ */ (0,
|
|
7147
|
-
/* @__PURE__ */ (0,
|
|
7148
|
-
/* @__PURE__ */ (0,
|
|
7242
|
+
/* @__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: [
|
|
7243
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "flex items-center justify-between", children: [
|
|
7244
|
+
/* @__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: [
|
|
7245
|
+
/* @__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: [
|
|
7246
|
+
/* @__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" }),
|
|
7247
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("path", { d: "m14 7 3 3" })
|
|
7149
7248
|
] }),
|
|
7150
7249
|
"Generative Inpainting"
|
|
7151
7250
|
] }),
|
|
7152
|
-
isInpainting && /* @__PURE__ */ (0,
|
|
7251
|
+
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..." })
|
|
7153
7252
|
] }),
|
|
7154
|
-
/* @__PURE__ */ (0,
|
|
7155
|
-
/* @__PURE__ */ (0,
|
|
7156
|
-
/* @__PURE__ */ (0,
|
|
7157
|
-
/* @__PURE__ */ (0,
|
|
7253
|
+
/* @__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." }),
|
|
7254
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "flex flex-col gap-1", children: [
|
|
7255
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("label", { htmlFor: "ai-inpaint-prompt-react", className: "text-slate-300 text-[11px] font-medium", children: "Prompt" }),
|
|
7256
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
7158
7257
|
"textarea",
|
|
7159
7258
|
{
|
|
7160
7259
|
id: "ai-inpaint-prompt-react",
|
|
@@ -7166,10 +7265,10 @@ var ImageEditor = ({
|
|
|
7166
7265
|
}
|
|
7167
7266
|
)
|
|
7168
7267
|
] }),
|
|
7169
|
-
/* @__PURE__ */ (0,
|
|
7170
|
-
/* @__PURE__ */ (0,
|
|
7171
|
-
/* @__PURE__ */ (0,
|
|
7172
|
-
/* @__PURE__ */ (0,
|
|
7268
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "flex flex-col gap-1", children: [
|
|
7269
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", { className: "text-slate-300 text-[11px] font-medium", children: "Target Mask Region" }),
|
|
7270
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "grid grid-cols-2 gap-1.5", children: [
|
|
7271
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(
|
|
7173
7272
|
"button",
|
|
7174
7273
|
{
|
|
7175
7274
|
type: "button",
|
|
@@ -7182,7 +7281,7 @@ var ImageEditor = ({
|
|
|
7182
7281
|
]
|
|
7183
7282
|
}
|
|
7184
7283
|
),
|
|
7185
|
-
/* @__PURE__ */ (0,
|
|
7284
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(
|
|
7186
7285
|
"button",
|
|
7187
7286
|
{
|
|
7188
7287
|
type: "button",
|
|
@@ -7197,25 +7296,25 @@ var ImageEditor = ({
|
|
|
7197
7296
|
)
|
|
7198
7297
|
] })
|
|
7199
7298
|
] }),
|
|
7200
|
-
/* @__PURE__ */ (0,
|
|
7299
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
7201
7300
|
"button",
|
|
7202
7301
|
{
|
|
7203
7302
|
type: "button",
|
|
7204
7303
|
onClick: handleInpaint,
|
|
7205
7304
|
disabled: isInpainting || isRemovingBg || !inpaintPrompt.trim(),
|
|
7206
7305
|
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",
|
|
7207
|
-
children: isInpainting ? /* @__PURE__ */ (0,
|
|
7208
|
-
/* @__PURE__ */ (0,
|
|
7306
|
+
children: isInpainting ? /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(import_jsx_runtime30.Fragment, { children: [
|
|
7307
|
+
/* @__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" }),
|
|
7209
7308
|
"Generating Inpaint..."
|
|
7210
|
-
] }) : /* @__PURE__ */ (0,
|
|
7211
|
-
/* @__PURE__ */ (0,
|
|
7309
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(import_jsx_runtime30.Fragment, { children: [
|
|
7310
|
+
/* @__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" }) }),
|
|
7212
7311
|
"Apply Inpainting"
|
|
7213
7312
|
] })
|
|
7214
7313
|
}
|
|
7215
7314
|
)
|
|
7216
7315
|
] }),
|
|
7217
|
-
aiError && /* @__PURE__ */ (0,
|
|
7218
|
-
aiSuccess && /* @__PURE__ */ (0,
|
|
7316
|
+
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 }),
|
|
7317
|
+
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 })
|
|
7219
7318
|
] })
|
|
7220
7319
|
] })
|
|
7221
7320
|
] })
|
|
@@ -7225,7 +7324,7 @@ var ImageEditor = ({
|
|
|
7225
7324
|
};
|
|
7226
7325
|
|
|
7227
7326
|
// src/review/useReview.ts
|
|
7228
|
-
var
|
|
7327
|
+
var import_react48 = require("react");
|
|
7229
7328
|
var import_editor12 = require("@pixerate/editor");
|
|
7230
7329
|
var EMPTY_COMMENTS = Object.freeze({
|
|
7231
7330
|
threads: [],
|
|
@@ -7244,23 +7343,23 @@ function isCommentStore(value) {
|
|
|
7244
7343
|
}
|
|
7245
7344
|
function useComments(source) {
|
|
7246
7345
|
const store = isCommentStore(source) ? source : (0, import_editor12.getCommentStore)(source);
|
|
7247
|
-
const subscribe = (0,
|
|
7346
|
+
const subscribe = (0, import_react48.useCallback)(
|
|
7248
7347
|
(onChange) => store ? store.subscribe(() => onChange()) : noopUnsubscribe,
|
|
7249
7348
|
[store]
|
|
7250
7349
|
);
|
|
7251
7350
|
const getSnapshot = () => store?.getSnapshot() ?? EMPTY_COMMENTS;
|
|
7252
|
-
const snapshot = (0,
|
|
7253
|
-
return (0,
|
|
7351
|
+
const snapshot = (0, import_react48.useSyncExternalStore)(subscribe, getSnapshot, getSnapshot);
|
|
7352
|
+
return (0, import_react48.useMemo)(() => ({ ...snapshot, store }), [snapshot, store]);
|
|
7254
7353
|
}
|
|
7255
7354
|
function useTrackChanges(editor) {
|
|
7256
7355
|
const store = (0, import_editor12.getTrackChangesStore)(editor ?? null);
|
|
7257
|
-
const subscribe = (0,
|
|
7356
|
+
const subscribe = (0, import_react48.useCallback)(
|
|
7258
7357
|
(onChange) => store ? store.subscribe(() => onChange()) : noopUnsubscribe,
|
|
7259
7358
|
[store]
|
|
7260
7359
|
);
|
|
7261
7360
|
const getSnapshot = () => store?.getSnapshot() ?? EMPTY_TRACK_CHANGES;
|
|
7262
|
-
const snapshot = (0,
|
|
7263
|
-
return (0,
|
|
7361
|
+
const snapshot = (0, import_react48.useSyncExternalStore)(subscribe, getSnapshot, getSnapshot);
|
|
7362
|
+
return (0, import_react48.useMemo)(() => {
|
|
7264
7363
|
const run = (fn) => () => {
|
|
7265
7364
|
if (editor && !editor.isDestroyed) fn(editor);
|
|
7266
7365
|
};
|
|
@@ -7283,9 +7382,9 @@ function useTrackChanges(editor) {
|
|
|
7283
7382
|
}
|
|
7284
7383
|
|
|
7285
7384
|
// src/review/CommentsPanel.tsx
|
|
7286
|
-
var
|
|
7385
|
+
var import_react49 = require("react");
|
|
7287
7386
|
var import_editor13 = require("@pixerate/editor");
|
|
7288
|
-
var
|
|
7387
|
+
var import_jsx_runtime31 = require("react/jsx-runtime");
|
|
7289
7388
|
var buttonClass2 = "rounded px-2 py-1 text-xs text-muted-foreground hover:bg-muted hover:text-foreground disabled:opacity-50";
|
|
7290
7389
|
var primaryButtonClass = "rounded px-2 py-1 text-xs bg-primary/10 text-primary hover:bg-primary/20 disabled:opacity-50";
|
|
7291
7390
|
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";
|
|
@@ -7299,18 +7398,18 @@ var CommentsPanel = ({
|
|
|
7299
7398
|
emptyMessage = "No comments yet. Select text and add a comment."
|
|
7300
7399
|
}) => {
|
|
7301
7400
|
const { threads, activeThreadId, store } = useComments(storeProp ?? editor);
|
|
7302
|
-
const [showResolved, setShowResolved] = (0,
|
|
7401
|
+
const [showResolved, setShowResolved] = (0, import_react49.useState)(showResolvedInitial);
|
|
7303
7402
|
const author = authorProp ?? (0, import_editor13.getCommentAuthor)(editor) ?? { id: "anonymous", name: "Anonymous" };
|
|
7304
7403
|
const visible = threads.filter((t) => showResolved || !t.resolved);
|
|
7305
7404
|
const resolvedCount = threads.filter((t) => t.resolved).length;
|
|
7306
|
-
return /* @__PURE__ */ (0,
|
|
7307
|
-
/* @__PURE__ */ (0,
|
|
7308
|
-
/* @__PURE__ */ (0,
|
|
7405
|
+
return /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("aside", { className, "aria-label": "Comments", children: [
|
|
7406
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("div", { className: "flex items-center justify-between gap-2", children: [
|
|
7407
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("span", { className: "text-xs font-medium text-muted-foreground", children: [
|
|
7309
7408
|
threads.length - resolvedCount,
|
|
7310
7409
|
" open",
|
|
7311
7410
|
resolvedCount > 0 ? ` \xB7 ${resolvedCount} resolved` : ""
|
|
7312
7411
|
] }),
|
|
7313
|
-
resolvedCount > 0 && /* @__PURE__ */ (0,
|
|
7412
|
+
resolvedCount > 0 && /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
|
|
7314
7413
|
"button",
|
|
7315
7414
|
{
|
|
7316
7415
|
type: "button",
|
|
@@ -7321,7 +7420,7 @@ var CommentsPanel = ({
|
|
|
7321
7420
|
}
|
|
7322
7421
|
)
|
|
7323
7422
|
] }),
|
|
7324
|
-
visible.length === 0 ? /* @__PURE__ */ (0,
|
|
7423
|
+
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)(
|
|
7325
7424
|
CommentThreadCard,
|
|
7326
7425
|
{
|
|
7327
7426
|
thread,
|
|
@@ -7343,7 +7442,7 @@ var CommentThreadCard = ({
|
|
|
7343
7442
|
author,
|
|
7344
7443
|
formatTime
|
|
7345
7444
|
}) => {
|
|
7346
|
-
const [draft, setDraft] = (0,
|
|
7445
|
+
const [draft, setDraft] = (0, import_react49.useState)("");
|
|
7347
7446
|
const isDraft = thread.body === "";
|
|
7348
7447
|
const quote = thread.anchor?.quote ?? thread.lastQuote ?? "";
|
|
7349
7448
|
const live = editor && !editor.isDestroyed ? editor : null;
|
|
@@ -7369,7 +7468,7 @@ var CommentThreadCard = ({
|
|
|
7369
7468
|
setDraft("");
|
|
7370
7469
|
};
|
|
7371
7470
|
const stop = (e) => e.stopPropagation();
|
|
7372
|
-
return /* @__PURE__ */ (0,
|
|
7471
|
+
return /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(
|
|
7373
7472
|
"li",
|
|
7374
7473
|
{
|
|
7375
7474
|
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" : ""}`,
|
|
@@ -7385,24 +7484,24 @@ var CommentThreadCard = ({
|
|
|
7385
7484
|
}
|
|
7386
7485
|
},
|
|
7387
7486
|
children: [
|
|
7388
|
-
/* @__PURE__ */ (0,
|
|
7389
|
-
/* @__PURE__ */ (0,
|
|
7390
|
-
/* @__PURE__ */ (0,
|
|
7487
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("div", { className: "flex items-baseline justify-between gap-2", children: [
|
|
7488
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)("span", { className: "font-medium", children: thread.author.name }),
|
|
7489
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)("span", { className: "text-xs text-muted-foreground", children: formatTime(thread.createdAt) })
|
|
7391
7490
|
] }),
|
|
7392
|
-
quote && /* @__PURE__ */ (0,
|
|
7393
|
-
thread.orphaned && /* @__PURE__ */ (0,
|
|
7394
|
-
thread.resolved && /* @__PURE__ */ (0,
|
|
7395
|
-
!isDraft && /* @__PURE__ */ (0,
|
|
7396
|
-
thread.replies.length > 0 && /* @__PURE__ */ (0,
|
|
7397
|
-
/* @__PURE__ */ (0,
|
|
7398
|
-
/* @__PURE__ */ (0,
|
|
7491
|
+
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 }),
|
|
7492
|
+
thread.orphaned && /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("span", { className: "text-xs text-destructive", children: "The commented text was deleted." }),
|
|
7493
|
+
thread.resolved && /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("span", { className: "text-xs text-muted-foreground", children: "Resolved" }),
|
|
7494
|
+
!isDraft && /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("p", { className: "whitespace-pre-wrap break-words", children: thread.body }),
|
|
7495
|
+
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: [
|
|
7496
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("span", { className: "text-xs", children: [
|
|
7497
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)("span", { className: "font-medium", children: reply.author.name }),
|
|
7399
7498
|
" ",
|
|
7400
|
-
/* @__PURE__ */ (0,
|
|
7499
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)("span", { className: "text-muted-foreground", children: formatTime(reply.createdAt) })
|
|
7401
7500
|
] }),
|
|
7402
|
-
/* @__PURE__ */ (0,
|
|
7501
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)("p", { className: "whitespace-pre-wrap break-words", children: reply.body })
|
|
7403
7502
|
] }, reply.id)) }),
|
|
7404
|
-
(active || isDraft) && !thread.resolved && /* @__PURE__ */ (0,
|
|
7405
|
-
/* @__PURE__ */ (0,
|
|
7503
|
+
(active || isDraft) && !thread.resolved && /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("div", { className: "flex flex-col gap-1", onClick: stop, children: [
|
|
7504
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
|
|
7406
7505
|
"textarea",
|
|
7407
7506
|
{
|
|
7408
7507
|
className: textareaClass,
|
|
@@ -7420,9 +7519,9 @@ var CommentThreadCard = ({
|
|
|
7420
7519
|
}
|
|
7421
7520
|
}
|
|
7422
7521
|
),
|
|
7423
|
-
/* @__PURE__ */ (0,
|
|
7424
|
-
isDraft && /* @__PURE__ */ (0,
|
|
7425
|
-
/* @__PURE__ */ (0,
|
|
7522
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("div", { className: "flex justify-end gap-1", children: [
|
|
7523
|
+
isDraft && /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("button", { type: "button", className: buttonClass2, onClick: remove, children: "Cancel" }),
|
|
7524
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
|
|
7426
7525
|
"button",
|
|
7427
7526
|
{
|
|
7428
7527
|
type: "button",
|
|
@@ -7434,9 +7533,9 @@ var CommentThreadCard = ({
|
|
|
7434
7533
|
)
|
|
7435
7534
|
] })
|
|
7436
7535
|
] }),
|
|
7437
|
-
!isDraft && /* @__PURE__ */ (0,
|
|
7438
|
-
/* @__PURE__ */ (0,
|
|
7439
|
-
/* @__PURE__ */ (0,
|
|
7536
|
+
!isDraft && /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("div", { className: "flex justify-end gap-1", onClick: stop, children: [
|
|
7537
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)("button", { type: "button", className: buttonClass2, onClick: () => setResolved(!thread.resolved), children: thread.resolved ? "Reopen" : "Resolve" }),
|
|
7538
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
|
|
7440
7539
|
"button",
|
|
7441
7540
|
{
|
|
7442
7541
|
type: "button",
|
|
@@ -7452,7 +7551,7 @@ var CommentThreadCard = ({
|
|
|
7452
7551
|
};
|
|
7453
7552
|
|
|
7454
7553
|
// src/review/ReviewToolbar.tsx
|
|
7455
|
-
var
|
|
7554
|
+
var import_jsx_runtime32 = require("react/jsx-runtime");
|
|
7456
7555
|
var defaultDescriptionClass = "max-w-[16rem] truncate px-1 text-xs text-muted-foreground";
|
|
7457
7556
|
var buttonClass3 = "rounded px-2 py-1 text-xs text-foreground hover:bg-muted disabled:opacity-40 disabled:hover:bg-transparent";
|
|
7458
7557
|
var ReviewToolbar = ({
|
|
@@ -7465,8 +7564,8 @@ var ReviewToolbar = ({
|
|
|
7465
7564
|
const count = review.changes.length;
|
|
7466
7565
|
const current = review.currentChange;
|
|
7467
7566
|
const index = current ? review.changes.findIndex((c) => c.id === current.id) + 1 : 0;
|
|
7468
|
-
return /* @__PURE__ */ (0,
|
|
7469
|
-
/* @__PURE__ */ (0,
|
|
7567
|
+
return /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { className, role: "toolbar", "aria-label": "Review", children: [
|
|
7568
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
7470
7569
|
"button",
|
|
7471
7570
|
{
|
|
7472
7571
|
type: "button",
|
|
@@ -7477,8 +7576,8 @@ var ReviewToolbar = ({
|
|
|
7477
7576
|
children: review.enabled ? "Tracking on" : "Track changes"
|
|
7478
7577
|
}
|
|
7479
7578
|
),
|
|
7480
|
-
/* @__PURE__ */ (0,
|
|
7481
|
-
/* @__PURE__ */ (0,
|
|
7579
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)("span", { className: "mx-1 h-4 w-px bg-border", "aria-hidden": "true" }),
|
|
7580
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
7482
7581
|
"button",
|
|
7483
7582
|
{
|
|
7484
7583
|
type: "button",
|
|
@@ -7489,8 +7588,8 @@ var ReviewToolbar = ({
|
|
|
7489
7588
|
children: "\u2039"
|
|
7490
7589
|
}
|
|
7491
7590
|
),
|
|
7492
|
-
/* @__PURE__ */ (0,
|
|
7493
|
-
/* @__PURE__ */ (0,
|
|
7591
|
+
/* @__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` }),
|
|
7592
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
7494
7593
|
"button",
|
|
7495
7594
|
{
|
|
7496
7595
|
type: "button",
|
|
@@ -7501,7 +7600,7 @@ var ReviewToolbar = ({
|
|
|
7501
7600
|
children: "\u203A"
|
|
7502
7601
|
}
|
|
7503
7602
|
),
|
|
7504
|
-
showDescription && current && /* @__PURE__ */ (0,
|
|
7603
|
+
showDescription && current && /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(
|
|
7505
7604
|
"span",
|
|
7506
7605
|
{
|
|
7507
7606
|
className: descriptionClassName,
|
|
@@ -7513,8 +7612,8 @@ var ReviewToolbar = ({
|
|
|
7513
7612
|
]
|
|
7514
7613
|
}
|
|
7515
7614
|
),
|
|
7516
|
-
/* @__PURE__ */ (0,
|
|
7517
|
-
/* @__PURE__ */ (0,
|
|
7615
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)("span", { className: "mx-1 h-4 w-px bg-border", "aria-hidden": "true" }),
|
|
7616
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
7518
7617
|
"button",
|
|
7519
7618
|
{
|
|
7520
7619
|
type: "button",
|
|
@@ -7524,7 +7623,7 @@ var ReviewToolbar = ({
|
|
|
7524
7623
|
children: "Accept"
|
|
7525
7624
|
}
|
|
7526
7625
|
),
|
|
7527
|
-
/* @__PURE__ */ (0,
|
|
7626
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
7528
7627
|
"button",
|
|
7529
7628
|
{
|
|
7530
7629
|
type: "button",
|
|
@@ -7534,18 +7633,18 @@ var ReviewToolbar = ({
|
|
|
7534
7633
|
children: "Reject"
|
|
7535
7634
|
}
|
|
7536
7635
|
),
|
|
7537
|
-
/* @__PURE__ */ (0,
|
|
7538
|
-
/* @__PURE__ */ (0,
|
|
7636
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)("button", { type: "button", className: buttonClass3, disabled: count === 0, onClick: review.acceptAll, children: "Accept all" }),
|
|
7637
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)("button", { type: "button", className: buttonClass3, disabled: count === 0, onClick: review.rejectAll, children: "Reject all" })
|
|
7539
7638
|
] });
|
|
7540
7639
|
};
|
|
7541
7640
|
|
|
7542
7641
|
// src/review/CommentButton.tsx
|
|
7543
|
-
var
|
|
7642
|
+
var import_jsx_runtime33 = require("react/jsx-runtime");
|
|
7544
7643
|
var CommentButton = ({
|
|
7545
7644
|
editor,
|
|
7546
7645
|
className = "rounded px-2 py-1 text-xs text-popover-foreground hover:bg-muted",
|
|
7547
7646
|
children = "Comment"
|
|
7548
|
-
}) => /* @__PURE__ */ (0,
|
|
7647
|
+
}) => /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
|
|
7549
7648
|
"button",
|
|
7550
7649
|
{
|
|
7551
7650
|
type: "button",
|
|
@@ -7557,13 +7656,13 @@ var CommentButton = ({
|
|
|
7557
7656
|
);
|
|
7558
7657
|
|
|
7559
7658
|
// src/review/useDocumentCompare.ts
|
|
7560
|
-
var
|
|
7659
|
+
var import_react50 = require("react");
|
|
7561
7660
|
var import_editor14 = require("@pixerate/editor");
|
|
7562
7661
|
function useDocumentCompare(editor, options) {
|
|
7563
|
-
const [summary, setSummary] = (0,
|
|
7564
|
-
const defaults = (0,
|
|
7662
|
+
const [summary, setSummary] = (0, import_react50.useState)(null);
|
|
7663
|
+
const defaults = (0, import_react50.useRef)(options);
|
|
7565
7664
|
defaults.current = options;
|
|
7566
|
-
const compare = (0,
|
|
7665
|
+
const compare = (0, import_react50.useCallback)(
|
|
7567
7666
|
(original, revised, overrides) => {
|
|
7568
7667
|
if (!editor || editor.isDestroyed) return null;
|
|
7569
7668
|
const result = (0, import_editor14.applyDocumentComparison)(editor, original, revised, {
|
|
@@ -7575,13 +7674,13 @@ function useDocumentCompare(editor, options) {
|
|
|
7575
7674
|
},
|
|
7576
7675
|
[editor]
|
|
7577
7676
|
);
|
|
7578
|
-
const clear = (0,
|
|
7579
|
-
return (0,
|
|
7677
|
+
const clear = (0, import_react50.useCallback)(() => setSummary(null), []);
|
|
7678
|
+
return (0, import_react50.useMemo)(() => ({ summary, compare, clear }), [summary, compare, clear]);
|
|
7580
7679
|
}
|
|
7581
7680
|
|
|
7582
7681
|
// src/review/TrackedChangesList.tsx
|
|
7583
7682
|
var import_editor15 = require("@pixerate/editor");
|
|
7584
|
-
var
|
|
7683
|
+
var import_jsx_runtime34 = require("react/jsx-runtime");
|
|
7585
7684
|
var buttonClass4 = "rounded px-1.5 py-0.5 text-xs text-foreground hover:bg-muted disabled:opacity-40";
|
|
7586
7685
|
var TrackedChangesList = ({
|
|
7587
7686
|
editor,
|
|
@@ -7592,18 +7691,18 @@ var TrackedChangesList = ({
|
|
|
7592
7691
|
}) => {
|
|
7593
7692
|
const review = useTrackChanges(editor);
|
|
7594
7693
|
if (review.changes.length === 0) {
|
|
7595
|
-
return /* @__PURE__ */ (0,
|
|
7694
|
+
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 }) });
|
|
7596
7695
|
}
|
|
7597
|
-
return /* @__PURE__ */ (0,
|
|
7696
|
+
return /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("ul", { className, role: "list", "aria-label": "Tracked changes", "data-tracked-changes-list": "", children: review.changes.map((change) => {
|
|
7598
7697
|
const active = change.id === review.currentChangeId;
|
|
7599
|
-
return /* @__PURE__ */ (0,
|
|
7698
|
+
return /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(
|
|
7600
7699
|
"li",
|
|
7601
7700
|
{
|
|
7602
7701
|
className: active ? `${itemClassName} ${activeItemClassName}` : itemClassName,
|
|
7603
7702
|
"data-change-type": change.type,
|
|
7604
7703
|
"data-change-id": change.id,
|
|
7605
7704
|
children: [
|
|
7606
|
-
/* @__PURE__ */ (0,
|
|
7705
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(
|
|
7607
7706
|
"button",
|
|
7608
7707
|
{
|
|
7609
7708
|
type: "button",
|
|
@@ -7611,14 +7710,14 @@ var TrackedChangesList = ({
|
|
|
7611
7710
|
title: `${change.author.name}: ${change.description}`,
|
|
7612
7711
|
onClick: () => review.select(change.id),
|
|
7613
7712
|
children: [
|
|
7614
|
-
/* @__PURE__ */ (0,
|
|
7713
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)("span", { className: "font-medium", children: (0, import_editor15.trackedChangeLabel)(change) }),
|
|
7615
7714
|
change.author.name ? ` \xB7 ${change.author.name}` : "",
|
|
7616
|
-
/* @__PURE__ */ (0,
|
|
7715
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)("span", { className: "block truncate text-muted-foreground", children: change.description })
|
|
7617
7716
|
]
|
|
7618
7717
|
}
|
|
7619
7718
|
),
|
|
7620
|
-
/* @__PURE__ */ (0,
|
|
7621
|
-
/* @__PURE__ */ (0,
|
|
7719
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)("button", { type: "button", className: buttonClass4, onClick: () => review.accept(change.id), children: "Accept" }),
|
|
7720
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)("button", { type: "button", className: buttonClass4, onClick: () => review.reject(change.id), children: "Reject" })
|
|
7622
7721
|
]
|
|
7623
7722
|
},
|
|
7624
7723
|
`${change.type}:${change.id}`
|
|
@@ -7627,12 +7726,12 @@ var TrackedChangesList = ({
|
|
|
7627
7726
|
};
|
|
7628
7727
|
|
|
7629
7728
|
// src/commands/useCommandPalette.ts
|
|
7630
|
-
var
|
|
7729
|
+
var import_react51 = require("react");
|
|
7631
7730
|
var import_commands2 = require("@pixerate/editor/commands");
|
|
7632
7731
|
function useCommandPalette(registry, options = {}) {
|
|
7633
|
-
const optionsRef = (0,
|
|
7732
|
+
const optionsRef = (0, import_react51.useRef)(options);
|
|
7634
7733
|
optionsRef.current = options;
|
|
7635
|
-
const controller = (0,
|
|
7734
|
+
const controller = (0, import_react51.useMemo)(
|
|
7636
7735
|
() => (0, import_commands2.createCommandPaletteController)(registry, {
|
|
7637
7736
|
context: () => {
|
|
7638
7737
|
const c = optionsRef.current.context;
|
|
@@ -7653,9 +7752,9 @@ function useCommandPalette(registry, options = {}) {
|
|
|
7653
7752
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
7654
7753
|
[registry]
|
|
7655
7754
|
);
|
|
7656
|
-
const state = (0,
|
|
7755
|
+
const state = (0, import_react51.useSyncExternalStore)(controller.subscribe, controller.getState, controller.getState);
|
|
7657
7756
|
const { hotkey, hotkeyTarget } = options;
|
|
7658
|
-
(0,
|
|
7757
|
+
(0, import_react51.useEffect)(() => {
|
|
7659
7758
|
if (!hotkey) return;
|
|
7660
7759
|
const target = hotkeyTarget ?? (typeof window !== "undefined" ? window : null);
|
|
7661
7760
|
if (!target) return;
|
|
@@ -7683,13 +7782,13 @@ function useCommandPalette(registry, options = {}) {
|
|
|
7683
7782
|
}
|
|
7684
7783
|
|
|
7685
7784
|
// src/commands/CommandPalette.tsx
|
|
7686
|
-
var
|
|
7687
|
-
var
|
|
7785
|
+
var import_react52 = __toESM(require("react"), 1);
|
|
7786
|
+
var import_jsx_runtime35 = require("react/jsx-runtime");
|
|
7688
7787
|
function HighlightedLabel({ item }) {
|
|
7689
|
-
if (item.labelIndices.length === 0) return /* @__PURE__ */ (0,
|
|
7788
|
+
if (item.labelIndices.length === 0) return /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(import_jsx_runtime35.Fragment, { children: item.label });
|
|
7690
7789
|
const marked = new Set(item.labelIndices);
|
|
7691
|
-
return /* @__PURE__ */ (0,
|
|
7692
|
-
(ch, i) => marked.has(i) ? /* @__PURE__ */ (0,
|
|
7790
|
+
return /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(import_jsx_runtime35.Fragment, { children: Array.from(item.label).map(
|
|
7791
|
+
(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)
|
|
7693
7792
|
) });
|
|
7694
7793
|
}
|
|
7695
7794
|
var CommandPalette = ({
|
|
@@ -7698,22 +7797,22 @@ var CommandPalette = ({
|
|
|
7698
7797
|
emptyMessage = "No matching commands",
|
|
7699
7798
|
className = ""
|
|
7700
7799
|
}) => {
|
|
7701
|
-
const inputRef = (0,
|
|
7702
|
-
const listRef = (0,
|
|
7703
|
-
const baseId = (0,
|
|
7800
|
+
const inputRef = (0, import_react52.useRef)(null);
|
|
7801
|
+
const listRef = (0, import_react52.useRef)(null);
|
|
7802
|
+
const baseId = (0, import_react52.useId)();
|
|
7704
7803
|
const listId = `${baseId}-list`;
|
|
7705
7804
|
const optionId = (index) => `${baseId}-option-${index}`;
|
|
7706
7805
|
const { open, query, items, activeIndex } = palette;
|
|
7707
|
-
(0,
|
|
7806
|
+
(0, import_react52.useEffect)(() => {
|
|
7708
7807
|
if (open) inputRef.current?.focus();
|
|
7709
7808
|
}, [open]);
|
|
7710
|
-
(0,
|
|
7809
|
+
(0, import_react52.useEffect)(() => {
|
|
7711
7810
|
if (!open) return;
|
|
7712
7811
|
const active = listRef.current?.querySelector('[aria-selected="true"]');
|
|
7713
7812
|
active?.scrollIntoView?.({ block: "nearest" });
|
|
7714
7813
|
}, [open, activeIndex]);
|
|
7715
7814
|
if (!open) return null;
|
|
7716
|
-
return /* @__PURE__ */ (0,
|
|
7815
|
+
return /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
|
|
7717
7816
|
"div",
|
|
7718
7817
|
{
|
|
7719
7818
|
className: "fixed inset-0 z-50 flex items-start justify-center bg-black/30 px-4 pt-[15vh]",
|
|
@@ -7721,7 +7820,7 @@ var CommandPalette = ({
|
|
|
7721
7820
|
onMouseDown: (e) => {
|
|
7722
7821
|
if (e.target === e.currentTarget) palette.setOpen(false);
|
|
7723
7822
|
},
|
|
7724
|
-
children: /* @__PURE__ */ (0,
|
|
7823
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)(
|
|
7725
7824
|
"div",
|
|
7726
7825
|
{
|
|
7727
7826
|
role: "dialog",
|
|
@@ -7730,7 +7829,7 @@ var CommandPalette = ({
|
|
|
7730
7829
|
className: `w-full max-w-lg overflow-hidden rounded-lg border border-border bg-popover text-popover-foreground shadow-xl ${className}`,
|
|
7731
7830
|
style: { background: "var(--popover, var(--background, #fff))" },
|
|
7732
7831
|
children: [
|
|
7733
|
-
/* @__PURE__ */ (0,
|
|
7832
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
|
|
7734
7833
|
"input",
|
|
7735
7834
|
{
|
|
7736
7835
|
ref: inputRef,
|
|
@@ -7750,7 +7849,7 @@ var CommandPalette = ({
|
|
|
7750
7849
|
className: "w-full border-b border-border bg-transparent px-3 py-2 text-sm outline-none placeholder:text-muted-foreground"
|
|
7751
7850
|
}
|
|
7752
7851
|
),
|
|
7753
|
-
items.length === 0 ? /* @__PURE__ */ (0,
|
|
7852
|
+
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)(
|
|
7754
7853
|
"li",
|
|
7755
7854
|
{
|
|
7756
7855
|
id: optionId(index),
|
|
@@ -7765,12 +7864,12 @@ var CommandPalette = ({
|
|
|
7765
7864
|
onClick: () => palette.run(item.id),
|
|
7766
7865
|
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"}`,
|
|
7767
7866
|
children: [
|
|
7768
|
-
/* @__PURE__ */ (0,
|
|
7769
|
-
/* @__PURE__ */ (0,
|
|
7770
|
-
item.disabledReason && /* @__PURE__ */ (0,
|
|
7867
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("span", { className: "min-w-0 flex-1 truncate", children: [
|
|
7868
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsx)(HighlightedLabel, { item }),
|
|
7869
|
+
item.disabledReason && /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("span", { className: "ml-2 text-xs text-muted-foreground", "data-disabled-reason": "", children: item.disabledReason })
|
|
7771
7870
|
] }),
|
|
7772
|
-
item.group && /* @__PURE__ */ (0,
|
|
7773
|
-
item.shortcut && /* @__PURE__ */ (0,
|
|
7871
|
+
item.group && /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("span", { className: "shrink-0 text-xs text-muted-foreground", children: item.group }),
|
|
7872
|
+
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 })
|
|
7774
7873
|
]
|
|
7775
7874
|
},
|
|
7776
7875
|
item.id
|
|
@@ -7783,12 +7882,12 @@ var CommandPalette = ({
|
|
|
7783
7882
|
};
|
|
7784
7883
|
|
|
7785
7884
|
// src/commands/useCommandShortcuts.ts
|
|
7786
|
-
var
|
|
7885
|
+
var import_react53 = require("react");
|
|
7787
7886
|
function useCommandShortcuts(registry, options = {}) {
|
|
7788
|
-
const optionsRef = (0,
|
|
7887
|
+
const optionsRef = (0, import_react53.useRef)(options);
|
|
7789
7888
|
optionsRef.current = options;
|
|
7790
7889
|
const { enabled = true, target } = options;
|
|
7791
|
-
(0,
|
|
7890
|
+
(0, import_react53.useEffect)(() => {
|
|
7792
7891
|
if (!registry || !enabled) return;
|
|
7793
7892
|
const eventTarget = target ?? (typeof window !== "undefined" ? window : null);
|
|
7794
7893
|
if (!eventTarget) return;
|
|
@@ -7806,14 +7905,14 @@ function useCommandShortcuts(registry, options = {}) {
|
|
|
7806
7905
|
}, [registry, enabled, target]);
|
|
7807
7906
|
}
|
|
7808
7907
|
function useRegisterCommands(registry, specs) {
|
|
7809
|
-
(0,
|
|
7908
|
+
(0, import_react53.useEffect)(() => {
|
|
7810
7909
|
if (!registry || !specs || specs.length === 0) return;
|
|
7811
7910
|
return registry.register(specs);
|
|
7812
7911
|
}, [registry, specs]);
|
|
7813
7912
|
}
|
|
7814
7913
|
|
|
7815
7914
|
// src/persistence/useAutosave.ts
|
|
7816
|
-
var
|
|
7915
|
+
var import_react54 = require("react");
|
|
7817
7916
|
var import_persistence = require("@pixerate/editor/persistence");
|
|
7818
7917
|
var IDLE = {
|
|
7819
7918
|
status: "idle",
|
|
@@ -7824,18 +7923,18 @@ var IDLE = {
|
|
|
7824
7923
|
ready: false
|
|
7825
7924
|
};
|
|
7826
7925
|
function useAutosave(options) {
|
|
7827
|
-
const optionsRef = (0,
|
|
7926
|
+
const optionsRef = (0, import_react54.useRef)(options);
|
|
7828
7927
|
optionsRef.current = options;
|
|
7829
7928
|
const { storage, key, history, dirty } = options;
|
|
7830
7929
|
const recover = options.recover !== false;
|
|
7831
7930
|
const flushOnHide = options.flushOnHide !== false;
|
|
7832
7931
|
const ready = options.ready !== false;
|
|
7833
|
-
const [controller, setController] = (0,
|
|
7834
|
-
const [status, setStatus] = (0,
|
|
7835
|
-
const [recovery, setRecovery] = (0,
|
|
7836
|
-
const [pendingRecovery, setPendingRecovery] = (0,
|
|
7837
|
-
const revisionsRef = (0,
|
|
7838
|
-
(0,
|
|
7932
|
+
const [controller, setController] = (0, import_react54.useState)(null);
|
|
7933
|
+
const [status, setStatus] = (0, import_react54.useState)(IDLE);
|
|
7934
|
+
const [recovery, setRecovery] = (0, import_react54.useState)(null);
|
|
7935
|
+
const [pendingRecovery, setPendingRecovery] = (0, import_react54.useState)(recover);
|
|
7936
|
+
const revisionsRef = (0, import_react54.useRef)(null);
|
|
7937
|
+
(0, import_react54.useEffect)(() => {
|
|
7839
7938
|
const revisions = (0, import_persistence.createRevisionTracker)({ history, dirty });
|
|
7840
7939
|
const o = optionsRef.current;
|
|
7841
7940
|
const instance = (0, import_persistence.createAutosaveController)({
|
|
@@ -7878,10 +7977,10 @@ function useAutosave(options) {
|
|
|
7878
7977
|
if (revisionsRef.current === revisions) revisionsRef.current = null;
|
|
7879
7978
|
};
|
|
7880
7979
|
}, [storage, key, history, dirty, recover]);
|
|
7881
|
-
(0,
|
|
7980
|
+
(0, import_react54.useEffect)(() => {
|
|
7882
7981
|
if (controller && ready && !pendingRecovery) controller.ready();
|
|
7883
7982
|
}, [controller, ready, pendingRecovery]);
|
|
7884
|
-
(0,
|
|
7983
|
+
(0, import_react54.useEffect)(() => {
|
|
7885
7984
|
if (!controller || !flushOnHide || typeof window === "undefined") return;
|
|
7886
7985
|
const flush = () => void controller.flushNow();
|
|
7887
7986
|
const onVisibility = () => {
|
|
@@ -7894,31 +7993,31 @@ function useAutosave(options) {
|
|
|
7894
7993
|
document.removeEventListener("visibilitychange", onVisibility);
|
|
7895
7994
|
};
|
|
7896
7995
|
}, [controller, flushOnHide]);
|
|
7897
|
-
const restore = (0,
|
|
7996
|
+
const restore = (0, import_react54.useCallback)(() => {
|
|
7898
7997
|
const snapshot = recovery?.snapshot;
|
|
7899
7998
|
setRecovery(null);
|
|
7900
7999
|
setPendingRecovery(false);
|
|
7901
8000
|
return snapshot;
|
|
7902
8001
|
}, [recovery]);
|
|
7903
|
-
const discard = (0,
|
|
8002
|
+
const discard = (0, import_react54.useCallback)(async () => {
|
|
7904
8003
|
if (controller) await controller.discardRecovery();
|
|
7905
8004
|
setRecovery(null);
|
|
7906
8005
|
setPendingRecovery(false);
|
|
7907
8006
|
}, [controller]);
|
|
7908
|
-
const flushNow = (0,
|
|
8007
|
+
const flushNow = (0, import_react54.useCallback)(async () => {
|
|
7909
8008
|
await controller?.flushNow();
|
|
7910
8009
|
}, [controller]);
|
|
7911
|
-
const markClean = (0,
|
|
8010
|
+
const markClean = (0, import_react54.useCallback)(async () => {
|
|
7912
8011
|
revisionsRef.current?.markSaved();
|
|
7913
8012
|
await controller?.markClean();
|
|
7914
8013
|
}, [controller]);
|
|
7915
|
-
const notifyChange = (0,
|
|
8014
|
+
const notifyChange = (0, import_react54.useCallback)(() => revisionsRef.current?.bump(), []);
|
|
7916
8015
|
return { status, recovery, pendingRecovery, restore, discard, flushNow, markClean, notifyChange, controller };
|
|
7917
8016
|
}
|
|
7918
8017
|
|
|
7919
8018
|
// src/persistence/RecoveryPrompt.tsx
|
|
7920
8019
|
var import_persistence2 = require("@pixerate/editor/persistence");
|
|
7921
|
-
var
|
|
8020
|
+
var import_jsx_runtime36 = require("react/jsx-runtime");
|
|
7922
8021
|
var RecoveryPrompt = ({
|
|
7923
8022
|
recovery,
|
|
7924
8023
|
onRestore,
|
|
@@ -7930,7 +8029,7 @@ var RecoveryPrompt = ({
|
|
|
7930
8029
|
}) => {
|
|
7931
8030
|
if (!recovery) return null;
|
|
7932
8031
|
const { name } = recovery.meta;
|
|
7933
|
-
return /* @__PURE__ */ (0,
|
|
8032
|
+
return /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(
|
|
7934
8033
|
"div",
|
|
7935
8034
|
{
|
|
7936
8035
|
role: "alertdialog",
|
|
@@ -7938,15 +8037,15 @@ var RecoveryPrompt = ({
|
|
|
7938
8037
|
"data-recovery-prompt": "",
|
|
7939
8038
|
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}`,
|
|
7940
8039
|
children: [
|
|
7941
|
-
/* @__PURE__ */ (0,
|
|
8040
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("span", { className: "min-w-0 flex-1", children: [
|
|
7942
8041
|
(0, import_persistence2.formatRecoveryMessage)(recovery.meta, formatTime),
|
|
7943
|
-
name ? /* @__PURE__ */ (0,
|
|
8042
|
+
name ? /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("span", { className: "ml-1 text-xs text-muted-foreground", children: [
|
|
7944
8043
|
"(",
|
|
7945
8044
|
name,
|
|
7946
8045
|
")"
|
|
7947
8046
|
] }) : null
|
|
7948
8047
|
] }),
|
|
7949
|
-
/* @__PURE__ */ (0,
|
|
8048
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
7950
8049
|
"button",
|
|
7951
8050
|
{
|
|
7952
8051
|
type: "button",
|
|
@@ -7956,7 +8055,7 @@ var RecoveryPrompt = ({
|
|
|
7956
8055
|
children: restoreLabel
|
|
7957
8056
|
}
|
|
7958
8057
|
),
|
|
7959
|
-
/* @__PURE__ */ (0,
|
|
8058
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
7960
8059
|
"button",
|
|
7961
8060
|
{
|
|
7962
8061
|
type: "button",
|
|
@@ -7972,17 +8071,17 @@ var RecoveryPrompt = ({
|
|
|
7972
8071
|
};
|
|
7973
8072
|
|
|
7974
8073
|
// src/generation/useGenerationPlan.ts
|
|
7975
|
-
var
|
|
8074
|
+
var import_react55 = require("react");
|
|
7976
8075
|
var import_generation = require("@pixerate/editor/generation");
|
|
7977
8076
|
function useGenerationPlan(request, capabilities, options = {}) {
|
|
7978
8077
|
const key = JSON.stringify([request, capabilities, options]);
|
|
7979
|
-
return (0,
|
|
8078
|
+
return (0, import_react55.useMemo)(() => (0, import_generation.planGenerationRequest)(request, capabilities, options), [key]);
|
|
7980
8079
|
}
|
|
7981
8080
|
function useJobProgress(options) {
|
|
7982
8081
|
const { startedAt, expectedMs, done, now, intervalMs = 1e3 } = options;
|
|
7983
|
-
const [tick, setTick] = (0,
|
|
8082
|
+
const [tick, setTick] = (0, import_react55.useState)(() => Date.now());
|
|
7984
8083
|
const ticking = !done && now === void 0;
|
|
7985
|
-
(0,
|
|
8084
|
+
(0, import_react55.useEffect)(() => {
|
|
7986
8085
|
if (!ticking) return;
|
|
7987
8086
|
setTick(Date.now());
|
|
7988
8087
|
const id = setInterval(() => setTick(Date.now()), Math.max(16, intervalMs));
|
|
@@ -7992,9 +8091,9 @@ function useJobProgress(options) {
|
|
|
7992
8091
|
}
|
|
7993
8092
|
|
|
7994
8093
|
// src/generation/GenerationSettings.tsx
|
|
7995
|
-
var
|
|
8094
|
+
var import_react56 = require("react");
|
|
7996
8095
|
var import_generation2 = require("@pixerate/editor/generation");
|
|
7997
|
-
var
|
|
8096
|
+
var import_jsx_runtime37 = require("react/jsx-runtime");
|
|
7998
8097
|
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";
|
|
7999
8098
|
function Control({
|
|
8000
8099
|
control,
|
|
@@ -8004,7 +8103,7 @@ function Control({
|
|
|
8004
8103
|
}) {
|
|
8005
8104
|
const shown = value ?? control.defaultValue;
|
|
8006
8105
|
if (control.kind === "checkbox") {
|
|
8007
|
-
return /* @__PURE__ */ (0,
|
|
8106
|
+
return /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
|
|
8008
8107
|
"input",
|
|
8009
8108
|
{
|
|
8010
8109
|
id,
|
|
@@ -8016,7 +8115,7 @@ function Control({
|
|
|
8016
8115
|
);
|
|
8017
8116
|
}
|
|
8018
8117
|
if (control.kind === "select") {
|
|
8019
|
-
return /* @__PURE__ */ (0,
|
|
8118
|
+
return /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)(
|
|
8020
8119
|
"select",
|
|
8021
8120
|
{
|
|
8022
8121
|
id,
|
|
@@ -8025,14 +8124,14 @@ function Control({
|
|
|
8025
8124
|
value: shown === void 0 ? "" : String(shown),
|
|
8026
8125
|
onChange: (e) => onValue((0, import_generation2.parseControlValue)(control, e.target.value)),
|
|
8027
8126
|
children: [
|
|
8028
|
-
shown === void 0 && /* @__PURE__ */ (0,
|
|
8029
|
-
control.options.map((option) => /* @__PURE__ */ (0,
|
|
8127
|
+
shown === void 0 && /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("option", { value: "", children: "Default" }),
|
|
8128
|
+
control.options.map((option) => /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("option", { value: String(option.value), children: option.label }, String(option.value)))
|
|
8030
8129
|
]
|
|
8031
8130
|
}
|
|
8032
8131
|
);
|
|
8033
8132
|
}
|
|
8034
8133
|
if (control.kind === "textarea") {
|
|
8035
|
-
return /* @__PURE__ */ (0,
|
|
8134
|
+
return /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
|
|
8036
8135
|
"textarea",
|
|
8037
8136
|
{
|
|
8038
8137
|
id,
|
|
@@ -8046,8 +8145,8 @@ function Control({
|
|
|
8046
8145
|
);
|
|
8047
8146
|
}
|
|
8048
8147
|
const numeric = typeof shown === "number" ? shown : void 0;
|
|
8049
|
-
return /* @__PURE__ */ (0,
|
|
8050
|
-
/* @__PURE__ */ (0,
|
|
8148
|
+
return /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
8149
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
|
|
8051
8150
|
"input",
|
|
8052
8151
|
{
|
|
8053
8152
|
id,
|
|
@@ -8061,7 +8160,7 @@ function Control({
|
|
|
8061
8160
|
onChange: (e) => onValue((0, import_generation2.parseControlValue)(control, e.target.value))
|
|
8062
8161
|
}
|
|
8063
8162
|
),
|
|
8064
|
-
control.kind === "range" && /* @__PURE__ */ (0,
|
|
8163
|
+
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" })
|
|
8065
8164
|
] });
|
|
8066
8165
|
}
|
|
8067
8166
|
var GenerationSettings = ({
|
|
@@ -8075,17 +8174,17 @@ var GenerationSettings = ({
|
|
|
8075
8174
|
renderReference,
|
|
8076
8175
|
className = ""
|
|
8077
8176
|
}) => {
|
|
8078
|
-
const baseId = (0,
|
|
8079
|
-
const controls = (0,
|
|
8177
|
+
const baseId = (0, import_react56.useId)();
|
|
8178
|
+
const controls = (0, import_react56.useMemo)(() => (0, import_generation2.getGenerationControls)(capabilities), [capabilities]);
|
|
8080
8179
|
const computed = useGenerationPlan(value, capabilities, { strategy });
|
|
8081
8180
|
const plan = planProp ?? computed;
|
|
8082
8181
|
const slots = (0, import_generation2.getReferenceSlots)(capabilities, value);
|
|
8083
|
-
return /* @__PURE__ */ (0,
|
|
8182
|
+
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: [
|
|
8084
8183
|
controls.map((control) => {
|
|
8085
8184
|
const id = `${baseId}-${control.key}`;
|
|
8086
|
-
return /* @__PURE__ */ (0,
|
|
8087
|
-
/* @__PURE__ */ (0,
|
|
8088
|
-
/* @__PURE__ */ (0,
|
|
8185
|
+
return /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("div", { className: "flex flex-col gap-1", "data-control": control.key, children: [
|
|
8186
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsx)("label", { htmlFor: id, className: "text-xs font-medium text-muted-foreground", title: control.description, children: control.label }),
|
|
8187
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
|
|
8089
8188
|
Control,
|
|
8090
8189
|
{
|
|
8091
8190
|
control,
|
|
@@ -8096,23 +8195,23 @@ var GenerationSettings = ({
|
|
|
8096
8195
|
)
|
|
8097
8196
|
] }, control.key);
|
|
8098
8197
|
}),
|
|
8099
|
-
slots.map((slot) => /* @__PURE__ */ (0,
|
|
8100
|
-
/* @__PURE__ */ (0,
|
|
8198
|
+
slots.map((slot) => /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("fieldset", { className: "flex flex-col gap-1", "data-reference-role": slot.role, children: [
|
|
8199
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("legend", { className: "text-xs font-medium text-muted-foreground", title: slot.description, children: [
|
|
8101
8200
|
slot.label,
|
|
8102
8201
|
" ",
|
|
8103
|
-
/* @__PURE__ */ (0,
|
|
8202
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("span", { className: "tabular-nums", "data-reference-count": "", children: [
|
|
8104
8203
|
"(",
|
|
8105
8204
|
slot.references.length,
|
|
8106
8205
|
"/",
|
|
8107
8206
|
slot.max,
|
|
8108
8207
|
")"
|
|
8109
8208
|
] }),
|
|
8110
|
-
slot.min > 0 && /* @__PURE__ */ (0,
|
|
8209
|
+
slot.min > 0 && /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("span", { className: "text-destructive", children: " *" })
|
|
8111
8210
|
] }),
|
|
8112
|
-
/* @__PURE__ */ (0,
|
|
8113
|
-
slot.references.map((ref) => /* @__PURE__ */ (0,
|
|
8114
|
-
renderReference ? renderReference(ref) : /* @__PURE__ */ (0,
|
|
8115
|
-
/* @__PURE__ */ (0,
|
|
8211
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("ul", { className: "flex flex-wrap gap-1", children: [
|
|
8212
|
+
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: [
|
|
8213
|
+
renderReference ? renderReference(ref) : /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("span", { className: "max-w-[10rem] truncate", children: ref.id }),
|
|
8214
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
|
|
8116
8215
|
"button",
|
|
8117
8216
|
{
|
|
8118
8217
|
type: "button",
|
|
@@ -8123,7 +8222,7 @@ var GenerationSettings = ({
|
|
|
8123
8222
|
}
|
|
8124
8223
|
)
|
|
8125
8224
|
] }, ref.id)),
|
|
8126
|
-
onAddReference && slot.canAdd && /* @__PURE__ */ (0,
|
|
8225
|
+
onAddReference && slot.canAdd && /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("li", { children: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
|
|
8127
8226
|
"button",
|
|
8128
8227
|
{
|
|
8129
8228
|
type: "button",
|
|
@@ -8134,21 +8233,21 @@ var GenerationSettings = ({
|
|
|
8134
8233
|
) })
|
|
8135
8234
|
] })
|
|
8136
8235
|
] }, slot.role)),
|
|
8137
|
-
showAdjustments && plan.adjustments.length > 0 && /* @__PURE__ */ (0,
|
|
8138
|
-
showAdjustments && plan.errors.length > 0 && /* @__PURE__ */ (0,
|
|
8236
|
+
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)) }),
|
|
8237
|
+
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)) })
|
|
8139
8238
|
] });
|
|
8140
8239
|
};
|
|
8141
8240
|
|
|
8142
8241
|
// src/generation/JobProgress.tsx
|
|
8143
|
-
var
|
|
8242
|
+
var import_jsx_runtime38 = require("react/jsx-runtime");
|
|
8144
8243
|
var JobProgress = ({ title, className = "", ...options }) => {
|
|
8145
8244
|
const progress = useJobProgress(options);
|
|
8146
|
-
return /* @__PURE__ */ (0,
|
|
8147
|
-
/* @__PURE__ */ (0,
|
|
8148
|
-
title && /* @__PURE__ */ (0,
|
|
8149
|
-
/* @__PURE__ */ (0,
|
|
8245
|
+
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: [
|
|
8246
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsxs)("div", { className: "flex items-center justify-between gap-2 text-muted-foreground", children: [
|
|
8247
|
+
title && /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("span", { className: "truncate text-foreground", children: title }),
|
|
8248
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)("span", { "data-job-progress-label": "", "aria-live": "polite", children: progress.label })
|
|
8150
8249
|
] }),
|
|
8151
|
-
/* @__PURE__ */ (0,
|
|
8250
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
|
|
8152
8251
|
"div",
|
|
8153
8252
|
{
|
|
8154
8253
|
role: "progressbar",
|
|
@@ -8158,7 +8257,7 @@ var JobProgress = ({ title, className = "", ...options }) => {
|
|
|
8158
8257
|
"aria-valuenow": progress.percent,
|
|
8159
8258
|
"aria-valuetext": `${progress.percent}%, ${progress.label}`,
|
|
8160
8259
|
className: "h-1.5 w-full overflow-hidden rounded-full bg-muted",
|
|
8161
|
-
children: /* @__PURE__ */ (0,
|
|
8260
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
|
|
8162
8261
|
"div",
|
|
8163
8262
|
{
|
|
8164
8263
|
className: "h-full rounded-full bg-primary transition-[width] duration-500",
|
|
@@ -8171,9 +8270,9 @@ var JobProgress = ({ title, className = "", ...options }) => {
|
|
|
8171
8270
|
};
|
|
8172
8271
|
|
|
8173
8272
|
// src/generation/AssetMentionChips.tsx
|
|
8174
|
-
var
|
|
8273
|
+
var import_react57 = require("react");
|
|
8175
8274
|
var import_generation3 = require("@pixerate/editor/generation");
|
|
8176
|
-
var
|
|
8275
|
+
var import_jsx_runtime39 = require("react/jsx-runtime");
|
|
8177
8276
|
var AssetMentionChips = ({
|
|
8178
8277
|
content,
|
|
8179
8278
|
onChange,
|
|
@@ -8183,14 +8282,14 @@ var AssetMentionChips = ({
|
|
|
8183
8282
|
renderAsset,
|
|
8184
8283
|
className = ""
|
|
8185
8284
|
}) => {
|
|
8186
|
-
const [open, setOpen] = (0,
|
|
8187
|
-
const rootRef = (0,
|
|
8188
|
-
const chips = (0,
|
|
8285
|
+
const [open, setOpen] = (0, import_react57.useState)(null);
|
|
8286
|
+
const rootRef = (0, import_react57.useRef)(null);
|
|
8287
|
+
const chips = (0, import_react57.useMemo)(
|
|
8189
8288
|
() => (0, import_generation3.describeAssetMentions)((0, import_generation3.findTextMentions)(content), assets, capabilities),
|
|
8190
8289
|
[content, assets, capabilities]
|
|
8191
8290
|
);
|
|
8192
8291
|
const options = roles ?? (capabilities ? (0, import_generation3.getAssetRoleOptions)(capabilities) : (0, import_generation3.defaultAssetRoleOptions)());
|
|
8193
|
-
(0,
|
|
8292
|
+
(0, import_react57.useEffect)(() => {
|
|
8194
8293
|
if (open === null) return;
|
|
8195
8294
|
const onPointer = (event) => {
|
|
8196
8295
|
if (!rootRef.current?.contains(event.target)) setOpen(null);
|
|
@@ -8198,19 +8297,19 @@ var AssetMentionChips = ({
|
|
|
8198
8297
|
document.addEventListener("mousedown", onPointer);
|
|
8199
8298
|
return () => document.removeEventListener("mousedown", onPointer);
|
|
8200
8299
|
}, [open]);
|
|
8201
|
-
const pick = (
|
|
8300
|
+
const pick = (chip6, role) => {
|
|
8202
8301
|
setOpen(null);
|
|
8203
|
-
if (
|
|
8204
|
-
onChange((0, import_generation3.setMentionRoleInText)(content,
|
|
8302
|
+
if (chip6.start === void 0) return;
|
|
8303
|
+
onChange((0, import_generation3.setMentionRoleInText)(content, chip6.start, role));
|
|
8205
8304
|
};
|
|
8206
8305
|
if (chips.length === 0) return null;
|
|
8207
|
-
return /* @__PURE__ */ (0,
|
|
8208
|
-
const error =
|
|
8209
|
-
const warning =
|
|
8306
|
+
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) => {
|
|
8307
|
+
const error = chip6.issues.find((issue) => issue.severity === "error");
|
|
8308
|
+
const warning = chip6.issues.find((issue) => issue.severity === "warning");
|
|
8210
8309
|
const problem = error ?? warning;
|
|
8211
|
-
const isOpen = open ===
|
|
8212
|
-
return /* @__PURE__ */ (0,
|
|
8213
|
-
/* @__PURE__ */ (0,
|
|
8310
|
+
const isOpen = open === chip6.index;
|
|
8311
|
+
return /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("span", { className: "relative inline-flex", "data-asset-chip": chip6.asset.id, children: [
|
|
8312
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsxs)(
|
|
8214
8313
|
"button",
|
|
8215
8314
|
{
|
|
8216
8315
|
type: "button",
|
|
@@ -8218,82 +8317,82 @@ var AssetMentionChips = ({
|
|
|
8218
8317
|
"aria-expanded": isOpen,
|
|
8219
8318
|
title: problem?.message,
|
|
8220
8319
|
"data-issue": problem?.code,
|
|
8221
|
-
onClick: () => setOpen(isOpen ? null :
|
|
8320
|
+
onClick: () => setOpen(isOpen ? null : chip6.index),
|
|
8222
8321
|
onKeyDown: (e) => {
|
|
8223
8322
|
if (e.key === "Escape") setOpen(null);
|
|
8224
8323
|
},
|
|
8225
8324
|
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`,
|
|
8226
8325
|
children: [
|
|
8227
|
-
/* @__PURE__ */ (0,
|
|
8228
|
-
/* @__PURE__ */ (0,
|
|
8326
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsx)("span", { children: renderAsset ? renderAsset(chip6) : `@${chip6.asset.label ?? chip6.handle}` }),
|
|
8327
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
|
|
8229
8328
|
"span",
|
|
8230
8329
|
{
|
|
8231
|
-
className: `rounded px-1 text-[10px] uppercase tracking-wide ${
|
|
8232
|
-
"data-role-badge":
|
|
8233
|
-
children:
|
|
8330
|
+
className: `rounded px-1 text-[10px] uppercase tracking-wide ${chip6.role ? "bg-primary/15" : "opacity-60"}`,
|
|
8331
|
+
"data-role-badge": chip6.role ?? "",
|
|
8332
|
+
children: chip6.roleLabel ?? "No role"
|
|
8234
8333
|
}
|
|
8235
8334
|
)
|
|
8236
8335
|
]
|
|
8237
8336
|
}
|
|
8238
8337
|
),
|
|
8239
|
-
isOpen && /* @__PURE__ */ (0,
|
|
8338
|
+
isOpen && /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)(
|
|
8240
8339
|
"div",
|
|
8241
8340
|
{
|
|
8242
8341
|
role: "listbox",
|
|
8243
|
-
"aria-label": `Role for ${
|
|
8342
|
+
"aria-label": `Role for ${chip6.asset.label ?? chip6.handle}`,
|
|
8244
8343
|
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",
|
|
8245
8344
|
"data-role-picker": "",
|
|
8246
8345
|
onKeyDown: (e) => {
|
|
8247
8346
|
if (e.key === "Escape") setOpen(null);
|
|
8248
8347
|
},
|
|
8249
8348
|
children: [
|
|
8250
|
-
options.map((option) => /* @__PURE__ */ (0,
|
|
8349
|
+
options.map((option) => /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)(
|
|
8251
8350
|
"button",
|
|
8252
8351
|
{
|
|
8253
8352
|
type: "button",
|
|
8254
8353
|
role: "option",
|
|
8255
|
-
"aria-selected":
|
|
8354
|
+
"aria-selected": chip6.role === option.role,
|
|
8256
8355
|
"data-role-option": option.role,
|
|
8257
8356
|
title: option.description,
|
|
8258
|
-
onClick: () => pick(
|
|
8357
|
+
onClick: () => pick(chip6, option.role),
|
|
8259
8358
|
className: "flex items-center justify-between gap-2 rounded px-2 py-1 text-left hover:bg-muted",
|
|
8260
8359
|
children: [
|
|
8261
|
-
/* @__PURE__ */ (0,
|
|
8262
|
-
option.accepts?.length ? /* @__PURE__ */ (0,
|
|
8360
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsx)("span", { children: option.label }),
|
|
8361
|
+
option.accepts?.length ? /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("span", { className: "text-[10px] opacity-60", children: option.accepts.join(", ") }) : null
|
|
8263
8362
|
]
|
|
8264
8363
|
},
|
|
8265
8364
|
option.role
|
|
8266
8365
|
)),
|
|
8267
|
-
/* @__PURE__ */ (0,
|
|
8366
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
|
|
8268
8367
|
"button",
|
|
8269
8368
|
{
|
|
8270
8369
|
type: "button",
|
|
8271
8370
|
role: "option",
|
|
8272
|
-
"aria-selected": !
|
|
8371
|
+
"aria-selected": !chip6.role,
|
|
8273
8372
|
"data-role-option": "",
|
|
8274
|
-
onClick: () => pick(
|
|
8373
|
+
onClick: () => pick(chip6, null),
|
|
8275
8374
|
className: "rounded px-2 py-1 text-left opacity-70 hover:bg-muted",
|
|
8276
8375
|
children: "No role"
|
|
8277
8376
|
}
|
|
8278
8377
|
),
|
|
8279
|
-
|
|
8378
|
+
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)) })
|
|
8280
8379
|
]
|
|
8281
8380
|
}
|
|
8282
8381
|
)
|
|
8283
|
-
] }, `${
|
|
8382
|
+
] }, `${chip6.start}-${chip6.index}`);
|
|
8284
8383
|
}) });
|
|
8285
8384
|
};
|
|
8286
8385
|
|
|
8287
8386
|
// src/generation/GenerationHistory.tsx
|
|
8288
|
-
var
|
|
8387
|
+
var import_react58 = require("react");
|
|
8289
8388
|
var import_generation4 = require("@pixerate/editor/generation");
|
|
8290
|
-
var
|
|
8389
|
+
var import_jsx_runtime40 = require("react/jsx-runtime");
|
|
8291
8390
|
function useGenerationRecords(store, filter) {
|
|
8292
|
-
const [records, setRecords] = (0,
|
|
8293
|
-
const [loading, setLoading] = (0,
|
|
8294
|
-
const [error, setError] = (0,
|
|
8391
|
+
const [records, setRecords] = (0, import_react58.useState)([]);
|
|
8392
|
+
const [loading, setLoading] = (0, import_react58.useState)(!!store);
|
|
8393
|
+
const [error, setError] = (0, import_react58.useState)(null);
|
|
8295
8394
|
const filterKey = (0, import_generation4.stableStringify)(filter ?? {});
|
|
8296
|
-
const refresh = (0,
|
|
8395
|
+
const refresh = (0, import_react58.useCallback)(async () => {
|
|
8297
8396
|
if (!store) {
|
|
8298
8397
|
setRecords([]);
|
|
8299
8398
|
setLoading(false);
|
|
@@ -8310,7 +8409,7 @@ function useGenerationRecords(store, filter) {
|
|
|
8310
8409
|
setLoading(false);
|
|
8311
8410
|
}
|
|
8312
8411
|
}, [store, filterKey]);
|
|
8313
|
-
(0,
|
|
8412
|
+
(0, import_react58.useEffect)(() => {
|
|
8314
8413
|
void refresh();
|
|
8315
8414
|
if (!store) return;
|
|
8316
8415
|
return store.subscribe(() => void refresh());
|
|
@@ -8336,21 +8435,21 @@ var GenerationHistory = ({
|
|
|
8336
8435
|
emptyText = "No generations yet.",
|
|
8337
8436
|
className = ""
|
|
8338
8437
|
}) => {
|
|
8339
|
-
const [innerMode, setInnerMode] = (0,
|
|
8438
|
+
const [innerMode, setInnerMode] = (0, import_react58.useState)("exact");
|
|
8340
8439
|
const mode = modeProp ?? innerMode;
|
|
8341
8440
|
const setMode = (next) => {
|
|
8342
8441
|
if (modeProp === void 0) setInnerMode(next);
|
|
8343
8442
|
onModeChange?.(next);
|
|
8344
8443
|
};
|
|
8345
|
-
const options = (0,
|
|
8346
|
-
const results = (0,
|
|
8347
|
-
const models = (0,
|
|
8444
|
+
const options = (0, import_react58.useMemo)(() => ({ templates, capabilities, assets, mode }), [templates, capabilities, assets, mode]);
|
|
8445
|
+
const results = (0, import_react58.useMemo)(() => records.map((record) => (0, import_generation4.recreateRequest)(record, options)), [records, options]);
|
|
8446
|
+
const models = (0, import_react58.useMemo)(
|
|
8348
8447
|
() => capabilities ? Array.isArray(capabilities) ? capabilities : [capabilities] : [],
|
|
8349
8448
|
[capabilities]
|
|
8350
8449
|
);
|
|
8351
|
-
return /* @__PURE__ */ (0,
|
|
8352
|
-
/* @__PURE__ */ (0,
|
|
8353
|
-
/* @__PURE__ */ (0,
|
|
8450
|
+
return /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)("div", { className: `flex flex-col gap-2 text-sm ${className}`, "data-generation-history": "", children: [
|
|
8451
|
+
/* @__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: [
|
|
8452
|
+
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
|
|
8354
8453
|
"input",
|
|
8355
8454
|
{
|
|
8356
8455
|
type: "radio",
|
|
@@ -8363,34 +8462,34 @@ var GenerationHistory = ({
|
|
|
8363
8462
|
),
|
|
8364
8463
|
value === "exact" ? "Exact (recorded versions)" : "Latest templates & settings"
|
|
8365
8464
|
] }, value)) }),
|
|
8366
|
-
records.length === 0 && /* @__PURE__ */ (0,
|
|
8367
|
-
/* @__PURE__ */ (0,
|
|
8465
|
+
records.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("p", { className: "text-xs text-muted-foreground", children: emptyText }),
|
|
8466
|
+
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)("ul", { className: "flex flex-col gap-2", children: records.map((record, i) => {
|
|
8368
8467
|
const result = results[i];
|
|
8369
8468
|
const model = models.find((m) => m.id === record.provenance.modelId);
|
|
8370
8469
|
const blocked = !result.ok;
|
|
8371
|
-
return /* @__PURE__ */ (0,
|
|
8470
|
+
return /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(
|
|
8372
8471
|
"li",
|
|
8373
8472
|
{
|
|
8374
8473
|
className: "rounded-md border border-border p-2",
|
|
8375
8474
|
"data-record": record.id,
|
|
8376
8475
|
"data-drift": result.drift.length,
|
|
8377
8476
|
children: [
|
|
8378
|
-
/* @__PURE__ */ (0,
|
|
8379
|
-
/* @__PURE__ */ (0,
|
|
8380
|
-
/* @__PURE__ */ (0,
|
|
8381
|
-
record.kind !== "generate" && /* @__PURE__ */ (0,
|
|
8477
|
+
/* @__PURE__ */ (0, import_jsx_runtime40.jsxs)("div", { className: "flex flex-wrap items-center justify-between gap-2 text-xs", children: [
|
|
8478
|
+
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)("span", { className: "font-medium", children: model?.name ?? record.provenance.modelId }),
|
|
8479
|
+
/* @__PURE__ */ (0, import_jsx_runtime40.jsxs)("span", { className: "text-muted-foreground", children: [
|
|
8480
|
+
record.kind !== "generate" && /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)("span", { "data-kind": "", children: [
|
|
8382
8481
|
record.kind,
|
|
8383
8482
|
" \xB7 "
|
|
8384
8483
|
] }),
|
|
8385
|
-
/* @__PURE__ */ (0,
|
|
8386
|
-
record.seed !== void 0 && /* @__PURE__ */ (0,
|
|
8484
|
+
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)("time", { dateTime: record.createdAt, children: record.createdAt.replace("T", " ").slice(0, 16) }),
|
|
8485
|
+
record.seed !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(import_jsx_runtime40.Fragment, { children: [
|
|
8387
8486
|
" \xB7 seed ",
|
|
8388
8487
|
record.seed
|
|
8389
8488
|
] })
|
|
8390
8489
|
] })
|
|
8391
8490
|
] }),
|
|
8392
|
-
/* @__PURE__ */ (0,
|
|
8393
|
-
record.assets.length > 0 && /* @__PURE__ */ (0,
|
|
8491
|
+
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)("p", { className: "mt-1 line-clamp-3 break-words text-xs", "data-record-prompt": "", children: record.provenance.resolvedPrompt }),
|
|
8492
|
+
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)(
|
|
8394
8493
|
"span",
|
|
8395
8494
|
{
|
|
8396
8495
|
className: "rounded-full bg-muted px-2 py-0.5 text-[10px]",
|
|
@@ -8404,16 +8503,16 @@ var GenerationHistory = ({
|
|
|
8404
8503
|
`${asset.role}:${asset.id}`
|
|
8405
8504
|
)) }),
|
|
8406
8505
|
renderPreview?.(record),
|
|
8407
|
-
result.drift.length > 0 && /* @__PURE__ */ (0,
|
|
8408
|
-
/* @__PURE__ */ (0,
|
|
8506
|
+
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: [
|
|
8507
|
+
/* @__PURE__ */ (0, import_jsx_runtime40.jsxs)("strong", { children: [
|
|
8409
8508
|
import_generation4.DRIFT_TYPE_LABELS[item.type],
|
|
8410
8509
|
":"
|
|
8411
8510
|
] }),
|
|
8412
8511
|
" ",
|
|
8413
8512
|
item.message
|
|
8414
8513
|
] }, j)) }),
|
|
8415
|
-
/* @__PURE__ */ (0,
|
|
8416
|
-
onRecreate && /* @__PURE__ */ (0,
|
|
8514
|
+
/* @__PURE__ */ (0, import_jsx_runtime40.jsxs)("div", { className: "mt-2 flex gap-2", children: [
|
|
8515
|
+
onRecreate && /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
|
|
8417
8516
|
"button",
|
|
8418
8517
|
{
|
|
8419
8518
|
type: "button",
|
|
@@ -8425,7 +8524,7 @@ var GenerationHistory = ({
|
|
|
8425
8524
|
children: "Recreate"
|
|
8426
8525
|
}
|
|
8427
8526
|
),
|
|
8428
|
-
onVariation && /* @__PURE__ */ (0,
|
|
8527
|
+
onVariation && /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
|
|
8429
8528
|
"button",
|
|
8430
8529
|
{
|
|
8431
8530
|
type: "button",
|
|
@@ -8435,7 +8534,7 @@ var GenerationHistory = ({
|
|
|
8435
8534
|
children: "Variation"
|
|
8436
8535
|
}
|
|
8437
8536
|
),
|
|
8438
|
-
onRemove && /* @__PURE__ */ (0,
|
|
8537
|
+
onRemove && /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
|
|
8439
8538
|
"button",
|
|
8440
8539
|
{
|
|
8441
8540
|
type: "button",
|
|
@@ -8455,19 +8554,19 @@ var GenerationHistory = ({
|
|
|
8455
8554
|
};
|
|
8456
8555
|
|
|
8457
8556
|
// src/find-replace/useFindReplace.ts
|
|
8458
|
-
var
|
|
8557
|
+
var import_react59 = require("react");
|
|
8459
8558
|
var import_editor16 = require("@pixerate/editor");
|
|
8460
8559
|
var noopUnsubscribe2 = () => {
|
|
8461
8560
|
};
|
|
8462
8561
|
function useFindReplace(editor) {
|
|
8463
8562
|
const store = (0, import_editor16.getFindReplaceStore)(editor ?? null);
|
|
8464
|
-
const subscribe = (0,
|
|
8563
|
+
const subscribe = (0, import_react59.useCallback)(
|
|
8465
8564
|
(onChange) => store ? store.subscribe(() => onChange()) : noopUnsubscribe2,
|
|
8466
8565
|
[store]
|
|
8467
8566
|
);
|
|
8468
8567
|
const getSnapshot = () => store?.getSnapshot() ?? import_editor16.EMPTY_FIND_REPLACE_SNAPSHOT;
|
|
8469
|
-
const snapshot = (0,
|
|
8470
|
-
return (0,
|
|
8568
|
+
const snapshot = (0, import_react59.useSyncExternalStore)(subscribe, getSnapshot, getSnapshot);
|
|
8569
|
+
return (0, import_react59.useMemo)(() => {
|
|
8471
8570
|
const run = (fn) => {
|
|
8472
8571
|
if (editor && !editor.isDestroyed && store) fn(editor);
|
|
8473
8572
|
};
|
|
@@ -8491,9 +8590,9 @@ function useFindReplace(editor) {
|
|
|
8491
8590
|
}
|
|
8492
8591
|
|
|
8493
8592
|
// src/find-replace/FindReplaceBar.tsx
|
|
8494
|
-
var
|
|
8593
|
+
var import_react60 = require("react");
|
|
8495
8594
|
var import_editor17 = require("@pixerate/editor");
|
|
8496
|
-
var
|
|
8595
|
+
var import_jsx_runtime41 = require("react/jsx-runtime");
|
|
8497
8596
|
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";
|
|
8498
8597
|
var buttonClass5 = "rounded px-2 py-1 text-xs text-foreground hover:bg-muted disabled:opacity-40 disabled:hover:bg-transparent";
|
|
8499
8598
|
var toggleClass = (on) => `${buttonClass5} font-mono ${on ? "bg-primary/10 text-primary" : "text-muted-foreground"}`;
|
|
@@ -8506,10 +8605,10 @@ var FindReplaceBar = ({
|
|
|
8506
8605
|
onClose
|
|
8507
8606
|
}) => {
|
|
8508
8607
|
const find = useFindReplace(editor);
|
|
8509
|
-
const findInput = (0,
|
|
8510
|
-
const [moreOpen, setMoreOpen] = (0,
|
|
8608
|
+
const findInput = (0, import_react60.useRef)(null);
|
|
8609
|
+
const [moreOpen, setMoreOpen] = (0, import_react60.useState)(false);
|
|
8511
8610
|
const visible = find.available && (alwaysOpen || find.open);
|
|
8512
|
-
(0,
|
|
8611
|
+
(0, import_react60.useEffect)(() => {
|
|
8513
8612
|
if (!visible || find.focusRequest === 0) return;
|
|
8514
8613
|
findInput.current?.focus();
|
|
8515
8614
|
findInput.current?.select();
|
|
@@ -8547,9 +8646,9 @@ var FindReplaceBar = ({
|
|
|
8547
8646
|
if (isMod(e)) find.replaceAll();
|
|
8548
8647
|
else find.replace();
|
|
8549
8648
|
};
|
|
8550
|
-
return /* @__PURE__ */ (0,
|
|
8551
|
-
/* @__PURE__ */ (0,
|
|
8552
|
-
/* @__PURE__ */ (0,
|
|
8649
|
+
return /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("div", { className, role: "search", "aria-label": "Find and replace", onKeyDown: onBarKeyDown, children: [
|
|
8650
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("div", { className: "flex items-center gap-1", children: [
|
|
8651
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
|
|
8553
8652
|
"button",
|
|
8554
8653
|
{
|
|
8555
8654
|
type: "button",
|
|
@@ -8560,7 +8659,7 @@ var FindReplaceBar = ({
|
|
|
8560
8659
|
children: showReplace ? "\u25BE" : "\u25B8"
|
|
8561
8660
|
}
|
|
8562
8661
|
),
|
|
8563
|
-
/* @__PURE__ */ (0,
|
|
8662
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
|
|
8564
8663
|
"input",
|
|
8565
8664
|
{
|
|
8566
8665
|
ref: findInput,
|
|
@@ -8574,7 +8673,7 @@ var FindReplaceBar = ({
|
|
|
8574
8673
|
onKeyDown: onFindKeyDown
|
|
8575
8674
|
}
|
|
8576
8675
|
),
|
|
8577
|
-
import_editor17.FIND_OPTION_TOGGLES.filter((t) => !t.advanced).map((t) => /* @__PURE__ */ (0,
|
|
8676
|
+
import_editor17.FIND_OPTION_TOGGLES.filter((t) => !t.advanced).map((t) => /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
|
|
8578
8677
|
"button",
|
|
8579
8678
|
{
|
|
8580
8679
|
type: "button",
|
|
@@ -8587,7 +8686,7 @@ var FindReplaceBar = ({
|
|
|
8587
8686
|
},
|
|
8588
8687
|
t.key
|
|
8589
8688
|
)),
|
|
8590
|
-
/* @__PURE__ */ (0,
|
|
8689
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
|
|
8591
8690
|
"span",
|
|
8592
8691
|
{
|
|
8593
8692
|
className: `min-w-[5rem] px-1 text-center text-xs ${find.error ? "text-destructive" : "text-muted-foreground"}`,
|
|
@@ -8597,9 +8696,9 @@ var FindReplaceBar = ({
|
|
|
8597
8696
|
children: status
|
|
8598
8697
|
}
|
|
8599
8698
|
),
|
|
8600
|
-
/* @__PURE__ */ (0,
|
|
8601
|
-
/* @__PURE__ */ (0,
|
|
8602
|
-
showMoreOptions && /* @__PURE__ */ (0,
|
|
8699
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)("button", { type: "button", className: buttonClass5, "aria-label": "Previous match", disabled: !hasMatches, onClick: find.previous, children: "\u2191" }),
|
|
8700
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)("button", { type: "button", className: buttonClass5, "aria-label": "Next match", disabled: !hasMatches, onClick: find.next, children: "\u2193" }),
|
|
8701
|
+
showMoreOptions && /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
|
|
8603
8702
|
"button",
|
|
8604
8703
|
{
|
|
8605
8704
|
type: "button",
|
|
@@ -8610,10 +8709,10 @@ var FindReplaceBar = ({
|
|
|
8610
8709
|
children: "\u2026"
|
|
8611
8710
|
}
|
|
8612
8711
|
),
|
|
8613
|
-
/* @__PURE__ */ (0,
|
|
8712
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)("button", { type: "button", className: buttonClass5, "aria-label": "Close find", onClick: close, children: "\xD7" })
|
|
8614
8713
|
] }),
|
|
8615
|
-
showReplace && /* @__PURE__ */ (0,
|
|
8616
|
-
/* @__PURE__ */ (0,
|
|
8714
|
+
showReplace && /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("div", { className: "flex items-center gap-1 pl-7", children: [
|
|
8715
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
|
|
8617
8716
|
"input",
|
|
8618
8717
|
{
|
|
8619
8718
|
type: "text",
|
|
@@ -8625,7 +8724,7 @@ var FindReplaceBar = ({
|
|
|
8625
8724
|
onKeyDown: onReplaceKeyDown
|
|
8626
8725
|
}
|
|
8627
8726
|
),
|
|
8628
|
-
/* @__PURE__ */ (0,
|
|
8727
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
|
|
8629
8728
|
"button",
|
|
8630
8729
|
{
|
|
8631
8730
|
type: "button",
|
|
@@ -8635,11 +8734,11 @@ var FindReplaceBar = ({
|
|
|
8635
8734
|
children: "Replace"
|
|
8636
8735
|
}
|
|
8637
8736
|
),
|
|
8638
|
-
/* @__PURE__ */ (0,
|
|
8639
|
-
find.lastReplaceCount !== null && /* @__PURE__ */ (0,
|
|
8737
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)("button", { type: "button", className: buttonClass5, disabled: !hasMatches, onClick: find.replaceAll, children: "Replace all" }),
|
|
8738
|
+
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` })
|
|
8640
8739
|
] }),
|
|
8641
|
-
showMoreOptions && moreOpen && /* @__PURE__ */ (0,
|
|
8642
|
-
/* @__PURE__ */ (0,
|
|
8740
|
+
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: [
|
|
8741
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
|
|
8643
8742
|
"input",
|
|
8644
8743
|
{
|
|
8645
8744
|
type: "checkbox",
|
|
@@ -8653,12 +8752,12 @@ var FindReplaceBar = ({
|
|
|
8653
8752
|
};
|
|
8654
8753
|
|
|
8655
8754
|
// src/tables/useTableMenu.ts
|
|
8656
|
-
var
|
|
8755
|
+
var import_react61 = require("react");
|
|
8657
8756
|
var import_editor18 = require("@pixerate/editor");
|
|
8658
8757
|
function useTableMenu(editor) {
|
|
8659
|
-
const store = (0,
|
|
8660
|
-
const snapshot = (0,
|
|
8661
|
-
return (0,
|
|
8758
|
+
const store = (0, import_react61.useMemo)(() => (0, import_editor18.createTableStore)(editor), [editor]);
|
|
8759
|
+
const snapshot = (0, import_react61.useSyncExternalStore)(store.subscribe, store.getSnapshot, store.getSnapshot);
|
|
8760
|
+
return (0, import_react61.useMemo)(
|
|
8662
8761
|
() => ({
|
|
8663
8762
|
...snapshot,
|
|
8664
8763
|
run: (action, params) => (0, import_editor18.runTableAction)(editor, action, params, { focus: true }),
|
|
@@ -8669,9 +8768,9 @@ function useTableMenu(editor) {
|
|
|
8669
8768
|
}
|
|
8670
8769
|
|
|
8671
8770
|
// src/tables/TableToolbar.tsx
|
|
8672
|
-
var
|
|
8771
|
+
var import_react62 = __toESM(require("react"), 1);
|
|
8673
8772
|
var import_editor19 = require("@pixerate/editor");
|
|
8674
|
-
var
|
|
8773
|
+
var import_jsx_runtime42 = require("react/jsx-runtime");
|
|
8675
8774
|
var keepSelection2 = (event) => event.preventDefault();
|
|
8676
8775
|
var TableToolbar = ({
|
|
8677
8776
|
editor,
|
|
@@ -8685,14 +8784,14 @@ var TableToolbar = ({
|
|
|
8685
8784
|
}) => {
|
|
8686
8785
|
const table = useTableMenu(editor);
|
|
8687
8786
|
if (!editor || !table.inTable && !showWhenOutside) return null;
|
|
8688
|
-
return /* @__PURE__ */ (0,
|
|
8787
|
+
return /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("div", { className, role: "toolbar", "aria-label": "Table", "data-table-toolbar": "", children: items.map((item, index) => {
|
|
8689
8788
|
const status = table.check(item.action, item.params);
|
|
8690
8789
|
const enabled = status === true;
|
|
8691
8790
|
const active = item.active?.(table);
|
|
8692
8791
|
const separator = index > 0 && items[index - 1].group !== item.group;
|
|
8693
|
-
return /* @__PURE__ */ (0,
|
|
8694
|
-
separator && /* @__PURE__ */ (0,
|
|
8695
|
-
/* @__PURE__ */ (0,
|
|
8792
|
+
return /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)(import_react62.default.Fragment, { children: [
|
|
8793
|
+
separator && /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("span", { className: separatorClassName, "aria-hidden": "true" }),
|
|
8794
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
|
|
8696
8795
|
"button",
|
|
8697
8796
|
{
|
|
8698
8797
|
type: "button",
|
|
@@ -8714,8 +8813,8 @@ var TableToolbar = ({
|
|
|
8714
8813
|
};
|
|
8715
8814
|
|
|
8716
8815
|
// src/tables/InsertTableGrid.tsx
|
|
8717
|
-
var
|
|
8718
|
-
var
|
|
8816
|
+
var import_react63 = require("react");
|
|
8817
|
+
var import_jsx_runtime43 = require("react/jsx-runtime");
|
|
8719
8818
|
var keepSelection3 = (event) => event.preventDefault();
|
|
8720
8819
|
var InsertTableGrid = ({
|
|
8721
8820
|
editor,
|
|
@@ -8728,14 +8827,14 @@ var InsertTableGrid = ({
|
|
|
8728
8827
|
onInsert
|
|
8729
8828
|
}) => {
|
|
8730
8829
|
const table = useTableMenu(editor);
|
|
8731
|
-
const [hover, setHover] = (0,
|
|
8830
|
+
const [hover, setHover] = (0, import_react63.useState)(null);
|
|
8732
8831
|
const status = table.actions.insertTable;
|
|
8733
8832
|
const disabled = !editor || !status.enabled;
|
|
8734
8833
|
const insert = (size) => {
|
|
8735
8834
|
if (table.run("insertTable", { ...size, withHeaderRow })) onInsert?.(size);
|
|
8736
8835
|
setHover(null);
|
|
8737
8836
|
};
|
|
8738
|
-
return /* @__PURE__ */ (0,
|
|
8837
|
+
return /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)(
|
|
8739
8838
|
"div",
|
|
8740
8839
|
{
|
|
8741
8840
|
className,
|
|
@@ -8745,7 +8844,7 @@ var InsertTableGrid = ({
|
|
|
8745
8844
|
"data-insert-table-grid": "",
|
|
8746
8845
|
onMouseLeave: () => setHover(null),
|
|
8747
8846
|
children: [
|
|
8748
|
-
/* @__PURE__ */ (0,
|
|
8847
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
|
|
8749
8848
|
"div",
|
|
8750
8849
|
{
|
|
8751
8850
|
role: "grid",
|
|
@@ -8754,7 +8853,7 @@ var InsertTableGrid = ({
|
|
|
8754
8853
|
children: Array.from({ length: rows * cols }, (_, i) => {
|
|
8755
8854
|
const size = { rows: Math.floor(i / cols) + 1, cols: i % cols + 1 };
|
|
8756
8855
|
const active = !!hover && size.rows <= hover.rows && size.cols <= hover.cols;
|
|
8757
|
-
return /* @__PURE__ */ (0,
|
|
8856
|
+
return /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
|
|
8758
8857
|
"button",
|
|
8759
8858
|
{
|
|
8760
8859
|
type: "button",
|
|
@@ -8774,7 +8873,7 @@ var InsertTableGrid = ({
|
|
|
8774
8873
|
})
|
|
8775
8874
|
}
|
|
8776
8875
|
),
|
|
8777
|
-
/* @__PURE__ */ (0,
|
|
8876
|
+
/* @__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" })
|
|
8778
8877
|
]
|
|
8779
8878
|
}
|
|
8780
8879
|
);
|
|
@@ -8782,31 +8881,31 @@ var InsertTableGrid = ({
|
|
|
8782
8881
|
|
|
8783
8882
|
// src/tables/TableBubbleMenu.tsx
|
|
8784
8883
|
var import_editor20 = require("@pixerate/editor");
|
|
8785
|
-
var
|
|
8884
|
+
var import_jsx_runtime44 = require("react/jsx-runtime");
|
|
8786
8885
|
var TableBubbleMenu = ({
|
|
8787
8886
|
editor,
|
|
8788
8887
|
children,
|
|
8789
8888
|
toolbarProps,
|
|
8790
8889
|
pluginKey = "tableBubbleMenu",
|
|
8791
8890
|
...rest
|
|
8792
|
-
}) => /* @__PURE__ */ (0,
|
|
8891
|
+
}) => /* @__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 }) });
|
|
8793
8892
|
|
|
8794
8893
|
// src/chart-node/ChartNodeView.tsx
|
|
8795
8894
|
var import_client = require("react-dom/client");
|
|
8796
8895
|
|
|
8797
8896
|
// src/chart/ChartCanvas.tsx
|
|
8798
|
-
var
|
|
8897
|
+
var import_react65 = require("react");
|
|
8799
8898
|
var import_chart2 = require("@pixerate/editor/chart");
|
|
8800
8899
|
|
|
8801
8900
|
// src/chart/useChartEditor.ts
|
|
8802
|
-
var
|
|
8901
|
+
var import_react64 = require("react");
|
|
8803
8902
|
var import_chart = require("@pixerate/editor/chart");
|
|
8804
8903
|
function useChartState(controller) {
|
|
8805
|
-
return (0,
|
|
8904
|
+
return (0, import_react64.useSyncExternalStore)(controller.subscribe, controller.getState, controller.getState);
|
|
8806
8905
|
}
|
|
8807
8906
|
|
|
8808
8907
|
// src/chart/ChartCanvas.tsx
|
|
8809
|
-
var
|
|
8908
|
+
var import_jsx_runtime45 = require("react/jsx-runtime");
|
|
8810
8909
|
function renderChartMark(mark, fontFamily, interactive) {
|
|
8811
8910
|
const common = {
|
|
8812
8911
|
"data-role": mark.role,
|
|
@@ -8818,9 +8917,9 @@ function renderChartMark(mark, fontFamily, interactive) {
|
|
|
8818
8917
|
};
|
|
8819
8918
|
switch (mark.kind) {
|
|
8820
8919
|
case "rect":
|
|
8821
|
-
return /* @__PURE__ */ (0,
|
|
8920
|
+
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);
|
|
8822
8921
|
case "path":
|
|
8823
|
-
return /* @__PURE__ */ (0,
|
|
8922
|
+
return /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
|
|
8824
8923
|
"path",
|
|
8825
8924
|
{
|
|
8826
8925
|
...common,
|
|
@@ -8833,11 +8932,11 @@ function renderChartMark(mark, fontFamily, interactive) {
|
|
|
8833
8932
|
mark.key
|
|
8834
8933
|
);
|
|
8835
8934
|
case "circle":
|
|
8836
|
-
return /* @__PURE__ */ (0,
|
|
8935
|
+
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);
|
|
8837
8936
|
case "line":
|
|
8838
|
-
return /* @__PURE__ */ (0,
|
|
8937
|
+
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);
|
|
8839
8938
|
case "text":
|
|
8840
|
-
return /* @__PURE__ */ (0,
|
|
8939
|
+
return /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
|
|
8841
8940
|
"text",
|
|
8842
8941
|
{
|
|
8843
8942
|
...common,
|
|
@@ -8854,23 +8953,23 @@ function renderChartMark(mark, fontFamily, interactive) {
|
|
|
8854
8953
|
}
|
|
8855
8954
|
}
|
|
8856
8955
|
function ChartPresenceLayer({ presence }) {
|
|
8857
|
-
const { actors } = (0,
|
|
8858
|
-
return /* @__PURE__ */ (0,
|
|
8859
|
-
/* @__PURE__ */ (0,
|
|
8860
|
-
/* @__PURE__ */ (0,
|
|
8861
|
-
/* @__PURE__ */ (0,
|
|
8862
|
-
/* @__PURE__ */ (0,
|
|
8956
|
+
const { actors } = (0, import_react65.useSyncExternalStore)(presence.subscribe, presence.getState, presence.getState);
|
|
8957
|
+
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: [
|
|
8958
|
+
/* @__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 }),
|
|
8959
|
+
/* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("g", { transform: "translate(13 16)", children: [
|
|
8960
|
+
/* @__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 } }),
|
|
8961
|
+
/* @__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 })
|
|
8863
8962
|
] })
|
|
8864
8963
|
] }, a.id)) });
|
|
8865
8964
|
}
|
|
8866
8965
|
function ChartCanvas({ controller, width = 640, height = 400, responsive = true, theme, editable = true, measureText, emptyMessage, className, presence, sceneRef }) {
|
|
8867
8966
|
const state = useChartState(controller);
|
|
8868
|
-
const wrapper = (0,
|
|
8869
|
-
const svg = (0,
|
|
8870
|
-
const drag = (0,
|
|
8871
|
-
const [measured, setMeasured] = (0,
|
|
8872
|
-
const [frozen, setFrozen] = (0,
|
|
8873
|
-
(0,
|
|
8967
|
+
const wrapper = (0, import_react65.useRef)(null);
|
|
8968
|
+
const svg = (0, import_react65.useRef)(null);
|
|
8969
|
+
const drag = (0, import_react65.useRef)(null);
|
|
8970
|
+
const [measured, setMeasured] = (0, import_react65.useState)(null);
|
|
8971
|
+
const [frozen, setFrozen] = (0, import_react65.useState)(null);
|
|
8972
|
+
(0, import_react65.useEffect)(() => {
|
|
8874
8973
|
const el = wrapper.current;
|
|
8875
8974
|
if (!responsive || !el || typeof ResizeObserver === "undefined") return;
|
|
8876
8975
|
const observer = new ResizeObserver(([entry]) => {
|
|
@@ -8881,8 +8980,8 @@ function ChartCanvas({ controller, width = 640, height = 400, responsive = true,
|
|
|
8881
8980
|
return () => observer.disconnect();
|
|
8882
8981
|
}, [responsive]);
|
|
8883
8982
|
const sceneWidth = responsive && measured || width;
|
|
8884
|
-
const fullTheme = (0,
|
|
8885
|
-
const scene = (0,
|
|
8983
|
+
const fullTheme = (0, import_react65.useMemo)(() => ({ ...import_chart2.CSS_VARIABLE_CHART_THEME, ...theme }), [theme]);
|
|
8984
|
+
const scene = (0, import_react65.useMemo)(
|
|
8886
8985
|
() => (0, import_chart2.layoutChart)(state.spec, {
|
|
8887
8986
|
width: sceneWidth,
|
|
8888
8987
|
height,
|
|
@@ -8898,8 +8997,8 @@ function ChartCanvas({ controller, width = 640, height = 400, responsive = true,
|
|
|
8898
8997
|
[state.spec, state.selection, sceneWidth, height, fullTheme, editable, measureText, emptyMessage, frozen]
|
|
8899
8998
|
);
|
|
8900
8999
|
if (sceneRef) sceneRef.current = scene;
|
|
8901
|
-
const byKey = (0,
|
|
8902
|
-
(0,
|
|
9000
|
+
const byKey = (0, import_react65.useMemo)(() => new Map(scene.marks.map((m) => [m.key, m])), [scene]);
|
|
9001
|
+
(0, import_react65.useEffect)(() => () => drag.current?.end(), []);
|
|
8903
9002
|
const scenePoint = (e) => (0, import_chart2.chartClientToScene)(scene, svg.current.getBoundingClientRect(), e.clientX, e.clientY);
|
|
8904
9003
|
const onPointerDown = (e) => {
|
|
8905
9004
|
if (!editable || e.button !== 0) return;
|
|
@@ -8932,7 +9031,7 @@ function ChartCanvas({ controller, width = 640, height = 400, responsive = true,
|
|
|
8932
9031
|
if (editable && (0, import_chart2.handleChartKey)(controller, scene, e)) e.preventDefault();
|
|
8933
9032
|
};
|
|
8934
9033
|
const label = state.spec.title || "Chart";
|
|
8935
|
-
return /* @__PURE__ */ (0,
|
|
9034
|
+
return /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("div", { ref: wrapper, className: `w-full ${className ?? ""}`, "data-chart-canvas": "", children: /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)(
|
|
8936
9035
|
"svg",
|
|
8937
9036
|
{
|
|
8938
9037
|
ref: svg,
|
|
@@ -8950,14 +9049,14 @@ function ChartCanvas({ controller, width = 640, height = 400, responsive = true,
|
|
|
8950
9049
|
onKeyDown,
|
|
8951
9050
|
children: [
|
|
8952
9051
|
scene.marks.map((m) => renderChartMark(m, scene.theme.fontFamily, editable)),
|
|
8953
|
-
presence && /* @__PURE__ */ (0,
|
|
9052
|
+
presence && /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(ChartPresenceLayer, { presence })
|
|
8954
9053
|
]
|
|
8955
9054
|
}
|
|
8956
9055
|
) });
|
|
8957
9056
|
}
|
|
8958
9057
|
|
|
8959
9058
|
// src/chart/ChartDataGrid.tsx
|
|
8960
|
-
var
|
|
9059
|
+
var import_react66 = require("react");
|
|
8961
9060
|
var import_chart3 = require("@pixerate/editor/chart");
|
|
8962
9061
|
|
|
8963
9062
|
// src/chart/styles.ts
|
|
@@ -8970,11 +9069,11 @@ var chartSectionClass = "space-y-2 border-b border-border pb-3 last:border-b-0";
|
|
|
8970
9069
|
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";
|
|
8971
9070
|
|
|
8972
9071
|
// src/chart/ChartDataGrid.tsx
|
|
8973
|
-
var
|
|
9072
|
+
var import_jsx_runtime46 = require("react/jsx-runtime");
|
|
8974
9073
|
function ChartCommitInput({ value, onCommit, onKeyDown, onBlur, ...rest }) {
|
|
8975
|
-
const [draft, setDraft] = (0,
|
|
8976
|
-
const typing = (0,
|
|
8977
|
-
(0,
|
|
9074
|
+
const [draft, setDraft] = (0, import_react66.useState)(value);
|
|
9075
|
+
const typing = (0, import_react66.useRef)(false);
|
|
9076
|
+
(0, import_react66.useEffect)(() => {
|
|
8978
9077
|
if (!typing.current) setDraft(value);
|
|
8979
9078
|
}, [value]);
|
|
8980
9079
|
const commit = () => {
|
|
@@ -8983,7 +9082,7 @@ function ChartCommitInput({ value, onCommit, onKeyDown, onBlur, ...rest }) {
|
|
|
8983
9082
|
if (draft === value) return;
|
|
8984
9083
|
if (onCommit(draft) === false) setDraft(value);
|
|
8985
9084
|
};
|
|
8986
|
-
return /* @__PURE__ */ (0,
|
|
9085
|
+
return /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
|
|
8987
9086
|
"input",
|
|
8988
9087
|
{
|
|
8989
9088
|
...rest,
|
|
@@ -9018,15 +9117,15 @@ function ChartDataGrid({ controller, categoryHeader = "Category", readOnly = fal
|
|
|
9018
9117
|
e.preventDefault();
|
|
9019
9118
|
controller.pasteCells(row, column, text);
|
|
9020
9119
|
};
|
|
9021
|
-
return /* @__PURE__ */ (0,
|
|
9022
|
-
/* @__PURE__ */ (0,
|
|
9023
|
-
/* @__PURE__ */ (0,
|
|
9024
|
-
/* @__PURE__ */ (0,
|
|
9120
|
+
return /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("div", { className: `overflow-auto rounded-md border border-border ${className ?? ""}`, "data-chart-grid": "", children: [
|
|
9121
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("table", { className: "w-full border-collapse text-xs", children: [
|
|
9122
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsx)("thead", { className: "bg-muted/50", children: /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("tr", { children: [
|
|
9123
|
+
/* @__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 }),
|
|
9025
9124
|
spec.series.map((s, si) => {
|
|
9026
9125
|
const color = (0, import_chart3.chartSeriesColor)(spec, si);
|
|
9027
9126
|
const selected = selection?.kind === "series" && selection.seriesId === s.id;
|
|
9028
|
-
return /* @__PURE__ */ (0,
|
|
9029
|
-
/* @__PURE__ */ (0,
|
|
9127
|
+
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: [
|
|
9128
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
|
|
9030
9129
|
"input",
|
|
9031
9130
|
{
|
|
9032
9131
|
type: "color",
|
|
@@ -9039,7 +9138,7 @@ function ChartDataGrid({ controller, categoryHeader = "Category", readOnly = fal
|
|
|
9039
9138
|
className: "h-5 w-5 shrink-0 cursor-pointer rounded border-0 bg-transparent p-0"
|
|
9040
9139
|
}
|
|
9041
9140
|
),
|
|
9042
|
-
/* @__PURE__ */ (0,
|
|
9141
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
|
|
9043
9142
|
ChartCommitInput,
|
|
9044
9143
|
{
|
|
9045
9144
|
value: s.name,
|
|
@@ -9049,8 +9148,8 @@ function ChartDataGrid({ controller, categoryHeader = "Category", readOnly = fal
|
|
|
9049
9148
|
className: `${chartInputClass} h-6 min-w-[5rem] border-transparent bg-transparent font-medium ${s.hidden ? "text-muted-foreground line-through" : ""}`
|
|
9050
9149
|
}
|
|
9051
9150
|
),
|
|
9052
|
-
!readOnly && /* @__PURE__ */ (0,
|
|
9053
|
-
/* @__PURE__ */ (0,
|
|
9151
|
+
!readOnly && /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)(import_jsx_runtime46.Fragment, { children: [
|
|
9152
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
|
|
9054
9153
|
"button",
|
|
9055
9154
|
{
|
|
9056
9155
|
type: "button",
|
|
@@ -9063,16 +9162,16 @@ function ChartDataGrid({ controller, categoryHeader = "Category", readOnly = fal
|
|
|
9063
9162
|
children: s.hidden ? "\u25CB" : "\u25CF"
|
|
9064
9163
|
}
|
|
9065
9164
|
),
|
|
9066
|
-
/* @__PURE__ */ (0,
|
|
9165
|
+
/* @__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" })
|
|
9067
9166
|
] })
|
|
9068
9167
|
] }) }, s.id);
|
|
9069
9168
|
}),
|
|
9070
|
-
!readOnly && /* @__PURE__ */ (0,
|
|
9169
|
+
!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: "+" }) })
|
|
9071
9170
|
] }) }),
|
|
9072
|
-
/* @__PURE__ */ (0,
|
|
9171
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsx)("tbody", { children: spec.categories.map((category, i) => {
|
|
9073
9172
|
const rowSelected = selection?.kind === "category" && selection.index === i;
|
|
9074
|
-
return /* @__PURE__ */ (0,
|
|
9075
|
-
/* @__PURE__ */ (0,
|
|
9173
|
+
return /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("tr", { "data-category-index": i, className: rowSelected ? "bg-primary/10" : void 0, children: [
|
|
9174
|
+
/* @__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)(
|
|
9076
9175
|
ChartCommitInput,
|
|
9077
9176
|
{
|
|
9078
9177
|
value: category,
|
|
@@ -9086,7 +9185,7 @@ function ChartDataGrid({ controller, categoryHeader = "Category", readOnly = fal
|
|
|
9086
9185
|
spec.series.map((s) => {
|
|
9087
9186
|
const value = s.values[i];
|
|
9088
9187
|
const selected = selection?.kind === "point" && selection.seriesId === s.id && selection.index === i;
|
|
9089
|
-
return /* @__PURE__ */ (0,
|
|
9188
|
+
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)(
|
|
9090
9189
|
ChartCommitInput,
|
|
9091
9190
|
{
|
|
9092
9191
|
value: value === null || value === void 0 ? "" : String(value),
|
|
@@ -9101,38 +9200,38 @@ function ChartDataGrid({ controller, categoryHeader = "Category", readOnly = fal
|
|
|
9101
9200
|
}
|
|
9102
9201
|
) }, s.id);
|
|
9103
9202
|
}),
|
|
9104
|
-
!readOnly && /* @__PURE__ */ (0,
|
|
9203
|
+
!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" }) })
|
|
9105
9204
|
] }, i);
|
|
9106
9205
|
}) })
|
|
9107
9206
|
] }),
|
|
9108
|
-
!readOnly && /* @__PURE__ */ (0,
|
|
9207
|
+
!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" }) })
|
|
9109
9208
|
] });
|
|
9110
9209
|
}
|
|
9111
9210
|
|
|
9112
9211
|
// src/chart/ChartInspector.tsx
|
|
9113
|
-
var
|
|
9212
|
+
var import_react67 = require("react");
|
|
9114
9213
|
var import_chart4 = require("@pixerate/editor/chart");
|
|
9115
|
-
var
|
|
9214
|
+
var import_jsx_runtime47 = require("react/jsx-runtime");
|
|
9116
9215
|
var cap = (s) => s.charAt(0).toUpperCase() + s.slice(1);
|
|
9117
9216
|
function Field({ label, htmlFor, children }) {
|
|
9118
|
-
return /* @__PURE__ */ (0,
|
|
9119
|
-
/* @__PURE__ */ (0,
|
|
9120
|
-
/* @__PURE__ */ (0,
|
|
9217
|
+
return /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
9218
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)("label", { htmlFor, className: `${chartLabelClass} w-20 shrink-0`, children: label }),
|
|
9219
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)("div", { className: "min-w-0 flex-1", children })
|
|
9121
9220
|
] });
|
|
9122
9221
|
}
|
|
9123
9222
|
function Toggle({ label, checked, onChange, name }) {
|
|
9124
|
-
return /* @__PURE__ */ (0,
|
|
9125
|
-
/* @__PURE__ */ (0,
|
|
9223
|
+
return /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("label", { className: "flex cursor-pointer items-center gap-2 text-xs text-foreground", children: [
|
|
9224
|
+
/* @__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) }),
|
|
9126
9225
|
label
|
|
9127
9226
|
] });
|
|
9128
9227
|
}
|
|
9129
9228
|
function Select({ id, value, options, onChange, name, labels }) {
|
|
9130
|
-
return /* @__PURE__ */ (0,
|
|
9229
|
+
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)) });
|
|
9131
9230
|
}
|
|
9132
9231
|
function AxisSection({ controller, axis, value, idBase, horizontal, numeric = false, scales = false }) {
|
|
9133
9232
|
const set = (patch) => controller.setAxis(axis, patch);
|
|
9134
9233
|
const setFormat = (patch) => set({ format: { ...value.format, ...patch } });
|
|
9135
|
-
const bound = (key2) => /* @__PURE__ */ (0,
|
|
9234
|
+
const bound = (key2) => /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
|
|
9136
9235
|
ChartCommitInput,
|
|
9137
9236
|
{
|
|
9138
9237
|
id: `${idBase}-${axis}-${key2}`,
|
|
@@ -9147,26 +9246,26 @@ function AxisSection({ controller, axis, value, idBase, horizontal, numeric = fa
|
|
|
9147
9246
|
const name = axis === "x" ? numeric ? "X axis" : "Category axis" : axis === "y" ? "Value axis" : "Secondary axis";
|
|
9148
9247
|
const valueAxis = axis !== "x" || numeric;
|
|
9149
9248
|
const key = axis === "y2" ? "yAxis2" : `${axis}Axis`;
|
|
9150
|
-
return /* @__PURE__ */ (0,
|
|
9151
|
-
/* @__PURE__ */ (0,
|
|
9152
|
-
/* @__PURE__ */ (0,
|
|
9249
|
+
return /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: chartSectionClass, "data-section": `axis-${axis}`, children: [
|
|
9250
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: "flex items-center justify-between", children: [
|
|
9251
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("h4", { className: "text-xs font-semibold text-foreground", children: [
|
|
9153
9252
|
name,
|
|
9154
|
-
/* @__PURE__ */ (0,
|
|
9253
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("span", { className: "ml-1 font-normal text-muted-foreground", children: [
|
|
9155
9254
|
"(",
|
|
9156
9255
|
axis === "x" ? horizontal ? "left" : "bottom" : axis === "y2" ? horizontal ? "top" : "right" : horizontal ? "bottom" : "left",
|
|
9157
9256
|
")"
|
|
9158
9257
|
] })
|
|
9159
9258
|
] }),
|
|
9160
|
-
/* @__PURE__ */ (0,
|
|
9259
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)(Toggle, { label: "Show", name: `${axis}Axis.show`, checked: value.show, onChange: (show) => set({ show }) })
|
|
9161
9260
|
] }),
|
|
9162
|
-
/* @__PURE__ */ (0,
|
|
9163
|
-
/* @__PURE__ */ (0,
|
|
9164
|
-
/* @__PURE__ */ (0,
|
|
9165
|
-
axis === "x" && !numeric && /* @__PURE__ */ (0,
|
|
9166
|
-
scales && /* @__PURE__ */ (0,
|
|
9167
|
-
scales && valueAxis && /* @__PURE__ */ (0,
|
|
9261
|
+
/* @__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 }) }) }),
|
|
9262
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: "flex flex-wrap gap-x-4 gap-y-1", children: [
|
|
9263
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)(Toggle, { label: "Grid lines", name: `${key}.gridlines`, checked: value.gridlines, onChange: (gridlines) => set({ gridlines }) }),
|
|
9264
|
+
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 }) }),
|
|
9265
|
+
scales && /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(Toggle, { label: "Reverse", name: `${key}.reverse`, checked: !!value.reverse, onChange: (reverse) => set({ reverse }) }),
|
|
9266
|
+
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" }) })
|
|
9168
9267
|
] }),
|
|
9169
|
-
scales && valueAxis && value.scale === "log" && /* @__PURE__ */ (0,
|
|
9268
|
+
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)(
|
|
9170
9269
|
ChartCommitInput,
|
|
9171
9270
|
{
|
|
9172
9271
|
id: `${idBase}-${axis}-log-base`,
|
|
@@ -9177,7 +9276,7 @@ function AxisSection({ controller, axis, value, idBase, horizontal, numeric = fa
|
|
|
9177
9276
|
onCommit: (text) => set({ logBase: text.trim() === "" ? void 0 : Number(text) }).ok
|
|
9178
9277
|
}
|
|
9179
9278
|
) }),
|
|
9180
|
-
valueAxis && value.scale !== "log" && /* @__PURE__ */ (0,
|
|
9279
|
+
valueAxis && value.scale !== "log" && /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(Field, { label: "Step", htmlFor: `${idBase}-${axis}-step`, children: /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
|
|
9181
9280
|
ChartCommitInput,
|
|
9182
9281
|
{
|
|
9183
9282
|
id: `${idBase}-${axis}-step`,
|
|
@@ -9189,14 +9288,14 @@ function AxisSection({ controller, axis, value, idBase, horizontal, numeric = fa
|
|
|
9189
9288
|
onCommit: (text) => set({ step: text.trim() === "" ? null : Number(text) }).ok
|
|
9190
9289
|
}
|
|
9191
9290
|
) }),
|
|
9192
|
-
valueAxis && /* @__PURE__ */ (0,
|
|
9193
|
-
/* @__PURE__ */ (0,
|
|
9291
|
+
valueAxis && /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)(import_jsx_runtime47.Fragment, { children: [
|
|
9292
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)(Field, { label: "Min / max", children: /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: "flex gap-1", children: [
|
|
9194
9293
|
bound("min"),
|
|
9195
9294
|
bound("max")
|
|
9196
9295
|
] }) }),
|
|
9197
|
-
/* @__PURE__ */ (0,
|
|
9198
|
-
/* @__PURE__ */ (0,
|
|
9199
|
-
/* @__PURE__ */ (0,
|
|
9296
|
+
/* @__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: [
|
|
9297
|
+
/* @__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 }) }),
|
|
9298
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
|
|
9200
9299
|
ChartCommitInput,
|
|
9201
9300
|
{
|
|
9202
9301
|
value: value.format.decimals === void 0 ? "" : String(value.format.decimals),
|
|
@@ -9215,8 +9314,8 @@ function AxisSection({ controller, axis, value, idBase, horizontal, numeric = fa
|
|
|
9215
9314
|
}
|
|
9216
9315
|
)
|
|
9217
9316
|
] }) }),
|
|
9218
|
-
value.format.style === "currency" && /* @__PURE__ */ (0,
|
|
9219
|
-
/* @__PURE__ */ (0,
|
|
9317
|
+
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() }) }) }),
|
|
9318
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)(Field, { label: "Code", htmlFor: `${idBase}-${axis}-code`, children: /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
|
|
9220
9319
|
ChartCommitInput,
|
|
9221
9320
|
{
|
|
9222
9321
|
id: `${idBase}-${axis}-code`,
|
|
@@ -9242,15 +9341,15 @@ function ErrorBarFields({ controller, series, which, idBase }) {
|
|
|
9242
9341
|
const values = which === "xErrorBars" ? series.x ?? [] : series.values;
|
|
9243
9342
|
const set = (next) => controller.updateSeries(series.id, { [which]: next });
|
|
9244
9343
|
const patch = (p) => bars && set({ ...bars, ...p });
|
|
9245
|
-
return /* @__PURE__ */ (0,
|
|
9246
|
-
/* @__PURE__ */ (0,
|
|
9247
|
-
/* @__PURE__ */ (0,
|
|
9248
|
-
import_chart4.CHART_ERROR_BAR_TYPES.map((t) => /* @__PURE__ */ (0,
|
|
9344
|
+
return /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: "space-y-1.5", "data-section": which === "errorBars" ? "error-bars" : "x-error-bars", children: [
|
|
9345
|
+
/* @__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: [
|
|
9346
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)("option", { value: "", children: "None" }),
|
|
9347
|
+
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))
|
|
9249
9348
|
] }) }),
|
|
9250
|
-
bars && (bars.type === "fixed" || bars.type === "percent" || bars.type === "stddev") && /* @__PURE__ */ (0,
|
|
9251
|
-
bars?.type === "custom" && /* @__PURE__ */ (0,
|
|
9252
|
-
/* @__PURE__ */ (0,
|
|
9253
|
-
/* @__PURE__ */ (0,
|
|
9349
|
+
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 }) }),
|
|
9350
|
+
bars?.type === "custom" && /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)(import_jsx_runtime47.Fragment, { children: [
|
|
9351
|
+
/* @__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 }) }),
|
|
9352
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)(Field, { label: "Minus", htmlFor: `${id}-minus`, children: /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
|
|
9254
9353
|
ChartCommitInput,
|
|
9255
9354
|
{
|
|
9256
9355
|
id: `${id}-minus`,
|
|
@@ -9267,15 +9366,15 @@ function ErrorBarFields({ controller, series, which, idBase }) {
|
|
|
9267
9366
|
}
|
|
9268
9367
|
) })
|
|
9269
9368
|
] }),
|
|
9270
|
-
bars && /* @__PURE__ */ (0,
|
|
9271
|
-
/* @__PURE__ */ (0,
|
|
9272
|
-
/* @__PURE__ */ (0,
|
|
9369
|
+
bars && /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
9370
|
+
/* @__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)) }),
|
|
9371
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)(Toggle, { label: "Caps", name: `${key}.cap`, checked: bars.cap !== false, onChange: (cap2) => patch({ cap: cap2 }) })
|
|
9273
9372
|
] })
|
|
9274
9373
|
] });
|
|
9275
9374
|
}
|
|
9276
9375
|
function ChartInspector({ controller, sections, className }) {
|
|
9277
9376
|
const { spec, selectedSeries } = useChartState(controller);
|
|
9278
|
-
const idBase = (0,
|
|
9377
|
+
const idBase = (0, import_react67.useId)();
|
|
9279
9378
|
const show = (section) => !sections || sections.includes(section);
|
|
9280
9379
|
const cartesian = (0, import_chart4.isCartesianChart)(spec.type);
|
|
9281
9380
|
const family = (0, import_chart4.chartFamily)(spec);
|
|
@@ -9287,29 +9386,29 @@ function ChartInspector({ controller, sections, className }) {
|
|
|
9287
9386
|
const hasLines = cartesian && types.some((t) => t === "line" || t === "area");
|
|
9288
9387
|
const seriesIndex = selectedSeries ? spec.series.findIndex((s) => s.id === selectedSeries.id) : -1;
|
|
9289
9388
|
const scales = family === "cartesian" || family === "xy";
|
|
9290
|
-
return /* @__PURE__ */ (0,
|
|
9291
|
-
show("type") && /* @__PURE__ */ (0,
|
|
9292
|
-
show("style") && /* @__PURE__ */ (0,
|
|
9293
|
-
/* @__PURE__ */ (0,
|
|
9294
|
-
/* @__PURE__ */ (0,
|
|
9295
|
-
import_chart4.CHART_LAYOUT_PRESETS.map((p) => /* @__PURE__ */ (0,
|
|
9389
|
+
return /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: `space-y-3 text-xs ${className ?? ""}`, "data-chart-inspector": "", children: [
|
|
9390
|
+
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)) }) }),
|
|
9391
|
+
show("style") && /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: chartSectionClass, "data-section": "style", children: [
|
|
9392
|
+
/* @__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: [
|
|
9393
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)("option", { value: "", children: "Quick layout\u2026" }),
|
|
9394
|
+
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))
|
|
9296
9395
|
] }) }),
|
|
9297
|
-
/* @__PURE__ */ (0,
|
|
9298
|
-
/* @__PURE__ */ (0,
|
|
9299
|
-
import_chart4.CHART_COLOR_SCHEMES.map((c) => /* @__PURE__ */ (0,
|
|
9396
|
+
/* @__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: [
|
|
9397
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)("option", { value: "", children: "Custom" }),
|
|
9398
|
+
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))
|
|
9300
9399
|
] }) }),
|
|
9301
|
-
!colorCheck.ok && /* @__PURE__ */ (0,
|
|
9302
|
-
/* @__PURE__ */ (0,
|
|
9400
|
+
!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] }),
|
|
9401
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)("button", { type: "button", className: chartButtonClass, "data-action": "transpose", onClick: () => controller.transpose(), children: "Switch rows and columns" })
|
|
9303
9402
|
] }),
|
|
9304
|
-
show("titles") && /* @__PURE__ */ (0,
|
|
9305
|
-
/* @__PURE__ */ (0,
|
|
9306
|
-
/* @__PURE__ */ (0,
|
|
9403
|
+
show("titles") && /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: chartSectionClass, "data-section": "titles", children: [
|
|
9404
|
+
/* @__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) }) }),
|
|
9405
|
+
/* @__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) }) })
|
|
9307
9406
|
] }),
|
|
9308
|
-
show("options") && /* @__PURE__ */ (0,
|
|
9309
|
-
cartesian && /* @__PURE__ */ (0,
|
|
9310
|
-
hasBars && /* @__PURE__ */ (0,
|
|
9311
|
-
hasLines && /* @__PURE__ */ (0,
|
|
9312
|
-
spec.type === "donut" && /* @__PURE__ */ (0,
|
|
9407
|
+
show("options") && /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: chartSectionClass, "data-section": "options", children: [
|
|
9408
|
+
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 }) }) }),
|
|
9409
|
+
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)) }) }),
|
|
9410
|
+
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 }) }) }),
|
|
9411
|
+
spec.type === "donut" && /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(Field, { label: "Hole", htmlFor: `${idBase}-hole`, children: /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
|
|
9313
9412
|
"input",
|
|
9314
9413
|
{
|
|
9315
9414
|
id: `${idBase}-hole`,
|
|
@@ -9325,7 +9424,7 @@ function ChartInspector({ controller, sections, className }) {
|
|
|
9325
9424
|
onChange: (e) => controller.update({ innerRadius: Number(e.currentTarget.value) })
|
|
9326
9425
|
}
|
|
9327
9426
|
) }),
|
|
9328
|
-
hasBars && /* @__PURE__ */ (0,
|
|
9427
|
+
hasBars && /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(Field, { label: "Spacing", htmlFor: `${idBase}-gap`, children: /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
|
|
9329
9428
|
"input",
|
|
9330
9429
|
{
|
|
9331
9430
|
id: `${idBase}-gap`,
|
|
@@ -9341,31 +9440,31 @@ function ChartInspector({ controller, sections, className }) {
|
|
|
9341
9440
|
onChange: (e) => controller.update({ gapWidth: Number(e.currentTarget.value) })
|
|
9342
9441
|
}
|
|
9343
9442
|
) }),
|
|
9344
|
-
spec.dataLabels && hasBars && /* @__PURE__ */ (0,
|
|
9345
|
-
spec.type === "histogram" && /* @__PURE__ */ (0,
|
|
9346
|
-
/* @__PURE__ */ (0,
|
|
9347
|
-
spec.type === "waterfall" && /* @__PURE__ */ (0,
|
|
9348
|
-
hasLines && /* @__PURE__ */ (0,
|
|
9349
|
-
/* @__PURE__ */ (0,
|
|
9443
|
+
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 }) }) }),
|
|
9444
|
+
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 }) }),
|
|
9445
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: "flex flex-wrap gap-x-4 gap-y-1", children: [
|
|
9446
|
+
spec.type === "waterfall" && /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(Toggle, { label: "Total bar", name: "showTotal", checked: spec.showTotal, onChange: (showTotal) => controller.update({ showTotal }) }),
|
|
9447
|
+
hasLines && /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(Toggle, { label: "Points", name: "points", checked: spec.points, onChange: (points) => controller.update({ points }) }),
|
|
9448
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)(Toggle, { label: "Data labels", name: "dataLabels", checked: spec.dataLabels, onChange: (dataLabels) => controller.update({ dataLabels }) })
|
|
9350
9449
|
] })
|
|
9351
9450
|
] }),
|
|
9352
|
-
show("legend") && /* @__PURE__ */ (0,
|
|
9353
|
-
/* @__PURE__ */ (0,
|
|
9354
|
-
/* @__PURE__ */ (0,
|
|
9355
|
-
/* @__PURE__ */ (0,
|
|
9451
|
+
show("legend") && /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: chartSectionClass, "data-section": "legend", children: [
|
|
9452
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: "flex items-center justify-between", children: [
|
|
9453
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)("h4", { className: "text-xs font-semibold text-foreground", children: "Legend" }),
|
|
9454
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)(Toggle, { label: "Show", name: "legend.show", checked: spec.legend.show, onChange: (v) => controller.setLegend({ show: v }) })
|
|
9356
9455
|
] }),
|
|
9357
|
-
spec.legend.show && /* @__PURE__ */ (0,
|
|
9456
|
+
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)) })
|
|
9358
9457
|
] }),
|
|
9359
|
-
show("axes") && hasAxes && /* @__PURE__ */ (0,
|
|
9360
|
-
family !== "box" && family !== "histogram" && /* @__PURE__ */ (0,
|
|
9361
|
-
/* @__PURE__ */ (0,
|
|
9362
|
-
usesSecondary && /* @__PURE__ */ (0,
|
|
9458
|
+
show("axes") && hasAxes && /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)(import_jsx_runtime47.Fragment, { children: [
|
|
9459
|
+
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 }),
|
|
9460
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)(AxisSection, { controller, axis: "y", value: spec.yAxis, idBase, horizontal: spec.orientation === "horizontal", scales }),
|
|
9461
|
+
usesSecondary && /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(AxisSection, { controller, axis: "y2", value: spec.yAxis2, idBase, horizontal: spec.orientation === "horizontal", scales })
|
|
9363
9462
|
] }),
|
|
9364
|
-
show("series") && selectedSeries && /* @__PURE__ */ (0,
|
|
9365
|
-
/* @__PURE__ */ (0,
|
|
9366
|
-
/* @__PURE__ */ (0,
|
|
9367
|
-
/* @__PURE__ */ (0,
|
|
9368
|
-
/* @__PURE__ */ (0,
|
|
9463
|
+
show("series") && selectedSeries && /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: chartSectionClass, "data-section": "series", "data-series-id": selectedSeries.id, children: [
|
|
9464
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)("h4", { className: "text-xs font-semibold text-foreground", children: "Series" }),
|
|
9465
|
+
/* @__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 }) }) }),
|
|
9466
|
+
/* @__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: [
|
|
9467
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
|
|
9369
9468
|
"input",
|
|
9370
9469
|
{
|
|
9371
9470
|
id: `${idBase}-series-color`,
|
|
@@ -9378,9 +9477,9 @@ function ChartInspector({ controller, sections, className }) {
|
|
|
9378
9477
|
onChange: (e) => controller.updateSeries(selectedSeries.id, { color: e.currentTarget.value })
|
|
9379
9478
|
}
|
|
9380
9479
|
),
|
|
9381
|
-
selectedSeries.color && /* @__PURE__ */ (0,
|
|
9480
|
+
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" })
|
|
9382
9481
|
] }) }),
|
|
9383
|
-
cartesian && /* @__PURE__ */ (0,
|
|
9482
|
+
cartesian && /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(Field, { label: "Draw as", htmlFor: `${idBase}-series-type`, children: /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)(
|
|
9384
9483
|
"select",
|
|
9385
9484
|
{
|
|
9386
9485
|
id: `${idBase}-series-type`,
|
|
@@ -9389,12 +9488,12 @@ function ChartInspector({ controller, sections, className }) {
|
|
|
9389
9488
|
"data-option": "series.type",
|
|
9390
9489
|
onChange: (e) => controller.updateSeries(selectedSeries.id, { type: e.currentTarget.value || null }),
|
|
9391
9490
|
children: [
|
|
9392
|
-
/* @__PURE__ */ (0,
|
|
9393
|
-
import_chart4.CHART_SERIES_TYPES.map((t) => /* @__PURE__ */ (0,
|
|
9491
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)("option", { value: "", children: "Chart type" }),
|
|
9492
|
+
import_chart4.CHART_SERIES_TYPES.map((t) => /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("option", { value: t, children: import_chart4.CHART_TYPE_LABELS[t] }, t))
|
|
9394
9493
|
]
|
|
9395
9494
|
}
|
|
9396
9495
|
) }),
|
|
9397
|
-
(cartesian || family === "xy") && ["line", "area", "scatter"].includes((0, import_chart4.chartSeriesType)(spec, selectedSeries)) && /* @__PURE__ */ (0,
|
|
9496
|
+
(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)(
|
|
9398
9497
|
"select",
|
|
9399
9498
|
{
|
|
9400
9499
|
id: `${idBase}-series-marker`,
|
|
@@ -9403,20 +9502,20 @@ function ChartInspector({ controller, sections, className }) {
|
|
|
9403
9502
|
"data-option": "series.marker",
|
|
9404
9503
|
onChange: (e) => controller.updateSeries(selectedSeries.id, { marker: e.currentTarget.value || null }),
|
|
9405
9504
|
children: [
|
|
9406
|
-
/* @__PURE__ */ (0,
|
|
9407
|
-
import_chart4.CHART_MARKERS.map((m) => /* @__PURE__ */ (0,
|
|
9505
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)("option", { value: "", children: "Default" }),
|
|
9506
|
+
import_chart4.CHART_MARKERS.map((m) => /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("option", { value: m, children: cap(m) }, m))
|
|
9408
9507
|
]
|
|
9409
9508
|
}
|
|
9410
9509
|
) }),
|
|
9411
|
-
scales && /* @__PURE__ */ (0,
|
|
9412
|
-
family === "xy" && /* @__PURE__ */ (0,
|
|
9413
|
-
(0, import_chart4.chartSupportsTrendlines)(spec.type, spec.stacking) && /* @__PURE__ */ (0,
|
|
9414
|
-
(selectedSeries.trendlines ?? []).map((t, i) => /* @__PURE__ */ (0,
|
|
9415
|
-
/* @__PURE__ */ (0,
|
|
9416
|
-
/* @__PURE__ */ (0,
|
|
9417
|
-
/* @__PURE__ */ (0,
|
|
9510
|
+
scales && /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(ErrorBarFields, { controller, series: selectedSeries, which: "errorBars", idBase }),
|
|
9511
|
+
family === "xy" && /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(ErrorBarFields, { controller, series: selectedSeries, which: "xErrorBars", idBase }),
|
|
9512
|
+
(0, import_chart4.chartSupportsTrendlines)(spec.type, spec.stacking) && /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: "space-y-1", "data-section": "trendlines", children: [
|
|
9513
|
+
(selectedSeries.trendlines ?? []).map((t, i) => /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: "flex items-center gap-1", "data-trendline": i, children: [
|
|
9514
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)("span", { className: "flex-1 truncate text-muted-foreground", children: (0, import_chart4.chartTrendlineName)(t, selectedSeries.name) }),
|
|
9515
|
+
/* @__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 }) }),
|
|
9516
|
+
/* @__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" })
|
|
9418
9517
|
] }, i)),
|
|
9419
|
-
/* @__PURE__ */ (0,
|
|
9518
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsxs)(
|
|
9420
9519
|
"select",
|
|
9421
9520
|
{
|
|
9422
9521
|
className: chartInputClass,
|
|
@@ -9425,32 +9524,32 @@ function ChartInspector({ controller, sections, className }) {
|
|
|
9425
9524
|
"data-option": "trendline.add",
|
|
9426
9525
|
onChange: (e) => e.currentTarget.value && controller.addTrendline(selectedSeries.id, { type: e.currentTarget.value }),
|
|
9427
9526
|
children: [
|
|
9428
|
-
/* @__PURE__ */ (0,
|
|
9429
|
-
import_chart4.CHART_TRENDLINE_TYPES.map((t) => /* @__PURE__ */ (0,
|
|
9527
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)("option", { value: "", children: "Add trendline\u2026" }),
|
|
9528
|
+
import_chart4.CHART_TRENDLINE_TYPES.map((t) => /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("option", { value: t, children: cap(t.replace("-", " ")) }, t))
|
|
9430
9529
|
]
|
|
9431
9530
|
}
|
|
9432
9531
|
)
|
|
9433
9532
|
] }),
|
|
9434
|
-
/* @__PURE__ */ (0,
|
|
9435
|
-
/* @__PURE__ */ (0,
|
|
9436
|
-
family === "cartesian" && /* @__PURE__ */ (0,
|
|
9437
|
-
/* @__PURE__ */ (0,
|
|
9438
|
-
/* @__PURE__ */ (0,
|
|
9439
|
-
/* @__PURE__ */ (0,
|
|
9440
|
-
/* @__PURE__ */ (0,
|
|
9533
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: "flex flex-wrap items-center gap-1", children: [
|
|
9534
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)(Toggle, { label: "Hidden", name: "series.hidden", checked: !!selectedSeries.hidden, onChange: (hidden) => controller.updateSeries(selectedSeries.id, { hidden }) }),
|
|
9535
|
+
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 }) }),
|
|
9536
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)("span", { className: "flex-1" }),
|
|
9537
|
+
/* @__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" }),
|
|
9538
|
+
/* @__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" }),
|
|
9539
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)("button", { type: "button", className: `${chartButtonClass} text-destructive`, "data-action": "series-delete", onClick: () => controller.removeSeries(selectedSeries.id), children: "Delete" })
|
|
9441
9540
|
] })
|
|
9442
9541
|
] })
|
|
9443
9542
|
] });
|
|
9444
9543
|
}
|
|
9445
9544
|
|
|
9446
9545
|
// src/chart-node/ChartNodeView.tsx
|
|
9447
|
-
var
|
|
9546
|
+
var import_jsx_runtime48 = require("react/jsx-runtime");
|
|
9448
9547
|
function ChartNodeView({ state, theme, showDataGrid = true }) {
|
|
9449
9548
|
const { controller, editing, editable, selected, width, height, setEditing } = state;
|
|
9450
9549
|
const open = () => {
|
|
9451
9550
|
if (editable && !editing) setEditing(true);
|
|
9452
9551
|
};
|
|
9453
|
-
return /* @__PURE__ */ (0,
|
|
9552
|
+
return /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)(
|
|
9454
9553
|
"div",
|
|
9455
9554
|
{
|
|
9456
9555
|
className: `not-prose my-2 rounded-md border bg-background p-1 ${selected ? "border-primary ring-1 ring-primary" : "border-border"}`,
|
|
@@ -9463,24 +9562,24 @@ function ChartNodeView({ state, theme, showDataGrid = true }) {
|
|
|
9463
9562
|
}
|
|
9464
9563
|
},
|
|
9465
9564
|
children: [
|
|
9466
|
-
editing && /* @__PURE__ */ (0,
|
|
9467
|
-
/* @__PURE__ */ (0,
|
|
9468
|
-
/* @__PURE__ */ (0,
|
|
9565
|
+
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: [
|
|
9566
|
+
/* @__PURE__ */ (0, import_jsx_runtime48.jsx)("span", { className: "text-xs text-muted-foreground", children: "Editing chart" }),
|
|
9567
|
+
/* @__PURE__ */ (0, import_jsx_runtime48.jsx)("button", { type: "button", className: chartButtonClass, "data-action": "done", onClick: () => setEditing(false), children: "Done" })
|
|
9469
9568
|
] }),
|
|
9470
|
-
/* @__PURE__ */ (0,
|
|
9569
|
+
/* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
|
|
9471
9570
|
"div",
|
|
9472
9571
|
{
|
|
9473
9572
|
className: editable && !editing ? "cursor-pointer" : void 0,
|
|
9474
9573
|
onClick: open,
|
|
9475
9574
|
title: editable && !editing ? "Click to edit the chart" : void 0,
|
|
9476
9575
|
"data-chart-node-canvas": "",
|
|
9477
|
-
children: /* @__PURE__ */ (0,
|
|
9576
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(ChartCanvas, { controller, width: width ?? 640, height, responsive: width === null, editable: editing, theme })
|
|
9478
9577
|
}
|
|
9479
9578
|
),
|
|
9480
9579
|
editing && // Wraps by the document's width, not the viewport's: side by side when there is room.
|
|
9481
|
-
/* @__PURE__ */ (0,
|
|
9482
|
-
showDataGrid && /* @__PURE__ */ (0,
|
|
9483
|
-
/* @__PURE__ */ (0,
|
|
9580
|
+
/* @__PURE__ */ (0, import_jsx_runtime48.jsxs)("div", { className: "mt-2 flex flex-wrap items-start gap-2", "data-chart-node-panel": "", children: [
|
|
9581
|
+
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 }) }),
|
|
9582
|
+
/* @__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" })
|
|
9484
9583
|
] })
|
|
9485
9584
|
]
|
|
9486
9585
|
}
|
|
@@ -9498,7 +9597,7 @@ function createReactChartNodeView(options = {}) {
|
|
|
9498
9597
|
scheduled = true;
|
|
9499
9598
|
queueMicrotask(() => {
|
|
9500
9599
|
scheduled = false;
|
|
9501
|
-
if (!destroyed) root.render(/* @__PURE__ */ (0,
|
|
9600
|
+
if (!destroyed) root.render(/* @__PURE__ */ (0, import_jsx_runtime48.jsx)(Component, { ...props, state: latest }));
|
|
9502
9601
|
});
|
|
9503
9602
|
};
|
|
9504
9603
|
schedule();
|
|
@@ -9521,6 +9620,7 @@ function createReactChartNodeView(options = {}) {
|
|
|
9521
9620
|
BrushOptionsBar,
|
|
9522
9621
|
BubbleMenu,
|
|
9523
9622
|
ChartNodeView,
|
|
9623
|
+
ColorProfilePanel,
|
|
9524
9624
|
CommandPalette,
|
|
9525
9625
|
CommentButton,
|
|
9526
9626
|
CommentsPanel,
|