@pixerate/editor-react 0.76.0 → 0.77.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/PaintGradientEditorView-CCPCY5Ib.d.cts +14 -0
- package/dist/PaintGradientEditorView-CCPCY5Ib.d.ts +14 -0
- package/dist/canvas/index.cjs +662 -561
- package/dist/canvas/index.cjs.map +1 -1
- package/dist/canvas/index.d.cts +36 -5
- package/dist/canvas/index.d.ts +36 -5
- package/dist/canvas/index.js +232 -129
- package/dist/canvas/index.js.map +1 -1
- package/dist/chunk-MO354USR.js +126 -0
- package/dist/chunk-MO354USR.js.map +1 -0
- package/dist/{chunk-LWMUV5TC.js → chunk-QARGR5E5.js} +278 -253
- package/dist/chunk-QARGR5E5.js.map +1 -0
- package/dist/image-editor/index.cjs +677 -531
- package/dist/image-editor/index.cjs.map +1 -1
- package/dist/image-editor/index.d.cts +8 -2
- package/dist/image-editor/index.d.ts +8 -2
- package/dist/image-editor/index.js +4 -1
- package/dist/index.cjs +1095 -949
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +3 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.js +4 -1
- package/dist/index.js.map +1 -1
- package/dist/paint-editor/index.cjs +438 -289
- package/dist/paint-editor/index.cjs.map +1 -1
- package/dist/paint-editor/index.d.cts +8 -3
- package/dist/paint-editor/index.d.ts +8 -3
- package/dist/paint-editor/index.js +215 -187
- package/dist/paint-editor/index.js.map +1 -1
- package/package.json +3 -3
- package/dist/chunk-LWMUV5TC.js.map +0 -1
package/dist/index.cjs
CHANGED
|
@@ -60,6 +60,7 @@ __export(src_exports, {
|
|
|
60
60
|
MergePreview: () => MergePreview,
|
|
61
61
|
NameManager: () => NameManager,
|
|
62
62
|
OutlinePanel: () => OutlinePanel,
|
|
63
|
+
PaintGradientEditor: () => PaintGradientEditor,
|
|
63
64
|
RecoveryPrompt: () => RecoveryPrompt,
|
|
64
65
|
RefineEdgePanel: () => RefineEdgePanel,
|
|
65
66
|
ReviewToolbar: () => ReviewToolbar,
|
|
@@ -2008,17 +2009,17 @@ var SpreadsheetValidationDialog = ({ prompt, onResolve }) => {
|
|
|
2008
2009
|
style === "warning" && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { className: "mt-2", children: "Continue?" })
|
|
2009
2010
|
] })
|
|
2010
2011
|
] }),
|
|
2011
|
-
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "mt-4 flex justify-end gap-2", children: buttons.map((
|
|
2012
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "mt-4 flex justify-end gap-2", children: buttons.map((button4, i) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
2012
2013
|
"button",
|
|
2013
2014
|
{
|
|
2014
2015
|
ref: i === 0 ? firstButton : void 0,
|
|
2015
2016
|
type: "button",
|
|
2016
|
-
"data-action":
|
|
2017
|
+
"data-action": button4.action,
|
|
2017
2018
|
className: `rounded border border-border px-3 py-1 ${i === 0 ? "bg-primary text-primary-foreground" : "hover:bg-muted"}`,
|
|
2018
|
-
onClick: () => onResolve(
|
|
2019
|
-
children:
|
|
2019
|
+
onClick: () => onResolve(button4.action),
|
|
2020
|
+
children: button4.label
|
|
2020
2021
|
},
|
|
2021
|
-
|
|
2022
|
+
button4.action
|
|
2022
2023
|
)) })
|
|
2023
2024
|
]
|
|
2024
2025
|
}
|
|
@@ -3788,8 +3789,8 @@ function useImageEditor(options = {}) {
|
|
|
3788
3789
|
}
|
|
3789
3790
|
|
|
3790
3791
|
// src/image-editor/ImageEditor.tsx
|
|
3791
|
-
var
|
|
3792
|
-
var
|
|
3792
|
+
var import_react48 = __toESM(require("react"), 1);
|
|
3793
|
+
var import_image_editor17 = require("@pixerate/editor/image-editor");
|
|
3793
3794
|
|
|
3794
3795
|
// src/image-editor/ControlSlider.tsx
|
|
3795
3796
|
var import_image_editor2 = require("@pixerate/editor/image-editor");
|
|
@@ -4839,16 +4840,148 @@ var LayersPanel = ({ controller, thumbnailSize = 32, psd = true, psdFileName = "
|
|
|
4839
4840
|
};
|
|
4840
4841
|
|
|
4841
4842
|
// src/image-editor/BrushOptionsBar.tsx
|
|
4842
|
-
var
|
|
4843
|
+
var import_react41 = require("react");
|
|
4844
|
+
var import_image_editor9 = require("@pixerate/editor/image-editor");
|
|
4845
|
+
var import_image_editor10 = require("@pixerate/editor/image-editor");
|
|
4846
|
+
|
|
4847
|
+
// src/image-editor/PaintGradientEditor.tsx
|
|
4843
4848
|
var import_image_editor8 = require("@pixerate/editor/image-editor");
|
|
4849
|
+
|
|
4850
|
+
// src/paint-editor/PaintGradientEditorView.tsx
|
|
4851
|
+
var import_react40 = require("react");
|
|
4844
4852
|
var import_jsx_runtime23 = require("react/jsx-runtime");
|
|
4853
|
+
var button2 = "px-2 py-1 rounded text-[11px] bg-slate-800 text-slate-200 hover:bg-slate-700 disabled:opacity-40";
|
|
4854
|
+
var select = "rounded bg-slate-800 px-1 py-0.5 text-[11px]";
|
|
4855
|
+
var number = "w-16 rounded bg-slate-800 px-1 py-0.5 text-[11px]";
|
|
4856
|
+
var pct = (v) => Math.round(v * 1e3) / 10;
|
|
4857
|
+
var PaintGradientEditorView = ({ value, onChange, colors, className, kit }) => {
|
|
4858
|
+
const {
|
|
4859
|
+
PAINT_GRADIENT_MAPPINGS,
|
|
4860
|
+
PAINT_GRADIENT_MAPPING_LABELS,
|
|
4861
|
+
PAINT_GRADIENT_PRESETS,
|
|
4862
|
+
PAINT_GRADIENT_REPEATS,
|
|
4863
|
+
PAINT_GRADIENT_REPEAT_LABELS,
|
|
4864
|
+
PAINT_GRADIENT_SPACES,
|
|
4865
|
+
PAINT_GRADIENT_SPACE_LABELS,
|
|
4866
|
+
addPaintGradientStop,
|
|
4867
|
+
paintGradientMappingFor,
|
|
4868
|
+
paintSourceCss,
|
|
4869
|
+
removePaintGradientStop,
|
|
4870
|
+
reversePaintGradient,
|
|
4871
|
+
updatePaintGradientStop
|
|
4872
|
+
} = kit;
|
|
4873
|
+
const [selected, setSelected] = (0, import_react40.useState)(0);
|
|
4874
|
+
const sel = Math.min(selected, value.stops.length - 1);
|
|
4875
|
+
const stop = value.stops[sel];
|
|
4876
|
+
const map = value.map;
|
|
4877
|
+
const stopHex = (c) => c === "paint" ? colors.paint : c === "secondary" ? colors.secondary : c;
|
|
4878
|
+
const patchStop = (patch) => {
|
|
4879
|
+
const r = updatePaintGradientStop(value, sel, patch);
|
|
4880
|
+
setSelected(r.index);
|
|
4881
|
+
onChange(r.paint);
|
|
4882
|
+
};
|
|
4883
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: `flex flex-col gap-1.5 text-xs text-slate-200 ${className ?? ""}`, "data-testid": "paint-gradient-editor", "aria-label": "Gradient paint", children: [
|
|
4884
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex items-center gap-1", children: [
|
|
4885
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("select", { "aria-label": "Gradient preset", className: select, value: "", onChange: (e) => e.target.value && (setSelected(0), onChange(PAINT_GRADIENT_PRESETS[Number(e.target.value)].paint)), children: [
|
|
4886
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("option", { value: "", children: "Presets\u2026" }),
|
|
4887
|
+
PAINT_GRADIENT_PRESETS.map((p, i) => /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("option", { value: i, children: p.name }, p.name))
|
|
4888
|
+
] }),
|
|
4889
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("button", { type: "button", className: button2, onClick: () => onChange(reversePaintGradient(value)), children: "Reverse" })
|
|
4890
|
+
] }),
|
|
4891
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
4892
|
+
"div",
|
|
4893
|
+
{
|
|
4894
|
+
role: "slider",
|
|
4895
|
+
tabIndex: 0,
|
|
4896
|
+
"aria-label": "Gradient ramp: click to add a stop",
|
|
4897
|
+
"aria-valuemin": 0,
|
|
4898
|
+
"aria-valuemax": 100,
|
|
4899
|
+
"aria-valuenow": pct(stop.offset),
|
|
4900
|
+
"data-testid": "paint-gradient-ramp",
|
|
4901
|
+
className: "relative h-6 cursor-copy rounded ring-1 ring-slate-700",
|
|
4902
|
+
style: { background: paintSourceCss(value, colors) },
|
|
4903
|
+
onClick: (e) => {
|
|
4904
|
+
const rect = e.currentTarget.getBoundingClientRect();
|
|
4905
|
+
const r = addPaintGradientStop(value, rect.width ? (e.clientX - rect.left) / rect.width : 0.5, colors);
|
|
4906
|
+
if (r.index >= 0) {
|
|
4907
|
+
setSelected(r.index);
|
|
4908
|
+
onChange(r.paint);
|
|
4909
|
+
}
|
|
4910
|
+
}
|
|
4911
|
+
}
|
|
4912
|
+
),
|
|
4913
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "relative h-4", "aria-label": "Stops", children: value.stops.map((s, i) => /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
4914
|
+
"button",
|
|
4915
|
+
{
|
|
4916
|
+
type: "button",
|
|
4917
|
+
"aria-label": `Stop ${i + 1} at ${pct(s.offset)}%`,
|
|
4918
|
+
"aria-pressed": i === sel,
|
|
4919
|
+
className: `absolute top-0 h-4 w-3 -translate-x-1/2 rounded-sm ring-1 ${i === sel ? "ring-white" : "ring-slate-600"}`,
|
|
4920
|
+
style: { left: `${s.offset * 100}%`, background: stopHex(s.color) },
|
|
4921
|
+
onClick: () => setSelected(i)
|
|
4922
|
+
},
|
|
4923
|
+
i
|
|
4924
|
+
)) }),
|
|
4925
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex flex-wrap items-center gap-1", "data-testid": "paint-gradient-stop", children: [
|
|
4926
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("select", { "aria-label": "Stop colour source", className: select, value: stop.color === "paint" || stop.color === "secondary" ? stop.color : "color", onChange: (e) => patchStop({ color: e.target.value === "color" ? stopHex(stop.color) : e.target.value }), children: [
|
|
4927
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("option", { value: "color", children: "Colour" }),
|
|
4928
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("option", { value: "paint", children: "Paint colour" }),
|
|
4929
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("option", { value: "secondary", children: "Second colour" })
|
|
4930
|
+
] }),
|
|
4931
|
+
stop.color !== "paint" && stop.color !== "secondary" && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("input", { type: "color", "aria-label": "Stop colour", value: stop.color, onChange: (e) => patchStop({ color: e.target.value }), className: "h-6 w-8 rounded bg-transparent" }),
|
|
4932
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("label", { className: "flex items-center gap-1", children: [
|
|
4933
|
+
"At",
|
|
4934
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("input", { type: "number", "aria-label": "Stop position", min: 0, max: 100, step: 1, value: pct(stop.offset), onChange: (e) => patchStop({ offset: Number(e.target.value) / 100 }), className: number }),
|
|
4935
|
+
"%"
|
|
4936
|
+
] }),
|
|
4937
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("label", { className: "flex items-center gap-1", children: [
|
|
4938
|
+
"Opacity",
|
|
4939
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("input", { type: "number", "aria-label": "Stop opacity", min: 0, max: 100, step: 5, value: pct(stop.opacity ?? 1), onChange: (e) => patchStop({ opacity: Number(e.target.value) / 100 }), className: number }),
|
|
4940
|
+
"%"
|
|
4941
|
+
] }),
|
|
4942
|
+
sel < value.stops.length - 1 && /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("label", { className: "flex items-center gap-1", children: [
|
|
4943
|
+
"Midpoint",
|
|
4944
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("input", { type: "number", "aria-label": "Stop midpoint", min: 5, max: 95, step: 1, value: pct(stop.midpoint ?? 0.5), onChange: (e) => patchStop({ midpoint: Number(e.target.value) / 100 }), className: number }),
|
|
4945
|
+
"%"
|
|
4946
|
+
] }),
|
|
4947
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("button", { type: "button", className: button2, disabled: value.stops.length <= 2, onClick: () => (setSelected(Math.max(0, sel - 1)), onChange(removePaintGradientStop(value, sel))), children: "Remove stop" })
|
|
4948
|
+
] }),
|
|
4949
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex flex-wrap items-center gap-1", "data-testid": "paint-gradient-mapping", children: [
|
|
4950
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("select", { "aria-label": "Gradient follows", className: select, value: map.by, onChange: (e) => onChange({ ...value, map: paintGradientMappingFor(e.target.value, map) }), children: PAINT_GRADIENT_MAPPINGS.map((m) => /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("option", { value: m, children: PAINT_GRADIENT_MAPPING_LABELS[m] }, m)) }),
|
|
4951
|
+
map.by === "distance" && /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(import_jsx_runtime23.Fragment, { children: [
|
|
4952
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("input", { type: "number", "aria-label": "Gradient length", min: 1, max: 1e5, value: map.length, onChange: (e) => onChange({ ...value, map: { ...map, length: Math.max(1, Number(e.target.value) || 1) } }), className: number }),
|
|
4953
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("select", { "aria-label": "Gradient length unit", className: select, value: map.unit ?? "px", onChange: (e) => onChange({ ...value, map: { ...map, unit: e.target.value } }), children: [
|
|
4954
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("option", { value: "px", children: "px" }),
|
|
4955
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("option", { value: "dabs", children: "dabs" })
|
|
4956
|
+
] })
|
|
4957
|
+
] }),
|
|
4958
|
+
map.by === "time" && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("input", { type: "number", "aria-label": "Gradient duration", min: 1, max: 6e5, value: map.duration, onChange: (e) => onChange({ ...value, map: { ...map, duration: Math.max(1, Number(e.target.value) || 1) } }), className: number }),
|
|
4959
|
+
map.by === "random" && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("input", { type: "number", "aria-label": "Dabs per pick", min: 1, max: 500, value: map.every ?? 1, onChange: (e) => onChange({ ...value, map: { ...map, every: Math.max(1, Math.round(Number(e.target.value) || 1)) } }), className: number }),
|
|
4960
|
+
(map.by === "distance" || map.by === "time") && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("select", { "aria-label": "Gradient repeat", className: select, value: map.repeat ?? "clamp", onChange: (e) => onChange({ ...value, map: { ...map, repeat: e.target.value } }), children: PAINT_GRADIENT_REPEATS.map((r) => /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("option", { value: r, children: PAINT_GRADIENT_REPEAT_LABELS[r] }, r)) })
|
|
4961
|
+
] }),
|
|
4962
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex items-center gap-1", children: [
|
|
4963
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("select", { "aria-label": "Gradient mixing", className: select, value: value.space, onChange: (e) => onChange({ ...value, space: e.target.value }), children: PAINT_GRADIENT_SPACES.map((s) => /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("option", { value: s, children: PAINT_GRADIENT_SPACE_LABELS[s] }, s)) }),
|
|
4964
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("label", { className: "flex flex-1 items-center gap-1", children: [
|
|
4965
|
+
"Softness",
|
|
4966
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("input", { type: "range", "aria-label": "Gradient softness", min: 0, max: 1, step: 0.05, value: value.softness ?? 1, onChange: (e) => onChange({ ...value, softness: Number(e.target.value) }), className: "flex-1 accent-indigo-500" })
|
|
4967
|
+
] })
|
|
4968
|
+
] })
|
|
4969
|
+
] });
|
|
4970
|
+
};
|
|
4971
|
+
|
|
4972
|
+
// src/image-editor/PaintGradientEditor.tsx
|
|
4973
|
+
var import_jsx_runtime24 = require("react/jsx-runtime");
|
|
4974
|
+
var PaintGradientEditor = (props) => /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(PaintGradientEditorView, { ...props, kit: import_image_editor8.PAINT_GRADIENT_KIT });
|
|
4975
|
+
|
|
4976
|
+
// src/image-editor/BrushOptionsBar.tsx
|
|
4977
|
+
var import_jsx_runtime25 = require("react/jsx-runtime");
|
|
4845
4978
|
var chip = (on) => `px-2 py-1 rounded text-[11px] ${on ? "bg-indigo-600 text-white" : "bg-slate-800 text-slate-300 hover:text-white"}`;
|
|
4846
4979
|
var BrushOptionsBar = ({ controller, className }) => {
|
|
4847
|
-
const [, setTick] = (0,
|
|
4848
|
-
(0,
|
|
4849
|
-
const [error, setError] = (0,
|
|
4980
|
+
const [, setTick] = (0, import_react41.useState)(0);
|
|
4981
|
+
(0, import_react41.useEffect)(() => controller.subscribe(() => setTick((n) => n + 1)), [controller]);
|
|
4982
|
+
const [error, setError] = (0, import_react41.useState)(null);
|
|
4850
4983
|
const state = controller.getState();
|
|
4851
|
-
const { brush, foreground, background, mixer, mixerLoad, retouch, cloneSource } = state.paint;
|
|
4984
|
+
const { brush, foreground, background, mixer, mixerLoad, retouch, cloneSource, paint } = state.paint;
|
|
4852
4985
|
const tool = state.activeTool;
|
|
4853
4986
|
const attempt = (fn) => {
|
|
4854
4987
|
try {
|
|
@@ -4858,8 +4991,8 @@ var BrushOptionsBar = ({ controller, className }) => {
|
|
|
4858
4991
|
setError(err instanceof Error ? err.message : String(err));
|
|
4859
4992
|
}
|
|
4860
4993
|
};
|
|
4861
|
-
return /* @__PURE__ */ (0,
|
|
4862
|
-
/* @__PURE__ */ (0,
|
|
4994
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: `flex flex-col gap-2 text-xs text-slate-200 ${className ?? ""}`, "data-testid": "brush-options", children: [
|
|
4995
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "flex flex-wrap gap-1", role: "toolbar", "aria-label": "Paint tools", children: import_image_editor9.PAINT_TOOLS.map((t) => /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
4863
4996
|
"button",
|
|
4864
4997
|
{
|
|
4865
4998
|
type: "button",
|
|
@@ -4871,9 +5004,9 @@ var BrushOptionsBar = ({ controller, className }) => {
|
|
|
4871
5004
|
},
|
|
4872
5005
|
t.id
|
|
4873
5006
|
)) }),
|
|
4874
|
-
/* @__PURE__ */ (0,
|
|
4875
|
-
/* @__PURE__ */ (0,
|
|
4876
|
-
/* @__PURE__ */ (0,
|
|
5007
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "flex items-center gap-2", role: "group", "aria-label": "Colours", children: [
|
|
5008
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("label", { className: "flex items-center gap-1", children: [
|
|
5009
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
4877
5010
|
"input",
|
|
4878
5011
|
{
|
|
4879
5012
|
type: "color",
|
|
@@ -4883,10 +5016,10 @@ var BrushOptionsBar = ({ controller, className }) => {
|
|
|
4883
5016
|
className: "h-6 w-8 rounded border border-slate-700 bg-transparent"
|
|
4884
5017
|
}
|
|
4885
5018
|
),
|
|
4886
|
-
/* @__PURE__ */ (0,
|
|
5019
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: "text-slate-400", children: "FG" })
|
|
4887
5020
|
] }),
|
|
4888
|
-
/* @__PURE__ */ (0,
|
|
4889
|
-
/* @__PURE__ */ (0,
|
|
5021
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("label", { className: "flex items-center gap-1", children: [
|
|
5022
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
4890
5023
|
"input",
|
|
4891
5024
|
{
|
|
4892
5025
|
type: "color",
|
|
@@ -4896,12 +5029,24 @@ var BrushOptionsBar = ({ controller, className }) => {
|
|
|
4896
5029
|
className: "h-6 w-8 rounded border border-slate-700 bg-transparent"
|
|
4897
5030
|
}
|
|
4898
5031
|
),
|
|
4899
|
-
/* @__PURE__ */ (0,
|
|
5032
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: "text-slate-400", children: "BG" })
|
|
4900
5033
|
] }),
|
|
4901
|
-
/* @__PURE__ */ (0,
|
|
4902
|
-
/* @__PURE__ */ (0,
|
|
5034
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("button", { type: "button", title: "Swap colours (X)", className: chip(false), onClick: () => controller.swapPaintColors(), children: "Swap" }),
|
|
5035
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("button", { type: "button", title: "Default colours (D)", className: chip(false), onClick: () => controller.resetPaintColors(), children: "Default" }),
|
|
5036
|
+
state.activeTool === "brush" && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
5037
|
+
"button",
|
|
5038
|
+
{
|
|
5039
|
+
type: "button",
|
|
5040
|
+
"aria-pressed": paint.type === "gradient",
|
|
5041
|
+
title: "Gradient paint: the brush changes colour as the stroke goes",
|
|
5042
|
+
className: chip(paint.type === "gradient"),
|
|
5043
|
+
onClick: () => attempt(() => controller.setPaintOptions(paint.type === "gradient" ? { foreground } : { paint: import_image_editor10.DEFAULT_PAINT_GRADIENT })),
|
|
5044
|
+
children: "Gradient"
|
|
5045
|
+
}
|
|
5046
|
+
)
|
|
4903
5047
|
] }),
|
|
4904
|
-
|
|
5048
|
+
state.activeTool === "brush" && paint.type === "gradient" && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(PaintGradientEditor, { value: paint, colors: { paint: foreground, secondary: background }, onChange: (g) => attempt(() => controller.setPaintOptions({ paint: g })) }),
|
|
5049
|
+
import_image_editor9.BRUSH_OPTION_CONTROLS.map((spec) => /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
4905
5050
|
ControlSlider,
|
|
4906
5051
|
{
|
|
4907
5052
|
spec,
|
|
@@ -4910,21 +5055,21 @@ var BrushOptionsBar = ({ controller, className }) => {
|
|
|
4910
5055
|
},
|
|
4911
5056
|
spec.id
|
|
4912
5057
|
)),
|
|
4913
|
-
state.activeTool === "mixer" && /* @__PURE__ */ (0,
|
|
4914
|
-
/* @__PURE__ */ (0,
|
|
4915
|
-
/* @__PURE__ */ (0,
|
|
5058
|
+
state.activeTool === "mixer" && /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "flex flex-col gap-2 border-t border-slate-800 pt-2", role: "group", "aria-label": "Mixer Brush", "data-testid": "mixer-options", children: [
|
|
5059
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
5060
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
4916
5061
|
"span",
|
|
4917
5062
|
{
|
|
4918
5063
|
"aria-label": "Brush load",
|
|
4919
|
-
title: mixerLoad.reservoir ? `Loaded ${(0,
|
|
5064
|
+
title: mixerLoad.reservoir ? `Loaded ${(0, import_image_editor9.rgbUnitToHex)(mixerLoad.reservoir)}, ${Math.round(mixerLoad.amount * 100)}% left` : "Unloaded",
|
|
4920
5065
|
className: "h-6 w-6 rounded border border-slate-700",
|
|
4921
|
-
style: { background: mixerLoad.reservoir ? (0,
|
|
5066
|
+
style: { background: mixerLoad.reservoir ? (0, import_image_editor9.rgbUnitToHex)(mixerLoad.reservoir) : "transparent" }
|
|
4922
5067
|
}
|
|
4923
5068
|
),
|
|
4924
|
-
/* @__PURE__ */ (0,
|
|
4925
|
-
/* @__PURE__ */ (0,
|
|
5069
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("button", { type: "button", title: "Fill the reservoir with the foreground colour", className: chip(false), onClick: () => controller.loadMixerBrush(), children: "Load brush" }),
|
|
5070
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("button", { type: "button", title: "Empty the picked-up colour", className: chip(false), onClick: () => controller.cleanMixerBrush(), children: "Clean brush" })
|
|
4926
5071
|
] }),
|
|
4927
|
-
/* @__PURE__ */ (0,
|
|
5072
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "flex gap-1", role: "group", "aria-label": "Mixing", children: import_image_editor9.MIXER_MIXING_OPTIONS.map((m) => /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
4928
5073
|
"button",
|
|
4929
5074
|
{
|
|
4930
5075
|
type: "button",
|
|
@@ -4936,10 +5081,10 @@ var BrushOptionsBar = ({ controller, className }) => {
|
|
|
4936
5081
|
},
|
|
4937
5082
|
m.id
|
|
4938
5083
|
)) }),
|
|
4939
|
-
|
|
4940
|
-
/* @__PURE__ */ (0,
|
|
4941
|
-
/* @__PURE__ */ (0,
|
|
4942
|
-
/* @__PURE__ */ (0,
|
|
5084
|
+
import_image_editor9.MIXER_OPTION_CONTROLS.map((spec) => /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(ControlSlider, { spec, value: mixer[spec.id], onChange: (v) => controller.setPaintOptions({ mixer: { [spec.id]: v } }) }, spec.id)),
|
|
5085
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "flex flex-wrap gap-3 text-slate-300", children: [
|
|
5086
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("label", { className: "flex items-center gap-1.5", children: [
|
|
5087
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
4943
5088
|
"input",
|
|
4944
5089
|
{
|
|
4945
5090
|
type: "checkbox",
|
|
@@ -4951,8 +5096,8 @@ var BrushOptionsBar = ({ controller, className }) => {
|
|
|
4951
5096
|
),
|
|
4952
5097
|
"Load each stroke"
|
|
4953
5098
|
] }),
|
|
4954
|
-
/* @__PURE__ */ (0,
|
|
4955
|
-
/* @__PURE__ */ (0,
|
|
5099
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("label", { className: "flex items-center gap-1.5", children: [
|
|
5100
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
4956
5101
|
"input",
|
|
4957
5102
|
{
|
|
4958
5103
|
type: "checkbox",
|
|
@@ -4966,29 +5111,29 @@ var BrushOptionsBar = ({ controller, className }) => {
|
|
|
4966
5111
|
] })
|
|
4967
5112
|
] })
|
|
4968
5113
|
] }),
|
|
4969
|
-
(0,
|
|
4970
|
-
(tool === "clone" || tool === "heal") && /* @__PURE__ */ (0,
|
|
4971
|
-
/* @__PURE__ */ (0,
|
|
4972
|
-
cloneSource && /* @__PURE__ */ (0,
|
|
5114
|
+
(0, import_image_editor9.isRetouchPaintTool)(tool) && /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "flex flex-col gap-2 border-t border-slate-800 pt-2", role: "group", "aria-label": "Retouch options", "data-testid": "retouch-options", children: [
|
|
5115
|
+
(tool === "clone" || tool === "heal") && /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
5116
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: "text-slate-400", "data-testid": "clone-source", children: (0, import_image_editor9.cloneSourceLabel)(controller) }),
|
|
5117
|
+
cloneSource && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("button", { type: "button", title: "Forget the source point", className: chip(false), onClick: () => controller.setCloneSource(null), children: "Clear source" })
|
|
4973
5118
|
] }),
|
|
4974
|
-
|
|
4975
|
-
/* @__PURE__ */ (0,
|
|
4976
|
-
choice.options.map((o) => /* @__PURE__ */ (0,
|
|
5119
|
+
import_image_editor9.RETOUCH_CHOICES.filter((c) => c.tools.includes(tool)).map((choice) => /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "flex flex-wrap items-center gap-1", role: "group", "aria-label": choice.label, children: [
|
|
5120
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: "text-slate-400", children: choice.label }),
|
|
5121
|
+
choice.options.map((o) => /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
4977
5122
|
"button",
|
|
4978
5123
|
{
|
|
4979
5124
|
type: "button",
|
|
4980
5125
|
"aria-pressed": retouch[choice.id] === o.id,
|
|
4981
5126
|
title: o.title,
|
|
4982
5127
|
className: chip(retouch[choice.id] === o.id),
|
|
4983
|
-
onClick: () => (0,
|
|
5128
|
+
onClick: () => (0, import_image_editor9.setRetouchChoice)(controller, choice.id, o.id),
|
|
4984
5129
|
children: o.label
|
|
4985
5130
|
},
|
|
4986
5131
|
o.id
|
|
4987
5132
|
))
|
|
4988
5133
|
] }, choice.id)),
|
|
4989
|
-
|
|
4990
|
-
/* @__PURE__ */ (0,
|
|
4991
|
-
/* @__PURE__ */ (0,
|
|
5134
|
+
import_image_editor9.RETOUCH_OPTION_CONTROLS.filter((c) => c.tools.includes(tool)).map((spec) => /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(ControlSlider, { spec, value: retouch[spec.id], onChange: (v) => controller.setPaintOptions({ retouch: { [spec.id]: v } }) }, spec.id)),
|
|
5135
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "flex flex-wrap gap-3 text-slate-300", children: import_image_editor9.RETOUCH_TOGGLES.filter((t) => t.tools.includes(tool)).map((t) => /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("label", { className: "flex items-center gap-1.5", children: [
|
|
5136
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
4992
5137
|
"input",
|
|
4993
5138
|
{
|
|
4994
5139
|
type: "checkbox",
|
|
@@ -5001,9 +5146,9 @@ var BrushOptionsBar = ({ controller, className }) => {
|
|
|
5001
5146
|
t.label
|
|
5002
5147
|
] }, t.id)) })
|
|
5003
5148
|
] }),
|
|
5004
|
-
/* @__PURE__ */ (0,
|
|
5005
|
-
/* @__PURE__ */ (0,
|
|
5006
|
-
/* @__PURE__ */ (0,
|
|
5149
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "flex flex-wrap gap-3 text-slate-300", role: "group", "aria-label": "Pressure", children: [
|
|
5150
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("label", { className: "flex items-center gap-1.5", children: [
|
|
5151
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
5007
5152
|
"input",
|
|
5008
5153
|
{
|
|
5009
5154
|
type: "checkbox",
|
|
@@ -5015,8 +5160,8 @@ var BrushOptionsBar = ({ controller, className }) => {
|
|
|
5015
5160
|
),
|
|
5016
5161
|
"Pressure size"
|
|
5017
5162
|
] }),
|
|
5018
|
-
/* @__PURE__ */ (0,
|
|
5019
|
-
/* @__PURE__ */ (0,
|
|
5163
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("label", { className: "flex items-center gap-1.5", children: [
|
|
5164
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
5020
5165
|
"input",
|
|
5021
5166
|
{
|
|
5022
5167
|
type: "checkbox",
|
|
@@ -5029,28 +5174,28 @@ var BrushOptionsBar = ({ controller, className }) => {
|
|
|
5029
5174
|
"Pressure opacity"
|
|
5030
5175
|
] })
|
|
5031
5176
|
] }),
|
|
5032
|
-
/* @__PURE__ */ (0,
|
|
5033
|
-
/* @__PURE__ */ (0,
|
|
5034
|
-
/* @__PURE__ */ (0,
|
|
5177
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "flex gap-1", children: [
|
|
5178
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("button", { type: "button", className: chip(false), onClick: () => attempt(() => controller.fillPixels()), children: "Fill" }),
|
|
5179
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("button", { type: "button", className: chip(false), onClick: () => attempt(() => controller.clearPixels()), children: "Clear" })
|
|
5035
5180
|
] }),
|
|
5036
|
-
error && /* @__PURE__ */ (0,
|
|
5181
|
+
error && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("p", { role: "alert", className: "text-rose-400", children: error })
|
|
5037
5182
|
] });
|
|
5038
5183
|
};
|
|
5039
5184
|
|
|
5040
5185
|
// src/image-editor/ColorProfilePanel.tsx
|
|
5041
|
-
var
|
|
5042
|
-
var
|
|
5043
|
-
var
|
|
5186
|
+
var import_react42 = require("react");
|
|
5187
|
+
var import_image_editor11 = require("@pixerate/editor/image-editor");
|
|
5188
|
+
var import_jsx_runtime26 = require("react/jsx-runtime");
|
|
5044
5189
|
var chip2 = "px-2 py-1 rounded text-[11px] bg-slate-800 text-slate-300 hover:text-white";
|
|
5045
|
-
var
|
|
5190
|
+
var select2 = "rounded bg-slate-800 px-1 py-0.5 text-[11px] text-slate-200";
|
|
5046
5191
|
var ColorProfilePanel = ({ controller, className }) => {
|
|
5047
|
-
const [, setTick] = (0,
|
|
5048
|
-
(0,
|
|
5049
|
-
const [target, setTarget] = (0,
|
|
5050
|
-
const [intent, setIntent] = (0,
|
|
5051
|
-
const [bpc, setBpc] = (0,
|
|
5052
|
-
const [error, setError] = (0,
|
|
5053
|
-
const view = (0,
|
|
5192
|
+
const [, setTick] = (0, import_react42.useState)(0);
|
|
5193
|
+
(0, import_react42.useEffect)(() => controller.subscribe(() => setTick((n) => n + 1)), [controller]);
|
|
5194
|
+
const [target, setTarget] = (0, import_react42.useState)("display-p3");
|
|
5195
|
+
const [intent, setIntent] = (0, import_react42.useState)("relative");
|
|
5196
|
+
const [bpc, setBpc] = (0, import_react42.useState)(true);
|
|
5197
|
+
const [error, setError] = (0, import_react42.useState)(null);
|
|
5198
|
+
const view = (0, import_image_editor11.colorPanelView)(controller);
|
|
5054
5199
|
const attempt = (fn) => {
|
|
5055
5200
|
try {
|
|
5056
5201
|
setError(null);
|
|
@@ -5071,61 +5216,61 @@ var ColorProfilePanel = ({ controller, className }) => {
|
|
|
5071
5216
|
})
|
|
5072
5217
|
);
|
|
5073
5218
|
};
|
|
5074
|
-
return /* @__PURE__ */ (0,
|
|
5075
|
-
/* @__PURE__ */ (0,
|
|
5076
|
-
/* @__PURE__ */ (0,
|
|
5077
|
-
/* @__PURE__ */ (0,
|
|
5219
|
+
return /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: `flex flex-col gap-2 text-xs text-slate-200 ${className ?? ""}`, "data-testid": "color-profile-panel", children: [
|
|
5220
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
5221
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { className: "text-slate-400", children: "Profile" }),
|
|
5222
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { "data-testid": "color-profile-name", children: view.profileName })
|
|
5078
5223
|
] }),
|
|
5079
|
-
/* @__PURE__ */ (0,
|
|
5080
|
-
/* @__PURE__ */ (0,
|
|
5081
|
-
/* @__PURE__ */ (0,
|
|
5082
|
-
view.cmykProfileName && /* @__PURE__ */ (0,
|
|
5224
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "flex flex-wrap items-center gap-1", role: "group", "aria-label": "Colour mode", children: [
|
|
5225
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { className: "text-slate-400", children: "Mode" }),
|
|
5226
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("select", { "aria-label": "Colour mode", className: select2, value: view.mode, onChange: (e) => attempt(() => controller.setColorMode(e.target.value)), children: import_image_editor11.COLOR_MODE_OPTIONS.map((o) => /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("option", { value: o.id, title: o.title, children: o.label }, o.id)) }),
|
|
5227
|
+
view.cmykProfileName && /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { className: "text-slate-400", children: view.cmykProfileName })
|
|
5083
5228
|
] }),
|
|
5084
|
-
/* @__PURE__ */ (0,
|
|
5085
|
-
/* @__PURE__ */ (0,
|
|
5086
|
-
/* @__PURE__ */ (0,
|
|
5087
|
-
/* @__PURE__ */ (0,
|
|
5088
|
-
/* @__PURE__ */ (0,
|
|
5229
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "flex flex-wrap items-center gap-1", role: "group", "aria-label": "Assign or convert", children: [
|
|
5230
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("select", { "aria-label": "Target profile", className: select2, value: target, onChange: (e) => setTarget(e.target.value), children: import_image_editor11.WORKING_SPACE_OPTIONS.map((o) => /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("option", { value: o.id, children: o.label }, o.id)) }),
|
|
5231
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("select", { "aria-label": "Rendering intent", className: select2, value: intent, onChange: (e) => setIntent(e.target.value), children: import_image_editor11.INTENT_OPTIONS.map((o) => /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("option", { value: o.id, title: o.title, children: o.label }, o.id)) }),
|
|
5232
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("label", { className: "flex items-center gap-1", children: [
|
|
5233
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("input", { type: "checkbox", "aria-label": "Black point compensation", checked: bpc, onChange: (e) => setBpc(e.target.checked), className: "accent-indigo-500" }),
|
|
5089
5234
|
"BPC"
|
|
5090
5235
|
] }),
|
|
5091
|
-
/* @__PURE__ */ (0,
|
|
5092
|
-
/* @__PURE__ */ (0,
|
|
5236
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("button", { type: "button", className: chip2, title: "Edit \u203A Assign Profile: keep the numbers", onClick: () => attempt(() => controller.assignProfile(target)), children: "Assign" }),
|
|
5237
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("button", { type: "button", className: chip2, title: "Edit \u203A Convert to Profile: keep the look", onClick: () => attempt(() => controller.convertToProfile(target, { intent, bpc })), children: "Convert" })
|
|
5093
5238
|
] }),
|
|
5094
|
-
/* @__PURE__ */ (0,
|
|
5095
|
-
/* @__PURE__ */ (0,
|
|
5096
|
-
/* @__PURE__ */ (0,
|
|
5239
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "flex flex-wrap items-center gap-1", role: "group", "aria-label": "Proof setup", children: [
|
|
5240
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { className: "text-slate-400", children: "Proof" }),
|
|
5241
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(
|
|
5097
5242
|
"select",
|
|
5098
5243
|
{
|
|
5099
5244
|
"aria-label": "Proof profile",
|
|
5100
|
-
className:
|
|
5245
|
+
className: select2,
|
|
5101
5246
|
value: view.proof?.id ?? "",
|
|
5102
5247
|
onChange: (e) => e.target.value ? proofWith({ id: e.target.value }) : attempt(() => controller.setProofSetup(null)),
|
|
5103
5248
|
children: [
|
|
5104
|
-
/* @__PURE__ */ (0,
|
|
5105
|
-
|
|
5249
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("option", { value: "", children: "Off" }),
|
|
5250
|
+
import_image_editor11.PROOF_PROFILE_OPTIONS.map((o) => /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("option", { value: o.id, children: o.label }, o.id))
|
|
5106
5251
|
]
|
|
5107
5252
|
}
|
|
5108
5253
|
),
|
|
5109
|
-
view.proof && /* @__PURE__ */ (0,
|
|
5110
|
-
/* @__PURE__ */ (0,
|
|
5111
|
-
/* @__PURE__ */ (0,
|
|
5112
|
-
/* @__PURE__ */ (0,
|
|
5254
|
+
view.proof && /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(import_jsx_runtime26.Fragment, { children: [
|
|
5255
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("select", { "aria-label": "Proof intent", className: select2, value: view.proof.intent, onChange: (e) => proofWith({ intent: e.target.value }), children: import_image_editor11.INTENT_OPTIONS.map((o) => /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("option", { value: o.id, children: o.label }, o.id)) }),
|
|
5256
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("label", { className: "flex items-center gap-1", children: [
|
|
5257
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("input", { type: "checkbox", "aria-label": "Simulate paper colour", checked: view.proof.simulatePaper, onChange: (e) => proofWith({ simulatePaper: e.target.checked }), className: "accent-indigo-500" }),
|
|
5113
5258
|
"Paper"
|
|
5114
5259
|
] }),
|
|
5115
|
-
/* @__PURE__ */ (0,
|
|
5116
|
-
/* @__PURE__ */ (0,
|
|
5260
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("label", { className: "flex items-center gap-1", children: [
|
|
5261
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("input", { type: "checkbox", "aria-label": "Gamut warning", checked: view.proof.gamutWarning, onChange: (e) => proofWith({ gamutWarning: e.target.checked }), className: "accent-indigo-500" }),
|
|
5117
5262
|
"Gamut warning"
|
|
5118
5263
|
] })
|
|
5119
5264
|
] })
|
|
5120
5265
|
] }),
|
|
5121
|
-
error && /* @__PURE__ */ (0,
|
|
5266
|
+
error && /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("p", { role: "alert", className: "text-rose-400", children: error })
|
|
5122
5267
|
] });
|
|
5123
5268
|
};
|
|
5124
5269
|
|
|
5125
5270
|
// src/image-editor/SelectionOptionsBar.tsx
|
|
5126
|
-
var
|
|
5127
|
-
var
|
|
5128
|
-
var
|
|
5271
|
+
var import_react43 = require("react");
|
|
5272
|
+
var import_image_editor12 = require("@pixerate/editor/image-editor");
|
|
5273
|
+
var import_jsx_runtime27 = require("react/jsx-runtime");
|
|
5129
5274
|
var MODIFY_OPS = [
|
|
5130
5275
|
{ op: "grow", label: "Grow" },
|
|
5131
5276
|
{ op: "shrink", label: "Shrink" },
|
|
@@ -5142,20 +5287,20 @@ var SelectionOptionsBar = ({
|
|
|
5142
5287
|
quickMask,
|
|
5143
5288
|
className = ""
|
|
5144
5289
|
}) => {
|
|
5145
|
-
const [radius, setRadius] = (0,
|
|
5290
|
+
const [radius, setRadius] = (0, import_react43.useState)(2);
|
|
5146
5291
|
const set = (patch) => onOptionsChange({ ...options, ...patch });
|
|
5147
5292
|
const sel = selection === void 0 ? controller.getSelection() : selection;
|
|
5148
5293
|
const qm = quickMask ?? Boolean(controller.getState().quickMask);
|
|
5149
|
-
return /* @__PURE__ */ (0,
|
|
5150
|
-
/* @__PURE__ */ (0,
|
|
5151
|
-
/* @__PURE__ */ (0,
|
|
5152
|
-
options.tool === "wand" && /* @__PURE__ */ (0,
|
|
5153
|
-
/* @__PURE__ */ (0,
|
|
5154
|
-
/* @__PURE__ */ (0,
|
|
5155
|
-
/* @__PURE__ */ (0,
|
|
5156
|
-
/* @__PURE__ */ (0,
|
|
5294
|
+
return /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { "data-testid": "selection-options-bar", className: `flex flex-col gap-3 text-xs ${className}`, children: [
|
|
5295
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { role: "group", "aria-label": "Selection tool", className: "flex flex-wrap gap-1", children: import_image_editor12.SELECTION_TOOLS.map((t) => /* @__PURE__ */ (0, import_jsx_runtime27.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)) }),
|
|
5296
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { role: "group", "aria-label": "Selection mode", className: "flex flex-wrap gap-1", children: import_image_editor12.SELECTION_MODES.map((m) => /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("button", { type: "button", "aria-pressed": options.mode === m, className: btn(options.mode === m), onClick: () => set({ mode: m }), children: import_image_editor12.SELECTION_MODE_LABELS[m] }, m)) }),
|
|
5297
|
+
options.tool === "wand" && /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "flex flex-col gap-2", children: [
|
|
5298
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("label", { className: "flex flex-col gap-1", children: [
|
|
5299
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("span", { className: "flex justify-between text-slate-400", children: [
|
|
5300
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { children: "Tolerance" }),
|
|
5301
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: "font-mono", children: options.tolerance })
|
|
5157
5302
|
] }),
|
|
5158
|
-
/* @__PURE__ */ (0,
|
|
5303
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
5159
5304
|
"input",
|
|
5160
5305
|
{
|
|
5161
5306
|
type: "range",
|
|
@@ -5169,17 +5314,17 @@ var SelectionOptionsBar = ({
|
|
|
5169
5314
|
}
|
|
5170
5315
|
)
|
|
5171
5316
|
] }),
|
|
5172
|
-
/* @__PURE__ */ (0,
|
|
5173
|
-
/* @__PURE__ */ (0,
|
|
5317
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("label", { className: "flex items-center gap-2 text-slate-300", children: [
|
|
5318
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("input", { type: "checkbox", checked: options.contiguous, onChange: (e) => set({ contiguous: e.target.checked }) }),
|
|
5174
5319
|
"Contiguous"
|
|
5175
5320
|
] }),
|
|
5176
|
-
/* @__PURE__ */ (0,
|
|
5177
|
-
/* @__PURE__ */ (0,
|
|
5321
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("label", { className: "flex items-center gap-2 text-slate-300", children: [
|
|
5322
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("input", { type: "checkbox", checked: options.sampleMerged, onChange: (e) => set({ sampleMerged: e.target.checked }) }),
|
|
5178
5323
|
"Sample adjusted image"
|
|
5179
5324
|
] }),
|
|
5180
|
-
/* @__PURE__ */ (0,
|
|
5325
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("label", { className: "flex items-center gap-2 text-slate-300", children: [
|
|
5181
5326
|
"Sample",
|
|
5182
|
-
/* @__PURE__ */ (0,
|
|
5327
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(
|
|
5183
5328
|
"select",
|
|
5184
5329
|
{
|
|
5185
5330
|
"aria-label": "Sample from",
|
|
@@ -5187,27 +5332,27 @@ var SelectionOptionsBar = ({
|
|
|
5187
5332
|
onChange: (e) => set({ sample: e.target.value }),
|
|
5188
5333
|
className: "bg-slate-800 border border-slate-700 rounded px-1 py-0.5",
|
|
5189
5334
|
children: [
|
|
5190
|
-
/* @__PURE__ */ (0,
|
|
5191
|
-
/* @__PURE__ */ (0,
|
|
5335
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("option", { value: "composite", children: "All layers" }),
|
|
5336
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("option", { value: "active-layer", children: "Active layer" })
|
|
5192
5337
|
]
|
|
5193
5338
|
}
|
|
5194
5339
|
)
|
|
5195
5340
|
] })
|
|
5196
5341
|
] }),
|
|
5197
|
-
/* @__PURE__ */ (0,
|
|
5198
|
-
/* @__PURE__ */ (0,
|
|
5342
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("label", { className: "flex items-center gap-2 text-slate-300", children: [
|
|
5343
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("input", { type: "checkbox", checked: options.antiAlias, onChange: (e) => set({ antiAlias: e.target.checked }) }),
|
|
5199
5344
|
"Anti-alias"
|
|
5200
5345
|
] }),
|
|
5201
|
-
/* @__PURE__ */ (0,
|
|
5202
|
-
/* @__PURE__ */ (0,
|
|
5203
|
-
/* @__PURE__ */ (0,
|
|
5204
|
-
/* @__PURE__ */ (0,
|
|
5205
|
-
/* @__PURE__ */ (0,
|
|
5346
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "flex flex-wrap gap-1", children: [
|
|
5347
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("button", { type: "button", className: btn(false), onClick: () => controller.selectAll(), children: "Select All" }),
|
|
5348
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("button", { type: "button", className: btn(false), disabled: !sel, onClick: () => controller.deselect(), children: "Deselect" }),
|
|
5349
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("button", { type: "button", className: btn(false), onClick: () => controller.invertSelection(), children: "Inverse" }),
|
|
5350
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("button", { type: "button", "aria-pressed": qm, className: btn(qm), onClick: () => controller.setQuickMask(!qm), children: "Quick Mask" })
|
|
5206
5351
|
] }),
|
|
5207
|
-
/* @__PURE__ */ (0,
|
|
5208
|
-
/* @__PURE__ */ (0,
|
|
5352
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "flex flex-wrap items-center gap-1", children: [
|
|
5353
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("label", { className: "flex items-center gap-1 text-slate-400", children: [
|
|
5209
5354
|
"Radius",
|
|
5210
|
-
/* @__PURE__ */ (0,
|
|
5355
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
5211
5356
|
"input",
|
|
5212
5357
|
{
|
|
5213
5358
|
type: "number",
|
|
@@ -5221,24 +5366,24 @@ var SelectionOptionsBar = ({
|
|
|
5221
5366
|
}
|
|
5222
5367
|
)
|
|
5223
5368
|
] }),
|
|
5224
|
-
MODIFY_OPS.map(({ op, label }) => /* @__PURE__ */ (0,
|
|
5369
|
+
MODIFY_OPS.map(({ op, label }) => /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("button", { type: "button", className: btn(false), disabled: !sel, onClick: () => controller.modifySelection(op, radius), children: label }, op))
|
|
5225
5370
|
] }),
|
|
5226
|
-
/* @__PURE__ */ (0,
|
|
5371
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("p", { "data-testid": "selection-status", className: "text-slate-400", children: (0, import_image_editor12.describeSelection)(sel) })
|
|
5227
5372
|
] });
|
|
5228
5373
|
};
|
|
5229
5374
|
|
|
5230
5375
|
// src/image-editor/RefineEdgePanel.tsx
|
|
5231
|
-
var
|
|
5232
|
-
var
|
|
5233
|
-
var
|
|
5376
|
+
var import_react44 = require("react");
|
|
5377
|
+
var import_image_editor13 = require("@pixerate/editor/image-editor");
|
|
5378
|
+
var import_jsx_runtime28 = require("react/jsx-runtime");
|
|
5234
5379
|
var DEFAULT_PARAMS = { radius: 8, smartRadius: false, smooth: 0, feather: 0, contrast: 0, shiftEdge: 0 };
|
|
5235
|
-
var
|
|
5380
|
+
var button3 = "px-2 py-1 rounded-md border border-slate-800 bg-slate-950 text-[11px] text-slate-200 hover:text-white disabled:opacity-40";
|
|
5236
5381
|
var RefineEdgePanel = ({ controller, selection, layers, className = "" }) => {
|
|
5237
|
-
const [params, setParams] = (0,
|
|
5238
|
-
const [busy, setBusy] = (0,
|
|
5239
|
-
const [error, setError] = (0,
|
|
5240
|
-
const [layerId, setLayerId] = (0,
|
|
5241
|
-
const [newKind, setNewKind] = (0,
|
|
5382
|
+
const [params, setParams] = (0, import_react44.useState)(DEFAULT_PARAMS);
|
|
5383
|
+
const [busy, setBusy] = (0, import_react44.useState)(false);
|
|
5384
|
+
const [error, setError] = (0, import_react44.useState)(null);
|
|
5385
|
+
const [layerId, setLayerId] = (0, import_react44.useState)("");
|
|
5386
|
+
const [newKind, setNewKind] = (0, import_react44.useState)("hueSaturation");
|
|
5242
5387
|
const sel = selection === void 0 ? controller.getSelection() : selection;
|
|
5243
5388
|
const list = layers ?? controller.getAdjustmentLayers();
|
|
5244
5389
|
const target = list.find((l) => l.id === layerId) ?? list[list.length - 1];
|
|
@@ -5253,17 +5398,17 @@ var RefineEdgePanel = ({ controller, selection, layers, className = "" }) => {
|
|
|
5253
5398
|
setBusy(false);
|
|
5254
5399
|
}
|
|
5255
5400
|
};
|
|
5256
|
-
return /* @__PURE__ */ (0,
|
|
5257
|
-
/* @__PURE__ */ (0,
|
|
5258
|
-
|
|
5259
|
-
/* @__PURE__ */ (0,
|
|
5260
|
-
/* @__PURE__ */ (0,
|
|
5261
|
-
/* @__PURE__ */ (0,
|
|
5401
|
+
return /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { "data-testid": "refine-edge-panel", className: `flex flex-col gap-3 text-xs ${className}`, children: [
|
|
5402
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Refine Edge" }),
|
|
5403
|
+
import_image_editor13.REFINE_EDGE_CONTROLS.map((c) => /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("label", { className: "flex flex-col gap-1", children: [
|
|
5404
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("span", { className: "flex justify-between text-slate-400", children: [
|
|
5405
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", { children: c.label }),
|
|
5406
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("span", { className: "font-mono", children: [
|
|
5262
5407
|
params[c.id],
|
|
5263
5408
|
c.unit
|
|
5264
5409
|
] })
|
|
5265
5410
|
] }),
|
|
5266
|
-
/* @__PURE__ */ (0,
|
|
5411
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
5267
5412
|
"input",
|
|
5268
5413
|
{
|
|
5269
5414
|
type: "range",
|
|
@@ -5277,67 +5422,67 @@ var RefineEdgePanel = ({ controller, selection, layers, className = "" }) => {
|
|
|
5277
5422
|
}
|
|
5278
5423
|
)
|
|
5279
5424
|
] }, c.id)),
|
|
5280
|
-
/* @__PURE__ */ (0,
|
|
5281
|
-
/* @__PURE__ */ (0,
|
|
5425
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("label", { className: "flex items-center gap-2 text-slate-300", children: [
|
|
5426
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)("input", { type: "checkbox", checked: params.smartRadius, onChange: (e) => setParams({ ...params, smartRadius: e.target.checked }) }),
|
|
5282
5427
|
"Smart Radius"
|
|
5283
5428
|
] }),
|
|
5284
|
-
/* @__PURE__ */ (0,
|
|
5285
|
-
/* @__PURE__ */ (0,
|
|
5286
|
-
/* @__PURE__ */ (0,
|
|
5429
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: "flex gap-1", children: [
|
|
5430
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)("button", { type: "button", className: button3, disabled: !sel || busy, onClick: refine, children: "Refine Edge" }),
|
|
5431
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)("button", { type: "button", className: button3, onClick: () => setParams(DEFAULT_PARAMS), children: "Reset" })
|
|
5287
5432
|
] }),
|
|
5288
|
-
error && /* @__PURE__ */ (0,
|
|
5289
|
-
/* @__PURE__ */ (0,
|
|
5290
|
-
/* @__PURE__ */ (0,
|
|
5291
|
-
/* @__PURE__ */ (0,
|
|
5433
|
+
error && /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("p", { role: "alert", className: "text-rose-400", children: error }),
|
|
5434
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px] mt-2", children: "Layer Mask" }),
|
|
5435
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: "flex gap-1 items-center", children: [
|
|
5436
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
5292
5437
|
"select",
|
|
5293
5438
|
{
|
|
5294
5439
|
"aria-label": "New masked layer kind",
|
|
5295
5440
|
value: newKind,
|
|
5296
5441
|
onChange: (e) => setNewKind(e.target.value),
|
|
5297
5442
|
className: "flex-1 bg-slate-950 border border-slate-800 rounded px-1 py-1 text-slate-200",
|
|
5298
|
-
children:
|
|
5443
|
+
children: import_image_editor13.ADJUSTMENT_KINDS.map((k) => /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("option", { value: k.kind, children: k.label }, k.kind))
|
|
5299
5444
|
}
|
|
5300
5445
|
),
|
|
5301
|
-
/* @__PURE__ */ (0,
|
|
5446
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
5302
5447
|
"button",
|
|
5303
5448
|
{
|
|
5304
5449
|
type: "button",
|
|
5305
|
-
className:
|
|
5450
|
+
className: button3,
|
|
5306
5451
|
disabled: !sel,
|
|
5307
|
-
onClick: () => sel && setLayerId(controller.addAdjustmentLayer({ kind: newKind, mask: (0,
|
|
5452
|
+
onClick: () => sel && setLayerId(controller.addAdjustmentLayer({ kind: newKind, mask: (0, import_image_editor13.layerMaskFromSelection)(sel) })),
|
|
5308
5453
|
children: "New Masked Layer"
|
|
5309
5454
|
}
|
|
5310
5455
|
)
|
|
5311
5456
|
] }),
|
|
5312
|
-
list.length > 0 && target && /* @__PURE__ */ (0,
|
|
5313
|
-
/* @__PURE__ */ (0,
|
|
5457
|
+
list.length > 0 && target && /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: "flex flex-col gap-2", children: [
|
|
5458
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
5314
5459
|
"select",
|
|
5315
5460
|
{
|
|
5316
5461
|
"aria-label": "Mask layer",
|
|
5317
5462
|
value: target.id,
|
|
5318
5463
|
onChange: (e) => setLayerId(e.target.value),
|
|
5319
5464
|
className: "bg-slate-950 border border-slate-800 rounded px-1 py-1 text-slate-200",
|
|
5320
|
-
children: list.map((l) => /* @__PURE__ */ (0,
|
|
5321
|
-
l.name || (0,
|
|
5465
|
+
children: list.map((l) => /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("option", { value: l.id, children: [
|
|
5466
|
+
l.name || (0, import_image_editor13.adjustmentKindLabel)(l.kind),
|
|
5322
5467
|
l.mask ? " (masked)" : ""
|
|
5323
5468
|
] }, l.id))
|
|
5324
5469
|
}
|
|
5325
5470
|
),
|
|
5326
|
-
/* @__PURE__ */ (0,
|
|
5327
|
-
/* @__PURE__ */ (0,
|
|
5328
|
-
/* @__PURE__ */ (0,
|
|
5329
|
-
/* @__PURE__ */ (0,
|
|
5471
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: "flex flex-wrap gap-1", children: [
|
|
5472
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)("button", { type: "button", className: button3, disabled: !sel, onClick: () => controller.applySelectionAsLayerMask(target.id), children: "Mask with Selection" }),
|
|
5473
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)("button", { type: "button", className: button3, disabled: !target.mask, onClick: () => controller.selectionFromLayerMask(target.id), children: "Load as Selection" }),
|
|
5474
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)("button", { type: "button", className: button3, disabled: !target.mask, onClick: () => controller.setAdjustmentLayerMask(target.id, null), children: "Remove Mask" })
|
|
5330
5475
|
] }),
|
|
5331
|
-
target.mask && /* @__PURE__ */ (0,
|
|
5332
|
-
/* @__PURE__ */ (0,
|
|
5333
|
-
/* @__PURE__ */ (0,
|
|
5334
|
-
/* @__PURE__ */ (0,
|
|
5335
|
-
/* @__PURE__ */ (0,
|
|
5476
|
+
target.mask && /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(import_jsx_runtime28.Fragment, { children: [
|
|
5477
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("label", { className: "flex flex-col gap-1", children: [
|
|
5478
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("span", { className: "flex justify-between text-slate-400", children: [
|
|
5479
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", { children: "Density" }),
|
|
5480
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("span", { className: "font-mono", children: [
|
|
5336
5481
|
Math.round((target.mask.density ?? 1) * 100),
|
|
5337
5482
|
"%"
|
|
5338
5483
|
] })
|
|
5339
5484
|
] }),
|
|
5340
|
-
/* @__PURE__ */ (0,
|
|
5485
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
5341
5486
|
"input",
|
|
5342
5487
|
{
|
|
5343
5488
|
type: "range",
|
|
@@ -5351,15 +5496,15 @@ var RefineEdgePanel = ({ controller, selection, layers, className = "" }) => {
|
|
|
5351
5496
|
}
|
|
5352
5497
|
)
|
|
5353
5498
|
] }),
|
|
5354
|
-
/* @__PURE__ */ (0,
|
|
5355
|
-
/* @__PURE__ */ (0,
|
|
5356
|
-
/* @__PURE__ */ (0,
|
|
5357
|
-
/* @__PURE__ */ (0,
|
|
5499
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("label", { className: "flex flex-col gap-1", children: [
|
|
5500
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("span", { className: "flex justify-between text-slate-400", children: [
|
|
5501
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", { children: "Mask Feather" }),
|
|
5502
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("span", { className: "font-mono", children: [
|
|
5358
5503
|
target.mask.feather ?? 0,
|
|
5359
5504
|
"px"
|
|
5360
5505
|
] })
|
|
5361
5506
|
] }),
|
|
5362
|
-
/* @__PURE__ */ (0,
|
|
5507
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
5363
5508
|
"input",
|
|
5364
5509
|
{
|
|
5365
5510
|
type: "range",
|
|
@@ -5379,14 +5524,14 @@ var RefineEdgePanel = ({ controller, selection, layers, className = "" }) => {
|
|
|
5379
5524
|
};
|
|
5380
5525
|
|
|
5381
5526
|
// src/image-editor/FreeTransformOptionsBar.tsx
|
|
5382
|
-
var
|
|
5383
|
-
var
|
|
5384
|
-
var
|
|
5527
|
+
var import_react45 = require("react");
|
|
5528
|
+
var import_image_editor14 = require("@pixerate/editor/image-editor");
|
|
5529
|
+
var import_jsx_runtime29 = require("react/jsx-runtime");
|
|
5385
5530
|
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"}`;
|
|
5386
5531
|
var round = (v, unit) => unit === "px" ? Math.round(v * 10) / 10 : Math.round(v * 100) / 100;
|
|
5387
5532
|
var FreeTransformOptionsBar = ({ tool, className }) => {
|
|
5388
|
-
const [, setTick] = (0,
|
|
5389
|
-
(0,
|
|
5533
|
+
const [, setTick] = (0, import_react45.useState)(0);
|
|
5534
|
+
(0, import_react45.useEffect)(() => tool.subscribe(() => setTick((n) => n + 1)), [tool]);
|
|
5390
5535
|
const bar = tool.bar();
|
|
5391
5536
|
if (!tool.active || !bar) return null;
|
|
5392
5537
|
const warp = tool.warpBar();
|
|
@@ -5398,17 +5543,17 @@ var FreeTransformOptionsBar = ({ tool, className }) => {
|
|
|
5398
5543
|
const v = Number(raw);
|
|
5399
5544
|
if (raw.trim() !== "" && Number.isFinite(v) && Math.abs(v - bar[field]) > 1e-9) tool.setField(field, v);
|
|
5400
5545
|
};
|
|
5401
|
-
return /* @__PURE__ */ (0,
|
|
5402
|
-
/* @__PURE__ */ (0,
|
|
5403
|
-
/* @__PURE__ */ (0,
|
|
5404
|
-
tool.mode === "warp" && /* @__PURE__ */ (0,
|
|
5405
|
-
/* @__PURE__ */ (0,
|
|
5406
|
-
/* @__PURE__ */ (0,
|
|
5407
|
-
/* @__PURE__ */ (0,
|
|
5546
|
+
return /* @__PURE__ */ (0, import_jsx_runtime29.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: [
|
|
5547
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: "flex gap-1", role: "group", "aria-label": "Transform mode", children: import_image_editor14.FREE_TRANSFORM_MODE_OPTIONS.map((m) => /* @__PURE__ */ (0, import_jsx_runtime29.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)) }),
|
|
5548
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: "grid grid-cols-3 gap-px", role: "group", "aria-label": "Reference point", children: import_image_editor14.TRANSFORM_ANCHORS.map((a) => /* @__PURE__ */ (0, import_jsx_runtime29.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)) }),
|
|
5549
|
+
tool.mode === "warp" && /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "flex flex-wrap items-center gap-2", role: "group", "aria-label": "Warp options", children: [
|
|
5550
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("label", { className: "flex items-center gap-1", children: [
|
|
5551
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { className: "text-slate-400", children: "Warp" }),
|
|
5552
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.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_editor14.WARP_STYLE_OPTIONS.map((o) => /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("option", { value: o.id, children: o.label }, o.id)) })
|
|
5408
5553
|
] }),
|
|
5409
|
-
["bend", "horizontal", "vertical"].map((k) => /* @__PURE__ */ (0,
|
|
5410
|
-
/* @__PURE__ */ (0,
|
|
5411
|
-
/* @__PURE__ */ (0,
|
|
5554
|
+
["bend", "horizontal", "vertical"].map((k) => /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("label", { className: "flex items-center gap-1", children: [
|
|
5555
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { className: "text-slate-400", children: k === "bend" ? "Bend" : k === "horizontal" ? "H" : "V" }),
|
|
5556
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
5412
5557
|
"input",
|
|
5413
5558
|
{
|
|
5414
5559
|
type: "number",
|
|
@@ -5429,9 +5574,9 @@ var FreeTransformOptionsBar = ({ tool, className }) => {
|
|
|
5429
5574
|
},
|
|
5430
5575
|
`${k}:${warp[k]}`
|
|
5431
5576
|
),
|
|
5432
|
-
/* @__PURE__ */ (0,
|
|
5577
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { className: "text-slate-500", children: "%" })
|
|
5433
5578
|
] }, k)),
|
|
5434
|
-
/* @__PURE__ */ (0,
|
|
5579
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
5435
5580
|
"button",
|
|
5436
5581
|
{
|
|
5437
5582
|
type: "button",
|
|
@@ -5443,26 +5588,26 @@ var FreeTransformOptionsBar = ({ tool, className }) => {
|
|
|
5443
5588
|
children: "Vertical"
|
|
5444
5589
|
}
|
|
5445
5590
|
),
|
|
5446
|
-
/* @__PURE__ */ (0,
|
|
5447
|
-
/* @__PURE__ */ (0,
|
|
5448
|
-
/* @__PURE__ */ (0,
|
|
5591
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("label", { className: "flex items-center gap-1", children: [
|
|
5592
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { className: "text-slate-400", children: "Grid" }),
|
|
5593
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
5449
5594
|
"select",
|
|
5450
5595
|
{
|
|
5451
5596
|
"aria-label": "Warp grid",
|
|
5452
|
-
value:
|
|
5597
|
+
value: import_image_editor14.WARP_GRID_OPTIONS.find((g) => g.columns === warp.columns && g.rows === warp.rows)?.id ?? "1x1",
|
|
5453
5598
|
onChange: (e) => {
|
|
5454
|
-
const g =
|
|
5599
|
+
const g = import_image_editor14.WARP_GRID_OPTIONS.find((o) => o.id === e.target.value);
|
|
5455
5600
|
tool.setWarp({ columns: g.columns, rows: g.rows });
|
|
5456
5601
|
},
|
|
5457
5602
|
className: "rounded border border-slate-700 bg-slate-900 px-1 py-0.5",
|
|
5458
|
-
children:
|
|
5603
|
+
children: import_image_editor14.WARP_GRID_OPTIONS.map((g) => /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("option", { value: g.id, children: g.label }, g.id))
|
|
5459
5604
|
}
|
|
5460
5605
|
)
|
|
5461
5606
|
] })
|
|
5462
5607
|
] }),
|
|
5463
|
-
tool.mode !== "warp" &&
|
|
5464
|
-
/* @__PURE__ */ (0,
|
|
5465
|
-
/* @__PURE__ */ (0,
|
|
5608
|
+
tool.mode !== "warp" && import_image_editor14.FREE_TRANSFORM_FIELDS.map((f) => /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("label", { className: "flex items-center gap-1", title: f.title, children: [
|
|
5609
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { className: "text-slate-400", children: f.label }),
|
|
5610
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
5466
5611
|
"input",
|
|
5467
5612
|
{
|
|
5468
5613
|
type: "number",
|
|
@@ -5482,8 +5627,8 @@ var FreeTransformOptionsBar = ({ tool, className }) => {
|
|
|
5482
5627
|
},
|
|
5483
5628
|
`${f.id}:${round(bar[f.id], f.unit)}`
|
|
5484
5629
|
),
|
|
5485
|
-
/* @__PURE__ */ (0,
|
|
5486
|
-
f.id === "scaleX" && /* @__PURE__ */ (0,
|
|
5630
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { className: "text-slate-500", children: f.unit }),
|
|
5631
|
+
f.id === "scaleX" && /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
5487
5632
|
"button",
|
|
5488
5633
|
{
|
|
5489
5634
|
type: "button",
|
|
@@ -5498,34 +5643,34 @@ var FreeTransformOptionsBar = ({ tool, className }) => {
|
|
|
5498
5643
|
}
|
|
5499
5644
|
)
|
|
5500
5645
|
] }, f.id)),
|
|
5501
|
-
/* @__PURE__ */ (0,
|
|
5502
|
-
/* @__PURE__ */ (0,
|
|
5503
|
-
/* @__PURE__ */ (0,
|
|
5646
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("label", { className: "flex items-center gap-1", children: [
|
|
5647
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { className: "text-slate-400", children: "Interpolation" }),
|
|
5648
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
5504
5649
|
"select",
|
|
5505
5650
|
{
|
|
5506
5651
|
"aria-label": "Interpolation",
|
|
5507
5652
|
value: tool.interpolation,
|
|
5508
5653
|
onChange: (e) => tool.setInterpolation(e.target.value),
|
|
5509
5654
|
className: "rounded border border-slate-700 bg-slate-900 px-1 py-0.5",
|
|
5510
|
-
children:
|
|
5655
|
+
children: import_image_editor14.INTERPOLATIONS.map((i) => /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("option", { value: i, children: i[0].toUpperCase() + i.slice(1) }, i))
|
|
5511
5656
|
}
|
|
5512
5657
|
)
|
|
5513
5658
|
] }),
|
|
5514
|
-
/* @__PURE__ */ (0,
|
|
5515
|
-
/* @__PURE__ */ (0,
|
|
5516
|
-
tool.error && /* @__PURE__ */ (0,
|
|
5659
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.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" }),
|
|
5660
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)("button", { type: "button", title: "Cancel (Esc)", className: chip3(false), onClick: () => tool.cancel(), children: "Cancel" }),
|
|
5661
|
+
tool.error && /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { role: "alert", className: "text-rose-400", children: tool.error })
|
|
5517
5662
|
] });
|
|
5518
5663
|
};
|
|
5519
5664
|
|
|
5520
5665
|
// src/image-editor/ShapeOptionsBar.tsx
|
|
5521
|
-
var
|
|
5522
|
-
var
|
|
5523
|
-
var
|
|
5666
|
+
var import_react46 = require("react");
|
|
5667
|
+
var import_image_editor15 = require("@pixerate/editor/image-editor");
|
|
5668
|
+
var import_jsx_runtime30 = require("react/jsx-runtime");
|
|
5524
5669
|
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"}`;
|
|
5525
5670
|
var ShapeOptionsBar = ({ controller, options, onChange, className }) => {
|
|
5526
|
-
const [, setTick] = (0,
|
|
5527
|
-
(0,
|
|
5528
|
-
const [error, setError] = (0,
|
|
5671
|
+
const [, setTick] = (0, import_react46.useState)(0);
|
|
5672
|
+
(0, import_react46.useEffect)(() => controller.subscribe(() => setTick((n) => n + 1)), [controller]);
|
|
5673
|
+
const [error, setError] = (0, import_react46.useState)(null);
|
|
5529
5674
|
const active = controller.getActiveLayer();
|
|
5530
5675
|
const shapeId = active?.type === "shape" ? active.id : null;
|
|
5531
5676
|
const set = (change) => {
|
|
@@ -5533,19 +5678,19 @@ var ShapeOptionsBar = ({ controller, options, onChange, className }) => {
|
|
|
5533
5678
|
if (!shapeId) return;
|
|
5534
5679
|
try {
|
|
5535
5680
|
setError(null);
|
|
5536
|
-
(0,
|
|
5681
|
+
(0, import_image_editor15.applyShapeOptions)(controller, shapeId, change);
|
|
5537
5682
|
} catch (e) {
|
|
5538
5683
|
setError(e instanceof Error ? e.message : String(e));
|
|
5539
5684
|
}
|
|
5540
5685
|
};
|
|
5541
5686
|
const num = (v, min, max) => Math.max(min, Math.min(max, Number(v) || min));
|
|
5542
|
-
return /* @__PURE__ */ (0,
|
|
5543
|
-
/* @__PURE__ */ (0,
|
|
5544
|
-
/* @__PURE__ */ (0,
|
|
5545
|
-
/* @__PURE__ */ (0,
|
|
5546
|
-
/* @__PURE__ */ (0,
|
|
5687
|
+
return /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: `flex flex-col gap-2 text-xs text-slate-200 ${className ?? ""}`, "data-testid": "shape-options", children: [
|
|
5688
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("div", { className: "flex flex-wrap gap-1", role: "toolbar", "aria-label": "Shape kind", children: import_image_editor15.LIVE_SHAPE_KINDS.map((k) => /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("button", { type: "button", "aria-pressed": options.kind === k, className: chip4(options.kind === k), onClick: () => onChange({ ...options, kind: k }), children: import_image_editor15.SHAPE_KIND_LABELS[k] }, k)) }),
|
|
5689
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "flex flex-wrap items-center gap-3", children: [
|
|
5690
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("label", { className: "flex items-center gap-1", children: [
|
|
5691
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("input", { type: "checkbox", "aria-label": "Fill", checked: options.fill !== null, onChange: (e) => set({ fill: e.target.checked ? "#4f46e5" : null }) }),
|
|
5547
5692
|
"Fill",
|
|
5548
|
-
/* @__PURE__ */ (0,
|
|
5693
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
5549
5694
|
"input",
|
|
5550
5695
|
{
|
|
5551
5696
|
type: "color",
|
|
@@ -5557,10 +5702,10 @@ var ShapeOptionsBar = ({ controller, options, onChange, className }) => {
|
|
|
5557
5702
|
}
|
|
5558
5703
|
)
|
|
5559
5704
|
] }),
|
|
5560
|
-
/* @__PURE__ */ (0,
|
|
5561
|
-
/* @__PURE__ */ (0,
|
|
5705
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("label", { className: "flex items-center gap-1", children: [
|
|
5706
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("input", { type: "checkbox", "aria-label": "Stroke", checked: options.stroke !== null, onChange: (e) => set({ stroke: e.target.checked ? "#000000" : null }) }),
|
|
5562
5707
|
"Stroke",
|
|
5563
|
-
/* @__PURE__ */ (0,
|
|
5708
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
5564
5709
|
"input",
|
|
5565
5710
|
{
|
|
5566
5711
|
type: "color",
|
|
@@ -5572,9 +5717,9 @@ var ShapeOptionsBar = ({ controller, options, onChange, className }) => {
|
|
|
5572
5717
|
}
|
|
5573
5718
|
)
|
|
5574
5719
|
] }),
|
|
5575
|
-
/* @__PURE__ */ (0,
|
|
5720
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("label", { className: "flex items-center gap-1", children: [
|
|
5576
5721
|
"Width",
|
|
5577
|
-
/* @__PURE__ */ (0,
|
|
5722
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
5578
5723
|
"input",
|
|
5579
5724
|
{
|
|
5580
5725
|
type: "number",
|
|
@@ -5588,23 +5733,23 @@ var ShapeOptionsBar = ({ controller, options, onChange, className }) => {
|
|
|
5588
5733
|
)
|
|
5589
5734
|
] })
|
|
5590
5735
|
] }),
|
|
5591
|
-
/* @__PURE__ */ (0,
|
|
5592
|
-
options.kind === "rect" && /* @__PURE__ */ (0,
|
|
5736
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "flex flex-wrap items-center gap-3", children: [
|
|
5737
|
+
options.kind === "rect" && /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("label", { className: "flex items-center gap-1", children: [
|
|
5593
5738
|
"Radius",
|
|
5594
|
-
/* @__PURE__ */ (0,
|
|
5739
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.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" })
|
|
5595
5740
|
] }),
|
|
5596
|
-
options.kind === "polygon" && /* @__PURE__ */ (0,
|
|
5741
|
+
options.kind === "polygon" && /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("label", { className: "flex items-center gap-1", children: [
|
|
5597
5742
|
"Sides",
|
|
5598
|
-
/* @__PURE__ */ (0,
|
|
5743
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.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" })
|
|
5599
5744
|
] }),
|
|
5600
|
-
options.kind === "star" && /* @__PURE__ */ (0,
|
|
5601
|
-
/* @__PURE__ */ (0,
|
|
5745
|
+
options.kind === "star" && /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(import_jsx_runtime30.Fragment, { children: [
|
|
5746
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("label", { className: "flex items-center gap-1", children: [
|
|
5602
5747
|
"Points",
|
|
5603
|
-
/* @__PURE__ */ (0,
|
|
5748
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.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" })
|
|
5604
5749
|
] }),
|
|
5605
|
-
/* @__PURE__ */ (0,
|
|
5750
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("label", { className: "flex items-center gap-1", children: [
|
|
5606
5751
|
"Inner",
|
|
5607
|
-
/* @__PURE__ */ (0,
|
|
5752
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
5608
5753
|
"input",
|
|
5609
5754
|
{
|
|
5610
5755
|
type: "range",
|
|
@@ -5619,33 +5764,33 @@ var ShapeOptionsBar = ({ controller, options, onChange, className }) => {
|
|
|
5619
5764
|
)
|
|
5620
5765
|
] })
|
|
5621
5766
|
] }),
|
|
5622
|
-
options.kind === "line" && /* @__PURE__ */ (0,
|
|
5623
|
-
/* @__PURE__ */ (0,
|
|
5767
|
+
options.kind === "line" && /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(import_jsx_runtime30.Fragment, { children: [
|
|
5768
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("label", { className: "flex items-center gap-1", children: [
|
|
5624
5769
|
"Weight",
|
|
5625
|
-
/* @__PURE__ */ (0,
|
|
5770
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.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" })
|
|
5626
5771
|
] }),
|
|
5627
|
-
/* @__PURE__ */ (0,
|
|
5628
|
-
/* @__PURE__ */ (0,
|
|
5772
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("label", { className: "flex items-center gap-1", children: [
|
|
5773
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("input", { type: "checkbox", "aria-label": "Arrowhead", checked: options.arrow, onChange: (e) => set({ arrow: e.target.checked }) }),
|
|
5629
5774
|
"Arrowhead"
|
|
5630
5775
|
] })
|
|
5631
5776
|
] })
|
|
5632
5777
|
] }),
|
|
5633
|
-
/* @__PURE__ */ (0,
|
|
5634
|
-
error && /* @__PURE__ */ (0,
|
|
5778
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.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." }),
|
|
5779
|
+
error && /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("p", { role: "alert", className: "text-rose-400", children: error })
|
|
5635
5780
|
] });
|
|
5636
5781
|
};
|
|
5637
5782
|
|
|
5638
5783
|
// src/image-editor/TypeOptionsBar.tsx
|
|
5639
|
-
var
|
|
5640
|
-
var
|
|
5641
|
-
var
|
|
5784
|
+
var import_react47 = require("react");
|
|
5785
|
+
var import_image_editor16 = require("@pixerate/editor/image-editor");
|
|
5786
|
+
var import_jsx_runtime31 = require("react/jsx-runtime");
|
|
5642
5787
|
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"}`;
|
|
5643
5788
|
var ALIGN_LABELS = { left: "Left", center: "Centre", right: "Right", justify: "Justify" };
|
|
5644
5789
|
var TypeOptionsBar = ({ controller, options, onChange, session, className }) => {
|
|
5645
|
-
const [, setTick] = (0,
|
|
5646
|
-
(0,
|
|
5647
|
-
(0,
|
|
5648
|
-
const [error, setError] = (0,
|
|
5790
|
+
const [, setTick] = (0, import_react47.useState)(0);
|
|
5791
|
+
(0, import_react47.useEffect)(() => controller.subscribe(() => setTick((n) => n + 1)), [controller]);
|
|
5792
|
+
(0, import_react47.useEffect)(() => session?.subscribe(() => setTick((n) => n + 1)), [session]);
|
|
5793
|
+
const [error, setError] = (0, import_react47.useState)(null);
|
|
5649
5794
|
const active = controller.getActiveLayer();
|
|
5650
5795
|
const typeId = !session && active?.type === "type" ? active.id : null;
|
|
5651
5796
|
const here = session?.alive ? session.styleHere() : {};
|
|
@@ -5677,11 +5822,11 @@ var TypeOptionsBar = ({ controller, options, onChange, session, className }) =>
|
|
|
5677
5822
|
setError(e instanceof Error ? e.message : String(e));
|
|
5678
5823
|
}
|
|
5679
5824
|
};
|
|
5680
|
-
return /* @__PURE__ */ (0,
|
|
5681
|
-
/* @__PURE__ */ (0,
|
|
5682
|
-
/* @__PURE__ */ (0,
|
|
5825
|
+
return /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("div", { className: `flex flex-col gap-2 text-xs text-slate-200 ${className ?? ""}`, "data-testid": "type-options", children: [
|
|
5826
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("div", { className: "flex flex-wrap items-center gap-2", children: [
|
|
5827
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("label", { className: "flex items-center gap-1", children: [
|
|
5683
5828
|
"Font",
|
|
5684
|
-
/* @__PURE__ */ (0,
|
|
5829
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
|
|
5685
5830
|
"input",
|
|
5686
5831
|
{
|
|
5687
5832
|
list: "pixerate-type-fonts",
|
|
@@ -5691,11 +5836,11 @@ var TypeOptionsBar = ({ controller, options, onChange, session, className }) =>
|
|
|
5691
5836
|
className: "w-32 rounded border border-slate-700 bg-slate-950 px-1 py-0.5"
|
|
5692
5837
|
}
|
|
5693
5838
|
),
|
|
5694
|
-
/* @__PURE__ */ (0,
|
|
5839
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)("datalist", { id: "pixerate-type-fonts", children: fonts.map((f) => /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("option", { value: f }, f)) })
|
|
5695
5840
|
] }),
|
|
5696
|
-
/* @__PURE__ */ (0,
|
|
5841
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("label", { className: "flex items-center gap-1", children: [
|
|
5697
5842
|
"Size",
|
|
5698
|
-
/* @__PURE__ */ (0,
|
|
5843
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
|
|
5699
5844
|
"input",
|
|
5700
5845
|
{
|
|
5701
5846
|
type: "number",
|
|
@@ -5708,24 +5853,24 @@ var TypeOptionsBar = ({ controller, options, onChange, session, className }) =>
|
|
|
5708
5853
|
}
|
|
5709
5854
|
)
|
|
5710
5855
|
] }),
|
|
5711
|
-
/* @__PURE__ */ (0,
|
|
5712
|
-
/* @__PURE__ */ (0,
|
|
5713
|
-
/* @__PURE__ */ (0,
|
|
5856
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.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" }),
|
|
5857
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)("button", { type: "button", "aria-pressed": shown.italic, className: `${chip5(shown.italic)} italic`, onClick: () => style({ italic: !shown.italic }), children: "I" }),
|
|
5858
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.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" })
|
|
5714
5859
|
] }),
|
|
5715
|
-
/* @__PURE__ */ (0,
|
|
5716
|
-
/* @__PURE__ */ (0,
|
|
5717
|
-
missing.length > 0 && /* @__PURE__ */ (0,
|
|
5860
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)("div", { className: "flex gap-1", role: "toolbar", "aria-label": "Alignment", children: import_image_editor16.TEXT_ALIGNS.map((a) => /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("button", { type: "button", "aria-pressed": options.align === a, className: chip5(options.align === a), onClick: () => style({ align: a }), children: ALIGN_LABELS[a] }, a)) }),
|
|
5861
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.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." }),
|
|
5862
|
+
missing.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("p", { role: "status", className: "text-amber-400", "data-testid": "type-missing-fonts", children: [
|
|
5718
5863
|
"Missing ",
|
|
5719
5864
|
missing.length === 1 ? "font" : "fonts",
|
|
5720
5865
|
": ",
|
|
5721
5866
|
missing.join(", ")
|
|
5722
5867
|
] }),
|
|
5723
|
-
error && /* @__PURE__ */ (0,
|
|
5868
|
+
error && /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("p", { role: "alert", className: "text-rose-400", children: error })
|
|
5724
5869
|
] });
|
|
5725
5870
|
};
|
|
5726
5871
|
|
|
5727
5872
|
// src/image-editor/ImageEditor.tsx
|
|
5728
|
-
var
|
|
5873
|
+
var import_jsx_runtime32 = require("react/jsx-runtime");
|
|
5729
5874
|
var ImageEditor = ({
|
|
5730
5875
|
editor: externalEditor,
|
|
5731
5876
|
src,
|
|
@@ -5740,65 +5885,65 @@ var ImageEditor = ({
|
|
|
5740
5885
|
const internalEditor = useImageEditor({ image: src });
|
|
5741
5886
|
const editor = externalEditor || internalEditor;
|
|
5742
5887
|
const { state, controller } = editor;
|
|
5743
|
-
const legacyProcess = (0,
|
|
5744
|
-
const canvasRef = (0,
|
|
5745
|
-
const containerRef = (0,
|
|
5746
|
-
const [activeTab, setActiveTab] = (0,
|
|
5747
|
-
const [activeCropRatio, setActiveCropRatio] = (0,
|
|
5748
|
-
const [selectionOptions, setSelectionOptions] = (0,
|
|
5749
|
-
const selectionOptionsRef = (0,
|
|
5888
|
+
const legacyProcess = (0, import_image_editor17.normalizeProcessVersion)(state.adjustments.process) < import_image_editor17.LATEST_PROCESS_VERSION;
|
|
5889
|
+
const canvasRef = (0, import_react48.useRef)(null);
|
|
5890
|
+
const containerRef = (0, import_react48.useRef)(null);
|
|
5891
|
+
const [activeTab, setActiveTab] = (0, import_react48.useState)("crop");
|
|
5892
|
+
const [activeCropRatio, setActiveCropRatio] = (0, import_react48.useState)(null);
|
|
5893
|
+
const [selectionOptions, setSelectionOptions] = (0, import_react48.useState)(import_image_editor17.DEFAULT_SELECTION_TOOL_OPTIONS);
|
|
5894
|
+
const selectionOptionsRef = (0, import_react48.useRef)(selectionOptions);
|
|
5750
5895
|
selectionOptionsRef.current = selectionOptions;
|
|
5751
|
-
const selectionGestureRef = (0,
|
|
5896
|
+
const selectionGestureRef = (0, import_react48.useRef)(null);
|
|
5752
5897
|
if (!selectionGestureRef.current || selectionGestureRef.current.controller !== controller) {
|
|
5753
|
-
selectionGestureRef.current = new
|
|
5898
|
+
selectionGestureRef.current = new import_image_editor17.SelectionGesture(controller, () => selectionOptionsRef.current);
|
|
5754
5899
|
}
|
|
5755
|
-
const selectionDraftRef = (0,
|
|
5756
|
-
const [selectionError, setSelectionError] = (0,
|
|
5757
|
-
const paintGestureRef = (0,
|
|
5758
|
-
const paintControllerRef = (0,
|
|
5900
|
+
const selectionDraftRef = (0, import_react48.useRef)(null);
|
|
5901
|
+
const [selectionError, setSelectionError] = (0, import_react48.useState)(null);
|
|
5902
|
+
const paintGestureRef = (0, import_react48.useRef)(null);
|
|
5903
|
+
const paintControllerRef = (0, import_react48.useRef)(controller);
|
|
5759
5904
|
if (!paintGestureRef.current || paintControllerRef.current !== controller) {
|
|
5760
|
-
paintGestureRef.current = new
|
|
5905
|
+
paintGestureRef.current = new import_image_editor17.PaintGesture(controller);
|
|
5761
5906
|
paintControllerRef.current = controller;
|
|
5762
5907
|
}
|
|
5763
|
-
const brushCursorRef = (0,
|
|
5764
|
-
const [paintError, setPaintError] = (0,
|
|
5765
|
-
const transformToolRef = (0,
|
|
5766
|
-
const transformControllerRef = (0,
|
|
5908
|
+
const brushCursorRef = (0, import_react48.useRef)(null);
|
|
5909
|
+
const [paintError, setPaintError] = (0, import_react48.useState)(null);
|
|
5910
|
+
const transformToolRef = (0, import_react48.useRef)(null);
|
|
5911
|
+
const transformControllerRef = (0, import_react48.useRef)(controller);
|
|
5767
5912
|
if (!transformToolRef.current || transformControllerRef.current !== controller) {
|
|
5768
5913
|
transformToolRef.current?.cancel();
|
|
5769
|
-
transformToolRef.current = new
|
|
5914
|
+
transformToolRef.current = new import_image_editor17.FreeTransformTool(controller, {
|
|
5770
5915
|
schedule: (run) => typeof requestAnimationFrame !== "undefined" ? requestAnimationFrame(run) : run()
|
|
5771
5916
|
});
|
|
5772
5917
|
transformControllerRef.current = controller;
|
|
5773
5918
|
}
|
|
5774
5919
|
const transformTool = transformToolRef.current;
|
|
5775
|
-
const [, setTransformTick] = (0,
|
|
5776
|
-
const [transformCursor, setTransformCursor] = (0,
|
|
5777
|
-
const [shapeOptions, setShapeOptions] = (0,
|
|
5778
|
-
const shapeOptionsRef = (0,
|
|
5920
|
+
const [, setTransformTick] = (0, import_react48.useState)(0);
|
|
5921
|
+
const [transformCursor, setTransformCursor] = (0, import_react48.useState)("default");
|
|
5922
|
+
const [shapeOptions, setShapeOptions] = (0, import_react48.useState)(import_image_editor17.DEFAULT_SHAPE_TOOL_OPTIONS);
|
|
5923
|
+
const shapeOptionsRef = (0, import_react48.useRef)(shapeOptions);
|
|
5779
5924
|
shapeOptionsRef.current = shapeOptions;
|
|
5780
|
-
const [typeOptions, setTypeOptions] = (0,
|
|
5781
|
-
const typeOptionsRef = (0,
|
|
5925
|
+
const [typeOptions, setTypeOptions] = (0, import_react48.useState)(import_image_editor17.DEFAULT_TYPE_TOOL_OPTIONS);
|
|
5926
|
+
const typeOptionsRef = (0, import_react48.useRef)(typeOptions);
|
|
5782
5927
|
typeOptionsRef.current = typeOptions;
|
|
5783
|
-
const shapeGestureRef = (0,
|
|
5784
|
-
const typeToolRef = (0,
|
|
5785
|
-
const shapeTypeControllerRef = (0,
|
|
5928
|
+
const shapeGestureRef = (0, import_react48.useRef)(null);
|
|
5929
|
+
const typeToolRef = (0, import_react48.useRef)(null);
|
|
5930
|
+
const shapeTypeControllerRef = (0, import_react48.useRef)(controller);
|
|
5786
5931
|
if (!shapeGestureRef.current || !typeToolRef.current || shapeTypeControllerRef.current !== controller) {
|
|
5787
5932
|
typeToolRef.current?.finish();
|
|
5788
|
-
shapeGestureRef.current = new
|
|
5789
|
-
typeToolRef.current = new
|
|
5933
|
+
shapeGestureRef.current = new import_image_editor17.ShapeDrawGesture(controller, () => shapeOptionsRef.current);
|
|
5934
|
+
typeToolRef.current = new import_image_editor17.TypeToolGesture(controller, () => typeOptionsRef.current);
|
|
5790
5935
|
shapeTypeControllerRef.current = controller;
|
|
5791
5936
|
}
|
|
5792
|
-
const typeInputRef = (0,
|
|
5793
|
-
const [typeSession, setTypeSession] = (0,
|
|
5794
|
-
const [shapeTypeError, setShapeTypeError] = (0,
|
|
5795
|
-
const [inpaintPrompt, setInpaintPrompt] = (0,
|
|
5796
|
-
const [inpaintMaskMode, setInpaintMaskMode] = (0,
|
|
5797
|
-
const [isRemovingBg, setIsRemovingBg] = (0,
|
|
5798
|
-
const [isInpainting, setIsInpainting] = (0,
|
|
5799
|
-
const [aiError, setAiError] = (0,
|
|
5800
|
-
const [aiSuccess, setAiSuccess] = (0,
|
|
5801
|
-
const [aiTarget, setAiTarget] = (0,
|
|
5937
|
+
const typeInputRef = (0, import_react48.useRef)(null);
|
|
5938
|
+
const [typeSession, setTypeSession] = (0, import_react48.useState)(typeToolRef.current.session);
|
|
5939
|
+
const [shapeTypeError, setShapeTypeError] = (0, import_react48.useState)(null);
|
|
5940
|
+
const [inpaintPrompt, setInpaintPrompt] = (0, import_react48.useState)("");
|
|
5941
|
+
const [inpaintMaskMode, setInpaintMaskMode] = (0, import_react48.useState)("annotations");
|
|
5942
|
+
const [isRemovingBg, setIsRemovingBg] = (0, import_react48.useState)(false);
|
|
5943
|
+
const [isInpainting, setIsInpainting] = (0, import_react48.useState)(false);
|
|
5944
|
+
const [aiError, setAiError] = (0, import_react48.useState)(null);
|
|
5945
|
+
const [aiSuccess, setAiSuccess] = (0, import_react48.useState)(null);
|
|
5946
|
+
const [aiTarget, setAiTarget] = (0, import_react48.useState)("auto");
|
|
5802
5947
|
const aiOptions = aiTarget === "auto" ? {} : { target: aiTarget };
|
|
5803
5948
|
const effectiveOnInpaint = onInpaint || aiHooks?.onInpaint;
|
|
5804
5949
|
const effectiveOnRemoveBg = onRemoveBackground || aiHooks?.onRemoveBackground;
|
|
@@ -5861,18 +6006,18 @@ var ImageEditor = ({
|
|
|
5861
6006
|
setIsInpainting(false);
|
|
5862
6007
|
}
|
|
5863
6008
|
};
|
|
5864
|
-
const [activeColor, setActiveColor] = (0,
|
|
5865
|
-
const [strokeWidth, setStrokeWidth] = (0,
|
|
5866
|
-
const [fontSize, setFontSize] = (0,
|
|
5867
|
-
const [textInput, setTextInput] = (0,
|
|
5868
|
-
const draftAnnotationRef = (0,
|
|
5869
|
-
const draftCropRef = (0,
|
|
5870
|
-
const cropDragInfoRef = (0,
|
|
5871
|
-
const annotationDragInfoRef = (0,
|
|
5872
|
-
const isDrawingRef = (0,
|
|
5873
|
-
const currentPathRef = (0,
|
|
5874
|
-
const dragStartPointRef = (0,
|
|
5875
|
-
const renderCanvas = (0,
|
|
6009
|
+
const [activeColor, setActiveColor] = (0, import_react48.useState)("#ef4444");
|
|
6010
|
+
const [strokeWidth, setStrokeWidth] = (0, import_react48.useState)(3);
|
|
6011
|
+
const [fontSize, setFontSize] = (0, import_react48.useState)(24);
|
|
6012
|
+
const [textInput, setTextInput] = (0, import_react48.useState)("");
|
|
6013
|
+
const draftAnnotationRef = (0, import_react48.useRef)(null);
|
|
6014
|
+
const draftCropRef = (0, import_react48.useRef)(null);
|
|
6015
|
+
const cropDragInfoRef = (0, import_react48.useRef)(null);
|
|
6016
|
+
const annotationDragInfoRef = (0, import_react48.useRef)(null);
|
|
6017
|
+
const isDrawingRef = (0, import_react48.useRef)(false);
|
|
6018
|
+
const currentPathRef = (0, import_react48.useRef)([]);
|
|
6019
|
+
const dragStartPointRef = (0, import_react48.useRef)(null);
|
|
6020
|
+
const renderCanvas = (0, import_react48.useCallback)(
|
|
5876
6021
|
async (draftAnnotation, draftCrop) => {
|
|
5877
6022
|
const canvas = canvasRef.current;
|
|
5878
6023
|
const container = containerRef.current;
|
|
@@ -5895,8 +6040,8 @@ var ImageEditor = ({
|
|
|
5895
6040
|
},
|
|
5896
6041
|
[controller, activeTab, transformTool]
|
|
5897
6042
|
);
|
|
5898
|
-
(0,
|
|
5899
|
-
(0,
|
|
6043
|
+
(0, import_react48.useEffect)(() => typeSession?.subscribe(() => void renderCanvas()), [typeSession, renderCanvas]);
|
|
6044
|
+
(0, import_react48.useEffect)(() => {
|
|
5900
6045
|
if (activeTab === "annotate" && state.activeTool === "type") return;
|
|
5901
6046
|
if (typeToolRef.current?.session) {
|
|
5902
6047
|
typeToolRef.current.finish();
|
|
@@ -5931,7 +6076,7 @@ var ImageEditor = ({
|
|
|
5931
6076
|
el.value = "";
|
|
5932
6077
|
}
|
|
5933
6078
|
};
|
|
5934
|
-
(0,
|
|
6079
|
+
(0, import_react48.useEffect)(() => transformTool.subscribe(() => {
|
|
5935
6080
|
setTransformTick((n) => n + 1);
|
|
5936
6081
|
void renderCanvas();
|
|
5937
6082
|
}), [transformTool, renderCanvas]);
|
|
@@ -5942,8 +6087,8 @@ var ImageEditor = ({
|
|
|
5942
6087
|
const sy = rect.height > 0 ? canvas.height / rect.height : 1;
|
|
5943
6088
|
const s = controller.getState();
|
|
5944
6089
|
const cropping = activeTab === "crop";
|
|
5945
|
-
const projection = (0,
|
|
5946
|
-
const pt = (0,
|
|
6090
|
+
const projection = (0, import_image_editor17.getViewportProjection)(s, canvas.width, canvas.height, cropping);
|
|
6091
|
+
const pt = (0, import_image_editor17.canvasToImagePoint)({ x: (e.clientX - rect.left) * sx, y: (e.clientY - rect.top) * sy }, s, canvas.width, canvas.height, cropping);
|
|
5947
6092
|
transformTool.setView(projection.scale);
|
|
5948
6093
|
return { pt, tolerance: 6 / (projection.scale || 1) };
|
|
5949
6094
|
};
|
|
@@ -5974,7 +6119,7 @@ var ImageEditor = ({
|
|
|
5974
6119
|
transformTool.up();
|
|
5975
6120
|
return true;
|
|
5976
6121
|
};
|
|
5977
|
-
(0,
|
|
6122
|
+
(0, import_react48.useEffect)(() => {
|
|
5978
6123
|
if (typeof window === "undefined") return;
|
|
5979
6124
|
const onKey = (e) => {
|
|
5980
6125
|
if (transformTool.key(e)) e.preventDefault();
|
|
@@ -5982,7 +6127,7 @@ var ImageEditor = ({
|
|
|
5982
6127
|
window.addEventListener("keydown", onKey);
|
|
5983
6128
|
return () => window.removeEventListener("keydown", onKey);
|
|
5984
6129
|
}, [transformTool]);
|
|
5985
|
-
(0,
|
|
6130
|
+
(0, import_react48.useEffect)(() => {
|
|
5986
6131
|
const raf = typeof requestAnimationFrame !== "undefined" ? requestAnimationFrame : (cb) => setTimeout(cb, 0);
|
|
5987
6132
|
const caf = typeof cancelAnimationFrame !== "undefined" ? cancelAnimationFrame : (id) => clearTimeout(id);
|
|
5988
6133
|
const animId = raf(() => {
|
|
@@ -5990,12 +6135,12 @@ var ImageEditor = ({
|
|
|
5990
6135
|
});
|
|
5991
6136
|
return () => caf(animId);
|
|
5992
6137
|
}, [renderCanvas, state]);
|
|
5993
|
-
(0,
|
|
6138
|
+
(0, import_react48.useEffect)(() => {
|
|
5994
6139
|
if (activeTab === "crop" && editor.state.activeTool !== "crop") {
|
|
5995
6140
|
editor.setTool("crop");
|
|
5996
6141
|
}
|
|
5997
6142
|
}, [activeTab, editor]);
|
|
5998
|
-
(0,
|
|
6143
|
+
(0, import_react48.useEffect)(() => {
|
|
5999
6144
|
const container = containerRef.current;
|
|
6000
6145
|
if (!container) return;
|
|
6001
6146
|
if (typeof ResizeObserver !== "undefined") {
|
|
@@ -6031,8 +6176,8 @@ var ImageEditor = ({
|
|
|
6031
6176
|
const sy = rect.height > 0 ? canvas.height / rect.height : 1;
|
|
6032
6177
|
const s = controller.getState();
|
|
6033
6178
|
return list.map((ev) => ({
|
|
6034
|
-
...(0,
|
|
6035
|
-
pressure: (0,
|
|
6179
|
+
...(0, import_image_editor17.canvasToImagePoint)({ x: (ev.clientX - rect.left) * sx, y: (ev.clientY - rect.top) * sy }, s, canvas.width, canvas.height, false),
|
|
6180
|
+
pressure: (0, import_image_editor17.pointerPressure)(ev)
|
|
6036
6181
|
}));
|
|
6037
6182
|
};
|
|
6038
6183
|
const handlePaintPointerDown = (e) => {
|
|
@@ -6063,10 +6208,10 @@ var ImageEditor = ({
|
|
|
6063
6208
|
if (g.error) setPaintError(g.error);
|
|
6064
6209
|
}
|
|
6065
6210
|
};
|
|
6066
|
-
(0,
|
|
6211
|
+
(0, import_react48.useEffect)(() => {
|
|
6067
6212
|
if (activeTab !== "paint" || typeof window === "undefined") return;
|
|
6068
6213
|
const onKey = (e) => {
|
|
6069
|
-
if ((0,
|
|
6214
|
+
if ((0, import_image_editor17.handlePaintShortcut)(controller, e)) e.preventDefault();
|
|
6070
6215
|
};
|
|
6071
6216
|
window.addEventListener("keydown", onKey);
|
|
6072
6217
|
return () => window.removeEventListener("keydown", onKey);
|
|
@@ -6077,7 +6222,7 @@ var ImageEditor = ({
|
|
|
6077
6222
|
const canvasPt = getCanvasEventPoint(e);
|
|
6078
6223
|
if (activeTab === "select") {
|
|
6079
6224
|
const gesture = selectionGestureRef.current;
|
|
6080
|
-
const imgPt = (0,
|
|
6225
|
+
const imgPt = (0, import_image_editor17.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false);
|
|
6081
6226
|
void gesture.begin(imgPt, e).then(() => setSelectionError(gesture.error));
|
|
6082
6227
|
return;
|
|
6083
6228
|
}
|
|
@@ -6088,8 +6233,8 @@ var ImageEditor = ({
|
|
|
6088
6233
|
width: state.imageDimensions.width,
|
|
6089
6234
|
height: state.imageDimensions.height
|
|
6090
6235
|
};
|
|
6091
|
-
const handle = (0,
|
|
6092
|
-
const startImgPt = (0,
|
|
6236
|
+
const handle = (0, import_image_editor17.hitTestCrop)(canvasPt, state, canvas.width, canvas.height, 14, activeCrop);
|
|
6237
|
+
const startImgPt = (0, import_image_editor17.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, true);
|
|
6093
6238
|
if (handle) {
|
|
6094
6239
|
cropDragInfoRef.current = {
|
|
6095
6240
|
handle,
|
|
@@ -6108,7 +6253,7 @@ var ImageEditor = ({
|
|
|
6108
6253
|
return;
|
|
6109
6254
|
}
|
|
6110
6255
|
if (activeTab === "annotate" && (state.activeTool === "shape" || state.activeTool === "type")) {
|
|
6111
|
-
const imgPt = (0,
|
|
6256
|
+
const imgPt = (0, import_image_editor17.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false);
|
|
6112
6257
|
setShapeTypeError(null);
|
|
6113
6258
|
if (state.activeTool === "shape") shapeGestureRef.current.down(imgPt);
|
|
6114
6259
|
else {
|
|
@@ -6119,12 +6264,12 @@ var ImageEditor = ({
|
|
|
6119
6264
|
return;
|
|
6120
6265
|
}
|
|
6121
6266
|
if (activeTab === "annotate") {
|
|
6122
|
-
const imgPt = (0,
|
|
6267
|
+
const imgPt = (0, import_image_editor17.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false);
|
|
6123
6268
|
dragStartPointRef.current = imgPt;
|
|
6124
6269
|
if (state.activeTool === "select") {
|
|
6125
6270
|
for (let i = state.annotations.length - 1; i >= 0; i--) {
|
|
6126
6271
|
const ann = state.annotations[i];
|
|
6127
|
-
if ((0,
|
|
6272
|
+
if ((0, import_image_editor17.hitTestAnnotation)(imgPt, ann)) {
|
|
6128
6273
|
editor.selectAnnotation(ann.id);
|
|
6129
6274
|
annotationDragInfoRef.current = {
|
|
6130
6275
|
annId: ann.id,
|
|
@@ -6160,7 +6305,7 @@ var ImageEditor = ({
|
|
|
6160
6305
|
const canvasPt = getCanvasEventPoint(e);
|
|
6161
6306
|
if (activeTab === "select") {
|
|
6162
6307
|
const gesture = selectionGestureRef.current;
|
|
6163
|
-
if (gesture.active && gesture.move((0,
|
|
6308
|
+
if (gesture.active && gesture.move((0, import_image_editor17.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false))) {
|
|
6164
6309
|
selectionDraftRef.current = gesture.draftPath;
|
|
6165
6310
|
renderCanvas();
|
|
6166
6311
|
}
|
|
@@ -6169,7 +6314,7 @@ var ImageEditor = ({
|
|
|
6169
6314
|
if (activeTab === "crop") {
|
|
6170
6315
|
const drag = cropDragInfoRef.current;
|
|
6171
6316
|
if (drag) {
|
|
6172
|
-
const currentImgPt = (0,
|
|
6317
|
+
const currentImgPt = (0, import_image_editor17.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, true);
|
|
6173
6318
|
let newCrop;
|
|
6174
6319
|
if (drag.handle === "new") {
|
|
6175
6320
|
const minX = Math.max(0, Math.min(drag.startImgPt.x, currentImgPt.x));
|
|
@@ -6183,7 +6328,7 @@ var ImageEditor = ({
|
|
|
6183
6328
|
height: Math.round(Math.max(20, maxY - minY))
|
|
6184
6329
|
};
|
|
6185
6330
|
} else {
|
|
6186
|
-
newCrop = (0,
|
|
6331
|
+
newCrop = (0, import_image_editor17.calculateCropDrag)(
|
|
6187
6332
|
drag.startCrop,
|
|
6188
6333
|
drag.handle,
|
|
6189
6334
|
drag.startImgPt,
|
|
@@ -6203,15 +6348,15 @@ var ImageEditor = ({
|
|
|
6203
6348
|
width: state.imageDimensions.width,
|
|
6204
6349
|
height: state.imageDimensions.height
|
|
6205
6350
|
};
|
|
6206
|
-
const handle = (0,
|
|
6207
|
-
canvas.style.cursor = (0,
|
|
6351
|
+
const handle = (0, import_image_editor17.hitTestCrop)(canvasPt, state, canvas.width, canvas.height, 14, activeCrop);
|
|
6352
|
+
canvas.style.cursor = (0, import_image_editor17.getCropCursor)(handle, state.transform);
|
|
6208
6353
|
}
|
|
6209
6354
|
return;
|
|
6210
6355
|
}
|
|
6211
6356
|
if (activeTab === "annotate" && state.activeTool === "shape") {
|
|
6212
6357
|
const g = shapeGestureRef.current;
|
|
6213
6358
|
if (g.active) {
|
|
6214
|
-
g.move((0,
|
|
6359
|
+
g.move((0, import_image_editor17.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false), { shift: e.shiftKey, alt: e.altKey });
|
|
6215
6360
|
if (g.error) setShapeTypeError(g.error);
|
|
6216
6361
|
}
|
|
6217
6362
|
return;
|
|
@@ -6219,7 +6364,7 @@ var ImageEditor = ({
|
|
|
6219
6364
|
if (activeTab === "annotate") {
|
|
6220
6365
|
if (annotationDragInfoRef.current) {
|
|
6221
6366
|
const drag = annotationDragInfoRef.current;
|
|
6222
|
-
const currentImgPt2 = (0,
|
|
6367
|
+
const currentImgPt2 = (0, import_image_editor17.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false);
|
|
6223
6368
|
const dx = currentImgPt2.x - drag.startImgPt.x;
|
|
6224
6369
|
const dy = currentImgPt2.y - drag.startImgPt.y;
|
|
6225
6370
|
editor.updateAnnotation(drag.annId, {
|
|
@@ -6231,10 +6376,10 @@ var ImageEditor = ({
|
|
|
6231
6376
|
const startPt = dragStartPointRef.current;
|
|
6232
6377
|
if (!startPt) {
|
|
6233
6378
|
if (state.activeTool === "select") {
|
|
6234
|
-
const imgPt = (0,
|
|
6379
|
+
const imgPt = (0, import_image_editor17.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false);
|
|
6235
6380
|
let hovered = false;
|
|
6236
6381
|
for (let i = state.annotations.length - 1; i >= 0; i--) {
|
|
6237
|
-
if ((0,
|
|
6382
|
+
if ((0, import_image_editor17.hitTestAnnotation)(imgPt, state.annotations[i])) {
|
|
6238
6383
|
hovered = true;
|
|
6239
6384
|
break;
|
|
6240
6385
|
}
|
|
@@ -6245,7 +6390,7 @@ var ImageEditor = ({
|
|
|
6245
6390
|
}
|
|
6246
6391
|
return;
|
|
6247
6392
|
}
|
|
6248
|
-
const currentImgPt = (0,
|
|
6393
|
+
const currentImgPt = (0, import_image_editor17.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false);
|
|
6249
6394
|
if (state.activeTool === "pen" && isDrawingRef.current) {
|
|
6250
6395
|
currentPathRef.current.push(currentImgPt);
|
|
6251
6396
|
const draft = {
|
|
@@ -6325,7 +6470,7 @@ var ImageEditor = ({
|
|
|
6325
6470
|
if (activeTab === "select") {
|
|
6326
6471
|
const gesture = selectionGestureRef.current;
|
|
6327
6472
|
if (gesture.active) {
|
|
6328
|
-
gesture.end((0,
|
|
6473
|
+
gesture.end((0, import_image_editor17.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false), e);
|
|
6329
6474
|
selectionDraftRef.current = null;
|
|
6330
6475
|
renderCanvas();
|
|
6331
6476
|
}
|
|
@@ -6348,7 +6493,7 @@ var ImageEditor = ({
|
|
|
6348
6493
|
}
|
|
6349
6494
|
if (activeTab === "annotate" && state.activeTool === "type") {
|
|
6350
6495
|
const tool = typeToolRef.current;
|
|
6351
|
-
tool.up((0,
|
|
6496
|
+
tool.up((0, import_image_editor17.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false));
|
|
6352
6497
|
setTypeSession(tool.session);
|
|
6353
6498
|
if (tool.error) setShapeTypeError(tool.error);
|
|
6354
6499
|
void renderCanvas();
|
|
@@ -6362,7 +6507,7 @@ var ImageEditor = ({
|
|
|
6362
6507
|
}
|
|
6363
6508
|
const startPt = dragStartPointRef.current;
|
|
6364
6509
|
if (startPt) {
|
|
6365
|
-
const currentImgPt = (0,
|
|
6510
|
+
const currentImgPt = (0, import_image_editor17.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false);
|
|
6366
6511
|
if (state.activeTool === "pen" && isDrawingRef.current) {
|
|
6367
6512
|
if (currentPathRef.current.length > 1) {
|
|
6368
6513
|
editor.addAnnotation({
|
|
@@ -6458,15 +6603,15 @@ var ImageEditor = ({
|
|
|
6458
6603
|
link.click();
|
|
6459
6604
|
}
|
|
6460
6605
|
};
|
|
6461
|
-
return /* @__PURE__ */ (0,
|
|
6606
|
+
return /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(
|
|
6462
6607
|
"div",
|
|
6463
6608
|
{
|
|
6464
6609
|
className: `flex flex-col bg-slate-900 border border-slate-800 rounded-xl overflow-hidden shadow-2xl text-slate-100 ${className}`,
|
|
6465
6610
|
style,
|
|
6466
6611
|
children: [
|
|
6467
|
-
/* @__PURE__ */ (0,
|
|
6468
|
-
/* @__PURE__ */ (0,
|
|
6469
|
-
/* @__PURE__ */ (0,
|
|
6612
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.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: [
|
|
6613
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { className: "flex items-center gap-1 bg-slate-900 p-1 rounded-lg border border-slate-800 text-xs", children: [
|
|
6614
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
6470
6615
|
"button",
|
|
6471
6616
|
{
|
|
6472
6617
|
type: "button",
|
|
@@ -6478,7 +6623,7 @@ var ImageEditor = ({
|
|
|
6478
6623
|
children: "Transform & Crop"
|
|
6479
6624
|
}
|
|
6480
6625
|
),
|
|
6481
|
-
/* @__PURE__ */ (0,
|
|
6626
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
6482
6627
|
"button",
|
|
6483
6628
|
{
|
|
6484
6629
|
type: "button",
|
|
@@ -6490,7 +6635,7 @@ var ImageEditor = ({
|
|
|
6490
6635
|
children: "Adjustments"
|
|
6491
6636
|
}
|
|
6492
6637
|
),
|
|
6493
|
-
/* @__PURE__ */ (0,
|
|
6638
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
6494
6639
|
"button",
|
|
6495
6640
|
{
|
|
6496
6641
|
type: "button",
|
|
@@ -6502,7 +6647,7 @@ var ImageEditor = ({
|
|
|
6502
6647
|
children: "Layers"
|
|
6503
6648
|
}
|
|
6504
6649
|
),
|
|
6505
|
-
/* @__PURE__ */ (0,
|
|
6650
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
6506
6651
|
"button",
|
|
6507
6652
|
{
|
|
6508
6653
|
type: "button",
|
|
@@ -6514,7 +6659,7 @@ var ImageEditor = ({
|
|
|
6514
6659
|
children: "Paint"
|
|
6515
6660
|
}
|
|
6516
6661
|
),
|
|
6517
|
-
/* @__PURE__ */ (0,
|
|
6662
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
6518
6663
|
"button",
|
|
6519
6664
|
{
|
|
6520
6665
|
type: "button",
|
|
@@ -6526,7 +6671,7 @@ var ImageEditor = ({
|
|
|
6526
6671
|
children: "Select & Mask"
|
|
6527
6672
|
}
|
|
6528
6673
|
),
|
|
6529
|
-
/* @__PURE__ */ (0,
|
|
6674
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
6530
6675
|
"button",
|
|
6531
6676
|
{
|
|
6532
6677
|
type: "button",
|
|
@@ -6538,7 +6683,7 @@ var ImageEditor = ({
|
|
|
6538
6683
|
children: "Annotations"
|
|
6539
6684
|
}
|
|
6540
6685
|
),
|
|
6541
|
-
/* @__PURE__ */ (0,
|
|
6686
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
6542
6687
|
"button",
|
|
6543
6688
|
{
|
|
6544
6689
|
type: "button",
|
|
@@ -6550,7 +6695,7 @@ var ImageEditor = ({
|
|
|
6550
6695
|
children: "Depth Mask"
|
|
6551
6696
|
}
|
|
6552
6697
|
),
|
|
6553
|
-
/* @__PURE__ */ (0,
|
|
6698
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(
|
|
6554
6699
|
"button",
|
|
6555
6700
|
{
|
|
6556
6701
|
type: "button",
|
|
@@ -6560,14 +6705,14 @@ var ImageEditor = ({
|
|
|
6560
6705
|
},
|
|
6561
6706
|
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"}`,
|
|
6562
6707
|
children: [
|
|
6563
|
-
/* @__PURE__ */ (0,
|
|
6708
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.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_runtime32.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" }) }),
|
|
6564
6709
|
"AI Tools"
|
|
6565
6710
|
]
|
|
6566
6711
|
}
|
|
6567
6712
|
)
|
|
6568
6713
|
] }),
|
|
6569
|
-
/* @__PURE__ */ (0,
|
|
6570
|
-
/* @__PURE__ */ (0,
|
|
6714
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { className: "flex items-center gap-2 text-xs", children: [
|
|
6715
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
6571
6716
|
"button",
|
|
6572
6717
|
{
|
|
6573
6718
|
type: "button",
|
|
@@ -6578,7 +6723,7 @@ var ImageEditor = ({
|
|
|
6578
6723
|
children: "\u21A9"
|
|
6579
6724
|
}
|
|
6580
6725
|
),
|
|
6581
|
-
/* @__PURE__ */ (0,
|
|
6726
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
6582
6727
|
"button",
|
|
6583
6728
|
{
|
|
6584
6729
|
type: "button",
|
|
@@ -6589,7 +6734,7 @@ var ImageEditor = ({
|
|
|
6589
6734
|
children: "\u21AA"
|
|
6590
6735
|
}
|
|
6591
6736
|
),
|
|
6592
|
-
/* @__PURE__ */ (0,
|
|
6737
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
6593
6738
|
"button",
|
|
6594
6739
|
{
|
|
6595
6740
|
type: "button",
|
|
@@ -6598,8 +6743,8 @@ var ImageEditor = ({
|
|
|
6598
6743
|
children: "Reset"
|
|
6599
6744
|
}
|
|
6600
6745
|
),
|
|
6601
|
-
/* @__PURE__ */ (0,
|
|
6602
|
-
/* @__PURE__ */ (0,
|
|
6746
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { className: "h-4 w-px bg-slate-800 mx-1" }),
|
|
6747
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
6603
6748
|
"button",
|
|
6604
6749
|
{
|
|
6605
6750
|
type: "button",
|
|
@@ -6609,11 +6754,11 @@ var ImageEditor = ({
|
|
|
6609
6754
|
children: "-"
|
|
6610
6755
|
}
|
|
6611
6756
|
),
|
|
6612
|
-
/* @__PURE__ */ (0,
|
|
6757
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("span", { className: "font-mono text-slate-400 w-10 text-center", children: [
|
|
6613
6758
|
Math.round(state.zoom * 100),
|
|
6614
6759
|
"%"
|
|
6615
6760
|
] }),
|
|
6616
|
-
/* @__PURE__ */ (0,
|
|
6761
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
6617
6762
|
"button",
|
|
6618
6763
|
{
|
|
6619
6764
|
type: "button",
|
|
@@ -6623,8 +6768,8 @@ var ImageEditor = ({
|
|
|
6623
6768
|
children: "+"
|
|
6624
6769
|
}
|
|
6625
6770
|
),
|
|
6626
|
-
/* @__PURE__ */ (0,
|
|
6627
|
-
/* @__PURE__ */ (0,
|
|
6771
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { className: "h-4 w-px bg-slate-800 mx-1" }),
|
|
6772
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
6628
6773
|
"button",
|
|
6629
6774
|
{
|
|
6630
6775
|
type: "button",
|
|
@@ -6635,7 +6780,7 @@ var ImageEditor = ({
|
|
|
6635
6780
|
children: "Hold Compare"
|
|
6636
6781
|
}
|
|
6637
6782
|
),
|
|
6638
|
-
/* @__PURE__ */ (0,
|
|
6783
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
6639
6784
|
"button",
|
|
6640
6785
|
{
|
|
6641
6786
|
type: "button",
|
|
@@ -6646,16 +6791,16 @@ var ImageEditor = ({
|
|
|
6646
6791
|
)
|
|
6647
6792
|
] })
|
|
6648
6793
|
] }),
|
|
6649
|
-
transformTool.active && /* @__PURE__ */ (0,
|
|
6650
|
-
!transformTool.active && transformTool.error && /* @__PURE__ */ (0,
|
|
6651
|
-
/* @__PURE__ */ (0,
|
|
6652
|
-
/* @__PURE__ */ (0,
|
|
6794
|
+
transformTool.active && /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(FreeTransformOptionsBar, { tool: transformTool, className: "border-b border-slate-800 bg-slate-900/95 px-4 py-2" }),
|
|
6795
|
+
!transformTool.active && transformTool.error && /* @__PURE__ */ (0, import_jsx_runtime32.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 }),
|
|
6796
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { className: "flex flex-col md:flex-row flex-1 min-h-[520px] md:h-[560px]", children: [
|
|
6797
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(
|
|
6653
6798
|
"div",
|
|
6654
6799
|
{
|
|
6655
6800
|
ref: containerRef,
|
|
6656
6801
|
className: "relative flex-1 h-[360px] md:h-full min-h-[320px] bg-slate-950 overflow-hidden select-none",
|
|
6657
6802
|
children: [
|
|
6658
|
-
/* @__PURE__ */ (0,
|
|
6803
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
6659
6804
|
"canvas",
|
|
6660
6805
|
{
|
|
6661
6806
|
ref: canvasRef,
|
|
@@ -6672,7 +6817,7 @@ var ImageEditor = ({
|
|
|
6672
6817
|
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" : ""}`
|
|
6673
6818
|
}
|
|
6674
6819
|
),
|
|
6675
|
-
typeSession && /* @__PURE__ */ (0,
|
|
6820
|
+
typeSession && /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
6676
6821
|
"textarea",
|
|
6677
6822
|
{
|
|
6678
6823
|
ref: typeInputRef,
|
|
@@ -6694,11 +6839,11 @@ var ImageEditor = ({
|
|
|
6694
6839
|
]
|
|
6695
6840
|
}
|
|
6696
6841
|
),
|
|
6697
|
-
/* @__PURE__ */ (0,
|
|
6698
|
-
activeTab === "crop" && /* @__PURE__ */ (0,
|
|
6699
|
-
/* @__PURE__ */ (0,
|
|
6700
|
-
/* @__PURE__ */ (0,
|
|
6701
|
-
/* @__PURE__ */ (0,
|
|
6842
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.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: [
|
|
6843
|
+
activeTab === "crop" && /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { className: "flex flex-col gap-4 text-xs", children: [
|
|
6844
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Aspect Ratio Presets" }),
|
|
6845
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { className: "grid grid-cols-3 gap-2", children: [
|
|
6846
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
6702
6847
|
"button",
|
|
6703
6848
|
{
|
|
6704
6849
|
type: "button",
|
|
@@ -6710,7 +6855,7 @@ var ImageEditor = ({
|
|
|
6710
6855
|
children: "Freeform"
|
|
6711
6856
|
}
|
|
6712
6857
|
),
|
|
6713
|
-
/* @__PURE__ */ (0,
|
|
6858
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
6714
6859
|
"button",
|
|
6715
6860
|
{
|
|
6716
6861
|
type: "button",
|
|
@@ -6722,7 +6867,7 @@ var ImageEditor = ({
|
|
|
6722
6867
|
children: "1:1 Square"
|
|
6723
6868
|
}
|
|
6724
6869
|
),
|
|
6725
|
-
/* @__PURE__ */ (0,
|
|
6870
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
6726
6871
|
"button",
|
|
6727
6872
|
{
|
|
6728
6873
|
type: "button",
|
|
@@ -6734,7 +6879,7 @@ var ImageEditor = ({
|
|
|
6734
6879
|
children: "4:3 Standard"
|
|
6735
6880
|
}
|
|
6736
6881
|
),
|
|
6737
|
-
/* @__PURE__ */ (0,
|
|
6882
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
6738
6883
|
"button",
|
|
6739
6884
|
{
|
|
6740
6885
|
type: "button",
|
|
@@ -6746,7 +6891,7 @@ var ImageEditor = ({
|
|
|
6746
6891
|
children: "16:9 Wide"
|
|
6747
6892
|
}
|
|
6748
6893
|
),
|
|
6749
|
-
/* @__PURE__ */ (0,
|
|
6894
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
6750
6895
|
"button",
|
|
6751
6896
|
{
|
|
6752
6897
|
type: "button",
|
|
@@ -6758,7 +6903,7 @@ var ImageEditor = ({
|
|
|
6758
6903
|
children: "3:2 Photo"
|
|
6759
6904
|
}
|
|
6760
6905
|
),
|
|
6761
|
-
/* @__PURE__ */ (0,
|
|
6906
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
6762
6907
|
"button",
|
|
6763
6908
|
{
|
|
6764
6909
|
type: "button",
|
|
@@ -6771,10 +6916,10 @@ var ImageEditor = ({
|
|
|
6771
6916
|
}
|
|
6772
6917
|
)
|
|
6773
6918
|
] }),
|
|
6774
|
-
/* @__PURE__ */ (0,
|
|
6775
|
-
/* @__PURE__ */ (0,
|
|
6776
|
-
/* @__PURE__ */ (0,
|
|
6777
|
-
/* @__PURE__ */ (0,
|
|
6919
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { className: "h-px bg-slate-800 my-1" }),
|
|
6920
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Orientation & Flips" }),
|
|
6921
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { className: "grid grid-cols-2 gap-2", children: [
|
|
6922
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
6778
6923
|
"button",
|
|
6779
6924
|
{
|
|
6780
6925
|
type: "button",
|
|
@@ -6783,7 +6928,7 @@ var ImageEditor = ({
|
|
|
6783
6928
|
children: "Rotate -90\xB0"
|
|
6784
6929
|
}
|
|
6785
6930
|
),
|
|
6786
|
-
/* @__PURE__ */ (0,
|
|
6931
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
6787
6932
|
"button",
|
|
6788
6933
|
{
|
|
6789
6934
|
type: "button",
|
|
@@ -6792,7 +6937,7 @@ var ImageEditor = ({
|
|
|
6792
6937
|
children: "Rotate +90\xB0"
|
|
6793
6938
|
}
|
|
6794
6939
|
),
|
|
6795
|
-
/* @__PURE__ */ (0,
|
|
6940
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
6796
6941
|
"button",
|
|
6797
6942
|
{
|
|
6798
6943
|
type: "button",
|
|
@@ -6801,7 +6946,7 @@ var ImageEditor = ({
|
|
|
6801
6946
|
children: "Flip Horizontal"
|
|
6802
6947
|
}
|
|
6803
6948
|
),
|
|
6804
|
-
/* @__PURE__ */ (0,
|
|
6949
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
6805
6950
|
"button",
|
|
6806
6951
|
{
|
|
6807
6952
|
type: "button",
|
|
@@ -6812,10 +6957,10 @@ var ImageEditor = ({
|
|
|
6812
6957
|
)
|
|
6813
6958
|
] })
|
|
6814
6959
|
] }),
|
|
6815
|
-
activeTab === "adjust" && /* @__PURE__ */ (0,
|
|
6816
|
-
/* @__PURE__ */ (0,
|
|
6817
|
-
/* @__PURE__ */ (0,
|
|
6818
|
-
/* @__PURE__ */ (0,
|
|
6960
|
+
activeTab === "adjust" && /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { className: "flex flex-col gap-3 text-xs", children: [
|
|
6961
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { className: "flex items-center justify-between", children: [
|
|
6962
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Color Adjustments" }),
|
|
6963
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
6819
6964
|
"button",
|
|
6820
6965
|
{
|
|
6821
6966
|
type: "button",
|
|
@@ -6825,25 +6970,25 @@ var ImageEditor = ({
|
|
|
6825
6970
|
}
|
|
6826
6971
|
)
|
|
6827
6972
|
] }),
|
|
6828
|
-
/* @__PURE__ */ (0,
|
|
6829
|
-
|
|
6830
|
-
/* @__PURE__ */ (0,
|
|
6973
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)(Histogram, { histogram: editor.histogram }),
|
|
6974
|
+
import_image_editor17.IMAGE_ADJUSTMENT_CONTROLS.map((spec) => /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(import_react48.default.Fragment, { children: [
|
|
6975
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
6831
6976
|
ControlSlider,
|
|
6832
6977
|
{
|
|
6833
6978
|
spec,
|
|
6834
|
-
value: (0,
|
|
6979
|
+
value: (0, import_image_editor17.readAdjustmentControls)(state.adjustments)[spec.id],
|
|
6835
6980
|
disabled: spec.requiresProcess !== void 0 && legacyProcess,
|
|
6836
6981
|
onChange: (v) => editor.setAdjustments({ [spec.id]: v })
|
|
6837
6982
|
}
|
|
6838
6983
|
),
|
|
6839
|
-
spec.id === "tint" && legacyProcess && /* @__PURE__ */ (0,
|
|
6984
|
+
spec.id === "tint" && legacyProcess && /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(
|
|
6840
6985
|
"div",
|
|
6841
6986
|
{
|
|
6842
6987
|
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",
|
|
6843
6988
|
"data-testid": "image-editor-process-notice",
|
|
6844
6989
|
children: [
|
|
6845
|
-
/* @__PURE__ */ (0,
|
|
6846
|
-
/* @__PURE__ */ (0,
|
|
6990
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)("span", { children: "Legacy rendering (process 1). Tint needs the current process." }),
|
|
6991
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
6847
6992
|
"button",
|
|
6848
6993
|
{
|
|
6849
6994
|
type: "button",
|
|
@@ -6856,7 +7001,7 @@ var ImageEditor = ({
|
|
|
6856
7001
|
}
|
|
6857
7002
|
)
|
|
6858
7003
|
] }, spec.id)),
|
|
6859
|
-
/* @__PURE__ */ (0,
|
|
7004
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { className: "border-t border-slate-700/60 pt-3", children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
6860
7005
|
AdjustmentLayersPanel,
|
|
6861
7006
|
{
|
|
6862
7007
|
controller,
|
|
@@ -6865,9 +7010,9 @@ var ImageEditor = ({
|
|
|
6865
7010
|
}
|
|
6866
7011
|
) })
|
|
6867
7012
|
] }),
|
|
6868
|
-
activeTab === "layers" && /* @__PURE__ */ (0,
|
|
6869
|
-
/* @__PURE__ */ (0,
|
|
6870
|
-
/* @__PURE__ */ (0,
|
|
7013
|
+
activeTab === "layers" && /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { className: "flex flex-col gap-3 text-xs", children: [
|
|
7014
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Layers" }),
|
|
7015
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
6871
7016
|
"button",
|
|
6872
7017
|
{
|
|
6873
7018
|
type: "button",
|
|
@@ -6878,14 +7023,14 @@ var ImageEditor = ({
|
|
|
6878
7023
|
children: "Free Transform"
|
|
6879
7024
|
}
|
|
6880
7025
|
),
|
|
6881
|
-
/* @__PURE__ */ (0,
|
|
6882
|
-
/* @__PURE__ */ (0,
|
|
6883
|
-
/* @__PURE__ */ (0,
|
|
7026
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)(LayersPanel, { controller }),
|
|
7027
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Colour" }),
|
|
7028
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)(ColorProfilePanel, { controller })
|
|
6884
7029
|
] }),
|
|
6885
|
-
activeTab === "paint" && /* @__PURE__ */ (0,
|
|
6886
|
-
/* @__PURE__ */ (0,
|
|
6887
|
-
/* @__PURE__ */ (0,
|
|
6888
|
-
/* @__PURE__ */ (0,
|
|
7030
|
+
activeTab === "paint" && /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { className: "flex flex-col gap-3 text-xs", children: [
|
|
7031
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Paint" }),
|
|
7032
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)(BrushOptionsBar, { controller }),
|
|
7033
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
6889
7034
|
"button",
|
|
6890
7035
|
{
|
|
6891
7036
|
type: "button",
|
|
@@ -6896,12 +7041,12 @@ var ImageEditor = ({
|
|
|
6896
7041
|
children: "Free Transform"
|
|
6897
7042
|
}
|
|
6898
7043
|
),
|
|
6899
|
-
paintError && /* @__PURE__ */ (0,
|
|
6900
|
-
/* @__PURE__ */ (0,
|
|
7044
|
+
paintError && /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("p", { role: "alert", className: "text-rose-400", "data-testid": "paint-error", children: paintError }),
|
|
7045
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { className: "border-t border-slate-700/60 pt-3", children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(LayersPanel, { controller }) })
|
|
6901
7046
|
] }),
|
|
6902
|
-
activeTab === "annotate" && /* @__PURE__ */ (0,
|
|
6903
|
-
/* @__PURE__ */ (0,
|
|
6904
|
-
/* @__PURE__ */ (0,
|
|
7047
|
+
activeTab === "annotate" && /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { className: "flex flex-col gap-3 text-xs", children: [
|
|
7048
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Shape & Type Layers" }),
|
|
7049
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { className: "grid grid-cols-2 gap-1.5", children: ["shape", "type"].map((t) => /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
6905
7050
|
"button",
|
|
6906
7051
|
{
|
|
6907
7052
|
type: "button",
|
|
@@ -6912,13 +7057,13 @@ var ImageEditor = ({
|
|
|
6912
7057
|
},
|
|
6913
7058
|
t
|
|
6914
7059
|
)) }),
|
|
6915
|
-
state.activeTool === "shape" && /* @__PURE__ */ (0,
|
|
6916
|
-
state.activeTool === "type" && /* @__PURE__ */ (0,
|
|
6917
|
-
state.activeTool === "type" && typeSession && /* @__PURE__ */ (0,
|
|
6918
|
-
shapeTypeError && /* @__PURE__ */ (0,
|
|
6919
|
-
/* @__PURE__ */ (0,
|
|
6920
|
-
/* @__PURE__ */ (0,
|
|
6921
|
-
/* @__PURE__ */ (0,
|
|
7060
|
+
state.activeTool === "shape" && /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(ShapeOptionsBar, { controller, options: shapeOptions, onChange: setShapeOptions }),
|
|
7061
|
+
state.activeTool === "type" && /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(TypeOptionsBar, { controller, options: typeOptions, onChange: setTypeOptions, session: typeSession }),
|
|
7062
|
+
state.activeTool === "type" && typeSession && /* @__PURE__ */ (0, import_jsx_runtime32.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" }),
|
|
7063
|
+
shapeTypeError && /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("p", { role: "alert", className: "text-rose-400", "data-testid": "shape-type-error", children: shapeTypeError }),
|
|
7064
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { className: "h-px bg-slate-800 my-1" }),
|
|
7065
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Draw & Annotate" }),
|
|
7066
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { className: "grid grid-cols-3 gap-1.5", children: ["pen", "rect", "circle", "arrow", "line"].map((t) => /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
6922
7067
|
"button",
|
|
6923
7068
|
{
|
|
6924
7069
|
type: "button",
|
|
@@ -6928,9 +7073,9 @@ var ImageEditor = ({
|
|
|
6928
7073
|
},
|
|
6929
7074
|
t
|
|
6930
7075
|
)) }),
|
|
6931
|
-
/* @__PURE__ */ (0,
|
|
6932
|
-
/* @__PURE__ */ (0,
|
|
6933
|
-
/* @__PURE__ */ (0,
|
|
7076
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { className: "flex items-center gap-2 mt-2", children: [
|
|
7077
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)("label", { className: "text-slate-400", children: "Color:" }),
|
|
7078
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
6934
7079
|
"input",
|
|
6935
7080
|
{
|
|
6936
7081
|
type: "color",
|
|
@@ -6939,15 +7084,15 @@ var ImageEditor = ({
|
|
|
6939
7084
|
className: "w-8 h-8 rounded border border-slate-700 cursor-pointer bg-transparent"
|
|
6940
7085
|
}
|
|
6941
7086
|
),
|
|
6942
|
-
/* @__PURE__ */ (0,
|
|
6943
|
-
/* @__PURE__ */ (0,
|
|
6944
|
-
/* @__PURE__ */ (0,
|
|
6945
|
-
/* @__PURE__ */ (0,
|
|
7087
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { className: "flex-1 ml-2", children: [
|
|
7088
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { className: "flex justify-between text-slate-400 mb-0.5", children: [
|
|
7089
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)("span", { children: "Width:" }),
|
|
7090
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("span", { className: "font-mono", children: [
|
|
6946
7091
|
strokeWidth,
|
|
6947
7092
|
"px"
|
|
6948
7093
|
] })
|
|
6949
7094
|
] }),
|
|
6950
|
-
/* @__PURE__ */ (0,
|
|
7095
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
6951
7096
|
"input",
|
|
6952
7097
|
{
|
|
6953
7098
|
type: "range",
|
|
@@ -6960,10 +7105,10 @@ var ImageEditor = ({
|
|
|
6960
7105
|
)
|
|
6961
7106
|
] })
|
|
6962
7107
|
] }),
|
|
6963
|
-
/* @__PURE__ */ (0,
|
|
6964
|
-
/* @__PURE__ */ (0,
|
|
6965
|
-
/* @__PURE__ */ (0,
|
|
6966
|
-
/* @__PURE__ */ (0,
|
|
7108
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { className: "h-px bg-slate-800 my-1" }),
|
|
7109
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Add Text" }),
|
|
7110
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { className: "flex gap-2", children: [
|
|
7111
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
6967
7112
|
"input",
|
|
6968
7113
|
{
|
|
6969
7114
|
type: "text",
|
|
@@ -6974,7 +7119,7 @@ var ImageEditor = ({
|
|
|
6974
7119
|
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"
|
|
6975
7120
|
}
|
|
6976
7121
|
),
|
|
6977
|
-
/* @__PURE__ */ (0,
|
|
7122
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
6978
7123
|
"button",
|
|
6979
7124
|
{
|
|
6980
7125
|
type: "button",
|
|
@@ -6984,14 +7129,14 @@ var ImageEditor = ({
|
|
|
6984
7129
|
}
|
|
6985
7130
|
)
|
|
6986
7131
|
] }),
|
|
6987
|
-
/* @__PURE__ */ (0,
|
|
6988
|
-
/* @__PURE__ */ (0,
|
|
6989
|
-
/* @__PURE__ */ (0,
|
|
7132
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { className: "flex items-center justify-between text-slate-400", children: [
|
|
7133
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)("span", { children: "Font Size:" }),
|
|
7134
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("span", { className: "font-mono", children: [
|
|
6990
7135
|
fontSize,
|
|
6991
7136
|
"px"
|
|
6992
7137
|
] })
|
|
6993
7138
|
] }),
|
|
6994
|
-
/* @__PURE__ */ (0,
|
|
7139
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
6995
7140
|
"input",
|
|
6996
7141
|
{
|
|
6997
7142
|
type: "range",
|
|
@@ -7002,14 +7147,14 @@ var ImageEditor = ({
|
|
|
7002
7147
|
className: "w-full accent-indigo-500"
|
|
7003
7148
|
}
|
|
7004
7149
|
),
|
|
7005
|
-
/* @__PURE__ */ (0,
|
|
7006
|
-
/* @__PURE__ */ (0,
|
|
7007
|
-
/* @__PURE__ */ (0,
|
|
7150
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { className: "h-px bg-slate-800 my-1" }),
|
|
7151
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { className: "flex items-center justify-between", children: [
|
|
7152
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("span", { className: "text-slate-400", children: [
|
|
7008
7153
|
"Layers (",
|
|
7009
7154
|
state.annotations.length,
|
|
7010
7155
|
")"
|
|
7011
7156
|
] }),
|
|
7012
|
-
state.selectedAnnotationId && /* @__PURE__ */ (0,
|
|
7157
|
+
state.selectedAnnotationId && /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
7013
7158
|
"button",
|
|
7014
7159
|
{
|
|
7015
7160
|
type: "button",
|
|
@@ -7018,7 +7163,7 @@ var ImageEditor = ({
|
|
|
7018
7163
|
children: "Delete Selected"
|
|
7019
7164
|
}
|
|
7020
7165
|
),
|
|
7021
|
-
state.annotations.length > 0 && /* @__PURE__ */ (0,
|
|
7166
|
+
state.annotations.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
7022
7167
|
"button",
|
|
7023
7168
|
{
|
|
7024
7169
|
type: "button",
|
|
@@ -7029,10 +7174,10 @@ var ImageEditor = ({
|
|
|
7029
7174
|
)
|
|
7030
7175
|
] })
|
|
7031
7176
|
] }),
|
|
7032
|
-
activeTab === "depth" && /* @__PURE__ */ (0,
|
|
7033
|
-
/* @__PURE__ */ (0,
|
|
7034
|
-
/* @__PURE__ */ (0,
|
|
7035
|
-
/* @__PURE__ */ (0,
|
|
7177
|
+
activeTab === "depth" && /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { className: "flex flex-col gap-3 text-xs", children: [
|
|
7178
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { className: "flex items-center justify-between", children: [
|
|
7179
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Depth Masking" }),
|
|
7180
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
7036
7181
|
"button",
|
|
7037
7182
|
{
|
|
7038
7183
|
type: "button",
|
|
@@ -7042,8 +7187,8 @@ var ImageEditor = ({
|
|
|
7042
7187
|
}
|
|
7043
7188
|
)
|
|
7044
7189
|
] }),
|
|
7045
|
-
/* @__PURE__ */ (0,
|
|
7046
|
-
/* @__PURE__ */ (0,
|
|
7190
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("label", { className: "flex items-center gap-2 cursor-pointer text-slate-300", children: [
|
|
7191
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
7047
7192
|
"input",
|
|
7048
7193
|
{
|
|
7049
7194
|
type: "checkbox",
|
|
@@ -7052,12 +7197,12 @@ var ImageEditor = ({
|
|
|
7052
7197
|
className: "rounded accent-indigo-500"
|
|
7053
7198
|
}
|
|
7054
7199
|
),
|
|
7055
|
-
/* @__PURE__ */ (0,
|
|
7200
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)("span", { children: "Enable Depth / Alpha Mask" })
|
|
7056
7201
|
] }),
|
|
7057
|
-
state.depthMask.enabled && /* @__PURE__ */ (0,
|
|
7058
|
-
/* @__PURE__ */ (0,
|
|
7059
|
-
/* @__PURE__ */ (0,
|
|
7060
|
-
/* @__PURE__ */ (0,
|
|
7202
|
+
state.depthMask.enabled && /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(import_jsx_runtime32.Fragment, { children: [
|
|
7203
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { children: [
|
|
7204
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)("label", { className: "text-slate-400 block mb-1", children: "Mask Image URL:" }),
|
|
7205
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
7061
7206
|
"input",
|
|
7062
7207
|
{
|
|
7063
7208
|
type: "text",
|
|
@@ -7068,8 +7213,8 @@ var ImageEditor = ({
|
|
|
7068
7213
|
}
|
|
7069
7214
|
)
|
|
7070
7215
|
] }),
|
|
7071
|
-
/* @__PURE__ */ (0,
|
|
7072
|
-
/* @__PURE__ */ (0,
|
|
7216
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { className: "flex gap-2", children: [
|
|
7217
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
7073
7218
|
"button",
|
|
7074
7219
|
{
|
|
7075
7220
|
type: "button",
|
|
@@ -7078,7 +7223,7 @@ var ImageEditor = ({
|
|
|
7078
7223
|
children: "Threshold Mode"
|
|
7079
7224
|
}
|
|
7080
7225
|
),
|
|
7081
|
-
/* @__PURE__ */ (0,
|
|
7226
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
7082
7227
|
"button",
|
|
7083
7228
|
{
|
|
7084
7229
|
type: "button",
|
|
@@ -7088,12 +7233,12 @@ var ImageEditor = ({
|
|
|
7088
7233
|
}
|
|
7089
7234
|
)
|
|
7090
7235
|
] }),
|
|
7091
|
-
/* @__PURE__ */ (0,
|
|
7092
|
-
/* @__PURE__ */ (0,
|
|
7093
|
-
/* @__PURE__ */ (0,
|
|
7094
|
-
/* @__PURE__ */ (0,
|
|
7236
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { children: [
|
|
7237
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { className: "flex justify-between text-slate-400 mb-1", children: [
|
|
7238
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)("span", { children: "Depth Start (Lower):" }),
|
|
7239
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)("span", { className: "font-mono", children: state.depthMask.depthRange[0] })
|
|
7095
7240
|
] }),
|
|
7096
|
-
/* @__PURE__ */ (0,
|
|
7241
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
7097
7242
|
"input",
|
|
7098
7243
|
{
|
|
7099
7244
|
type: "range",
|
|
@@ -7107,12 +7252,12 @@ var ImageEditor = ({
|
|
|
7107
7252
|
}
|
|
7108
7253
|
)
|
|
7109
7254
|
] }),
|
|
7110
|
-
/* @__PURE__ */ (0,
|
|
7111
|
-
/* @__PURE__ */ (0,
|
|
7112
|
-
/* @__PURE__ */ (0,
|
|
7113
|
-
/* @__PURE__ */ (0,
|
|
7255
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { children: [
|
|
7256
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { className: "flex justify-between text-slate-400 mb-1", children: [
|
|
7257
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)("span", { children: "Depth Stop (Upper):" }),
|
|
7258
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)("span", { className: "font-mono", children: state.depthMask.depthRange[1] })
|
|
7114
7259
|
] }),
|
|
7115
|
-
/* @__PURE__ */ (0,
|
|
7260
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
7116
7261
|
"input",
|
|
7117
7262
|
{
|
|
7118
7263
|
type: "range",
|
|
@@ -7126,12 +7271,12 @@ var ImageEditor = ({
|
|
|
7126
7271
|
}
|
|
7127
7272
|
)
|
|
7128
7273
|
] }),
|
|
7129
|
-
/* @__PURE__ */ (0,
|
|
7130
|
-
/* @__PURE__ */ (0,
|
|
7131
|
-
/* @__PURE__ */ (0,
|
|
7132
|
-
/* @__PURE__ */ (0,
|
|
7274
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { children: [
|
|
7275
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { className: "flex justify-between text-slate-400 mb-1", children: [
|
|
7276
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)("span", { children: "Softness:" }),
|
|
7277
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)("span", { className: "font-mono", children: state.depthMask.softness })
|
|
7133
7278
|
] }),
|
|
7134
|
-
/* @__PURE__ */ (0,
|
|
7279
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
7135
7280
|
"input",
|
|
7136
7281
|
{
|
|
7137
7282
|
type: "range",
|
|
@@ -7143,8 +7288,8 @@ var ImageEditor = ({
|
|
|
7143
7288
|
}
|
|
7144
7289
|
)
|
|
7145
7290
|
] }),
|
|
7146
|
-
/* @__PURE__ */ (0,
|
|
7147
|
-
/* @__PURE__ */ (0,
|
|
7291
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("label", { className: "flex items-center gap-2 cursor-pointer text-slate-300 mt-1", children: [
|
|
7292
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
7148
7293
|
"input",
|
|
7149
7294
|
{
|
|
7150
7295
|
type: "checkbox",
|
|
@@ -7153,12 +7298,12 @@ var ImageEditor = ({
|
|
|
7153
7298
|
className: "rounded accent-indigo-500"
|
|
7154
7299
|
}
|
|
7155
7300
|
),
|
|
7156
|
-
/* @__PURE__ */ (0,
|
|
7301
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)("span", { children: "Invert Mask" })
|
|
7157
7302
|
] })
|
|
7158
7303
|
] })
|
|
7159
7304
|
] }),
|
|
7160
|
-
activeTab === "select" && /* @__PURE__ */ (0,
|
|
7161
|
-
/* @__PURE__ */ (0,
|
|
7305
|
+
activeTab === "select" && /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { className: "flex flex-col gap-4 text-xs", children: [
|
|
7306
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
7162
7307
|
SelectionOptionsBar,
|
|
7163
7308
|
{
|
|
7164
7309
|
controller,
|
|
@@ -7168,9 +7313,9 @@ var ImageEditor = ({
|
|
|
7168
7313
|
quickMask: Boolean(state.quickMask)
|
|
7169
7314
|
}
|
|
7170
7315
|
),
|
|
7171
|
-
selectionError && /* @__PURE__ */ (0,
|
|
7172
|
-
/* @__PURE__ */ (0,
|
|
7173
|
-
/* @__PURE__ */ (0,
|
|
7316
|
+
selectionError && /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("p", { role: "alert", className: "text-rose-400", children: selectionError }),
|
|
7317
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { className: "flex gap-1", children: [
|
|
7318
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
7174
7319
|
"button",
|
|
7175
7320
|
{
|
|
7176
7321
|
type: "button",
|
|
@@ -7181,7 +7326,7 @@ var ImageEditor = ({
|
|
|
7181
7326
|
children: "Transform Selection"
|
|
7182
7327
|
}
|
|
7183
7328
|
),
|
|
7184
|
-
/* @__PURE__ */ (0,
|
|
7329
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
7185
7330
|
"button",
|
|
7186
7331
|
{
|
|
7187
7332
|
type: "button",
|
|
@@ -7193,12 +7338,12 @@ var ImageEditor = ({
|
|
|
7193
7338
|
}
|
|
7194
7339
|
)
|
|
7195
7340
|
] }),
|
|
7196
|
-
/* @__PURE__ */ (0,
|
|
7341
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)(RefineEdgePanel, { controller, selection: state.selection ?? null, layers: state.adjustments.layers })
|
|
7197
7342
|
] }),
|
|
7198
|
-
activeTab === "ai" && /* @__PURE__ */ (0,
|
|
7199
|
-
/* @__PURE__ */ (0,
|
|
7200
|
-
/* @__PURE__ */ (0,
|
|
7201
|
-
/* @__PURE__ */ (0,
|
|
7343
|
+
activeTab === "ai" && /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { className: "flex flex-col gap-4 text-xs", children: [
|
|
7344
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("label", { className: "flex items-center justify-between gap-2 text-slate-300", children: [
|
|
7345
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)("span", { children: "Results go to" }),
|
|
7346
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(
|
|
7202
7347
|
"select",
|
|
7203
7348
|
{
|
|
7204
7349
|
"aria-label": "AI result target",
|
|
@@ -7206,54 +7351,54 @@ var ImageEditor = ({
|
|
|
7206
7351
|
onChange: (e) => setAiTarget(e.target.value),
|
|
7207
7352
|
className: "bg-slate-800 border border-slate-700 rounded px-1.5 py-1",
|
|
7208
7353
|
children: [
|
|
7209
|
-
/* @__PURE__ */ (0,
|
|
7210
|
-
/* @__PURE__ */ (0,
|
|
7211
|
-
/* @__PURE__ */ (0,
|
|
7354
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)("option", { value: "auto", children: controller.isMultiLayer ? "Auto (new layer)" : "Auto (replace image)" }),
|
|
7355
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)("option", { value: "new-layer", children: "New layer / mask" }),
|
|
7356
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)("option", { value: "replace", children: "Replace image" })
|
|
7212
7357
|
]
|
|
7213
7358
|
}
|
|
7214
7359
|
)
|
|
7215
7360
|
] }),
|
|
7216
|
-
/* @__PURE__ */ (0,
|
|
7217
|
-
/* @__PURE__ */ (0,
|
|
7218
|
-
/* @__PURE__ */ (0,
|
|
7219
|
-
/* @__PURE__ */ (0,
|
|
7361
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { className: "p-3 rounded-lg bg-slate-950/60 border border-slate-800 flex flex-col gap-2.5", children: [
|
|
7362
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { className: "flex items-center justify-between", children: [
|
|
7363
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px] flex items-center gap-1.5", children: [
|
|
7364
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.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_runtime32.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" }) }),
|
|
7220
7365
|
"Background Removal"
|
|
7221
7366
|
] }),
|
|
7222
|
-
isRemovingBg && /* @__PURE__ */ (0,
|
|
7367
|
+
isRemovingBg && /* @__PURE__ */ (0, import_jsx_runtime32.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..." })
|
|
7223
7368
|
] }),
|
|
7224
|
-
/* @__PURE__ */ (0,
|
|
7225
|
-
/* @__PURE__ */ (0,
|
|
7369
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)("p", { className: "text-slate-400 text-[11px] leading-relaxed", children: "Isolate foreground subject with AI alpha transparency segmentation." }),
|
|
7370
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
7226
7371
|
"button",
|
|
7227
7372
|
{
|
|
7228
7373
|
type: "button",
|
|
7229
7374
|
onClick: handleRemoveBackground,
|
|
7230
7375
|
disabled: isRemovingBg || isInpainting,
|
|
7231
7376
|
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",
|
|
7232
|
-
children: isRemovingBg ? /* @__PURE__ */ (0,
|
|
7233
|
-
/* @__PURE__ */ (0,
|
|
7377
|
+
children: isRemovingBg ? /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(import_jsx_runtime32.Fragment, { children: [
|
|
7378
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { className: "w-3.5 h-3.5 border-2 border-white/30 border-t-white rounded-full animate-spin" }),
|
|
7234
7379
|
"Removing Background..."
|
|
7235
|
-
] }) : /* @__PURE__ */ (0,
|
|
7236
|
-
/* @__PURE__ */ (0,
|
|
7380
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(import_jsx_runtime32.Fragment, { children: [
|
|
7381
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.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_runtime32.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" }) }),
|
|
7237
7382
|
"Remove Background"
|
|
7238
7383
|
] })
|
|
7239
7384
|
}
|
|
7240
7385
|
)
|
|
7241
7386
|
] }),
|
|
7242
|
-
/* @__PURE__ */ (0,
|
|
7243
|
-
/* @__PURE__ */ (0,
|
|
7244
|
-
/* @__PURE__ */ (0,
|
|
7245
|
-
/* @__PURE__ */ (0,
|
|
7246
|
-
/* @__PURE__ */ (0,
|
|
7247
|
-
/* @__PURE__ */ (0,
|
|
7387
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { className: "p-3 rounded-lg bg-slate-950/60 border border-slate-800 flex flex-col gap-2.5", children: [
|
|
7388
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { className: "flex items-center justify-between", children: [
|
|
7389
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px] flex items-center gap-1.5", children: [
|
|
7390
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("svg", { className: "w-3.5 h-3.5 text-purple-400", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: [
|
|
7391
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.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" }),
|
|
7392
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)("path", { d: "m14 7 3 3" })
|
|
7248
7393
|
] }),
|
|
7249
7394
|
"Generative Inpainting"
|
|
7250
7395
|
] }),
|
|
7251
|
-
isInpainting && /* @__PURE__ */ (0,
|
|
7396
|
+
isInpainting && /* @__PURE__ */ (0, import_jsx_runtime32.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..." })
|
|
7252
7397
|
] }),
|
|
7253
|
-
/* @__PURE__ */ (0,
|
|
7254
|
-
/* @__PURE__ */ (0,
|
|
7255
|
-
/* @__PURE__ */ (0,
|
|
7256
|
-
/* @__PURE__ */ (0,
|
|
7398
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)("p", { className: "text-slate-400 text-[11px] leading-relaxed", children: "Replace, modify, or fill selected regions using prompt-guided generative inpainting." }),
|
|
7399
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { className: "flex flex-col gap-1", children: [
|
|
7400
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)("label", { htmlFor: "ai-inpaint-prompt-react", className: "text-slate-300 text-[11px] font-medium", children: "Prompt" }),
|
|
7401
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
7257
7402
|
"textarea",
|
|
7258
7403
|
{
|
|
7259
7404
|
id: "ai-inpaint-prompt-react",
|
|
@@ -7265,10 +7410,10 @@ var ImageEditor = ({
|
|
|
7265
7410
|
}
|
|
7266
7411
|
)
|
|
7267
7412
|
] }),
|
|
7268
|
-
/* @__PURE__ */ (0,
|
|
7269
|
-
/* @__PURE__ */ (0,
|
|
7270
|
-
/* @__PURE__ */ (0,
|
|
7271
|
-
/* @__PURE__ */ (0,
|
|
7413
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { className: "flex flex-col gap-1", children: [
|
|
7414
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)("span", { className: "text-slate-300 text-[11px] font-medium", children: "Target Mask Region" }),
|
|
7415
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { className: "grid grid-cols-2 gap-1.5", children: [
|
|
7416
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(
|
|
7272
7417
|
"button",
|
|
7273
7418
|
{
|
|
7274
7419
|
type: "button",
|
|
@@ -7281,7 +7426,7 @@ var ImageEditor = ({
|
|
|
7281
7426
|
]
|
|
7282
7427
|
}
|
|
7283
7428
|
),
|
|
7284
|
-
/* @__PURE__ */ (0,
|
|
7429
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(
|
|
7285
7430
|
"button",
|
|
7286
7431
|
{
|
|
7287
7432
|
type: "button",
|
|
@@ -7296,25 +7441,25 @@ var ImageEditor = ({
|
|
|
7296
7441
|
)
|
|
7297
7442
|
] })
|
|
7298
7443
|
] }),
|
|
7299
|
-
/* @__PURE__ */ (0,
|
|
7444
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
7300
7445
|
"button",
|
|
7301
7446
|
{
|
|
7302
7447
|
type: "button",
|
|
7303
7448
|
onClick: handleInpaint,
|
|
7304
7449
|
disabled: isInpainting || isRemovingBg || !inpaintPrompt.trim(),
|
|
7305
7450
|
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",
|
|
7306
|
-
children: isInpainting ? /* @__PURE__ */ (0,
|
|
7307
|
-
/* @__PURE__ */ (0,
|
|
7451
|
+
children: isInpainting ? /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(import_jsx_runtime32.Fragment, { children: [
|
|
7452
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { className: "w-3.5 h-3.5 border-2 border-white/30 border-t-white rounded-full animate-spin" }),
|
|
7308
7453
|
"Generating Inpaint..."
|
|
7309
|
-
] }) : /* @__PURE__ */ (0,
|
|
7310
|
-
/* @__PURE__ */ (0,
|
|
7454
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(import_jsx_runtime32.Fragment, { children: [
|
|
7455
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.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_runtime32.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" }) }),
|
|
7311
7456
|
"Apply Inpainting"
|
|
7312
7457
|
] })
|
|
7313
7458
|
}
|
|
7314
7459
|
)
|
|
7315
7460
|
] }),
|
|
7316
|
-
aiError && /* @__PURE__ */ (0,
|
|
7317
|
-
aiSuccess && /* @__PURE__ */ (0,
|
|
7461
|
+
aiError && /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { className: "p-2.5 rounded-lg bg-rose-950/60 border border-rose-800 text-rose-300 text-[11px]", children: aiError }),
|
|
7462
|
+
aiSuccess && /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { className: "p-2.5 rounded-lg bg-emerald-950/60 border border-emerald-800 text-emerald-300 text-[11px]", children: aiSuccess })
|
|
7318
7463
|
] })
|
|
7319
7464
|
] })
|
|
7320
7465
|
] })
|
|
@@ -7324,7 +7469,7 @@ var ImageEditor = ({
|
|
|
7324
7469
|
};
|
|
7325
7470
|
|
|
7326
7471
|
// src/review/useReview.ts
|
|
7327
|
-
var
|
|
7472
|
+
var import_react49 = require("react");
|
|
7328
7473
|
var import_editor12 = require("@pixerate/editor");
|
|
7329
7474
|
var EMPTY_COMMENTS = Object.freeze({
|
|
7330
7475
|
threads: [],
|
|
@@ -7343,23 +7488,23 @@ function isCommentStore(value) {
|
|
|
7343
7488
|
}
|
|
7344
7489
|
function useComments(source) {
|
|
7345
7490
|
const store = isCommentStore(source) ? source : (0, import_editor12.getCommentStore)(source);
|
|
7346
|
-
const subscribe = (0,
|
|
7491
|
+
const subscribe = (0, import_react49.useCallback)(
|
|
7347
7492
|
(onChange) => store ? store.subscribe(() => onChange()) : noopUnsubscribe,
|
|
7348
7493
|
[store]
|
|
7349
7494
|
);
|
|
7350
7495
|
const getSnapshot = () => store?.getSnapshot() ?? EMPTY_COMMENTS;
|
|
7351
|
-
const snapshot = (0,
|
|
7352
|
-
return (0,
|
|
7496
|
+
const snapshot = (0, import_react49.useSyncExternalStore)(subscribe, getSnapshot, getSnapshot);
|
|
7497
|
+
return (0, import_react49.useMemo)(() => ({ ...snapshot, store }), [snapshot, store]);
|
|
7353
7498
|
}
|
|
7354
7499
|
function useTrackChanges(editor) {
|
|
7355
7500
|
const store = (0, import_editor12.getTrackChangesStore)(editor ?? null);
|
|
7356
|
-
const subscribe = (0,
|
|
7501
|
+
const subscribe = (0, import_react49.useCallback)(
|
|
7357
7502
|
(onChange) => store ? store.subscribe(() => onChange()) : noopUnsubscribe,
|
|
7358
7503
|
[store]
|
|
7359
7504
|
);
|
|
7360
7505
|
const getSnapshot = () => store?.getSnapshot() ?? EMPTY_TRACK_CHANGES;
|
|
7361
|
-
const snapshot = (0,
|
|
7362
|
-
return (0,
|
|
7506
|
+
const snapshot = (0, import_react49.useSyncExternalStore)(subscribe, getSnapshot, getSnapshot);
|
|
7507
|
+
return (0, import_react49.useMemo)(() => {
|
|
7363
7508
|
const run = (fn) => () => {
|
|
7364
7509
|
if (editor && !editor.isDestroyed) fn(editor);
|
|
7365
7510
|
};
|
|
@@ -7382,9 +7527,9 @@ function useTrackChanges(editor) {
|
|
|
7382
7527
|
}
|
|
7383
7528
|
|
|
7384
7529
|
// src/review/CommentsPanel.tsx
|
|
7385
|
-
var
|
|
7530
|
+
var import_react50 = require("react");
|
|
7386
7531
|
var import_editor13 = require("@pixerate/editor");
|
|
7387
|
-
var
|
|
7532
|
+
var import_jsx_runtime33 = require("react/jsx-runtime");
|
|
7388
7533
|
var buttonClass2 = "rounded px-2 py-1 text-xs text-muted-foreground hover:bg-muted hover:text-foreground disabled:opacity-50";
|
|
7389
7534
|
var primaryButtonClass = "rounded px-2 py-1 text-xs bg-primary/10 text-primary hover:bg-primary/20 disabled:opacity-50";
|
|
7390
7535
|
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";
|
|
@@ -7398,18 +7543,18 @@ var CommentsPanel = ({
|
|
|
7398
7543
|
emptyMessage = "No comments yet. Select text and add a comment."
|
|
7399
7544
|
}) => {
|
|
7400
7545
|
const { threads, activeThreadId, store } = useComments(storeProp ?? editor);
|
|
7401
|
-
const [showResolved, setShowResolved] = (0,
|
|
7546
|
+
const [showResolved, setShowResolved] = (0, import_react50.useState)(showResolvedInitial);
|
|
7402
7547
|
const author = authorProp ?? (0, import_editor13.getCommentAuthor)(editor) ?? { id: "anonymous", name: "Anonymous" };
|
|
7403
7548
|
const visible = threads.filter((t) => showResolved || !t.resolved);
|
|
7404
7549
|
const resolvedCount = threads.filter((t) => t.resolved).length;
|
|
7405
|
-
return /* @__PURE__ */ (0,
|
|
7406
|
-
/* @__PURE__ */ (0,
|
|
7407
|
-
/* @__PURE__ */ (0,
|
|
7550
|
+
return /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("aside", { className, "aria-label": "Comments", children: [
|
|
7551
|
+
/* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("div", { className: "flex items-center justify-between gap-2", children: [
|
|
7552
|
+
/* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("span", { className: "text-xs font-medium text-muted-foreground", children: [
|
|
7408
7553
|
threads.length - resolvedCount,
|
|
7409
7554
|
" open",
|
|
7410
7555
|
resolvedCount > 0 ? ` \xB7 ${resolvedCount} resolved` : ""
|
|
7411
7556
|
] }),
|
|
7412
|
-
resolvedCount > 0 && /* @__PURE__ */ (0,
|
|
7557
|
+
resolvedCount > 0 && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
|
|
7413
7558
|
"button",
|
|
7414
7559
|
{
|
|
7415
7560
|
type: "button",
|
|
@@ -7420,7 +7565,7 @@ var CommentsPanel = ({
|
|
|
7420
7565
|
}
|
|
7421
7566
|
)
|
|
7422
7567
|
] }),
|
|
7423
|
-
visible.length === 0 ? /* @__PURE__ */ (0,
|
|
7568
|
+
visible.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("p", { className: "text-xs text-muted-foreground", children: emptyMessage }) : /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("ul", { className: "flex flex-col gap-2", role: "list", children: visible.map((thread) => /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
|
|
7424
7569
|
CommentThreadCard,
|
|
7425
7570
|
{
|
|
7426
7571
|
thread,
|
|
@@ -7442,7 +7587,7 @@ var CommentThreadCard = ({
|
|
|
7442
7587
|
author,
|
|
7443
7588
|
formatTime
|
|
7444
7589
|
}) => {
|
|
7445
|
-
const [draft, setDraft] = (0,
|
|
7590
|
+
const [draft, setDraft] = (0, import_react50.useState)("");
|
|
7446
7591
|
const isDraft = thread.body === "";
|
|
7447
7592
|
const quote = thread.anchor?.quote ?? thread.lastQuote ?? "";
|
|
7448
7593
|
const live = editor && !editor.isDestroyed ? editor : null;
|
|
@@ -7468,7 +7613,7 @@ var CommentThreadCard = ({
|
|
|
7468
7613
|
setDraft("");
|
|
7469
7614
|
};
|
|
7470
7615
|
const stop = (e) => e.stopPropagation();
|
|
7471
|
-
return /* @__PURE__ */ (0,
|
|
7616
|
+
return /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(
|
|
7472
7617
|
"li",
|
|
7473
7618
|
{
|
|
7474
7619
|
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" : ""}`,
|
|
@@ -7484,24 +7629,24 @@ var CommentThreadCard = ({
|
|
|
7484
7629
|
}
|
|
7485
7630
|
},
|
|
7486
7631
|
children: [
|
|
7487
|
-
/* @__PURE__ */ (0,
|
|
7488
|
-
/* @__PURE__ */ (0,
|
|
7489
|
-
/* @__PURE__ */ (0,
|
|
7632
|
+
/* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("div", { className: "flex items-baseline justify-between gap-2", children: [
|
|
7633
|
+
/* @__PURE__ */ (0, import_jsx_runtime33.jsx)("span", { className: "font-medium", children: thread.author.name }),
|
|
7634
|
+
/* @__PURE__ */ (0, import_jsx_runtime33.jsx)("span", { className: "text-xs text-muted-foreground", children: formatTime(thread.createdAt) })
|
|
7490
7635
|
] }),
|
|
7491
|
-
quote && /* @__PURE__ */ (0,
|
|
7492
|
-
thread.orphaned && /* @__PURE__ */ (0,
|
|
7493
|
-
thread.resolved && /* @__PURE__ */ (0,
|
|
7494
|
-
!isDraft && /* @__PURE__ */ (0,
|
|
7495
|
-
thread.replies.length > 0 && /* @__PURE__ */ (0,
|
|
7496
|
-
/* @__PURE__ */ (0,
|
|
7497
|
-
/* @__PURE__ */ (0,
|
|
7636
|
+
quote && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("blockquote", { className: "border-l-2 border-border pl-2 text-xs text-muted-foreground line-clamp-2", children: quote }),
|
|
7637
|
+
thread.orphaned && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("span", { className: "text-xs text-destructive", children: "The commented text was deleted." }),
|
|
7638
|
+
thread.resolved && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("span", { className: "text-xs text-muted-foreground", children: "Resolved" }),
|
|
7639
|
+
!isDraft && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("p", { className: "whitespace-pre-wrap break-words", children: thread.body }),
|
|
7640
|
+
thread.replies.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime33.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_runtime33.jsxs)("li", { className: "flex flex-col gap-0.5", "data-reply-id": reply.id, children: [
|
|
7641
|
+
/* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("span", { className: "text-xs", children: [
|
|
7642
|
+
/* @__PURE__ */ (0, import_jsx_runtime33.jsx)("span", { className: "font-medium", children: reply.author.name }),
|
|
7498
7643
|
" ",
|
|
7499
|
-
/* @__PURE__ */ (0,
|
|
7644
|
+
/* @__PURE__ */ (0, import_jsx_runtime33.jsx)("span", { className: "text-muted-foreground", children: formatTime(reply.createdAt) })
|
|
7500
7645
|
] }),
|
|
7501
|
-
/* @__PURE__ */ (0,
|
|
7646
|
+
/* @__PURE__ */ (0, import_jsx_runtime33.jsx)("p", { className: "whitespace-pre-wrap break-words", children: reply.body })
|
|
7502
7647
|
] }, reply.id)) }),
|
|
7503
|
-
(active || isDraft) && !thread.resolved && /* @__PURE__ */ (0,
|
|
7504
|
-
/* @__PURE__ */ (0,
|
|
7648
|
+
(active || isDraft) && !thread.resolved && /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("div", { className: "flex flex-col gap-1", onClick: stop, children: [
|
|
7649
|
+
/* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
|
|
7505
7650
|
"textarea",
|
|
7506
7651
|
{
|
|
7507
7652
|
className: textareaClass,
|
|
@@ -7519,9 +7664,9 @@ var CommentThreadCard = ({
|
|
|
7519
7664
|
}
|
|
7520
7665
|
}
|
|
7521
7666
|
),
|
|
7522
|
-
/* @__PURE__ */ (0,
|
|
7523
|
-
isDraft && /* @__PURE__ */ (0,
|
|
7524
|
-
/* @__PURE__ */ (0,
|
|
7667
|
+
/* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("div", { className: "flex justify-end gap-1", children: [
|
|
7668
|
+
isDraft && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("button", { type: "button", className: buttonClass2, onClick: remove, children: "Cancel" }),
|
|
7669
|
+
/* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
|
|
7525
7670
|
"button",
|
|
7526
7671
|
{
|
|
7527
7672
|
type: "button",
|
|
@@ -7533,9 +7678,9 @@ var CommentThreadCard = ({
|
|
|
7533
7678
|
)
|
|
7534
7679
|
] })
|
|
7535
7680
|
] }),
|
|
7536
|
-
!isDraft && /* @__PURE__ */ (0,
|
|
7537
|
-
/* @__PURE__ */ (0,
|
|
7538
|
-
/* @__PURE__ */ (0,
|
|
7681
|
+
!isDraft && /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("div", { className: "flex justify-end gap-1", onClick: stop, children: [
|
|
7682
|
+
/* @__PURE__ */ (0, import_jsx_runtime33.jsx)("button", { type: "button", className: buttonClass2, onClick: () => setResolved(!thread.resolved), children: thread.resolved ? "Reopen" : "Resolve" }),
|
|
7683
|
+
/* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
|
|
7539
7684
|
"button",
|
|
7540
7685
|
{
|
|
7541
7686
|
type: "button",
|
|
@@ -7551,7 +7696,7 @@ var CommentThreadCard = ({
|
|
|
7551
7696
|
};
|
|
7552
7697
|
|
|
7553
7698
|
// src/review/ReviewToolbar.tsx
|
|
7554
|
-
var
|
|
7699
|
+
var import_jsx_runtime34 = require("react/jsx-runtime");
|
|
7555
7700
|
var defaultDescriptionClass = "max-w-[16rem] truncate px-1 text-xs text-muted-foreground";
|
|
7556
7701
|
var buttonClass3 = "rounded px-2 py-1 text-xs text-foreground hover:bg-muted disabled:opacity-40 disabled:hover:bg-transparent";
|
|
7557
7702
|
var ReviewToolbar = ({
|
|
@@ -7564,8 +7709,8 @@ var ReviewToolbar = ({
|
|
|
7564
7709
|
const count = review.changes.length;
|
|
7565
7710
|
const current = review.currentChange;
|
|
7566
7711
|
const index = current ? review.changes.findIndex((c) => c.id === current.id) + 1 : 0;
|
|
7567
|
-
return /* @__PURE__ */ (0,
|
|
7568
|
-
/* @__PURE__ */ (0,
|
|
7712
|
+
return /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("div", { className, role: "toolbar", "aria-label": "Review", children: [
|
|
7713
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
7569
7714
|
"button",
|
|
7570
7715
|
{
|
|
7571
7716
|
type: "button",
|
|
@@ -7576,8 +7721,8 @@ var ReviewToolbar = ({
|
|
|
7576
7721
|
children: review.enabled ? "Tracking on" : "Track changes"
|
|
7577
7722
|
}
|
|
7578
7723
|
),
|
|
7579
|
-
/* @__PURE__ */ (0,
|
|
7580
|
-
/* @__PURE__ */ (0,
|
|
7724
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)("span", { className: "mx-1 h-4 w-px bg-border", "aria-hidden": "true" }),
|
|
7725
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
7581
7726
|
"button",
|
|
7582
7727
|
{
|
|
7583
7728
|
type: "button",
|
|
@@ -7588,8 +7733,8 @@ var ReviewToolbar = ({
|
|
|
7588
7733
|
children: "\u2039"
|
|
7589
7734
|
}
|
|
7590
7735
|
),
|
|
7591
|
-
/* @__PURE__ */ (0,
|
|
7592
|
-
/* @__PURE__ */ (0,
|
|
7736
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.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` }),
|
|
7737
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
7593
7738
|
"button",
|
|
7594
7739
|
{
|
|
7595
7740
|
type: "button",
|
|
@@ -7600,7 +7745,7 @@ var ReviewToolbar = ({
|
|
|
7600
7745
|
children: "\u203A"
|
|
7601
7746
|
}
|
|
7602
7747
|
),
|
|
7603
|
-
showDescription && current && /* @__PURE__ */ (0,
|
|
7748
|
+
showDescription && current && /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(
|
|
7604
7749
|
"span",
|
|
7605
7750
|
{
|
|
7606
7751
|
className: descriptionClassName,
|
|
@@ -7612,8 +7757,8 @@ var ReviewToolbar = ({
|
|
|
7612
7757
|
]
|
|
7613
7758
|
}
|
|
7614
7759
|
),
|
|
7615
|
-
/* @__PURE__ */ (0,
|
|
7616
|
-
/* @__PURE__ */ (0,
|
|
7760
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)("span", { className: "mx-1 h-4 w-px bg-border", "aria-hidden": "true" }),
|
|
7761
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
7617
7762
|
"button",
|
|
7618
7763
|
{
|
|
7619
7764
|
type: "button",
|
|
@@ -7623,7 +7768,7 @@ var ReviewToolbar = ({
|
|
|
7623
7768
|
children: "Accept"
|
|
7624
7769
|
}
|
|
7625
7770
|
),
|
|
7626
|
-
/* @__PURE__ */ (0,
|
|
7771
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
7627
7772
|
"button",
|
|
7628
7773
|
{
|
|
7629
7774
|
type: "button",
|
|
@@ -7633,18 +7778,18 @@ var ReviewToolbar = ({
|
|
|
7633
7778
|
children: "Reject"
|
|
7634
7779
|
}
|
|
7635
7780
|
),
|
|
7636
|
-
/* @__PURE__ */ (0,
|
|
7637
|
-
/* @__PURE__ */ (0,
|
|
7781
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)("button", { type: "button", className: buttonClass3, disabled: count === 0, onClick: review.acceptAll, children: "Accept all" }),
|
|
7782
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)("button", { type: "button", className: buttonClass3, disabled: count === 0, onClick: review.rejectAll, children: "Reject all" })
|
|
7638
7783
|
] });
|
|
7639
7784
|
};
|
|
7640
7785
|
|
|
7641
7786
|
// src/review/CommentButton.tsx
|
|
7642
|
-
var
|
|
7787
|
+
var import_jsx_runtime35 = require("react/jsx-runtime");
|
|
7643
7788
|
var CommentButton = ({
|
|
7644
7789
|
editor,
|
|
7645
7790
|
className = "rounded px-2 py-1 text-xs text-popover-foreground hover:bg-muted",
|
|
7646
7791
|
children = "Comment"
|
|
7647
|
-
}) => /* @__PURE__ */ (0,
|
|
7792
|
+
}) => /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
|
|
7648
7793
|
"button",
|
|
7649
7794
|
{
|
|
7650
7795
|
type: "button",
|
|
@@ -7656,13 +7801,13 @@ var CommentButton = ({
|
|
|
7656
7801
|
);
|
|
7657
7802
|
|
|
7658
7803
|
// src/review/useDocumentCompare.ts
|
|
7659
|
-
var
|
|
7804
|
+
var import_react51 = require("react");
|
|
7660
7805
|
var import_editor14 = require("@pixerate/editor");
|
|
7661
7806
|
function useDocumentCompare(editor, options) {
|
|
7662
|
-
const [summary, setSummary] = (0,
|
|
7663
|
-
const defaults = (0,
|
|
7807
|
+
const [summary, setSummary] = (0, import_react51.useState)(null);
|
|
7808
|
+
const defaults = (0, import_react51.useRef)(options);
|
|
7664
7809
|
defaults.current = options;
|
|
7665
|
-
const compare = (0,
|
|
7810
|
+
const compare = (0, import_react51.useCallback)(
|
|
7666
7811
|
(original, revised, overrides) => {
|
|
7667
7812
|
if (!editor || editor.isDestroyed) return null;
|
|
7668
7813
|
const result = (0, import_editor14.applyDocumentComparison)(editor, original, revised, {
|
|
@@ -7674,13 +7819,13 @@ function useDocumentCompare(editor, options) {
|
|
|
7674
7819
|
},
|
|
7675
7820
|
[editor]
|
|
7676
7821
|
);
|
|
7677
|
-
const clear = (0,
|
|
7678
|
-
return (0,
|
|
7822
|
+
const clear = (0, import_react51.useCallback)(() => setSummary(null), []);
|
|
7823
|
+
return (0, import_react51.useMemo)(() => ({ summary, compare, clear }), [summary, compare, clear]);
|
|
7679
7824
|
}
|
|
7680
7825
|
|
|
7681
7826
|
// src/review/TrackedChangesList.tsx
|
|
7682
7827
|
var import_editor15 = require("@pixerate/editor");
|
|
7683
|
-
var
|
|
7828
|
+
var import_jsx_runtime36 = require("react/jsx-runtime");
|
|
7684
7829
|
var buttonClass4 = "rounded px-1.5 py-0.5 text-xs text-foreground hover:bg-muted disabled:opacity-40";
|
|
7685
7830
|
var TrackedChangesList = ({
|
|
7686
7831
|
editor,
|
|
@@ -7691,18 +7836,18 @@ var TrackedChangesList = ({
|
|
|
7691
7836
|
}) => {
|
|
7692
7837
|
const review = useTrackChanges(editor);
|
|
7693
7838
|
if (review.changes.length === 0) {
|
|
7694
|
-
return /* @__PURE__ */ (0,
|
|
7839
|
+
return /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("div", { className, "data-tracked-changes-list": "", children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("div", { className: "pixerate-changes-empty text-xs text-muted-foreground", children: emptyState }) });
|
|
7695
7840
|
}
|
|
7696
|
-
return /* @__PURE__ */ (0,
|
|
7841
|
+
return /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("ul", { className, role: "list", "aria-label": "Tracked changes", "data-tracked-changes-list": "", children: review.changes.map((change) => {
|
|
7697
7842
|
const active = change.id === review.currentChangeId;
|
|
7698
|
-
return /* @__PURE__ */ (0,
|
|
7843
|
+
return /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(
|
|
7699
7844
|
"li",
|
|
7700
7845
|
{
|
|
7701
7846
|
className: active ? `${itemClassName} ${activeItemClassName}` : itemClassName,
|
|
7702
7847
|
"data-change-type": change.type,
|
|
7703
7848
|
"data-change-id": change.id,
|
|
7704
7849
|
children: [
|
|
7705
|
-
/* @__PURE__ */ (0,
|
|
7850
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(
|
|
7706
7851
|
"button",
|
|
7707
7852
|
{
|
|
7708
7853
|
type: "button",
|
|
@@ -7710,14 +7855,14 @@ var TrackedChangesList = ({
|
|
|
7710
7855
|
title: `${change.author.name}: ${change.description}`,
|
|
7711
7856
|
onClick: () => review.select(change.id),
|
|
7712
7857
|
children: [
|
|
7713
|
-
/* @__PURE__ */ (0,
|
|
7858
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)("span", { className: "font-medium", children: (0, import_editor15.trackedChangeLabel)(change) }),
|
|
7714
7859
|
change.author.name ? ` \xB7 ${change.author.name}` : "",
|
|
7715
|
-
/* @__PURE__ */ (0,
|
|
7860
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)("span", { className: "block truncate text-muted-foreground", children: change.description })
|
|
7716
7861
|
]
|
|
7717
7862
|
}
|
|
7718
7863
|
),
|
|
7719
|
-
/* @__PURE__ */ (0,
|
|
7720
|
-
/* @__PURE__ */ (0,
|
|
7864
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)("button", { type: "button", className: buttonClass4, onClick: () => review.accept(change.id), children: "Accept" }),
|
|
7865
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)("button", { type: "button", className: buttonClass4, onClick: () => review.reject(change.id), children: "Reject" })
|
|
7721
7866
|
]
|
|
7722
7867
|
},
|
|
7723
7868
|
`${change.type}:${change.id}`
|
|
@@ -7726,12 +7871,12 @@ var TrackedChangesList = ({
|
|
|
7726
7871
|
};
|
|
7727
7872
|
|
|
7728
7873
|
// src/commands/useCommandPalette.ts
|
|
7729
|
-
var
|
|
7874
|
+
var import_react52 = require("react");
|
|
7730
7875
|
var import_commands2 = require("@pixerate/editor/commands");
|
|
7731
7876
|
function useCommandPalette(registry, options = {}) {
|
|
7732
|
-
const optionsRef = (0,
|
|
7877
|
+
const optionsRef = (0, import_react52.useRef)(options);
|
|
7733
7878
|
optionsRef.current = options;
|
|
7734
|
-
const controller = (0,
|
|
7879
|
+
const controller = (0, import_react52.useMemo)(
|
|
7735
7880
|
() => (0, import_commands2.createCommandPaletteController)(registry, {
|
|
7736
7881
|
context: () => {
|
|
7737
7882
|
const c = optionsRef.current.context;
|
|
@@ -7752,9 +7897,9 @@ function useCommandPalette(registry, options = {}) {
|
|
|
7752
7897
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
7753
7898
|
[registry]
|
|
7754
7899
|
);
|
|
7755
|
-
const state = (0,
|
|
7900
|
+
const state = (0, import_react52.useSyncExternalStore)(controller.subscribe, controller.getState, controller.getState);
|
|
7756
7901
|
const { hotkey, hotkeyTarget } = options;
|
|
7757
|
-
(0,
|
|
7902
|
+
(0, import_react52.useEffect)(() => {
|
|
7758
7903
|
if (!hotkey) return;
|
|
7759
7904
|
const target = hotkeyTarget ?? (typeof window !== "undefined" ? window : null);
|
|
7760
7905
|
if (!target) return;
|
|
@@ -7782,13 +7927,13 @@ function useCommandPalette(registry, options = {}) {
|
|
|
7782
7927
|
}
|
|
7783
7928
|
|
|
7784
7929
|
// src/commands/CommandPalette.tsx
|
|
7785
|
-
var
|
|
7786
|
-
var
|
|
7930
|
+
var import_react53 = __toESM(require("react"), 1);
|
|
7931
|
+
var import_jsx_runtime37 = require("react/jsx-runtime");
|
|
7787
7932
|
function HighlightedLabel({ item }) {
|
|
7788
|
-
if (item.labelIndices.length === 0) return /* @__PURE__ */ (0,
|
|
7933
|
+
if (item.labelIndices.length === 0) return /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(import_jsx_runtime37.Fragment, { children: item.label });
|
|
7789
7934
|
const marked = new Set(item.labelIndices);
|
|
7790
|
-
return /* @__PURE__ */ (0,
|
|
7791
|
-
(ch, i) => marked.has(i) ? /* @__PURE__ */ (0,
|
|
7935
|
+
return /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(import_jsx_runtime37.Fragment, { children: Array.from(item.label).map(
|
|
7936
|
+
(ch, i) => marked.has(i) ? /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("span", { className: "font-semibold text-foreground", "data-match": "", children: ch }, i) : /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(import_react53.default.Fragment, { children: ch }, i)
|
|
7792
7937
|
) });
|
|
7793
7938
|
}
|
|
7794
7939
|
var CommandPalette = ({
|
|
@@ -7797,22 +7942,22 @@ var CommandPalette = ({
|
|
|
7797
7942
|
emptyMessage = "No matching commands",
|
|
7798
7943
|
className = ""
|
|
7799
7944
|
}) => {
|
|
7800
|
-
const inputRef = (0,
|
|
7801
|
-
const listRef = (0,
|
|
7802
|
-
const baseId = (0,
|
|
7945
|
+
const inputRef = (0, import_react53.useRef)(null);
|
|
7946
|
+
const listRef = (0, import_react53.useRef)(null);
|
|
7947
|
+
const baseId = (0, import_react53.useId)();
|
|
7803
7948
|
const listId = `${baseId}-list`;
|
|
7804
7949
|
const optionId = (index) => `${baseId}-option-${index}`;
|
|
7805
7950
|
const { open, query, items, activeIndex } = palette;
|
|
7806
|
-
(0,
|
|
7951
|
+
(0, import_react53.useEffect)(() => {
|
|
7807
7952
|
if (open) inputRef.current?.focus();
|
|
7808
7953
|
}, [open]);
|
|
7809
|
-
(0,
|
|
7954
|
+
(0, import_react53.useEffect)(() => {
|
|
7810
7955
|
if (!open) return;
|
|
7811
7956
|
const active = listRef.current?.querySelector('[aria-selected="true"]');
|
|
7812
7957
|
active?.scrollIntoView?.({ block: "nearest" });
|
|
7813
7958
|
}, [open, activeIndex]);
|
|
7814
7959
|
if (!open) return null;
|
|
7815
|
-
return /* @__PURE__ */ (0,
|
|
7960
|
+
return /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
|
|
7816
7961
|
"div",
|
|
7817
7962
|
{
|
|
7818
7963
|
className: "fixed inset-0 z-50 flex items-start justify-center bg-black/30 px-4 pt-[15vh]",
|
|
@@ -7820,7 +7965,7 @@ var CommandPalette = ({
|
|
|
7820
7965
|
onMouseDown: (e) => {
|
|
7821
7966
|
if (e.target === e.currentTarget) palette.setOpen(false);
|
|
7822
7967
|
},
|
|
7823
|
-
children: /* @__PURE__ */ (0,
|
|
7968
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)(
|
|
7824
7969
|
"div",
|
|
7825
7970
|
{
|
|
7826
7971
|
role: "dialog",
|
|
@@ -7829,7 +7974,7 @@ var CommandPalette = ({
|
|
|
7829
7974
|
className: `w-full max-w-lg overflow-hidden rounded-lg border border-border bg-popover text-popover-foreground shadow-xl ${className}`,
|
|
7830
7975
|
style: { background: "var(--popover, var(--background, #fff))" },
|
|
7831
7976
|
children: [
|
|
7832
|
-
/* @__PURE__ */ (0,
|
|
7977
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
|
|
7833
7978
|
"input",
|
|
7834
7979
|
{
|
|
7835
7980
|
ref: inputRef,
|
|
@@ -7849,7 +7994,7 @@ var CommandPalette = ({
|
|
|
7849
7994
|
className: "w-full border-b border-border bg-transparent px-3 py-2 text-sm outline-none placeholder:text-muted-foreground"
|
|
7850
7995
|
}
|
|
7851
7996
|
),
|
|
7852
|
-
items.length === 0 ? /* @__PURE__ */ (0,
|
|
7997
|
+
items.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("div", { className: "px-3 py-6 text-center text-sm text-muted-foreground", children: emptyMessage }) : /* @__PURE__ */ (0, import_jsx_runtime37.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_runtime37.jsxs)(
|
|
7853
7998
|
"li",
|
|
7854
7999
|
{
|
|
7855
8000
|
id: optionId(index),
|
|
@@ -7864,12 +8009,12 @@ var CommandPalette = ({
|
|
|
7864
8009
|
onClick: () => palette.run(item.id),
|
|
7865
8010
|
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"}`,
|
|
7866
8011
|
children: [
|
|
7867
|
-
/* @__PURE__ */ (0,
|
|
7868
|
-
/* @__PURE__ */ (0,
|
|
7869
|
-
item.disabledReason && /* @__PURE__ */ (0,
|
|
8012
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("span", { className: "min-w-0 flex-1 truncate", children: [
|
|
8013
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsx)(HighlightedLabel, { item }),
|
|
8014
|
+
item.disabledReason && /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("span", { className: "ml-2 text-xs text-muted-foreground", "data-disabled-reason": "", children: item.disabledReason })
|
|
7870
8015
|
] }),
|
|
7871
|
-
item.group && /* @__PURE__ */ (0,
|
|
7872
|
-
item.shortcut && /* @__PURE__ */ (0,
|
|
8016
|
+
item.group && /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("span", { className: "shrink-0 text-xs text-muted-foreground", children: item.group }),
|
|
8017
|
+
item.shortcut && /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("kbd", { className: "shrink-0 rounded border border-border px-1.5 font-mono text-[10px] text-muted-foreground", children: item.shortcut })
|
|
7873
8018
|
]
|
|
7874
8019
|
},
|
|
7875
8020
|
item.id
|
|
@@ -7882,12 +8027,12 @@ var CommandPalette = ({
|
|
|
7882
8027
|
};
|
|
7883
8028
|
|
|
7884
8029
|
// src/commands/useCommandShortcuts.ts
|
|
7885
|
-
var
|
|
8030
|
+
var import_react54 = require("react");
|
|
7886
8031
|
function useCommandShortcuts(registry, options = {}) {
|
|
7887
|
-
const optionsRef = (0,
|
|
8032
|
+
const optionsRef = (0, import_react54.useRef)(options);
|
|
7888
8033
|
optionsRef.current = options;
|
|
7889
8034
|
const { enabled = true, target } = options;
|
|
7890
|
-
(0,
|
|
8035
|
+
(0, import_react54.useEffect)(() => {
|
|
7891
8036
|
if (!registry || !enabled) return;
|
|
7892
8037
|
const eventTarget = target ?? (typeof window !== "undefined" ? window : null);
|
|
7893
8038
|
if (!eventTarget) return;
|
|
@@ -7905,14 +8050,14 @@ function useCommandShortcuts(registry, options = {}) {
|
|
|
7905
8050
|
}, [registry, enabled, target]);
|
|
7906
8051
|
}
|
|
7907
8052
|
function useRegisterCommands(registry, specs) {
|
|
7908
|
-
(0,
|
|
8053
|
+
(0, import_react54.useEffect)(() => {
|
|
7909
8054
|
if (!registry || !specs || specs.length === 0) return;
|
|
7910
8055
|
return registry.register(specs);
|
|
7911
8056
|
}, [registry, specs]);
|
|
7912
8057
|
}
|
|
7913
8058
|
|
|
7914
8059
|
// src/persistence/useAutosave.ts
|
|
7915
|
-
var
|
|
8060
|
+
var import_react55 = require("react");
|
|
7916
8061
|
var import_persistence = require("@pixerate/editor/persistence");
|
|
7917
8062
|
var IDLE = {
|
|
7918
8063
|
status: "idle",
|
|
@@ -7923,18 +8068,18 @@ var IDLE = {
|
|
|
7923
8068
|
ready: false
|
|
7924
8069
|
};
|
|
7925
8070
|
function useAutosave(options) {
|
|
7926
|
-
const optionsRef = (0,
|
|
8071
|
+
const optionsRef = (0, import_react55.useRef)(options);
|
|
7927
8072
|
optionsRef.current = options;
|
|
7928
8073
|
const { storage, key, history, dirty } = options;
|
|
7929
8074
|
const recover = options.recover !== false;
|
|
7930
8075
|
const flushOnHide = options.flushOnHide !== false;
|
|
7931
8076
|
const ready = options.ready !== false;
|
|
7932
|
-
const [controller, setController] = (0,
|
|
7933
|
-
const [status, setStatus] = (0,
|
|
7934
|
-
const [recovery, setRecovery] = (0,
|
|
7935
|
-
const [pendingRecovery, setPendingRecovery] = (0,
|
|
7936
|
-
const revisionsRef = (0,
|
|
7937
|
-
(0,
|
|
8077
|
+
const [controller, setController] = (0, import_react55.useState)(null);
|
|
8078
|
+
const [status, setStatus] = (0, import_react55.useState)(IDLE);
|
|
8079
|
+
const [recovery, setRecovery] = (0, import_react55.useState)(null);
|
|
8080
|
+
const [pendingRecovery, setPendingRecovery] = (0, import_react55.useState)(recover);
|
|
8081
|
+
const revisionsRef = (0, import_react55.useRef)(null);
|
|
8082
|
+
(0, import_react55.useEffect)(() => {
|
|
7938
8083
|
const revisions = (0, import_persistence.createRevisionTracker)({ history, dirty });
|
|
7939
8084
|
const o = optionsRef.current;
|
|
7940
8085
|
const instance = (0, import_persistence.createAutosaveController)({
|
|
@@ -7977,10 +8122,10 @@ function useAutosave(options) {
|
|
|
7977
8122
|
if (revisionsRef.current === revisions) revisionsRef.current = null;
|
|
7978
8123
|
};
|
|
7979
8124
|
}, [storage, key, history, dirty, recover]);
|
|
7980
|
-
(0,
|
|
8125
|
+
(0, import_react55.useEffect)(() => {
|
|
7981
8126
|
if (controller && ready && !pendingRecovery) controller.ready();
|
|
7982
8127
|
}, [controller, ready, pendingRecovery]);
|
|
7983
|
-
(0,
|
|
8128
|
+
(0, import_react55.useEffect)(() => {
|
|
7984
8129
|
if (!controller || !flushOnHide || typeof window === "undefined") return;
|
|
7985
8130
|
const flush = () => void controller.flushNow();
|
|
7986
8131
|
const onVisibility = () => {
|
|
@@ -7993,31 +8138,31 @@ function useAutosave(options) {
|
|
|
7993
8138
|
document.removeEventListener("visibilitychange", onVisibility);
|
|
7994
8139
|
};
|
|
7995
8140
|
}, [controller, flushOnHide]);
|
|
7996
|
-
const restore = (0,
|
|
8141
|
+
const restore = (0, import_react55.useCallback)(() => {
|
|
7997
8142
|
const snapshot = recovery?.snapshot;
|
|
7998
8143
|
setRecovery(null);
|
|
7999
8144
|
setPendingRecovery(false);
|
|
8000
8145
|
return snapshot;
|
|
8001
8146
|
}, [recovery]);
|
|
8002
|
-
const discard = (0,
|
|
8147
|
+
const discard = (0, import_react55.useCallback)(async () => {
|
|
8003
8148
|
if (controller) await controller.discardRecovery();
|
|
8004
8149
|
setRecovery(null);
|
|
8005
8150
|
setPendingRecovery(false);
|
|
8006
8151
|
}, [controller]);
|
|
8007
|
-
const flushNow = (0,
|
|
8152
|
+
const flushNow = (0, import_react55.useCallback)(async () => {
|
|
8008
8153
|
await controller?.flushNow();
|
|
8009
8154
|
}, [controller]);
|
|
8010
|
-
const markClean = (0,
|
|
8155
|
+
const markClean = (0, import_react55.useCallback)(async () => {
|
|
8011
8156
|
revisionsRef.current?.markSaved();
|
|
8012
8157
|
await controller?.markClean();
|
|
8013
8158
|
}, [controller]);
|
|
8014
|
-
const notifyChange = (0,
|
|
8159
|
+
const notifyChange = (0, import_react55.useCallback)(() => revisionsRef.current?.bump(), []);
|
|
8015
8160
|
return { status, recovery, pendingRecovery, restore, discard, flushNow, markClean, notifyChange, controller };
|
|
8016
8161
|
}
|
|
8017
8162
|
|
|
8018
8163
|
// src/persistence/RecoveryPrompt.tsx
|
|
8019
8164
|
var import_persistence2 = require("@pixerate/editor/persistence");
|
|
8020
|
-
var
|
|
8165
|
+
var import_jsx_runtime38 = require("react/jsx-runtime");
|
|
8021
8166
|
var RecoveryPrompt = ({
|
|
8022
8167
|
recovery,
|
|
8023
8168
|
onRestore,
|
|
@@ -8029,7 +8174,7 @@ var RecoveryPrompt = ({
|
|
|
8029
8174
|
}) => {
|
|
8030
8175
|
if (!recovery) return null;
|
|
8031
8176
|
const { name } = recovery.meta;
|
|
8032
|
-
return /* @__PURE__ */ (0,
|
|
8177
|
+
return /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(
|
|
8033
8178
|
"div",
|
|
8034
8179
|
{
|
|
8035
8180
|
role: "alertdialog",
|
|
@@ -8037,15 +8182,15 @@ var RecoveryPrompt = ({
|
|
|
8037
8182
|
"data-recovery-prompt": "",
|
|
8038
8183
|
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}`,
|
|
8039
8184
|
children: [
|
|
8040
|
-
/* @__PURE__ */ (0,
|
|
8185
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsxs)("span", { className: "min-w-0 flex-1", children: [
|
|
8041
8186
|
(0, import_persistence2.formatRecoveryMessage)(recovery.meta, formatTime),
|
|
8042
|
-
name ? /* @__PURE__ */ (0,
|
|
8187
|
+
name ? /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)("span", { className: "ml-1 text-xs text-muted-foreground", children: [
|
|
8043
8188
|
"(",
|
|
8044
8189
|
name,
|
|
8045
8190
|
")"
|
|
8046
8191
|
] }) : null
|
|
8047
8192
|
] }),
|
|
8048
|
-
/* @__PURE__ */ (0,
|
|
8193
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
|
|
8049
8194
|
"button",
|
|
8050
8195
|
{
|
|
8051
8196
|
type: "button",
|
|
@@ -8055,7 +8200,7 @@ var RecoveryPrompt = ({
|
|
|
8055
8200
|
children: restoreLabel
|
|
8056
8201
|
}
|
|
8057
8202
|
),
|
|
8058
|
-
/* @__PURE__ */ (0,
|
|
8203
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
|
|
8059
8204
|
"button",
|
|
8060
8205
|
{
|
|
8061
8206
|
type: "button",
|
|
@@ -8071,17 +8216,17 @@ var RecoveryPrompt = ({
|
|
|
8071
8216
|
};
|
|
8072
8217
|
|
|
8073
8218
|
// src/generation/useGenerationPlan.ts
|
|
8074
|
-
var
|
|
8219
|
+
var import_react56 = require("react");
|
|
8075
8220
|
var import_generation = require("@pixerate/editor/generation");
|
|
8076
8221
|
function useGenerationPlan(request, capabilities, options = {}) {
|
|
8077
8222
|
const key = JSON.stringify([request, capabilities, options]);
|
|
8078
|
-
return (0,
|
|
8223
|
+
return (0, import_react56.useMemo)(() => (0, import_generation.planGenerationRequest)(request, capabilities, options), [key]);
|
|
8079
8224
|
}
|
|
8080
8225
|
function useJobProgress(options) {
|
|
8081
8226
|
const { startedAt, expectedMs, done, now, intervalMs = 1e3 } = options;
|
|
8082
|
-
const [tick, setTick] = (0,
|
|
8227
|
+
const [tick, setTick] = (0, import_react56.useState)(() => Date.now());
|
|
8083
8228
|
const ticking = !done && now === void 0;
|
|
8084
|
-
(0,
|
|
8229
|
+
(0, import_react56.useEffect)(() => {
|
|
8085
8230
|
if (!ticking) return;
|
|
8086
8231
|
setTick(Date.now());
|
|
8087
8232
|
const id = setInterval(() => setTick(Date.now()), Math.max(16, intervalMs));
|
|
@@ -8091,9 +8236,9 @@ function useJobProgress(options) {
|
|
|
8091
8236
|
}
|
|
8092
8237
|
|
|
8093
8238
|
// src/generation/GenerationSettings.tsx
|
|
8094
|
-
var
|
|
8239
|
+
var import_react57 = require("react");
|
|
8095
8240
|
var import_generation2 = require("@pixerate/editor/generation");
|
|
8096
|
-
var
|
|
8241
|
+
var import_jsx_runtime39 = require("react/jsx-runtime");
|
|
8097
8242
|
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";
|
|
8098
8243
|
function Control({
|
|
8099
8244
|
control,
|
|
@@ -8103,7 +8248,7 @@ function Control({
|
|
|
8103
8248
|
}) {
|
|
8104
8249
|
const shown = value ?? control.defaultValue;
|
|
8105
8250
|
if (control.kind === "checkbox") {
|
|
8106
|
-
return /* @__PURE__ */ (0,
|
|
8251
|
+
return /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
|
|
8107
8252
|
"input",
|
|
8108
8253
|
{
|
|
8109
8254
|
id,
|
|
@@ -8115,7 +8260,7 @@ function Control({
|
|
|
8115
8260
|
);
|
|
8116
8261
|
}
|
|
8117
8262
|
if (control.kind === "select") {
|
|
8118
|
-
return /* @__PURE__ */ (0,
|
|
8263
|
+
return /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)(
|
|
8119
8264
|
"select",
|
|
8120
8265
|
{
|
|
8121
8266
|
id,
|
|
@@ -8124,14 +8269,14 @@ function Control({
|
|
|
8124
8269
|
value: shown === void 0 ? "" : String(shown),
|
|
8125
8270
|
onChange: (e) => onValue((0, import_generation2.parseControlValue)(control, e.target.value)),
|
|
8126
8271
|
children: [
|
|
8127
|
-
shown === void 0 && /* @__PURE__ */ (0,
|
|
8128
|
-
control.options.map((option) => /* @__PURE__ */ (0,
|
|
8272
|
+
shown === void 0 && /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("option", { value: "", children: "Default" }),
|
|
8273
|
+
control.options.map((option) => /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("option", { value: String(option.value), children: option.label }, String(option.value)))
|
|
8129
8274
|
]
|
|
8130
8275
|
}
|
|
8131
8276
|
);
|
|
8132
8277
|
}
|
|
8133
8278
|
if (control.kind === "textarea") {
|
|
8134
|
-
return /* @__PURE__ */ (0,
|
|
8279
|
+
return /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
|
|
8135
8280
|
"textarea",
|
|
8136
8281
|
{
|
|
8137
8282
|
id,
|
|
@@ -8145,8 +8290,8 @@ function Control({
|
|
|
8145
8290
|
);
|
|
8146
8291
|
}
|
|
8147
8292
|
const numeric = typeof shown === "number" ? shown : void 0;
|
|
8148
|
-
return /* @__PURE__ */ (0,
|
|
8149
|
-
/* @__PURE__ */ (0,
|
|
8293
|
+
return /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
8294
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
|
|
8150
8295
|
"input",
|
|
8151
8296
|
{
|
|
8152
8297
|
id,
|
|
@@ -8160,7 +8305,7 @@ function Control({
|
|
|
8160
8305
|
onChange: (e) => onValue((0, import_generation2.parseControlValue)(control, e.target.value))
|
|
8161
8306
|
}
|
|
8162
8307
|
),
|
|
8163
|
-
control.kind === "range" && /* @__PURE__ */ (0,
|
|
8308
|
+
control.kind === "range" && /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("span", { className: "w-10 text-right tabular-nums text-muted-foreground", "data-field-value": "", children: numeric ?? "\u2013" })
|
|
8164
8309
|
] });
|
|
8165
8310
|
}
|
|
8166
8311
|
var GenerationSettings = ({
|
|
@@ -8174,17 +8319,17 @@ var GenerationSettings = ({
|
|
|
8174
8319
|
renderReference,
|
|
8175
8320
|
className = ""
|
|
8176
8321
|
}) => {
|
|
8177
|
-
const baseId = (0,
|
|
8178
|
-
const controls = (0,
|
|
8322
|
+
const baseId = (0, import_react57.useId)();
|
|
8323
|
+
const controls = (0, import_react57.useMemo)(() => (0, import_generation2.getGenerationControls)(capabilities), [capabilities]);
|
|
8179
8324
|
const computed = useGenerationPlan(value, capabilities, { strategy });
|
|
8180
8325
|
const plan = planProp ?? computed;
|
|
8181
8326
|
const slots = (0, import_generation2.getReferenceSlots)(capabilities, value);
|
|
8182
|
-
return /* @__PURE__ */ (0,
|
|
8327
|
+
return /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("div", { className: `flex flex-col gap-3 text-sm ${className}`, "data-generation-settings": "", "data-model": capabilities.id, children: [
|
|
8183
8328
|
controls.map((control) => {
|
|
8184
8329
|
const id = `${baseId}-${control.key}`;
|
|
8185
|
-
return /* @__PURE__ */ (0,
|
|
8186
|
-
/* @__PURE__ */ (0,
|
|
8187
|
-
/* @__PURE__ */ (0,
|
|
8330
|
+
return /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("div", { className: "flex flex-col gap-1", "data-control": control.key, children: [
|
|
8331
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsx)("label", { htmlFor: id, className: "text-xs font-medium text-muted-foreground", title: control.description, children: control.label }),
|
|
8332
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
|
|
8188
8333
|
Control,
|
|
8189
8334
|
{
|
|
8190
8335
|
control,
|
|
@@ -8195,23 +8340,23 @@ var GenerationSettings = ({
|
|
|
8195
8340
|
)
|
|
8196
8341
|
] }, control.key);
|
|
8197
8342
|
}),
|
|
8198
|
-
slots.map((slot) => /* @__PURE__ */ (0,
|
|
8199
|
-
/* @__PURE__ */ (0,
|
|
8343
|
+
slots.map((slot) => /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("fieldset", { className: "flex flex-col gap-1", "data-reference-role": slot.role, children: [
|
|
8344
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("legend", { className: "text-xs font-medium text-muted-foreground", title: slot.description, children: [
|
|
8200
8345
|
slot.label,
|
|
8201
8346
|
" ",
|
|
8202
|
-
/* @__PURE__ */ (0,
|
|
8347
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("span", { className: "tabular-nums", "data-reference-count": "", children: [
|
|
8203
8348
|
"(",
|
|
8204
8349
|
slot.references.length,
|
|
8205
8350
|
"/",
|
|
8206
8351
|
slot.max,
|
|
8207
8352
|
")"
|
|
8208
8353
|
] }),
|
|
8209
|
-
slot.min > 0 && /* @__PURE__ */ (0,
|
|
8354
|
+
slot.min > 0 && /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("span", { className: "text-destructive", children: " *" })
|
|
8210
8355
|
] }),
|
|
8211
|
-
/* @__PURE__ */ (0,
|
|
8212
|
-
slot.references.map((ref) => /* @__PURE__ */ (0,
|
|
8213
|
-
renderReference ? renderReference(ref) : /* @__PURE__ */ (0,
|
|
8214
|
-
/* @__PURE__ */ (0,
|
|
8356
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("ul", { className: "flex flex-wrap gap-1", children: [
|
|
8357
|
+
slot.references.map((ref) => /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("li", { className: "flex items-center gap-1 rounded border border-border px-1.5 py-0.5", "data-reference-id": ref.id, children: [
|
|
8358
|
+
renderReference ? renderReference(ref) : /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("span", { className: "max-w-[10rem] truncate", children: ref.id }),
|
|
8359
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
|
|
8215
8360
|
"button",
|
|
8216
8361
|
{
|
|
8217
8362
|
type: "button",
|
|
@@ -8222,7 +8367,7 @@ var GenerationSettings = ({
|
|
|
8222
8367
|
}
|
|
8223
8368
|
)
|
|
8224
8369
|
] }, ref.id)),
|
|
8225
|
-
onAddReference && slot.canAdd && /* @__PURE__ */ (0,
|
|
8370
|
+
onAddReference && slot.canAdd && /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("li", { children: /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
|
|
8226
8371
|
"button",
|
|
8227
8372
|
{
|
|
8228
8373
|
type: "button",
|
|
@@ -8233,21 +8378,21 @@ var GenerationSettings = ({
|
|
|
8233
8378
|
) })
|
|
8234
8379
|
] })
|
|
8235
8380
|
] }, slot.role)),
|
|
8236
|
-
showAdjustments && plan.adjustments.length > 0 && /* @__PURE__ */ (0,
|
|
8237
|
-
showAdjustments && plan.errors.length > 0 && /* @__PURE__ */ (0,
|
|
8381
|
+
showAdjustments && plan.adjustments.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime39.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_runtime39.jsx)("li", { "data-adjustment-field": adjustment.field, "data-adjustment-kind": adjustment.kind, children: adjustment.reason }, index)) }),
|
|
8382
|
+
showAdjustments && plan.errors.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime39.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_runtime39.jsx)("li", { "data-error-field": error.field, children: error.message }, index)) })
|
|
8238
8383
|
] });
|
|
8239
8384
|
};
|
|
8240
8385
|
|
|
8241
8386
|
// src/generation/JobProgress.tsx
|
|
8242
|
-
var
|
|
8387
|
+
var import_jsx_runtime40 = require("react/jsx-runtime");
|
|
8243
8388
|
var JobProgress = ({ title, className = "", ...options }) => {
|
|
8244
8389
|
const progress = useJobProgress(options);
|
|
8245
|
-
return /* @__PURE__ */ (0,
|
|
8246
|
-
/* @__PURE__ */ (0,
|
|
8247
|
-
title && /* @__PURE__ */ (0,
|
|
8248
|
-
/* @__PURE__ */ (0,
|
|
8390
|
+
return /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)("div", { className: `flex flex-col gap-1 text-sm ${className}`, "data-job-progress": "", "data-done": options.done ? "" : void 0, children: [
|
|
8391
|
+
/* @__PURE__ */ (0, import_jsx_runtime40.jsxs)("div", { className: "flex items-center justify-between gap-2 text-muted-foreground", children: [
|
|
8392
|
+
title && /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("span", { className: "truncate text-foreground", children: title }),
|
|
8393
|
+
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)("span", { "data-job-progress-label": "", "aria-live": "polite", children: progress.label })
|
|
8249
8394
|
] }),
|
|
8250
|
-
/* @__PURE__ */ (0,
|
|
8395
|
+
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
|
|
8251
8396
|
"div",
|
|
8252
8397
|
{
|
|
8253
8398
|
role: "progressbar",
|
|
@@ -8257,7 +8402,7 @@ var JobProgress = ({ title, className = "", ...options }) => {
|
|
|
8257
8402
|
"aria-valuenow": progress.percent,
|
|
8258
8403
|
"aria-valuetext": `${progress.percent}%, ${progress.label}`,
|
|
8259
8404
|
className: "h-1.5 w-full overflow-hidden rounded-full bg-muted",
|
|
8260
|
-
children: /* @__PURE__ */ (0,
|
|
8405
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
|
|
8261
8406
|
"div",
|
|
8262
8407
|
{
|
|
8263
8408
|
className: "h-full rounded-full bg-primary transition-[width] duration-500",
|
|
@@ -8270,9 +8415,9 @@ var JobProgress = ({ title, className = "", ...options }) => {
|
|
|
8270
8415
|
};
|
|
8271
8416
|
|
|
8272
8417
|
// src/generation/AssetMentionChips.tsx
|
|
8273
|
-
var
|
|
8418
|
+
var import_react58 = require("react");
|
|
8274
8419
|
var import_generation3 = require("@pixerate/editor/generation");
|
|
8275
|
-
var
|
|
8420
|
+
var import_jsx_runtime41 = require("react/jsx-runtime");
|
|
8276
8421
|
var AssetMentionChips = ({
|
|
8277
8422
|
content,
|
|
8278
8423
|
onChange,
|
|
@@ -8282,14 +8427,14 @@ var AssetMentionChips = ({
|
|
|
8282
8427
|
renderAsset,
|
|
8283
8428
|
className = ""
|
|
8284
8429
|
}) => {
|
|
8285
|
-
const [open, setOpen] = (0,
|
|
8286
|
-
const rootRef = (0,
|
|
8287
|
-
const chips = (0,
|
|
8430
|
+
const [open, setOpen] = (0, import_react58.useState)(null);
|
|
8431
|
+
const rootRef = (0, import_react58.useRef)(null);
|
|
8432
|
+
const chips = (0, import_react58.useMemo)(
|
|
8288
8433
|
() => (0, import_generation3.describeAssetMentions)((0, import_generation3.findTextMentions)(content), assets, capabilities),
|
|
8289
8434
|
[content, assets, capabilities]
|
|
8290
8435
|
);
|
|
8291
8436
|
const options = roles ?? (capabilities ? (0, import_generation3.getAssetRoleOptions)(capabilities) : (0, import_generation3.defaultAssetRoleOptions)());
|
|
8292
|
-
(0,
|
|
8437
|
+
(0, import_react58.useEffect)(() => {
|
|
8293
8438
|
if (open === null) return;
|
|
8294
8439
|
const onPointer = (event) => {
|
|
8295
8440
|
if (!rootRef.current?.contains(event.target)) setOpen(null);
|
|
@@ -8303,13 +8448,13 @@ var AssetMentionChips = ({
|
|
|
8303
8448
|
onChange((0, import_generation3.setMentionRoleInText)(content, chip6.start, role));
|
|
8304
8449
|
};
|
|
8305
8450
|
if (chips.length === 0) return null;
|
|
8306
|
-
return /* @__PURE__ */ (0,
|
|
8451
|
+
return /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("div", { ref: rootRef, className: `flex flex-wrap gap-1.5 ${className}`, "data-asset-mention-chips": "", children: chips.map((chip6) => {
|
|
8307
8452
|
const error = chip6.issues.find((issue) => issue.severity === "error");
|
|
8308
8453
|
const warning = chip6.issues.find((issue) => issue.severity === "warning");
|
|
8309
8454
|
const problem = error ?? warning;
|
|
8310
8455
|
const isOpen = open === chip6.index;
|
|
8311
|
-
return /* @__PURE__ */ (0,
|
|
8312
|
-
/* @__PURE__ */ (0,
|
|
8456
|
+
return /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("span", { className: "relative inline-flex", "data-asset-chip": chip6.asset.id, children: [
|
|
8457
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsxs)(
|
|
8313
8458
|
"button",
|
|
8314
8459
|
{
|
|
8315
8460
|
type: "button",
|
|
@@ -8323,8 +8468,8 @@ var AssetMentionChips = ({
|
|
|
8323
8468
|
},
|
|
8324
8469
|
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`,
|
|
8325
8470
|
children: [
|
|
8326
|
-
/* @__PURE__ */ (0,
|
|
8327
|
-
/* @__PURE__ */ (0,
|
|
8471
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)("span", { children: renderAsset ? renderAsset(chip6) : `@${chip6.asset.label ?? chip6.handle}` }),
|
|
8472
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
|
|
8328
8473
|
"span",
|
|
8329
8474
|
{
|
|
8330
8475
|
className: `rounded px-1 text-[10px] uppercase tracking-wide ${chip6.role ? "bg-primary/15" : "opacity-60"}`,
|
|
@@ -8335,7 +8480,7 @@ var AssetMentionChips = ({
|
|
|
8335
8480
|
]
|
|
8336
8481
|
}
|
|
8337
8482
|
),
|
|
8338
|
-
isOpen && /* @__PURE__ */ (0,
|
|
8483
|
+
isOpen && /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)(
|
|
8339
8484
|
"div",
|
|
8340
8485
|
{
|
|
8341
8486
|
role: "listbox",
|
|
@@ -8346,7 +8491,7 @@ var AssetMentionChips = ({
|
|
|
8346
8491
|
if (e.key === "Escape") setOpen(null);
|
|
8347
8492
|
},
|
|
8348
8493
|
children: [
|
|
8349
|
-
options.map((option) => /* @__PURE__ */ (0,
|
|
8494
|
+
options.map((option) => /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)(
|
|
8350
8495
|
"button",
|
|
8351
8496
|
{
|
|
8352
8497
|
type: "button",
|
|
@@ -8357,13 +8502,13 @@ var AssetMentionChips = ({
|
|
|
8357
8502
|
onClick: () => pick(chip6, option.role),
|
|
8358
8503
|
className: "flex items-center justify-between gap-2 rounded px-2 py-1 text-left hover:bg-muted",
|
|
8359
8504
|
children: [
|
|
8360
|
-
/* @__PURE__ */ (0,
|
|
8361
|
-
option.accepts?.length ? /* @__PURE__ */ (0,
|
|
8505
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)("span", { children: option.label }),
|
|
8506
|
+
option.accepts?.length ? /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("span", { className: "text-[10px] opacity-60", children: option.accepts.join(", ") }) : null
|
|
8362
8507
|
]
|
|
8363
8508
|
},
|
|
8364
8509
|
option.role
|
|
8365
8510
|
)),
|
|
8366
|
-
/* @__PURE__ */ (0,
|
|
8511
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
|
|
8367
8512
|
"button",
|
|
8368
8513
|
{
|
|
8369
8514
|
type: "button",
|
|
@@ -8375,7 +8520,7 @@ var AssetMentionChips = ({
|
|
|
8375
8520
|
children: "No role"
|
|
8376
8521
|
}
|
|
8377
8522
|
),
|
|
8378
|
-
chip6.issues.length > 0 && /* @__PURE__ */ (0,
|
|
8523
|
+
chip6.issues.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime41.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_runtime41.jsx)("li", { className: issue.severity === "error" ? "text-red-500" : "text-amber-500", children: issue.message }, i)) })
|
|
8379
8524
|
]
|
|
8380
8525
|
}
|
|
8381
8526
|
)
|
|
@@ -8384,15 +8529,15 @@ var AssetMentionChips = ({
|
|
|
8384
8529
|
};
|
|
8385
8530
|
|
|
8386
8531
|
// src/generation/GenerationHistory.tsx
|
|
8387
|
-
var
|
|
8532
|
+
var import_react59 = require("react");
|
|
8388
8533
|
var import_generation4 = require("@pixerate/editor/generation");
|
|
8389
|
-
var
|
|
8534
|
+
var import_jsx_runtime42 = require("react/jsx-runtime");
|
|
8390
8535
|
function useGenerationRecords(store, filter) {
|
|
8391
|
-
const [records, setRecords] = (0,
|
|
8392
|
-
const [loading, setLoading] = (0,
|
|
8393
|
-
const [error, setError] = (0,
|
|
8536
|
+
const [records, setRecords] = (0, import_react59.useState)([]);
|
|
8537
|
+
const [loading, setLoading] = (0, import_react59.useState)(!!store);
|
|
8538
|
+
const [error, setError] = (0, import_react59.useState)(null);
|
|
8394
8539
|
const filterKey = (0, import_generation4.stableStringify)(filter ?? {});
|
|
8395
|
-
const refresh = (0,
|
|
8540
|
+
const refresh = (0, import_react59.useCallback)(async () => {
|
|
8396
8541
|
if (!store) {
|
|
8397
8542
|
setRecords([]);
|
|
8398
8543
|
setLoading(false);
|
|
@@ -8409,7 +8554,7 @@ function useGenerationRecords(store, filter) {
|
|
|
8409
8554
|
setLoading(false);
|
|
8410
8555
|
}
|
|
8411
8556
|
}, [store, filterKey]);
|
|
8412
|
-
(0,
|
|
8557
|
+
(0, import_react59.useEffect)(() => {
|
|
8413
8558
|
void refresh();
|
|
8414
8559
|
if (!store) return;
|
|
8415
8560
|
return store.subscribe(() => void refresh());
|
|
@@ -8435,21 +8580,21 @@ var GenerationHistory = ({
|
|
|
8435
8580
|
emptyText = "No generations yet.",
|
|
8436
8581
|
className = ""
|
|
8437
8582
|
}) => {
|
|
8438
|
-
const [innerMode, setInnerMode] = (0,
|
|
8583
|
+
const [innerMode, setInnerMode] = (0, import_react59.useState)("exact");
|
|
8439
8584
|
const mode = modeProp ?? innerMode;
|
|
8440
8585
|
const setMode = (next) => {
|
|
8441
8586
|
if (modeProp === void 0) setInnerMode(next);
|
|
8442
8587
|
onModeChange?.(next);
|
|
8443
8588
|
};
|
|
8444
|
-
const options = (0,
|
|
8445
|
-
const results = (0,
|
|
8446
|
-
const models = (0,
|
|
8589
|
+
const options = (0, import_react59.useMemo)(() => ({ templates, capabilities, assets, mode }), [templates, capabilities, assets, mode]);
|
|
8590
|
+
const results = (0, import_react59.useMemo)(() => records.map((record) => (0, import_generation4.recreateRequest)(record, options)), [records, options]);
|
|
8591
|
+
const models = (0, import_react59.useMemo)(
|
|
8447
8592
|
() => capabilities ? Array.isArray(capabilities) ? capabilities : [capabilities] : [],
|
|
8448
8593
|
[capabilities]
|
|
8449
8594
|
);
|
|
8450
|
-
return /* @__PURE__ */ (0,
|
|
8451
|
-
/* @__PURE__ */ (0,
|
|
8452
|
-
/* @__PURE__ */ (0,
|
|
8595
|
+
return /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("div", { className: `flex flex-col gap-2 text-sm ${className}`, "data-generation-history": "", children: [
|
|
8596
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.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_runtime42.jsxs)("label", { className: "inline-flex items-center gap-1", children: [
|
|
8597
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
|
|
8453
8598
|
"input",
|
|
8454
8599
|
{
|
|
8455
8600
|
type: "radio",
|
|
@@ -8462,34 +8607,34 @@ var GenerationHistory = ({
|
|
|
8462
8607
|
),
|
|
8463
8608
|
value === "exact" ? "Exact (recorded versions)" : "Latest templates & settings"
|
|
8464
8609
|
] }, value)) }),
|
|
8465
|
-
records.length === 0 && /* @__PURE__ */ (0,
|
|
8466
|
-
/* @__PURE__ */ (0,
|
|
8610
|
+
records.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("p", { className: "text-xs text-muted-foreground", children: emptyText }),
|
|
8611
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)("ul", { className: "flex flex-col gap-2", children: records.map((record, i) => {
|
|
8467
8612
|
const result = results[i];
|
|
8468
8613
|
const model = models.find((m) => m.id === record.provenance.modelId);
|
|
8469
8614
|
const blocked = !result.ok;
|
|
8470
|
-
return /* @__PURE__ */ (0,
|
|
8615
|
+
return /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)(
|
|
8471
8616
|
"li",
|
|
8472
8617
|
{
|
|
8473
8618
|
className: "rounded-md border border-border p-2",
|
|
8474
8619
|
"data-record": record.id,
|
|
8475
8620
|
"data-drift": result.drift.length,
|
|
8476
8621
|
children: [
|
|
8477
|
-
/* @__PURE__ */ (0,
|
|
8478
|
-
/* @__PURE__ */ (0,
|
|
8479
|
-
/* @__PURE__ */ (0,
|
|
8480
|
-
record.kind !== "generate" && /* @__PURE__ */ (0,
|
|
8622
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("div", { className: "flex flex-wrap items-center justify-between gap-2 text-xs", children: [
|
|
8623
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)("span", { className: "font-medium", children: model?.name ?? record.provenance.modelId }),
|
|
8624
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("span", { className: "text-muted-foreground", children: [
|
|
8625
|
+
record.kind !== "generate" && /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("span", { "data-kind": "", children: [
|
|
8481
8626
|
record.kind,
|
|
8482
8627
|
" \xB7 "
|
|
8483
8628
|
] }),
|
|
8484
|
-
/* @__PURE__ */ (0,
|
|
8485
|
-
record.seed !== void 0 && /* @__PURE__ */ (0,
|
|
8629
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)("time", { dateTime: record.createdAt, children: record.createdAt.replace("T", " ").slice(0, 16) }),
|
|
8630
|
+
record.seed !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)(import_jsx_runtime42.Fragment, { children: [
|
|
8486
8631
|
" \xB7 seed ",
|
|
8487
8632
|
record.seed
|
|
8488
8633
|
] })
|
|
8489
8634
|
] })
|
|
8490
8635
|
] }),
|
|
8491
|
-
/* @__PURE__ */ (0,
|
|
8492
|
-
record.assets.length > 0 && /* @__PURE__ */ (0,
|
|
8636
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)("p", { className: "mt-1 line-clamp-3 break-words text-xs", "data-record-prompt": "", children: record.provenance.resolvedPrompt }),
|
|
8637
|
+
record.assets.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("div", { className: "mt-1 flex flex-wrap gap-1", children: record.assets.map((asset) => /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)(
|
|
8493
8638
|
"span",
|
|
8494
8639
|
{
|
|
8495
8640
|
className: "rounded-full bg-muted px-2 py-0.5 text-[10px]",
|
|
@@ -8503,16 +8648,16 @@ var GenerationHistory = ({
|
|
|
8503
8648
|
`${asset.role}:${asset.id}`
|
|
8504
8649
|
)) }),
|
|
8505
8650
|
renderPreview?.(record),
|
|
8506
|
-
result.drift.length > 0 && /* @__PURE__ */ (0,
|
|
8507
|
-
/* @__PURE__ */ (0,
|
|
8651
|
+
result.drift.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime42.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_runtime42.jsxs)("li", { className: severityClass[item.severity], "data-drift-type": item.type, children: [
|
|
8652
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("strong", { children: [
|
|
8508
8653
|
import_generation4.DRIFT_TYPE_LABELS[item.type],
|
|
8509
8654
|
":"
|
|
8510
8655
|
] }),
|
|
8511
8656
|
" ",
|
|
8512
8657
|
item.message
|
|
8513
8658
|
] }, j)) }),
|
|
8514
|
-
/* @__PURE__ */ (0,
|
|
8515
|
-
onRecreate && /* @__PURE__ */ (0,
|
|
8659
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("div", { className: "mt-2 flex gap-2", children: [
|
|
8660
|
+
onRecreate && /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
|
|
8516
8661
|
"button",
|
|
8517
8662
|
{
|
|
8518
8663
|
type: "button",
|
|
@@ -8524,7 +8669,7 @@ var GenerationHistory = ({
|
|
|
8524
8669
|
children: "Recreate"
|
|
8525
8670
|
}
|
|
8526
8671
|
),
|
|
8527
|
-
onVariation && /* @__PURE__ */ (0,
|
|
8672
|
+
onVariation && /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
|
|
8528
8673
|
"button",
|
|
8529
8674
|
{
|
|
8530
8675
|
type: "button",
|
|
@@ -8534,7 +8679,7 @@ var GenerationHistory = ({
|
|
|
8534
8679
|
children: "Variation"
|
|
8535
8680
|
}
|
|
8536
8681
|
),
|
|
8537
|
-
onRemove && /* @__PURE__ */ (0,
|
|
8682
|
+
onRemove && /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
|
|
8538
8683
|
"button",
|
|
8539
8684
|
{
|
|
8540
8685
|
type: "button",
|
|
@@ -8554,19 +8699,19 @@ var GenerationHistory = ({
|
|
|
8554
8699
|
};
|
|
8555
8700
|
|
|
8556
8701
|
// src/find-replace/useFindReplace.ts
|
|
8557
|
-
var
|
|
8702
|
+
var import_react60 = require("react");
|
|
8558
8703
|
var import_editor16 = require("@pixerate/editor");
|
|
8559
8704
|
var noopUnsubscribe2 = () => {
|
|
8560
8705
|
};
|
|
8561
8706
|
function useFindReplace(editor) {
|
|
8562
8707
|
const store = (0, import_editor16.getFindReplaceStore)(editor ?? null);
|
|
8563
|
-
const subscribe = (0,
|
|
8708
|
+
const subscribe = (0, import_react60.useCallback)(
|
|
8564
8709
|
(onChange) => store ? store.subscribe(() => onChange()) : noopUnsubscribe2,
|
|
8565
8710
|
[store]
|
|
8566
8711
|
);
|
|
8567
8712
|
const getSnapshot = () => store?.getSnapshot() ?? import_editor16.EMPTY_FIND_REPLACE_SNAPSHOT;
|
|
8568
|
-
const snapshot = (0,
|
|
8569
|
-
return (0,
|
|
8713
|
+
const snapshot = (0, import_react60.useSyncExternalStore)(subscribe, getSnapshot, getSnapshot);
|
|
8714
|
+
return (0, import_react60.useMemo)(() => {
|
|
8570
8715
|
const run = (fn) => {
|
|
8571
8716
|
if (editor && !editor.isDestroyed && store) fn(editor);
|
|
8572
8717
|
};
|
|
@@ -8590,9 +8735,9 @@ function useFindReplace(editor) {
|
|
|
8590
8735
|
}
|
|
8591
8736
|
|
|
8592
8737
|
// src/find-replace/FindReplaceBar.tsx
|
|
8593
|
-
var
|
|
8738
|
+
var import_react61 = require("react");
|
|
8594
8739
|
var import_editor17 = require("@pixerate/editor");
|
|
8595
|
-
var
|
|
8740
|
+
var import_jsx_runtime43 = require("react/jsx-runtime");
|
|
8596
8741
|
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";
|
|
8597
8742
|
var buttonClass5 = "rounded px-2 py-1 text-xs text-foreground hover:bg-muted disabled:opacity-40 disabled:hover:bg-transparent";
|
|
8598
8743
|
var toggleClass = (on) => `${buttonClass5} font-mono ${on ? "bg-primary/10 text-primary" : "text-muted-foreground"}`;
|
|
@@ -8605,10 +8750,10 @@ var FindReplaceBar = ({
|
|
|
8605
8750
|
onClose
|
|
8606
8751
|
}) => {
|
|
8607
8752
|
const find = useFindReplace(editor);
|
|
8608
|
-
const findInput = (0,
|
|
8609
|
-
const [moreOpen, setMoreOpen] = (0,
|
|
8753
|
+
const findInput = (0, import_react61.useRef)(null);
|
|
8754
|
+
const [moreOpen, setMoreOpen] = (0, import_react61.useState)(false);
|
|
8610
8755
|
const visible = find.available && (alwaysOpen || find.open);
|
|
8611
|
-
(0,
|
|
8756
|
+
(0, import_react61.useEffect)(() => {
|
|
8612
8757
|
if (!visible || find.focusRequest === 0) return;
|
|
8613
8758
|
findInput.current?.focus();
|
|
8614
8759
|
findInput.current?.select();
|
|
@@ -8646,9 +8791,9 @@ var FindReplaceBar = ({
|
|
|
8646
8791
|
if (isMod(e)) find.replaceAll();
|
|
8647
8792
|
else find.replace();
|
|
8648
8793
|
};
|
|
8649
|
-
return /* @__PURE__ */ (0,
|
|
8650
|
-
/* @__PURE__ */ (0,
|
|
8651
|
-
/* @__PURE__ */ (0,
|
|
8794
|
+
return /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("div", { className, role: "search", "aria-label": "Find and replace", onKeyDown: onBarKeyDown, children: [
|
|
8795
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("div", { className: "flex items-center gap-1", children: [
|
|
8796
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
|
|
8652
8797
|
"button",
|
|
8653
8798
|
{
|
|
8654
8799
|
type: "button",
|
|
@@ -8659,7 +8804,7 @@ var FindReplaceBar = ({
|
|
|
8659
8804
|
children: showReplace ? "\u25BE" : "\u25B8"
|
|
8660
8805
|
}
|
|
8661
8806
|
),
|
|
8662
|
-
/* @__PURE__ */ (0,
|
|
8807
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
|
|
8663
8808
|
"input",
|
|
8664
8809
|
{
|
|
8665
8810
|
ref: findInput,
|
|
@@ -8673,7 +8818,7 @@ var FindReplaceBar = ({
|
|
|
8673
8818
|
onKeyDown: onFindKeyDown
|
|
8674
8819
|
}
|
|
8675
8820
|
),
|
|
8676
|
-
import_editor17.FIND_OPTION_TOGGLES.filter((t) => !t.advanced).map((t) => /* @__PURE__ */ (0,
|
|
8821
|
+
import_editor17.FIND_OPTION_TOGGLES.filter((t) => !t.advanced).map((t) => /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
|
|
8677
8822
|
"button",
|
|
8678
8823
|
{
|
|
8679
8824
|
type: "button",
|
|
@@ -8686,7 +8831,7 @@ var FindReplaceBar = ({
|
|
|
8686
8831
|
},
|
|
8687
8832
|
t.key
|
|
8688
8833
|
)),
|
|
8689
|
-
/* @__PURE__ */ (0,
|
|
8834
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
|
|
8690
8835
|
"span",
|
|
8691
8836
|
{
|
|
8692
8837
|
className: `min-w-[5rem] px-1 text-center text-xs ${find.error ? "text-destructive" : "text-muted-foreground"}`,
|
|
@@ -8696,9 +8841,9 @@ var FindReplaceBar = ({
|
|
|
8696
8841
|
children: status
|
|
8697
8842
|
}
|
|
8698
8843
|
),
|
|
8699
|
-
/* @__PURE__ */ (0,
|
|
8700
|
-
/* @__PURE__ */ (0,
|
|
8701
|
-
showMoreOptions && /* @__PURE__ */ (0,
|
|
8844
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)("button", { type: "button", className: buttonClass5, "aria-label": "Previous match", disabled: !hasMatches, onClick: find.previous, children: "\u2191" }),
|
|
8845
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)("button", { type: "button", className: buttonClass5, "aria-label": "Next match", disabled: !hasMatches, onClick: find.next, children: "\u2193" }),
|
|
8846
|
+
showMoreOptions && /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
|
|
8702
8847
|
"button",
|
|
8703
8848
|
{
|
|
8704
8849
|
type: "button",
|
|
@@ -8709,10 +8854,10 @@ var FindReplaceBar = ({
|
|
|
8709
8854
|
children: "\u2026"
|
|
8710
8855
|
}
|
|
8711
8856
|
),
|
|
8712
|
-
/* @__PURE__ */ (0,
|
|
8857
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)("button", { type: "button", className: buttonClass5, "aria-label": "Close find", onClick: close, children: "\xD7" })
|
|
8713
8858
|
] }),
|
|
8714
|
-
showReplace && /* @__PURE__ */ (0,
|
|
8715
|
-
/* @__PURE__ */ (0,
|
|
8859
|
+
showReplace && /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("div", { className: "flex items-center gap-1 pl-7", children: [
|
|
8860
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
|
|
8716
8861
|
"input",
|
|
8717
8862
|
{
|
|
8718
8863
|
type: "text",
|
|
@@ -8724,7 +8869,7 @@ var FindReplaceBar = ({
|
|
|
8724
8869
|
onKeyDown: onReplaceKeyDown
|
|
8725
8870
|
}
|
|
8726
8871
|
),
|
|
8727
|
-
/* @__PURE__ */ (0,
|
|
8872
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
|
|
8728
8873
|
"button",
|
|
8729
8874
|
{
|
|
8730
8875
|
type: "button",
|
|
@@ -8734,11 +8879,11 @@ var FindReplaceBar = ({
|
|
|
8734
8879
|
children: "Replace"
|
|
8735
8880
|
}
|
|
8736
8881
|
),
|
|
8737
|
-
/* @__PURE__ */ (0,
|
|
8738
|
-
find.lastReplaceCount !== null && /* @__PURE__ */ (0,
|
|
8882
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)("button", { type: "button", className: buttonClass5, disabled: !hasMatches, onClick: find.replaceAll, children: "Replace all" }),
|
|
8883
|
+
find.lastReplaceCount !== null && /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("span", { className: "px-1 text-xs text-muted-foreground", "aria-live": "polite", children: find.lastReplaceCount === 1 ? "1 replaced" : `${find.lastReplaceCount} replaced` })
|
|
8739
8884
|
] }),
|
|
8740
|
-
showMoreOptions && moreOpen && /* @__PURE__ */ (0,
|
|
8741
|
-
/* @__PURE__ */ (0,
|
|
8885
|
+
showMoreOptions && moreOpen && /* @__PURE__ */ (0, import_jsx_runtime43.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_runtime43.jsxs)("label", { className: "flex items-center gap-1", children: [
|
|
8886
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
|
|
8742
8887
|
"input",
|
|
8743
8888
|
{
|
|
8744
8889
|
type: "checkbox",
|
|
@@ -8752,12 +8897,12 @@ var FindReplaceBar = ({
|
|
|
8752
8897
|
};
|
|
8753
8898
|
|
|
8754
8899
|
// src/tables/useTableMenu.ts
|
|
8755
|
-
var
|
|
8900
|
+
var import_react62 = require("react");
|
|
8756
8901
|
var import_editor18 = require("@pixerate/editor");
|
|
8757
8902
|
function useTableMenu(editor) {
|
|
8758
|
-
const store = (0,
|
|
8759
|
-
const snapshot = (0,
|
|
8760
|
-
return (0,
|
|
8903
|
+
const store = (0, import_react62.useMemo)(() => (0, import_editor18.createTableStore)(editor), [editor]);
|
|
8904
|
+
const snapshot = (0, import_react62.useSyncExternalStore)(store.subscribe, store.getSnapshot, store.getSnapshot);
|
|
8905
|
+
return (0, import_react62.useMemo)(
|
|
8761
8906
|
() => ({
|
|
8762
8907
|
...snapshot,
|
|
8763
8908
|
run: (action, params) => (0, import_editor18.runTableAction)(editor, action, params, { focus: true }),
|
|
@@ -8768,9 +8913,9 @@ function useTableMenu(editor) {
|
|
|
8768
8913
|
}
|
|
8769
8914
|
|
|
8770
8915
|
// src/tables/TableToolbar.tsx
|
|
8771
|
-
var
|
|
8916
|
+
var import_react63 = __toESM(require("react"), 1);
|
|
8772
8917
|
var import_editor19 = require("@pixerate/editor");
|
|
8773
|
-
var
|
|
8918
|
+
var import_jsx_runtime44 = require("react/jsx-runtime");
|
|
8774
8919
|
var keepSelection2 = (event) => event.preventDefault();
|
|
8775
8920
|
var TableToolbar = ({
|
|
8776
8921
|
editor,
|
|
@@ -8784,14 +8929,14 @@ var TableToolbar = ({
|
|
|
8784
8929
|
}) => {
|
|
8785
8930
|
const table = useTableMenu(editor);
|
|
8786
8931
|
if (!editor || !table.inTable && !showWhenOutside) return null;
|
|
8787
|
-
return /* @__PURE__ */ (0,
|
|
8932
|
+
return /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("div", { className, role: "toolbar", "aria-label": "Table", "data-table-toolbar": "", children: items.map((item, index) => {
|
|
8788
8933
|
const status = table.check(item.action, item.params);
|
|
8789
8934
|
const enabled = status === true;
|
|
8790
8935
|
const active = item.active?.(table);
|
|
8791
8936
|
const separator = index > 0 && items[index - 1].group !== item.group;
|
|
8792
|
-
return /* @__PURE__ */ (0,
|
|
8793
|
-
separator && /* @__PURE__ */ (0,
|
|
8794
|
-
/* @__PURE__ */ (0,
|
|
8937
|
+
return /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)(import_react63.default.Fragment, { children: [
|
|
8938
|
+
separator && /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("span", { className: separatorClassName, "aria-hidden": "true" }),
|
|
8939
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
|
|
8795
8940
|
"button",
|
|
8796
8941
|
{
|
|
8797
8942
|
type: "button",
|
|
@@ -8813,8 +8958,8 @@ var TableToolbar = ({
|
|
|
8813
8958
|
};
|
|
8814
8959
|
|
|
8815
8960
|
// src/tables/InsertTableGrid.tsx
|
|
8816
|
-
var
|
|
8817
|
-
var
|
|
8961
|
+
var import_react64 = require("react");
|
|
8962
|
+
var import_jsx_runtime45 = require("react/jsx-runtime");
|
|
8818
8963
|
var keepSelection3 = (event) => event.preventDefault();
|
|
8819
8964
|
var InsertTableGrid = ({
|
|
8820
8965
|
editor,
|
|
@@ -8827,14 +8972,14 @@ var InsertTableGrid = ({
|
|
|
8827
8972
|
onInsert
|
|
8828
8973
|
}) => {
|
|
8829
8974
|
const table = useTableMenu(editor);
|
|
8830
|
-
const [hover, setHover] = (0,
|
|
8975
|
+
const [hover, setHover] = (0, import_react64.useState)(null);
|
|
8831
8976
|
const status = table.actions.insertTable;
|
|
8832
8977
|
const disabled = !editor || !status.enabled;
|
|
8833
8978
|
const insert = (size) => {
|
|
8834
8979
|
if (table.run("insertTable", { ...size, withHeaderRow })) onInsert?.(size);
|
|
8835
8980
|
setHover(null);
|
|
8836
8981
|
};
|
|
8837
|
-
return /* @__PURE__ */ (0,
|
|
8982
|
+
return /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)(
|
|
8838
8983
|
"div",
|
|
8839
8984
|
{
|
|
8840
8985
|
className,
|
|
@@ -8844,7 +8989,7 @@ var InsertTableGrid = ({
|
|
|
8844
8989
|
"data-insert-table-grid": "",
|
|
8845
8990
|
onMouseLeave: () => setHover(null),
|
|
8846
8991
|
children: [
|
|
8847
|
-
/* @__PURE__ */ (0,
|
|
8992
|
+
/* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
|
|
8848
8993
|
"div",
|
|
8849
8994
|
{
|
|
8850
8995
|
role: "grid",
|
|
@@ -8853,7 +8998,7 @@ var InsertTableGrid = ({
|
|
|
8853
8998
|
children: Array.from({ length: rows * cols }, (_, i) => {
|
|
8854
8999
|
const size = { rows: Math.floor(i / cols) + 1, cols: i % cols + 1 };
|
|
8855
9000
|
const active = !!hover && size.rows <= hover.rows && size.cols <= hover.cols;
|
|
8856
|
-
return /* @__PURE__ */ (0,
|
|
9001
|
+
return /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
|
|
8857
9002
|
"button",
|
|
8858
9003
|
{
|
|
8859
9004
|
type: "button",
|
|
@@ -8873,7 +9018,7 @@ var InsertTableGrid = ({
|
|
|
8873
9018
|
})
|
|
8874
9019
|
}
|
|
8875
9020
|
),
|
|
8876
|
-
/* @__PURE__ */ (0,
|
|
9021
|
+
/* @__PURE__ */ (0, import_jsx_runtime45.jsx)("div", { "aria-live": "polite", "data-testid": "insert-table-size", children: disabled ? status.reason : hover ? `${hover.rows} \xD7 ${hover.cols}` : "Insert table" })
|
|
8877
9022
|
]
|
|
8878
9023
|
}
|
|
8879
9024
|
);
|
|
@@ -8881,31 +9026,31 @@ var InsertTableGrid = ({
|
|
|
8881
9026
|
|
|
8882
9027
|
// src/tables/TableBubbleMenu.tsx
|
|
8883
9028
|
var import_editor20 = require("@pixerate/editor");
|
|
8884
|
-
var
|
|
9029
|
+
var import_jsx_runtime46 = require("react/jsx-runtime");
|
|
8885
9030
|
var TableBubbleMenu = ({
|
|
8886
9031
|
editor,
|
|
8887
9032
|
children,
|
|
8888
9033
|
toolbarProps,
|
|
8889
9034
|
pluginKey = "tableBubbleMenu",
|
|
8890
9035
|
...rest
|
|
8891
|
-
}) => /* @__PURE__ */ (0,
|
|
9036
|
+
}) => /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(BubbleMenu, { editor, pluginKey, shouldShow: import_editor20.shouldShowTableBubbleMenu, ...rest, children: children ?? /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(TableToolbar, { editor, ...toolbarProps }) });
|
|
8892
9037
|
|
|
8893
9038
|
// src/chart-node/ChartNodeView.tsx
|
|
8894
9039
|
var import_client = require("react-dom/client");
|
|
8895
9040
|
|
|
8896
9041
|
// src/chart/ChartCanvas.tsx
|
|
8897
|
-
var
|
|
9042
|
+
var import_react66 = require("react");
|
|
8898
9043
|
var import_chart2 = require("@pixerate/editor/chart");
|
|
8899
9044
|
|
|
8900
9045
|
// src/chart/useChartEditor.ts
|
|
8901
|
-
var
|
|
9046
|
+
var import_react65 = require("react");
|
|
8902
9047
|
var import_chart = require("@pixerate/editor/chart");
|
|
8903
9048
|
function useChartState(controller) {
|
|
8904
|
-
return (0,
|
|
9049
|
+
return (0, import_react65.useSyncExternalStore)(controller.subscribe, controller.getState, controller.getState);
|
|
8905
9050
|
}
|
|
8906
9051
|
|
|
8907
9052
|
// src/chart/ChartCanvas.tsx
|
|
8908
|
-
var
|
|
9053
|
+
var import_jsx_runtime47 = require("react/jsx-runtime");
|
|
8909
9054
|
function renderChartMark(mark, fontFamily, interactive) {
|
|
8910
9055
|
const common = {
|
|
8911
9056
|
"data-role": mark.role,
|
|
@@ -8917,9 +9062,9 @@ function renderChartMark(mark, fontFamily, interactive) {
|
|
|
8917
9062
|
};
|
|
8918
9063
|
switch (mark.kind) {
|
|
8919
9064
|
case "rect":
|
|
8920
|
-
return /* @__PURE__ */ (0,
|
|
9065
|
+
return /* @__PURE__ */ (0, import_jsx_runtime47.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);
|
|
8921
9066
|
case "path":
|
|
8922
|
-
return /* @__PURE__ */ (0,
|
|
9067
|
+
return /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
|
|
8923
9068
|
"path",
|
|
8924
9069
|
{
|
|
8925
9070
|
...common,
|
|
@@ -8932,11 +9077,11 @@ function renderChartMark(mark, fontFamily, interactive) {
|
|
|
8932
9077
|
mark.key
|
|
8933
9078
|
);
|
|
8934
9079
|
case "circle":
|
|
8935
|
-
return /* @__PURE__ */ (0,
|
|
9080
|
+
return /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("circle", { ...common, cx: mark.cx, cy: mark.cy, r: mark.r, style: { fill: mark.fill, stroke: mark.stroke, strokeWidth: mark.strokeWidth } }, mark.key);
|
|
8936
9081
|
case "line":
|
|
8937
|
-
return /* @__PURE__ */ (0,
|
|
9082
|
+
return /* @__PURE__ */ (0, import_jsx_runtime47.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);
|
|
8938
9083
|
case "text":
|
|
8939
|
-
return /* @__PURE__ */ (0,
|
|
9084
|
+
return /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
|
|
8940
9085
|
"text",
|
|
8941
9086
|
{
|
|
8942
9087
|
...common,
|
|
@@ -8953,23 +9098,23 @@ function renderChartMark(mark, fontFamily, interactive) {
|
|
|
8953
9098
|
}
|
|
8954
9099
|
}
|
|
8955
9100
|
function ChartPresenceLayer({ presence }) {
|
|
8956
|
-
const { actors } = (0,
|
|
8957
|
-
return /* @__PURE__ */ (0,
|
|
8958
|
-
/* @__PURE__ */ (0,
|
|
8959
|
-
/* @__PURE__ */ (0,
|
|
8960
|
-
/* @__PURE__ */ (0,
|
|
8961
|
-
/* @__PURE__ */ (0,
|
|
9101
|
+
const { actors } = (0, import_react66.useSyncExternalStore)(presence.subscribe, presence.getState, presence.getState);
|
|
9102
|
+
return /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("g", { "data-chart-presence": "", pointerEvents: "none", children: actors.map((a) => /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("g", { transform: `translate(${a.x} ${a.y})`, "data-actor": a.id, children: [
|
|
9103
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.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 }),
|
|
9104
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("g", { transform: "translate(13 16)", children: [
|
|
9105
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.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 } }),
|
|
9106
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)("text", { x: 6, y: 9, dominantBaseline: "central", style: { fill: "#ffffff", fontSize: 11, fontWeight: 600, fontFamily: "inherit" }, children: a.message ?? a.name })
|
|
8962
9107
|
] })
|
|
8963
9108
|
] }, a.id)) });
|
|
8964
9109
|
}
|
|
8965
9110
|
function ChartCanvas({ controller, width = 640, height = 400, responsive = true, theme, editable = true, measureText, emptyMessage, className, presence, sceneRef }) {
|
|
8966
9111
|
const state = useChartState(controller);
|
|
8967
|
-
const wrapper = (0,
|
|
8968
|
-
const svg = (0,
|
|
8969
|
-
const drag = (0,
|
|
8970
|
-
const [measured, setMeasured] = (0,
|
|
8971
|
-
const [frozen, setFrozen] = (0,
|
|
8972
|
-
(0,
|
|
9112
|
+
const wrapper = (0, import_react66.useRef)(null);
|
|
9113
|
+
const svg = (0, import_react66.useRef)(null);
|
|
9114
|
+
const drag = (0, import_react66.useRef)(null);
|
|
9115
|
+
const [measured, setMeasured] = (0, import_react66.useState)(null);
|
|
9116
|
+
const [frozen, setFrozen] = (0, import_react66.useState)(null);
|
|
9117
|
+
(0, import_react66.useEffect)(() => {
|
|
8973
9118
|
const el = wrapper.current;
|
|
8974
9119
|
if (!responsive || !el || typeof ResizeObserver === "undefined") return;
|
|
8975
9120
|
const observer = new ResizeObserver(([entry]) => {
|
|
@@ -8980,8 +9125,8 @@ function ChartCanvas({ controller, width = 640, height = 400, responsive = true,
|
|
|
8980
9125
|
return () => observer.disconnect();
|
|
8981
9126
|
}, [responsive]);
|
|
8982
9127
|
const sceneWidth = responsive && measured || width;
|
|
8983
|
-
const fullTheme = (0,
|
|
8984
|
-
const scene = (0,
|
|
9128
|
+
const fullTheme = (0, import_react66.useMemo)(() => ({ ...import_chart2.CSS_VARIABLE_CHART_THEME, ...theme }), [theme]);
|
|
9129
|
+
const scene = (0, import_react66.useMemo)(
|
|
8985
9130
|
() => (0, import_chart2.layoutChart)(state.spec, {
|
|
8986
9131
|
width: sceneWidth,
|
|
8987
9132
|
height,
|
|
@@ -8997,8 +9142,8 @@ function ChartCanvas({ controller, width = 640, height = 400, responsive = true,
|
|
|
8997
9142
|
[state.spec, state.selection, sceneWidth, height, fullTheme, editable, measureText, emptyMessage, frozen]
|
|
8998
9143
|
);
|
|
8999
9144
|
if (sceneRef) sceneRef.current = scene;
|
|
9000
|
-
const byKey = (0,
|
|
9001
|
-
(0,
|
|
9145
|
+
const byKey = (0, import_react66.useMemo)(() => new Map(scene.marks.map((m) => [m.key, m])), [scene]);
|
|
9146
|
+
(0, import_react66.useEffect)(() => () => drag.current?.end(), []);
|
|
9002
9147
|
const scenePoint = (e) => (0, import_chart2.chartClientToScene)(scene, svg.current.getBoundingClientRect(), e.clientX, e.clientY);
|
|
9003
9148
|
const onPointerDown = (e) => {
|
|
9004
9149
|
if (!editable || e.button !== 0) return;
|
|
@@ -9031,7 +9176,7 @@ function ChartCanvas({ controller, width = 640, height = 400, responsive = true,
|
|
|
9031
9176
|
if (editable && (0, import_chart2.handleChartKey)(controller, scene, e)) e.preventDefault();
|
|
9032
9177
|
};
|
|
9033
9178
|
const label = state.spec.title || "Chart";
|
|
9034
|
-
return /* @__PURE__ */ (0,
|
|
9179
|
+
return /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("div", { ref: wrapper, className: `w-full ${className ?? ""}`, "data-chart-canvas": "", children: /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)(
|
|
9035
9180
|
"svg",
|
|
9036
9181
|
{
|
|
9037
9182
|
ref: svg,
|
|
@@ -9049,14 +9194,14 @@ function ChartCanvas({ controller, width = 640, height = 400, responsive = true,
|
|
|
9049
9194
|
onKeyDown,
|
|
9050
9195
|
children: [
|
|
9051
9196
|
scene.marks.map((m) => renderChartMark(m, scene.theme.fontFamily, editable)),
|
|
9052
|
-
presence && /* @__PURE__ */ (0,
|
|
9197
|
+
presence && /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(ChartPresenceLayer, { presence })
|
|
9053
9198
|
]
|
|
9054
9199
|
}
|
|
9055
9200
|
) });
|
|
9056
9201
|
}
|
|
9057
9202
|
|
|
9058
9203
|
// src/chart/ChartDataGrid.tsx
|
|
9059
|
-
var
|
|
9204
|
+
var import_react67 = require("react");
|
|
9060
9205
|
var import_chart3 = require("@pixerate/editor/chart");
|
|
9061
9206
|
|
|
9062
9207
|
// src/chart/styles.ts
|
|
@@ -9069,11 +9214,11 @@ var chartSectionClass = "space-y-2 border-b border-border pb-3 last:border-b-0";
|
|
|
9069
9214
|
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";
|
|
9070
9215
|
|
|
9071
9216
|
// src/chart/ChartDataGrid.tsx
|
|
9072
|
-
var
|
|
9217
|
+
var import_jsx_runtime48 = require("react/jsx-runtime");
|
|
9073
9218
|
function ChartCommitInput({ value, onCommit, onKeyDown, onBlur, ...rest }) {
|
|
9074
|
-
const [draft, setDraft] = (0,
|
|
9075
|
-
const typing = (0,
|
|
9076
|
-
(0,
|
|
9219
|
+
const [draft, setDraft] = (0, import_react67.useState)(value);
|
|
9220
|
+
const typing = (0, import_react67.useRef)(false);
|
|
9221
|
+
(0, import_react67.useEffect)(() => {
|
|
9077
9222
|
if (!typing.current) setDraft(value);
|
|
9078
9223
|
}, [value]);
|
|
9079
9224
|
const commit = () => {
|
|
@@ -9082,7 +9227,7 @@ function ChartCommitInput({ value, onCommit, onKeyDown, onBlur, ...rest }) {
|
|
|
9082
9227
|
if (draft === value) return;
|
|
9083
9228
|
if (onCommit(draft) === false) setDraft(value);
|
|
9084
9229
|
};
|
|
9085
|
-
return /* @__PURE__ */ (0,
|
|
9230
|
+
return /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
|
|
9086
9231
|
"input",
|
|
9087
9232
|
{
|
|
9088
9233
|
...rest,
|
|
@@ -9117,15 +9262,15 @@ function ChartDataGrid({ controller, categoryHeader = "Category", readOnly = fal
|
|
|
9117
9262
|
e.preventDefault();
|
|
9118
9263
|
controller.pasteCells(row, column, text);
|
|
9119
9264
|
};
|
|
9120
|
-
return /* @__PURE__ */ (0,
|
|
9121
|
-
/* @__PURE__ */ (0,
|
|
9122
|
-
/* @__PURE__ */ (0,
|
|
9123
|
-
/* @__PURE__ */ (0,
|
|
9265
|
+
return /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)("div", { className: `overflow-auto rounded-md border border-border ${className ?? ""}`, "data-chart-grid": "", children: [
|
|
9266
|
+
/* @__PURE__ */ (0, import_jsx_runtime48.jsxs)("table", { className: "w-full border-collapse text-xs", children: [
|
|
9267
|
+
/* @__PURE__ */ (0, import_jsx_runtime48.jsx)("thead", { className: "bg-muted/50", children: /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)("tr", { children: [
|
|
9268
|
+
/* @__PURE__ */ (0, import_jsx_runtime48.jsx)("th", { className: "border-b border-r border-border px-2 py-1 text-left font-medium text-muted-foreground", children: categoryHeader }),
|
|
9124
9269
|
spec.series.map((s, si) => {
|
|
9125
9270
|
const color = (0, import_chart3.chartSeriesColor)(spec, si);
|
|
9126
9271
|
const selected = selection?.kind === "series" && selection.seriesId === s.id;
|
|
9127
|
-
return /* @__PURE__ */ (0,
|
|
9128
|
-
/* @__PURE__ */ (0,
|
|
9272
|
+
return /* @__PURE__ */ (0, import_jsx_runtime48.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_runtime48.jsxs)("div", { className: "flex items-center gap-1", children: [
|
|
9273
|
+
/* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
|
|
9129
9274
|
"input",
|
|
9130
9275
|
{
|
|
9131
9276
|
type: "color",
|
|
@@ -9138,7 +9283,7 @@ function ChartDataGrid({ controller, categoryHeader = "Category", readOnly = fal
|
|
|
9138
9283
|
className: "h-5 w-5 shrink-0 cursor-pointer rounded border-0 bg-transparent p-0"
|
|
9139
9284
|
}
|
|
9140
9285
|
),
|
|
9141
|
-
/* @__PURE__ */ (0,
|
|
9286
|
+
/* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
|
|
9142
9287
|
ChartCommitInput,
|
|
9143
9288
|
{
|
|
9144
9289
|
value: s.name,
|
|
@@ -9148,8 +9293,8 @@ function ChartDataGrid({ controller, categoryHeader = "Category", readOnly = fal
|
|
|
9148
9293
|
className: `${chartInputClass} h-6 min-w-[5rem] border-transparent bg-transparent font-medium ${s.hidden ? "text-muted-foreground line-through" : ""}`
|
|
9149
9294
|
}
|
|
9150
9295
|
),
|
|
9151
|
-
!readOnly && /* @__PURE__ */ (0,
|
|
9152
|
-
/* @__PURE__ */ (0,
|
|
9296
|
+
!readOnly && /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)(import_jsx_runtime48.Fragment, { children: [
|
|
9297
|
+
/* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
|
|
9153
9298
|
"button",
|
|
9154
9299
|
{
|
|
9155
9300
|
type: "button",
|
|
@@ -9162,16 +9307,16 @@ function ChartDataGrid({ controller, categoryHeader = "Category", readOnly = fal
|
|
|
9162
9307
|
children: s.hidden ? "\u25CB" : "\u25CF"
|
|
9163
9308
|
}
|
|
9164
9309
|
),
|
|
9165
|
-
/* @__PURE__ */ (0,
|
|
9310
|
+
/* @__PURE__ */ (0, import_jsx_runtime48.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" })
|
|
9166
9311
|
] })
|
|
9167
9312
|
] }) }, s.id);
|
|
9168
9313
|
}),
|
|
9169
|
-
!readOnly && /* @__PURE__ */ (0,
|
|
9314
|
+
!readOnly && /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("th", { className: "w-8 border-b border-border px-1", children: /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("button", { type: "button", className: chartIconButtonClass, title: "Add series", "aria-label": "Add series", "data-action": "add-series", onClick: () => controller.addSeries(), children: "+" }) })
|
|
9170
9315
|
] }) }),
|
|
9171
|
-
/* @__PURE__ */ (0,
|
|
9316
|
+
/* @__PURE__ */ (0, import_jsx_runtime48.jsx)("tbody", { children: spec.categories.map((category, i) => {
|
|
9172
9317
|
const rowSelected = selection?.kind === "category" && selection.index === i;
|
|
9173
|
-
return /* @__PURE__ */ (0,
|
|
9174
|
-
/* @__PURE__ */ (0,
|
|
9318
|
+
return /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)("tr", { "data-category-index": i, className: rowSelected ? "bg-primary/10" : void 0, children: [
|
|
9319
|
+
/* @__PURE__ */ (0, import_jsx_runtime48.jsx)("th", { className: "border-b border-r border-border p-0 text-left font-normal", children: /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
|
|
9175
9320
|
ChartCommitInput,
|
|
9176
9321
|
{
|
|
9177
9322
|
value: category,
|
|
@@ -9185,7 +9330,7 @@ function ChartDataGrid({ controller, categoryHeader = "Category", readOnly = fal
|
|
|
9185
9330
|
spec.series.map((s) => {
|
|
9186
9331
|
const value = s.values[i];
|
|
9187
9332
|
const selected = selection?.kind === "point" && selection.seriesId === s.id && selection.index === i;
|
|
9188
|
-
return /* @__PURE__ */ (0,
|
|
9333
|
+
return /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("td", { className: `border-b border-r border-border p-0 ${selected ? "bg-primary/10" : ""}`, children: /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
|
|
9189
9334
|
ChartCommitInput,
|
|
9190
9335
|
{
|
|
9191
9336
|
value: value === null || value === void 0 ? "" : String(value),
|
|
@@ -9200,38 +9345,38 @@ function ChartDataGrid({ controller, categoryHeader = "Category", readOnly = fal
|
|
|
9200
9345
|
}
|
|
9201
9346
|
) }, s.id);
|
|
9202
9347
|
}),
|
|
9203
|
-
!readOnly && /* @__PURE__ */ (0,
|
|
9348
|
+
!readOnly && /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("td", { className: "border-b border-border px-1", children: /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("button", { type: "button", className: chartIconButtonClass, title: "Delete category", "aria-label": `Delete ${category}`, "data-action": "remove-category", onClick: () => controller.removeCategory(i), children: "\xD7" }) })
|
|
9204
9349
|
] }, i);
|
|
9205
9350
|
}) })
|
|
9206
9351
|
] }),
|
|
9207
|
-
!readOnly && /* @__PURE__ */ (0,
|
|
9352
|
+
!readOnly && /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("div", { className: "p-1", children: /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("button", { type: "button", className: `${chartButtonClass} h-6 border-dashed`, "data-action": "add-category", onClick: () => controller.addCategory(), children: "+ Add category" }) })
|
|
9208
9353
|
] });
|
|
9209
9354
|
}
|
|
9210
9355
|
|
|
9211
9356
|
// src/chart/ChartInspector.tsx
|
|
9212
|
-
var
|
|
9357
|
+
var import_react68 = require("react");
|
|
9213
9358
|
var import_chart4 = require("@pixerate/editor/chart");
|
|
9214
|
-
var
|
|
9359
|
+
var import_jsx_runtime49 = require("react/jsx-runtime");
|
|
9215
9360
|
var cap = (s) => s.charAt(0).toUpperCase() + s.slice(1);
|
|
9216
9361
|
function Field({ label, htmlFor, children }) {
|
|
9217
|
-
return /* @__PURE__ */ (0,
|
|
9218
|
-
/* @__PURE__ */ (0,
|
|
9219
|
-
/* @__PURE__ */ (0,
|
|
9362
|
+
return /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
9363
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsx)("label", { htmlFor, className: `${chartLabelClass} w-20 shrink-0`, children: label }),
|
|
9364
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsx)("div", { className: "min-w-0 flex-1", children })
|
|
9220
9365
|
] });
|
|
9221
9366
|
}
|
|
9222
9367
|
function Toggle({ label, checked, onChange, name }) {
|
|
9223
|
-
return /* @__PURE__ */ (0,
|
|
9224
|
-
/* @__PURE__ */ (0,
|
|
9368
|
+
return /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)("label", { className: "flex cursor-pointer items-center gap-2 text-xs text-foreground", children: [
|
|
9369
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsx)("input", { type: "checkbox", className: "h-3.5 w-3.5 accent-primary", checked, "data-option": name, onChange: (e) => onChange(e.currentTarget.checked) }),
|
|
9225
9370
|
label
|
|
9226
9371
|
] });
|
|
9227
9372
|
}
|
|
9228
9373
|
function Select({ id, value, options, onChange, name, labels }) {
|
|
9229
|
-
return /* @__PURE__ */ (0,
|
|
9374
|
+
return /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("select", { id, className: chartInputClass, value, "data-option": name, onChange: (e) => onChange(e.currentTarget.value), children: options.map((o) => /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("option", { value: o, children: labels?.[o] ?? cap(o) }, o)) });
|
|
9230
9375
|
}
|
|
9231
9376
|
function AxisSection({ controller, axis, value, idBase, horizontal, numeric = false, scales = false }) {
|
|
9232
9377
|
const set = (patch) => controller.setAxis(axis, patch);
|
|
9233
9378
|
const setFormat = (patch) => set({ format: { ...value.format, ...patch } });
|
|
9234
|
-
const bound = (key2) => /* @__PURE__ */ (0,
|
|
9379
|
+
const bound = (key2) => /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
|
|
9235
9380
|
ChartCommitInput,
|
|
9236
9381
|
{
|
|
9237
9382
|
id: `${idBase}-${axis}-${key2}`,
|
|
@@ -9246,26 +9391,26 @@ function AxisSection({ controller, axis, value, idBase, horizontal, numeric = fa
|
|
|
9246
9391
|
const name = axis === "x" ? numeric ? "X axis" : "Category axis" : axis === "y" ? "Value axis" : "Secondary axis";
|
|
9247
9392
|
const valueAxis = axis !== "x" || numeric;
|
|
9248
9393
|
const key = axis === "y2" ? "yAxis2" : `${axis}Axis`;
|
|
9249
|
-
return /* @__PURE__ */ (0,
|
|
9250
|
-
/* @__PURE__ */ (0,
|
|
9251
|
-
/* @__PURE__ */ (0,
|
|
9394
|
+
return /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)("div", { className: chartSectionClass, "data-section": `axis-${axis}`, children: [
|
|
9395
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsxs)("div", { className: "flex items-center justify-between", children: [
|
|
9396
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsxs)("h4", { className: "text-xs font-semibold text-foreground", children: [
|
|
9252
9397
|
name,
|
|
9253
|
-
/* @__PURE__ */ (0,
|
|
9398
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsxs)("span", { className: "ml-1 font-normal text-muted-foreground", children: [
|
|
9254
9399
|
"(",
|
|
9255
9400
|
axis === "x" ? horizontal ? "left" : "bottom" : axis === "y2" ? horizontal ? "top" : "right" : horizontal ? "bottom" : "left",
|
|
9256
9401
|
")"
|
|
9257
9402
|
] })
|
|
9258
9403
|
] }),
|
|
9259
|
-
/* @__PURE__ */ (0,
|
|
9404
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsx)(Toggle, { label: "Show", name: `${axis}Axis.show`, checked: value.show, onChange: (show) => set({ show }) })
|
|
9260
9405
|
] }),
|
|
9261
|
-
/* @__PURE__ */ (0,
|
|
9262
|
-
/* @__PURE__ */ (0,
|
|
9263
|
-
/* @__PURE__ */ (0,
|
|
9264
|
-
axis === "x" && !numeric && /* @__PURE__ */ (0,
|
|
9265
|
-
scales && /* @__PURE__ */ (0,
|
|
9266
|
-
scales && valueAxis && /* @__PURE__ */ (0,
|
|
9406
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsx)(Field, { label: "Title", htmlFor: `${idBase}-${axis}-title`, children: /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(ChartCommitInput, { id: `${idBase}-${axis}-title`, value: value.title, "data-option": `${axis}Axis.title`, className: chartInputClass, onCommit: (title) => void set({ title }) }) }),
|
|
9407
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsxs)("div", { className: "flex flex-wrap gap-x-4 gap-y-1", children: [
|
|
9408
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsx)(Toggle, { label: "Grid lines", name: `${key}.gridlines`, checked: value.gridlines, onChange: (gridlines) => set({ gridlines }) }),
|
|
9409
|
+
axis === "x" && !numeric && /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(Toggle, { label: "Dates", name: "xAxis.kind", checked: value.kind === "date", onChange: (dates) => set({ kind: dates ? "date" : void 0 }) }),
|
|
9410
|
+
scales && /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(Toggle, { label: "Reverse", name: `${key}.reverse`, checked: !!value.reverse, onChange: (reverse) => set({ reverse }) }),
|
|
9411
|
+
scales && valueAxis && /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(Toggle, { label: "Log scale", name: `${key}.scale`, checked: value.scale === "log", onChange: (log) => set({ scale: log ? "log" : "linear" }) })
|
|
9267
9412
|
] }),
|
|
9268
|
-
scales && valueAxis && value.scale === "log" && /* @__PURE__ */ (0,
|
|
9413
|
+
scales && valueAxis && value.scale === "log" && /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(Field, { label: "Log base", htmlFor: `${idBase}-${axis}-log-base`, children: /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
|
|
9269
9414
|
ChartCommitInput,
|
|
9270
9415
|
{
|
|
9271
9416
|
id: `${idBase}-${axis}-log-base`,
|
|
@@ -9276,7 +9421,7 @@ function AxisSection({ controller, axis, value, idBase, horizontal, numeric = fa
|
|
|
9276
9421
|
onCommit: (text) => set({ logBase: text.trim() === "" ? void 0 : Number(text) }).ok
|
|
9277
9422
|
}
|
|
9278
9423
|
) }),
|
|
9279
|
-
valueAxis && value.scale !== "log" && /* @__PURE__ */ (0,
|
|
9424
|
+
valueAxis && value.scale !== "log" && /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(Field, { label: "Step", htmlFor: `${idBase}-${axis}-step`, children: /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
|
|
9280
9425
|
ChartCommitInput,
|
|
9281
9426
|
{
|
|
9282
9427
|
id: `${idBase}-${axis}-step`,
|
|
@@ -9288,14 +9433,14 @@ function AxisSection({ controller, axis, value, idBase, horizontal, numeric = fa
|
|
|
9288
9433
|
onCommit: (text) => set({ step: text.trim() === "" ? null : Number(text) }).ok
|
|
9289
9434
|
}
|
|
9290
9435
|
) }),
|
|
9291
|
-
valueAxis && /* @__PURE__ */ (0,
|
|
9292
|
-
/* @__PURE__ */ (0,
|
|
9436
|
+
valueAxis && /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)(import_jsx_runtime49.Fragment, { children: [
|
|
9437
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsx)(Field, { label: "Min / max", children: /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)("div", { className: "flex gap-1", children: [
|
|
9293
9438
|
bound("min"),
|
|
9294
9439
|
bound("max")
|
|
9295
9440
|
] }) }),
|
|
9296
|
-
/* @__PURE__ */ (0,
|
|
9297
|
-
/* @__PURE__ */ (0,
|
|
9298
|
-
/* @__PURE__ */ (0,
|
|
9441
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsx)(Field, { label: "Format", htmlFor: `${idBase}-${axis}-format`, children: /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)("div", { className: "flex gap-1", children: [
|
|
9442
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.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 }) }),
|
|
9443
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
|
|
9299
9444
|
ChartCommitInput,
|
|
9300
9445
|
{
|
|
9301
9446
|
value: value.format.decimals === void 0 ? "" : String(value.format.decimals),
|
|
@@ -9314,8 +9459,8 @@ function AxisSection({ controller, axis, value, idBase, horizontal, numeric = fa
|
|
|
9314
9459
|
}
|
|
9315
9460
|
)
|
|
9316
9461
|
] }) }),
|
|
9317
|
-
value.format.style === "currency" && /* @__PURE__ */ (0,
|
|
9318
|
-
/* @__PURE__ */ (0,
|
|
9462
|
+
value.format.style === "currency" && /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(Field, { label: "Currency", htmlFor: `${idBase}-${axis}-currency`, children: /* @__PURE__ */ (0, import_jsx_runtime49.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() }) }) }),
|
|
9463
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsx)(Field, { label: "Code", htmlFor: `${idBase}-${axis}-code`, children: /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
|
|
9319
9464
|
ChartCommitInput,
|
|
9320
9465
|
{
|
|
9321
9466
|
id: `${idBase}-${axis}-code`,
|
|
@@ -9341,15 +9486,15 @@ function ErrorBarFields({ controller, series, which, idBase }) {
|
|
|
9341
9486
|
const values = which === "xErrorBars" ? series.x ?? [] : series.values;
|
|
9342
9487
|
const set = (next) => controller.updateSeries(series.id, { [which]: next });
|
|
9343
9488
|
const patch = (p) => bars && set({ ...bars, ...p });
|
|
9344
|
-
return /* @__PURE__ */ (0,
|
|
9345
|
-
/* @__PURE__ */ (0,
|
|
9346
|
-
/* @__PURE__ */ (0,
|
|
9347
|
-
import_chart4.CHART_ERROR_BAR_TYPES.map((t) => /* @__PURE__ */ (0,
|
|
9489
|
+
return /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)("div", { className: "space-y-1.5", "data-section": which === "errorBars" ? "error-bars" : "x-error-bars", children: [
|
|
9490
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsx)(Field, { label: which === "errorBars" ? "Error bars" : "X error bars", htmlFor: `${id}-type`, children: /* @__PURE__ */ (0, import_jsx_runtime49.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: [
|
|
9491
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsx)("option", { value: "", children: "None" }),
|
|
9492
|
+
import_chart4.CHART_ERROR_BAR_TYPES.map((t) => /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("option", { value: t, children: import_chart4.CHART_ERROR_BAR_LABELS[t] }, t))
|
|
9348
9493
|
] }) }),
|
|
9349
|
-
bars && (bars.type === "fixed" || bars.type === "percent" || bars.type === "stddev") && /* @__PURE__ */ (0,
|
|
9350
|
-
bars?.type === "custom" && /* @__PURE__ */ (0,
|
|
9351
|
-
/* @__PURE__ */ (0,
|
|
9352
|
-
/* @__PURE__ */ (0,
|
|
9494
|
+
bars && (bars.type === "fixed" || bars.type === "percent" || bars.type === "stddev") && /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(Field, { label: bars.type === "percent" ? "Percent" : bars.type === "stddev" ? "Deviations" : "Amount", htmlFor: `${id}-value`, children: /* @__PURE__ */ (0, import_jsx_runtime49.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 }) }),
|
|
9495
|
+
bars?.type === "custom" && /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)(import_jsx_runtime49.Fragment, { children: [
|
|
9496
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsx)(Field, { label: "Plus", htmlFor: `${id}-plus`, children: /* @__PURE__ */ (0, import_jsx_runtime49.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 }) }),
|
|
9497
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsx)(Field, { label: "Minus", htmlFor: `${id}-minus`, children: /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
|
|
9353
9498
|
ChartCommitInput,
|
|
9354
9499
|
{
|
|
9355
9500
|
id: `${id}-minus`,
|
|
@@ -9366,15 +9511,15 @@ function ErrorBarFields({ controller, series, which, idBase }) {
|
|
|
9366
9511
|
}
|
|
9367
9512
|
) })
|
|
9368
9513
|
] }),
|
|
9369
|
-
bars && /* @__PURE__ */ (0,
|
|
9370
|
-
/* @__PURE__ */ (0,
|
|
9371
|
-
/* @__PURE__ */ (0,
|
|
9514
|
+
bars && /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
9515
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.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_runtime49.jsx)("option", { value: d, children: d === "both" ? "Both ways" : d === "plus" ? "Plus only" : "Minus only" }, d)) }),
|
|
9516
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsx)(Toggle, { label: "Caps", name: `${key}.cap`, checked: bars.cap !== false, onChange: (cap2) => patch({ cap: cap2 }) })
|
|
9372
9517
|
] })
|
|
9373
9518
|
] });
|
|
9374
9519
|
}
|
|
9375
9520
|
function ChartInspector({ controller, sections, className }) {
|
|
9376
9521
|
const { spec, selectedSeries } = useChartState(controller);
|
|
9377
|
-
const idBase = (0,
|
|
9522
|
+
const idBase = (0, import_react68.useId)();
|
|
9378
9523
|
const show = (section) => !sections || sections.includes(section);
|
|
9379
9524
|
const cartesian = (0, import_chart4.isCartesianChart)(spec.type);
|
|
9380
9525
|
const family = (0, import_chart4.chartFamily)(spec);
|
|
@@ -9386,29 +9531,29 @@ function ChartInspector({ controller, sections, className }) {
|
|
|
9386
9531
|
const hasLines = cartesian && types.some((t) => t === "line" || t === "area");
|
|
9387
9532
|
const seriesIndex = selectedSeries ? spec.series.findIndex((s) => s.id === selectedSeries.id) : -1;
|
|
9388
9533
|
const scales = family === "cartesian" || family === "xy";
|
|
9389
|
-
return /* @__PURE__ */ (0,
|
|
9390
|
-
show("type") && /* @__PURE__ */ (0,
|
|
9391
|
-
show("style") && /* @__PURE__ */ (0,
|
|
9392
|
-
/* @__PURE__ */ (0,
|
|
9393
|
-
/* @__PURE__ */ (0,
|
|
9394
|
-
import_chart4.CHART_LAYOUT_PRESETS.map((p) => /* @__PURE__ */ (0,
|
|
9534
|
+
return /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)("div", { className: `space-y-3 text-xs ${className ?? ""}`, "data-chart-inspector": "", children: [
|
|
9535
|
+
show("type") && /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("div", { className: chartSectionClass, "data-section": "type", children: /* @__PURE__ */ (0, import_jsx_runtime49.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_runtime49.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)) }) }),
|
|
9536
|
+
show("style") && /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)("div", { className: chartSectionClass, "data-section": "style", children: [
|
|
9537
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsx)(Field, { label: "Layout", htmlFor: `${idBase}-layout`, children: /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)("select", { id: `${idBase}-layout`, className: chartInputClass, value: "", "data-option": "preset.layout", onChange: (e) => e.currentTarget.value && controller.applyPreset({ layout: e.currentTarget.value }), children: [
|
|
9538
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsx)("option", { value: "", children: "Quick layout\u2026" }),
|
|
9539
|
+
import_chart4.CHART_LAYOUT_PRESETS.map((p) => /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("option", { value: p.id, title: p.description, children: p.label }, p.id))
|
|
9395
9540
|
] }) }),
|
|
9396
|
-
/* @__PURE__ */ (0,
|
|
9397
|
-
/* @__PURE__ */ (0,
|
|
9398
|
-
import_chart4.CHART_COLOR_SCHEMES.map((c) => /* @__PURE__ */ (0,
|
|
9541
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsx)(Field, { label: "Colours", htmlFor: `${idBase}-colors`, children: /* @__PURE__ */ (0, import_jsx_runtime49.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: [
|
|
9542
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsx)("option", { value: "", children: "Custom" }),
|
|
9543
|
+
import_chart4.CHART_COLOR_SCHEMES.map((c) => /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("option", { value: c.id, title: c.description, children: c.label }, c.id))
|
|
9399
9544
|
] }) }),
|
|
9400
|
-
!colorCheck.ok && /* @__PURE__ */ (0,
|
|
9401
|
-
/* @__PURE__ */ (0,
|
|
9545
|
+
!colorCheck.ok && /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("p", { className: "text-[11px] leading-snug text-amber-600 dark:text-amber-400", "data-chart-color-warning": "", children: colorCheck.issues[0] }),
|
|
9546
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsx)("button", { type: "button", className: chartButtonClass, "data-action": "transpose", onClick: () => controller.transpose(), children: "Switch rows and columns" })
|
|
9402
9547
|
] }),
|
|
9403
|
-
show("titles") && /* @__PURE__ */ (0,
|
|
9404
|
-
/* @__PURE__ */ (0,
|
|
9405
|
-
/* @__PURE__ */ (0,
|
|
9548
|
+
show("titles") && /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)("div", { className: chartSectionClass, "data-section": "titles", children: [
|
|
9549
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsx)(Field, { label: "Title", htmlFor: `${idBase}-title`, children: /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(ChartCommitInput, { id: `${idBase}-title`, value: spec.title, "data-option": "title", className: chartInputClass, onCommit: (title) => void controller.setTitle(title) }) }),
|
|
9550
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsx)(Field, { label: "Subtitle", htmlFor: `${idBase}-subtitle`, children: /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(ChartCommitInput, { id: `${idBase}-subtitle`, value: spec.subtitle, "data-option": "subtitle", className: chartInputClass, onCommit: (subtitle) => void controller.setSubtitle(subtitle) }) })
|
|
9406
9551
|
] }),
|
|
9407
|
-
show("options") && /* @__PURE__ */ (0,
|
|
9408
|
-
cartesian && /* @__PURE__ */ (0,
|
|
9409
|
-
hasBars && /* @__PURE__ */ (0,
|
|
9410
|
-
hasLines && /* @__PURE__ */ (0,
|
|
9411
|
-
spec.type === "donut" && /* @__PURE__ */ (0,
|
|
9552
|
+
show("options") && /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)("div", { className: chartSectionClass, "data-section": "options", children: [
|
|
9553
|
+
cartesian && /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(Field, { label: "Stacking", htmlFor: `${idBase}-stacking`, children: /* @__PURE__ */ (0, import_jsx_runtime49.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 }) }) }),
|
|
9554
|
+
hasBars && /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(Field, { label: "Bars", children: /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("div", { className: "flex gap-0.5 rounded-md bg-muted p-0.5", children: ["vertical", "horizontal"].map((o) => /* @__PURE__ */ (0, import_jsx_runtime49.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)) }) }),
|
|
9555
|
+
hasLines && /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(Field, { label: "Lines", htmlFor: `${idBase}-curve`, children: /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(Select, { id: `${idBase}-curve`, name: "curve", value: spec.curve, options: import_chart4.CHART_CURVES, onChange: (curve) => controller.update({ curve }) }) }),
|
|
9556
|
+
spec.type === "donut" && /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(Field, { label: "Hole", htmlFor: `${idBase}-hole`, children: /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
|
|
9412
9557
|
"input",
|
|
9413
9558
|
{
|
|
9414
9559
|
id: `${idBase}-hole`,
|
|
@@ -9424,7 +9569,7 @@ function ChartInspector({ controller, sections, className }) {
|
|
|
9424
9569
|
onChange: (e) => controller.update({ innerRadius: Number(e.currentTarget.value) })
|
|
9425
9570
|
}
|
|
9426
9571
|
) }),
|
|
9427
|
-
hasBars && /* @__PURE__ */ (0,
|
|
9572
|
+
hasBars && /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(Field, { label: "Spacing", htmlFor: `${idBase}-gap`, children: /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
|
|
9428
9573
|
"input",
|
|
9429
9574
|
{
|
|
9430
9575
|
id: `${idBase}-gap`,
|
|
@@ -9440,31 +9585,31 @@ function ChartInspector({ controller, sections, className }) {
|
|
|
9440
9585
|
onChange: (e) => controller.update({ gapWidth: Number(e.currentTarget.value) })
|
|
9441
9586
|
}
|
|
9442
9587
|
) }),
|
|
9443
|
-
spec.dataLabels && hasBars && /* @__PURE__ */ (0,
|
|
9444
|
-
spec.type === "histogram" && /* @__PURE__ */ (0,
|
|
9445
|
-
/* @__PURE__ */ (0,
|
|
9446
|
-
spec.type === "waterfall" && /* @__PURE__ */ (0,
|
|
9447
|
-
hasLines && /* @__PURE__ */ (0,
|
|
9448
|
-
/* @__PURE__ */ (0,
|
|
9588
|
+
spec.dataLabels && hasBars && /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(Field, { label: "Labels", htmlFor: `${idBase}-label-position`, children: /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(Select, { id: `${idBase}-label-position`, name: "labelPosition", value: spec.labelPosition, options: import_chart4.CHART_LABEL_POSITIONS, onChange: (labelPosition) => controller.update({ labelPosition }) }) }),
|
|
9589
|
+
spec.type === "histogram" && /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(Field, { label: "Bins", htmlFor: `${idBase}-bins`, children: /* @__PURE__ */ (0, import_jsx_runtime49.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 }) }),
|
|
9590
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsxs)("div", { className: "flex flex-wrap gap-x-4 gap-y-1", children: [
|
|
9591
|
+
spec.type === "waterfall" && /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(Toggle, { label: "Total bar", name: "showTotal", checked: spec.showTotal, onChange: (showTotal) => controller.update({ showTotal }) }),
|
|
9592
|
+
hasLines && /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(Toggle, { label: "Points", name: "points", checked: spec.points, onChange: (points) => controller.update({ points }) }),
|
|
9593
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsx)(Toggle, { label: "Data labels", name: "dataLabels", checked: spec.dataLabels, onChange: (dataLabels) => controller.update({ dataLabels }) })
|
|
9449
9594
|
] })
|
|
9450
9595
|
] }),
|
|
9451
|
-
show("legend") && /* @__PURE__ */ (0,
|
|
9452
|
-
/* @__PURE__ */ (0,
|
|
9453
|
-
/* @__PURE__ */ (0,
|
|
9454
|
-
/* @__PURE__ */ (0,
|
|
9596
|
+
show("legend") && /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)("div", { className: chartSectionClass, "data-section": "legend", children: [
|
|
9597
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsxs)("div", { className: "flex items-center justify-between", children: [
|
|
9598
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsx)("h4", { className: "text-xs font-semibold text-foreground", children: "Legend" }),
|
|
9599
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsx)(Toggle, { label: "Show", name: "legend.show", checked: spec.legend.show, onChange: (v) => controller.setLegend({ show: v }) })
|
|
9455
9600
|
] }),
|
|
9456
|
-
spec.legend.show && /* @__PURE__ */ (0,
|
|
9601
|
+
spec.legend.show && /* @__PURE__ */ (0, import_jsx_runtime49.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_runtime49.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)) })
|
|
9457
9602
|
] }),
|
|
9458
|
-
show("axes") && hasAxes && /* @__PURE__ */ (0,
|
|
9459
|
-
family !== "box" && family !== "histogram" && /* @__PURE__ */ (0,
|
|
9460
|
-
/* @__PURE__ */ (0,
|
|
9461
|
-
usesSecondary && /* @__PURE__ */ (0,
|
|
9603
|
+
show("axes") && hasAxes && /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)(import_jsx_runtime49.Fragment, { children: [
|
|
9604
|
+
family !== "box" && family !== "histogram" && /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(AxisSection, { controller, axis: "x", value: spec.xAxis, idBase, horizontal: spec.orientation === "horizontal", numeric: family === "xy", scales }),
|
|
9605
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsx)(AxisSection, { controller, axis: "y", value: spec.yAxis, idBase, horizontal: spec.orientation === "horizontal", scales }),
|
|
9606
|
+
usesSecondary && /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(AxisSection, { controller, axis: "y2", value: spec.yAxis2, idBase, horizontal: spec.orientation === "horizontal", scales })
|
|
9462
9607
|
] }),
|
|
9463
|
-
show("series") && selectedSeries && /* @__PURE__ */ (0,
|
|
9464
|
-
/* @__PURE__ */ (0,
|
|
9465
|
-
/* @__PURE__ */ (0,
|
|
9466
|
-
/* @__PURE__ */ (0,
|
|
9467
|
-
/* @__PURE__ */ (0,
|
|
9608
|
+
show("series") && selectedSeries && /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)("div", { className: chartSectionClass, "data-section": "series", "data-series-id": selectedSeries.id, children: [
|
|
9609
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsx)("h4", { className: "text-xs font-semibold text-foreground", children: "Series" }),
|
|
9610
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsx)(Field, { label: "Name", htmlFor: `${idBase}-series-name`, children: /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(ChartCommitInput, { id: `${idBase}-series-name`, value: selectedSeries.name, "data-option": "series.name", className: chartInputClass, onCommit: (name) => void controller.updateSeries(selectedSeries.id, { name }) }) }),
|
|
9611
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsx)(Field, { label: "Colour", htmlFor: `${idBase}-series-color`, children: /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)("div", { className: "flex items-center gap-1", children: [
|
|
9612
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
|
|
9468
9613
|
"input",
|
|
9469
9614
|
{
|
|
9470
9615
|
id: `${idBase}-series-color`,
|
|
@@ -9477,9 +9622,9 @@ function ChartInspector({ controller, sections, className }) {
|
|
|
9477
9622
|
onChange: (e) => controller.updateSeries(selectedSeries.id, { color: e.currentTarget.value })
|
|
9478
9623
|
}
|
|
9479
9624
|
),
|
|
9480
|
-
selectedSeries.color && /* @__PURE__ */ (0,
|
|
9625
|
+
selectedSeries.color && /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("button", { type: "button", className: chartButtonClass, "data-action": "reset-color", onClick: () => controller.updateSeries(selectedSeries.id, { color: null }), children: "Palette" })
|
|
9481
9626
|
] }) }),
|
|
9482
|
-
cartesian && /* @__PURE__ */ (0,
|
|
9627
|
+
cartesian && /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(Field, { label: "Draw as", htmlFor: `${idBase}-series-type`, children: /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)(
|
|
9483
9628
|
"select",
|
|
9484
9629
|
{
|
|
9485
9630
|
id: `${idBase}-series-type`,
|
|
@@ -9488,12 +9633,12 @@ function ChartInspector({ controller, sections, className }) {
|
|
|
9488
9633
|
"data-option": "series.type",
|
|
9489
9634
|
onChange: (e) => controller.updateSeries(selectedSeries.id, { type: e.currentTarget.value || null }),
|
|
9490
9635
|
children: [
|
|
9491
|
-
/* @__PURE__ */ (0,
|
|
9492
|
-
import_chart4.CHART_SERIES_TYPES.map((t) => /* @__PURE__ */ (0,
|
|
9636
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsx)("option", { value: "", children: "Chart type" }),
|
|
9637
|
+
import_chart4.CHART_SERIES_TYPES.map((t) => /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("option", { value: t, children: import_chart4.CHART_TYPE_LABELS[t] }, t))
|
|
9493
9638
|
]
|
|
9494
9639
|
}
|
|
9495
9640
|
) }),
|
|
9496
|
-
(cartesian || family === "xy") && ["line", "area", "scatter"].includes((0, import_chart4.chartSeriesType)(spec, selectedSeries)) && /* @__PURE__ */ (0,
|
|
9641
|
+
(cartesian || family === "xy") && ["line", "area", "scatter"].includes((0, import_chart4.chartSeriesType)(spec, selectedSeries)) && /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(Field, { label: "Marker", htmlFor: `${idBase}-series-marker`, children: /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)(
|
|
9497
9642
|
"select",
|
|
9498
9643
|
{
|
|
9499
9644
|
id: `${idBase}-series-marker`,
|
|
@@ -9502,20 +9647,20 @@ function ChartInspector({ controller, sections, className }) {
|
|
|
9502
9647
|
"data-option": "series.marker",
|
|
9503
9648
|
onChange: (e) => controller.updateSeries(selectedSeries.id, { marker: e.currentTarget.value || null }),
|
|
9504
9649
|
children: [
|
|
9505
|
-
/* @__PURE__ */ (0,
|
|
9506
|
-
import_chart4.CHART_MARKERS.map((m) => /* @__PURE__ */ (0,
|
|
9650
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsx)("option", { value: "", children: "Default" }),
|
|
9651
|
+
import_chart4.CHART_MARKERS.map((m) => /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("option", { value: m, children: cap(m) }, m))
|
|
9507
9652
|
]
|
|
9508
9653
|
}
|
|
9509
9654
|
) }),
|
|
9510
|
-
scales && /* @__PURE__ */ (0,
|
|
9511
|
-
family === "xy" && /* @__PURE__ */ (0,
|
|
9512
|
-
(0, import_chart4.chartSupportsTrendlines)(spec.type, spec.stacking) && /* @__PURE__ */ (0,
|
|
9513
|
-
(selectedSeries.trendlines ?? []).map((t, i) => /* @__PURE__ */ (0,
|
|
9514
|
-
/* @__PURE__ */ (0,
|
|
9515
|
-
/* @__PURE__ */ (0,
|
|
9516
|
-
/* @__PURE__ */ (0,
|
|
9655
|
+
scales && /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(ErrorBarFields, { controller, series: selectedSeries, which: "errorBars", idBase }),
|
|
9656
|
+
family === "xy" && /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(ErrorBarFields, { controller, series: selectedSeries, which: "xErrorBars", idBase }),
|
|
9657
|
+
(0, import_chart4.chartSupportsTrendlines)(spec.type, spec.stacking) && /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)("div", { className: "space-y-1", "data-section": "trendlines", children: [
|
|
9658
|
+
(selectedSeries.trendlines ?? []).map((t, i) => /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)("div", { className: "flex items-center gap-1", "data-trendline": i, children: [
|
|
9659
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsx)("span", { className: "flex-1 truncate text-muted-foreground", children: (0, import_chart4.chartTrendlineName)(t, selectedSeries.name) }),
|
|
9660
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsx)(Toggle, { label: "R\xB2", name: `trendline.${i}.showR2`, checked: !!t.showR2, onChange: (showR2) => controller.updateTrendline(selectedSeries.id, i, { showR2 }) }),
|
|
9661
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsx)("button", { type: "button", className: chartButtonClass, "aria-label": "Delete trendline", "data-action": "trendline-delete", onClick: () => controller.removeTrendline(selectedSeries.id, i), children: "\xD7" })
|
|
9517
9662
|
] }, i)),
|
|
9518
|
-
/* @__PURE__ */ (0,
|
|
9663
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsxs)(
|
|
9519
9664
|
"select",
|
|
9520
9665
|
{
|
|
9521
9666
|
className: chartInputClass,
|
|
@@ -9524,32 +9669,32 @@ function ChartInspector({ controller, sections, className }) {
|
|
|
9524
9669
|
"data-option": "trendline.add",
|
|
9525
9670
|
onChange: (e) => e.currentTarget.value && controller.addTrendline(selectedSeries.id, { type: e.currentTarget.value }),
|
|
9526
9671
|
children: [
|
|
9527
|
-
/* @__PURE__ */ (0,
|
|
9528
|
-
import_chart4.CHART_TRENDLINE_TYPES.map((t) => /* @__PURE__ */ (0,
|
|
9672
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsx)("option", { value: "", children: "Add trendline\u2026" }),
|
|
9673
|
+
import_chart4.CHART_TRENDLINE_TYPES.map((t) => /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("option", { value: t, children: cap(t.replace("-", " ")) }, t))
|
|
9529
9674
|
]
|
|
9530
9675
|
}
|
|
9531
9676
|
)
|
|
9532
9677
|
] }),
|
|
9533
|
-
/* @__PURE__ */ (0,
|
|
9534
|
-
/* @__PURE__ */ (0,
|
|
9535
|
-
family === "cartesian" && /* @__PURE__ */ (0,
|
|
9536
|
-
/* @__PURE__ */ (0,
|
|
9537
|
-
/* @__PURE__ */ (0,
|
|
9538
|
-
/* @__PURE__ */ (0,
|
|
9539
|
-
/* @__PURE__ */ (0,
|
|
9678
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsxs)("div", { className: "flex flex-wrap items-center gap-1", children: [
|
|
9679
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsx)(Toggle, { label: "Hidden", name: "series.hidden", checked: !!selectedSeries.hidden, onChange: (hidden) => controller.updateSeries(selectedSeries.id, { hidden }) }),
|
|
9680
|
+
family === "cartesian" && /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(Toggle, { label: "Secondary axis", name: "series.axis", checked: selectedSeries.axis === "secondary", onChange: (secondary) => controller.updateSeries(selectedSeries.id, { axis: secondary ? "secondary" : null }) }),
|
|
9681
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsx)("span", { className: "flex-1" }),
|
|
9682
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.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" }),
|
|
9683
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.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" }),
|
|
9684
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsx)("button", { type: "button", className: `${chartButtonClass} text-destructive`, "data-action": "series-delete", onClick: () => controller.removeSeries(selectedSeries.id), children: "Delete" })
|
|
9540
9685
|
] })
|
|
9541
9686
|
] })
|
|
9542
9687
|
] });
|
|
9543
9688
|
}
|
|
9544
9689
|
|
|
9545
9690
|
// src/chart-node/ChartNodeView.tsx
|
|
9546
|
-
var
|
|
9691
|
+
var import_jsx_runtime50 = require("react/jsx-runtime");
|
|
9547
9692
|
function ChartNodeView({ state, theme, showDataGrid = true }) {
|
|
9548
9693
|
const { controller, editing, editable, selected, width, height, setEditing } = state;
|
|
9549
9694
|
const open = () => {
|
|
9550
9695
|
if (editable && !editing) setEditing(true);
|
|
9551
9696
|
};
|
|
9552
|
-
return /* @__PURE__ */ (0,
|
|
9697
|
+
return /* @__PURE__ */ (0, import_jsx_runtime50.jsxs)(
|
|
9553
9698
|
"div",
|
|
9554
9699
|
{
|
|
9555
9700
|
className: `not-prose my-2 rounded-md border bg-background p-1 ${selected ? "border-primary ring-1 ring-primary" : "border-border"}`,
|
|
@@ -9562,24 +9707,24 @@ function ChartNodeView({ state, theme, showDataGrid = true }) {
|
|
|
9562
9707
|
}
|
|
9563
9708
|
},
|
|
9564
9709
|
children: [
|
|
9565
|
-
editing && /* @__PURE__ */ (0,
|
|
9566
|
-
/* @__PURE__ */ (0,
|
|
9567
|
-
/* @__PURE__ */ (0,
|
|
9710
|
+
editing && /* @__PURE__ */ (0, import_jsx_runtime50.jsxs)("div", { className: "mb-1 flex items-center justify-between gap-2 px-1", "data-chart-node-toolbar": "", children: [
|
|
9711
|
+
/* @__PURE__ */ (0, import_jsx_runtime50.jsx)("span", { className: "text-xs text-muted-foreground", children: "Editing chart" }),
|
|
9712
|
+
/* @__PURE__ */ (0, import_jsx_runtime50.jsx)("button", { type: "button", className: chartButtonClass, "data-action": "done", onClick: () => setEditing(false), children: "Done" })
|
|
9568
9713
|
] }),
|
|
9569
|
-
/* @__PURE__ */ (0,
|
|
9714
|
+
/* @__PURE__ */ (0, import_jsx_runtime50.jsx)(
|
|
9570
9715
|
"div",
|
|
9571
9716
|
{
|
|
9572
9717
|
className: editable && !editing ? "cursor-pointer" : void 0,
|
|
9573
9718
|
onClick: open,
|
|
9574
9719
|
title: editable && !editing ? "Click to edit the chart" : void 0,
|
|
9575
9720
|
"data-chart-node-canvas": "",
|
|
9576
|
-
children: /* @__PURE__ */ (0,
|
|
9721
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(ChartCanvas, { controller, width: width ?? 640, height, responsive: width === null, editable: editing, theme })
|
|
9577
9722
|
}
|
|
9578
9723
|
),
|
|
9579
9724
|
editing && // Wraps by the document's width, not the viewport's: side by side when there is room.
|
|
9580
|
-
/* @__PURE__ */ (0,
|
|
9581
|
-
showDataGrid && /* @__PURE__ */ (0,
|
|
9582
|
-
/* @__PURE__ */ (0,
|
|
9725
|
+
/* @__PURE__ */ (0, import_jsx_runtime50.jsxs)("div", { className: "mt-2 flex flex-wrap items-start gap-2", "data-chart-node-panel": "", children: [
|
|
9726
|
+
showDataGrid && /* @__PURE__ */ (0, import_jsx_runtime50.jsx)("div", { className: "min-w-0 flex-[1_1_20rem] overflow-x-auto", children: /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(ChartDataGrid, { controller }) }),
|
|
9727
|
+
/* @__PURE__ */ (0, import_jsx_runtime50.jsx)(ChartInspector, { controller, className: "max-h-96 min-w-0 flex-[1_1_16rem] overflow-y-auto rounded-md border border-border p-3" })
|
|
9583
9728
|
] })
|
|
9584
9729
|
]
|
|
9585
9730
|
}
|
|
@@ -9597,7 +9742,7 @@ function createReactChartNodeView(options = {}) {
|
|
|
9597
9742
|
scheduled = true;
|
|
9598
9743
|
queueMicrotask(() => {
|
|
9599
9744
|
scheduled = false;
|
|
9600
|
-
if (!destroyed) root.render(/* @__PURE__ */ (0,
|
|
9745
|
+
if (!destroyed) root.render(/* @__PURE__ */ (0, import_jsx_runtime50.jsx)(Component, { ...props, state: latest }));
|
|
9601
9746
|
});
|
|
9602
9747
|
};
|
|
9603
9748
|
schedule();
|
|
@@ -9645,6 +9790,7 @@ function createReactChartNodeView(options = {}) {
|
|
|
9645
9790
|
MergePreview,
|
|
9646
9791
|
NameManager,
|
|
9647
9792
|
OutlinePanel,
|
|
9793
|
+
PaintGradientEditor,
|
|
9648
9794
|
RecoveryPrompt,
|
|
9649
9795
|
RefineEdgePanel,
|
|
9650
9796
|
ReviewToolbar,
|