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