@pixerate/editor-react 0.70.0 → 0.72.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-LCTQWNTL.js → chunk-YAFNCBDA.js} +630 -231
- package/dist/chunk-YAFNCBDA.js.map +1 -0
- package/dist/image-editor/index.cjs +656 -273
- package/dist/image-editor/index.cjs.map +1 -1
- package/dist/image-editor/index.d.cts +33 -2
- package/dist/image-editor/index.d.ts +33 -2
- package/dist/image-editor/index.js +5 -1
- package/dist/index.cjs +1085 -702
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +5 -1
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
- package/dist/chunk-LCTQWNTL.js.map +0 -1
package/dist/index.cjs
CHANGED
|
@@ -63,6 +63,7 @@ __export(src_exports, {
|
|
|
63
63
|
RefineEdgePanel: () => RefineEdgePanel,
|
|
64
64
|
ReviewToolbar: () => ReviewToolbar,
|
|
65
65
|
SelectionOptionsBar: () => SelectionOptionsBar,
|
|
66
|
+
ShapeOptionsBar: () => ShapeOptionsBar,
|
|
66
67
|
SheetTabs: () => SheetTabs,
|
|
67
68
|
SpreadsheetConditionalFormatPanel: () => SpreadsheetConditionalFormatPanel,
|
|
68
69
|
SpreadsheetContextMenu: () => SpreadsheetContextMenu,
|
|
@@ -75,6 +76,7 @@ __export(src_exports, {
|
|
|
75
76
|
TableToolbar: () => TableToolbar,
|
|
76
77
|
TemplateRenderer: () => TemplateRenderer,
|
|
77
78
|
TrackedChangesList: () => TrackedChangesList,
|
|
79
|
+
TypeOptionsBar: () => TypeOptionsBar,
|
|
78
80
|
VariableForm: () => VariableForm,
|
|
79
81
|
bindDirtyToHistory: () => import_editor21.bindDirtyToHistory,
|
|
80
82
|
createDirtyTracker: () => import_editor21.createDirtyTracker,
|
|
@@ -3785,8 +3787,8 @@ function useImageEditor(options = {}) {
|
|
|
3785
3787
|
}
|
|
3786
3788
|
|
|
3787
3789
|
// src/image-editor/ImageEditor.tsx
|
|
3788
|
-
var
|
|
3789
|
-
var
|
|
3790
|
+
var import_react46 = __toESM(require("react"), 1);
|
|
3791
|
+
var import_image_editor14 = require("@pixerate/editor/image-editor");
|
|
3790
3792
|
|
|
3791
3793
|
// src/image-editor/ControlSlider.tsx
|
|
3792
3794
|
var import_image_editor2 = require("@pixerate/editor/image-editor");
|
|
@@ -4496,7 +4498,7 @@ var LayersPanel = ({ controller, thumbnailSize = 32, psd = true, psdFileName = "
|
|
|
4496
4498
|
const placement = (0, import_image_editor7.dropPlacement)(state.layers, id, row.layer.id, (0, import_image_editor7.dropZone)(fraction, row.layer.type === "group"));
|
|
4497
4499
|
if (placement) attempt(() => controller.moveLayer(id, placement));
|
|
4498
4500
|
};
|
|
4499
|
-
const thumb = (layer) => layer
|
|
4501
|
+
const thumb = (layer) => (0, import_image_editor7.layerHasThumbnail)(layer) ? controller.getLayerThumbnail(layer.id, { maxSide: 64 }) : null;
|
|
4500
4502
|
const maskThumb = (layer) => layer.mask && !layer.mask.source ? controller.getLayerThumbnail(layer.id, { maxSide: 64, mask: true }) : null;
|
|
4501
4503
|
const locked = (layer) => Boolean(layer.locks?.all || layer.locks?.pixels || layer.locks?.position || layer.locks?.transparency);
|
|
4502
4504
|
return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: `flex flex-col gap-2 text-xs text-slate-200 ${className ?? ""}`, "data-testid": "layers-panel", onClick: () => menu && setMenu(null), children: [
|
|
@@ -4689,15 +4691,25 @@ var LayersPanel = ({ controller, thumbnailSize = 32, psd = true, psdFileName = "
|
|
|
4689
4691
|
}
|
|
4690
4692
|
),
|
|
4691
4693
|
row.clipped && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "text-slate-500", "aria-label": "Clipped", children: "\u21B3" }),
|
|
4692
|
-
layer
|
|
4693
|
-
|
|
4694
|
-
|
|
4695
|
-
|
|
4696
|
-
|
|
4697
|
-
|
|
4698
|
-
|
|
4699
|
-
|
|
4700
|
-
|
|
4694
|
+
(0, import_image_editor7.layerHasThumbnail)(layer) ? /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("span", { className: "relative shrink-0", children: [
|
|
4695
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
4696
|
+
Thumbnail,
|
|
4697
|
+
{
|
|
4698
|
+
pixels: thumb(layer),
|
|
4699
|
+
size: thumbnailSize,
|
|
4700
|
+
label: `${row.label} pixels`,
|
|
4701
|
+
selected: row.active && state.activeTarget === "pixels" && Boolean(layer.mask)
|
|
4702
|
+
}
|
|
4703
|
+
),
|
|
4704
|
+
layer.type !== "pixel" && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
4705
|
+
"span",
|
|
4706
|
+
{
|
|
4707
|
+
"data-testid": "layer-kind-badge",
|
|
4708
|
+
className: "absolute -bottom-1 -right-1 rounded bg-slate-700 px-0.5 text-[8px] font-bold leading-tight text-slate-100 ring-1 ring-slate-900",
|
|
4709
|
+
children: (0, import_image_editor7.layerBadge)(layer)
|
|
4710
|
+
}
|
|
4711
|
+
)
|
|
4712
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
4701
4713
|
"span",
|
|
4702
4714
|
{
|
|
4703
4715
|
className: "shrink-0 grid place-items-center rounded bg-slate-800 text-[9px] text-slate-400 ring-1 ring-slate-700",
|
|
@@ -4764,6 +4776,7 @@ var LayersPanel = ({ controller, thumbnailSize = 32, psd = true, psdFileName = "
|
|
|
4764
4776
|
children: row.label
|
|
4765
4777
|
}
|
|
4766
4778
|
),
|
|
4779
|
+
(0, import_image_editor7.layerWarning)(layer) && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { role: "img", "data-testid": "layer-warning", "aria-label": (0, import_image_editor7.layerWarning)(layer), title: (0, import_image_editor7.layerWarning)(layer), className: "text-[10px] text-amber-400", children: "\u26A0" }),
|
|
4767
4780
|
(0, import_image_editor7.layerEffectsBadge)(layer) && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
4768
4781
|
"button",
|
|
4769
4782
|
{
|
|
@@ -4823,7 +4836,8 @@ var BrushOptionsBar = ({ controller, className }) => {
|
|
|
4823
4836
|
(0, import_react40.useEffect)(() => controller.subscribe(() => setTick((n) => n + 1)), [controller]);
|
|
4824
4837
|
const [error, setError] = (0, import_react40.useState)(null);
|
|
4825
4838
|
const state = controller.getState();
|
|
4826
|
-
const { brush, foreground, background, mixer, mixerLoad } = state.paint;
|
|
4839
|
+
const { brush, foreground, background, mixer, mixerLoad, retouch, cloneSource } = state.paint;
|
|
4840
|
+
const tool = state.activeTool;
|
|
4827
4841
|
const attempt = (fn) => {
|
|
4828
4842
|
try {
|
|
4829
4843
|
setError(null);
|
|
@@ -4833,12 +4847,12 @@ var BrushOptionsBar = ({ controller, className }) => {
|
|
|
4833
4847
|
}
|
|
4834
4848
|
};
|
|
4835
4849
|
return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: `flex flex-col gap-2 text-xs text-slate-200 ${className ?? ""}`, "data-testid": "brush-options", children: [
|
|
4836
|
-
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "flex gap-1", role: "toolbar", "aria-label": "Paint tools", children: import_image_editor8.PAINT_TOOLS.map((t) => /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
4850
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "flex flex-wrap gap-1", role: "toolbar", "aria-label": "Paint tools", children: import_image_editor8.PAINT_TOOLS.map((t) => /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
4837
4851
|
"button",
|
|
4838
4852
|
{
|
|
4839
4853
|
type: "button",
|
|
4840
4854
|
"aria-pressed": state.activeTool === t.id,
|
|
4841
|
-
title: `${t.label} (${t.shortcut})
|
|
4855
|
+
title: t.shortcut ? `${t.label} (${t.shortcut})` : t.label,
|
|
4842
4856
|
className: chip(state.activeTool === t.id),
|
|
4843
4857
|
onClick: () => controller.setTool(t.id),
|
|
4844
4858
|
children: t.label
|
|
@@ -4940,6 +4954,41 @@ var BrushOptionsBar = ({ controller, className }) => {
|
|
|
4940
4954
|
] })
|
|
4941
4955
|
] })
|
|
4942
4956
|
] }),
|
|
4957
|
+
(0, import_image_editor8.isRetouchPaintTool)(tool) && /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex flex-col gap-2 border-t border-slate-800 pt-2", role: "group", "aria-label": "Retouch options", "data-testid": "retouch-options", children: [
|
|
4958
|
+
(tool === "clone" || tool === "heal") && /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
4959
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "text-slate-400", "data-testid": "clone-source", children: (0, import_image_editor8.cloneSourceLabel)(controller) }),
|
|
4960
|
+
cloneSource && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("button", { type: "button", title: "Forget the source point", className: chip(false), onClick: () => controller.setCloneSource(null), children: "Clear source" })
|
|
4961
|
+
] }),
|
|
4962
|
+
import_image_editor8.RETOUCH_CHOICES.filter((c) => c.tools.includes(tool)).map((choice) => /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex flex-wrap items-center gap-1", role: "group", "aria-label": choice.label, children: [
|
|
4963
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "text-slate-400", children: choice.label }),
|
|
4964
|
+
choice.options.map((o) => /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
4965
|
+
"button",
|
|
4966
|
+
{
|
|
4967
|
+
type: "button",
|
|
4968
|
+
"aria-pressed": retouch[choice.id] === o.id,
|
|
4969
|
+
title: o.title,
|
|
4970
|
+
className: chip(retouch[choice.id] === o.id),
|
|
4971
|
+
onClick: () => (0, import_image_editor8.setRetouchChoice)(controller, choice.id, o.id),
|
|
4972
|
+
children: o.label
|
|
4973
|
+
},
|
|
4974
|
+
o.id
|
|
4975
|
+
))
|
|
4976
|
+
] }, choice.id)),
|
|
4977
|
+
import_image_editor8.RETOUCH_OPTION_CONTROLS.filter((c) => c.tools.includes(tool)).map((spec) => /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(ControlSlider, { spec, value: retouch[spec.id], onChange: (v) => controller.setPaintOptions({ retouch: { [spec.id]: v } }) }, spec.id)),
|
|
4978
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "flex flex-wrap gap-3 text-slate-300", children: import_image_editor8.RETOUCH_TOGGLES.filter((t) => t.tools.includes(tool)).map((t) => /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("label", { className: "flex items-center gap-1.5", children: [
|
|
4979
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
4980
|
+
"input",
|
|
4981
|
+
{
|
|
4982
|
+
type: "checkbox",
|
|
4983
|
+
"aria-label": t.label,
|
|
4984
|
+
checked: retouch[t.id],
|
|
4985
|
+
onChange: (e) => controller.setPaintOptions({ retouch: { [t.id]: e.target.checked } }),
|
|
4986
|
+
className: "accent-indigo-500"
|
|
4987
|
+
}
|
|
4988
|
+
),
|
|
4989
|
+
t.label
|
|
4990
|
+
] }, t.id)) })
|
|
4991
|
+
] }),
|
|
4943
4992
|
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex flex-wrap gap-3 text-slate-300", role: "group", "aria-label": "Pressure", children: [
|
|
4944
4993
|
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("label", { className: "flex items-center gap-1.5", children: [
|
|
4945
4994
|
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
@@ -5371,8 +5420,215 @@ var FreeTransformOptionsBar = ({ tool, className }) => {
|
|
|
5371
5420
|
] });
|
|
5372
5421
|
};
|
|
5373
5422
|
|
|
5374
|
-
// src/image-editor/
|
|
5423
|
+
// src/image-editor/ShapeOptionsBar.tsx
|
|
5424
|
+
var import_react44 = require("react");
|
|
5425
|
+
var import_image_editor12 = require("@pixerate/editor/image-editor");
|
|
5375
5426
|
var import_jsx_runtime27 = require("react/jsx-runtime");
|
|
5427
|
+
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"}`;
|
|
5428
|
+
var ShapeOptionsBar = ({ controller, options, onChange, className }) => {
|
|
5429
|
+
const [, setTick] = (0, import_react44.useState)(0);
|
|
5430
|
+
(0, import_react44.useEffect)(() => controller.subscribe(() => setTick((n) => n + 1)), [controller]);
|
|
5431
|
+
const [error, setError] = (0, import_react44.useState)(null);
|
|
5432
|
+
const active = controller.getActiveLayer();
|
|
5433
|
+
const shapeId = active?.type === "shape" ? active.id : null;
|
|
5434
|
+
const set = (change) => {
|
|
5435
|
+
onChange({ ...options, ...change });
|
|
5436
|
+
if (!shapeId) return;
|
|
5437
|
+
try {
|
|
5438
|
+
setError(null);
|
|
5439
|
+
(0, import_image_editor12.applyShapeOptions)(controller, shapeId, change);
|
|
5440
|
+
} catch (e) {
|
|
5441
|
+
setError(e instanceof Error ? e.message : String(e));
|
|
5442
|
+
}
|
|
5443
|
+
};
|
|
5444
|
+
const num = (v, min, max) => Math.max(min, Math.min(max, Number(v) || min));
|
|
5445
|
+
return /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: `flex flex-col gap-2 text-xs text-slate-200 ${className ?? ""}`, "data-testid": "shape-options", children: [
|
|
5446
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: "flex flex-wrap gap-1", role: "toolbar", "aria-label": "Shape kind", children: import_image_editor12.LIVE_SHAPE_KINDS.map((k) => /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("button", { type: "button", "aria-pressed": options.kind === k, className: chip3(options.kind === k), onClick: () => onChange({ ...options, kind: k }), children: import_image_editor12.SHAPE_KIND_LABELS[k] }, k)) }),
|
|
5447
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "flex flex-wrap items-center gap-3", children: [
|
|
5448
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("label", { className: "flex items-center gap-1", children: [
|
|
5449
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("input", { type: "checkbox", "aria-label": "Fill", checked: options.fill !== null, onChange: (e) => set({ fill: e.target.checked ? "#4f46e5" : null }) }),
|
|
5450
|
+
"Fill",
|
|
5451
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
5452
|
+
"input",
|
|
5453
|
+
{
|
|
5454
|
+
type: "color",
|
|
5455
|
+
"aria-label": "Fill colour",
|
|
5456
|
+
disabled: options.fill === null,
|
|
5457
|
+
value: options.fill ?? "#4f46e5",
|
|
5458
|
+
onChange: (e) => set({ fill: e.target.value }),
|
|
5459
|
+
className: "h-6 w-8 rounded border border-slate-700 bg-transparent"
|
|
5460
|
+
}
|
|
5461
|
+
)
|
|
5462
|
+
] }),
|
|
5463
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("label", { className: "flex items-center gap-1", children: [
|
|
5464
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("input", { type: "checkbox", "aria-label": "Stroke", checked: options.stroke !== null, onChange: (e) => set({ stroke: e.target.checked ? "#000000" : null }) }),
|
|
5465
|
+
"Stroke",
|
|
5466
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
5467
|
+
"input",
|
|
5468
|
+
{
|
|
5469
|
+
type: "color",
|
|
5470
|
+
"aria-label": "Stroke colour",
|
|
5471
|
+
disabled: options.stroke === null,
|
|
5472
|
+
value: options.stroke ?? "#000000",
|
|
5473
|
+
onChange: (e) => set({ stroke: e.target.value }),
|
|
5474
|
+
className: "h-6 w-8 rounded border border-slate-700 bg-transparent"
|
|
5475
|
+
}
|
|
5476
|
+
)
|
|
5477
|
+
] }),
|
|
5478
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("label", { className: "flex items-center gap-1", children: [
|
|
5479
|
+
"Width",
|
|
5480
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
5481
|
+
"input",
|
|
5482
|
+
{
|
|
5483
|
+
type: "number",
|
|
5484
|
+
"aria-label": "Stroke width",
|
|
5485
|
+
min: 0,
|
|
5486
|
+
max: 200,
|
|
5487
|
+
value: options.strokeWidth,
|
|
5488
|
+
onChange: (e) => set({ strokeWidth: num(e.target.value, 0, 200) }),
|
|
5489
|
+
className: "w-14 rounded border border-slate-700 bg-slate-950 px-1 py-0.5"
|
|
5490
|
+
}
|
|
5491
|
+
)
|
|
5492
|
+
] })
|
|
5493
|
+
] }),
|
|
5494
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "flex flex-wrap items-center gap-3", children: [
|
|
5495
|
+
options.kind === "rect" && /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("label", { className: "flex items-center gap-1", children: [
|
|
5496
|
+
"Radius",
|
|
5497
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("input", { type: "number", "aria-label": "Corner radius", min: 0, max: 1e3, value: options.radius, onChange: (e) => set({ radius: num(e.target.value, 0, 1e3) }), className: "w-14 rounded border border-slate-700 bg-slate-950 px-1 py-0.5" })
|
|
5498
|
+
] }),
|
|
5499
|
+
options.kind === "polygon" && /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("label", { className: "flex items-center gap-1", children: [
|
|
5500
|
+
"Sides",
|
|
5501
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("input", { type: "number", "aria-label": "Sides", min: 3, max: 100, value: options.sides, onChange: (e) => set({ sides: num(e.target.value, 3, 100) }), className: "w-14 rounded border border-slate-700 bg-slate-950 px-1 py-0.5" })
|
|
5502
|
+
] }),
|
|
5503
|
+
options.kind === "star" && /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(import_jsx_runtime27.Fragment, { children: [
|
|
5504
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("label", { className: "flex items-center gap-1", children: [
|
|
5505
|
+
"Points",
|
|
5506
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("input", { type: "number", "aria-label": "Points", min: 3, max: 100, value: options.points, onChange: (e) => set({ points: num(e.target.value, 3, 100) }), className: "w-14 rounded border border-slate-700 bg-slate-950 px-1 py-0.5" })
|
|
5507
|
+
] }),
|
|
5508
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("label", { className: "flex items-center gap-1", children: [
|
|
5509
|
+
"Inner",
|
|
5510
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
5511
|
+
"input",
|
|
5512
|
+
{
|
|
5513
|
+
type: "range",
|
|
5514
|
+
"aria-label": "Inner radius",
|
|
5515
|
+
min: 0.05,
|
|
5516
|
+
max: 1,
|
|
5517
|
+
step: 0.05,
|
|
5518
|
+
value: options.innerRatio,
|
|
5519
|
+
onChange: (e) => set({ innerRatio: Number(e.target.value) }),
|
|
5520
|
+
className: "accent-indigo-500"
|
|
5521
|
+
}
|
|
5522
|
+
)
|
|
5523
|
+
] })
|
|
5524
|
+
] }),
|
|
5525
|
+
options.kind === "line" && /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(import_jsx_runtime27.Fragment, { children: [
|
|
5526
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("label", { className: "flex items-center gap-1", children: [
|
|
5527
|
+
"Weight",
|
|
5528
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("input", { type: "number", "aria-label": "Line weight", min: 1, max: 200, value: options.weight, onChange: (e) => set({ weight: num(e.target.value, 1, 200) }), className: "w-14 rounded border border-slate-700 bg-slate-950 px-1 py-0.5" })
|
|
5529
|
+
] }),
|
|
5530
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("label", { className: "flex items-center gap-1", children: [
|
|
5531
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("input", { type: "checkbox", "aria-label": "Arrowhead", checked: options.arrow, onChange: (e) => set({ arrow: e.target.checked }) }),
|
|
5532
|
+
"Arrowhead"
|
|
5533
|
+
] })
|
|
5534
|
+
] })
|
|
5535
|
+
] }),
|
|
5536
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.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." }),
|
|
5537
|
+
error && /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("p", { role: "alert", className: "text-rose-400", children: error })
|
|
5538
|
+
] });
|
|
5539
|
+
};
|
|
5540
|
+
|
|
5541
|
+
// src/image-editor/TypeOptionsBar.tsx
|
|
5542
|
+
var import_react45 = require("react");
|
|
5543
|
+
var import_image_editor13 = require("@pixerate/editor/image-editor");
|
|
5544
|
+
var import_jsx_runtime28 = require("react/jsx-runtime");
|
|
5545
|
+
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"}`;
|
|
5546
|
+
var ALIGN_LABELS = { left: "Left", center: "Centre", right: "Right", justify: "Justify" };
|
|
5547
|
+
var TypeOptionsBar = ({ controller, options, onChange, session, className }) => {
|
|
5548
|
+
const [, setTick] = (0, import_react45.useState)(0);
|
|
5549
|
+
(0, import_react45.useEffect)(() => controller.subscribe(() => setTick((n) => n + 1)), [controller]);
|
|
5550
|
+
(0, import_react45.useEffect)(() => session?.subscribe(() => setTick((n) => n + 1)), [session]);
|
|
5551
|
+
const [error, setError] = (0, import_react45.useState)(null);
|
|
5552
|
+
const active = controller.getActiveLayer();
|
|
5553
|
+
const typeId = !session && active?.type === "type" ? active.id : null;
|
|
5554
|
+
const here = session?.alive ? session.styleHere() : {};
|
|
5555
|
+
const shown = {
|
|
5556
|
+
...options,
|
|
5557
|
+
...here.fontFamily ? { fontFamily: here.fontFamily } : {},
|
|
5558
|
+
...here.fontSize ? { fontSize: here.fontSize } : {},
|
|
5559
|
+
...here.fontWeight ? { fontWeight: here.fontWeight } : {},
|
|
5560
|
+
...session?.alive ? { italic: Boolean(here.italic), color: here.color ?? options.color } : {}
|
|
5561
|
+
};
|
|
5562
|
+
const fonts = controller.listFonts();
|
|
5563
|
+
const missing = active?.type === "type" ? active.missingFonts ?? [] : [];
|
|
5564
|
+
const style = (change) => {
|
|
5565
|
+
onChange({ ...options, ...change });
|
|
5566
|
+
const s = {};
|
|
5567
|
+
for (const k of ["fontFamily", "fontSize", "fontWeight", "italic", "color"]) if (k in change) s[k] = change[k];
|
|
5568
|
+
const p = change.align ? { align: change.align } : null;
|
|
5569
|
+
try {
|
|
5570
|
+
setError(null);
|
|
5571
|
+
if (session?.alive) {
|
|
5572
|
+
if (Object.keys(s).length) session.setStyle(s);
|
|
5573
|
+
if (p) session.setParagraph(p);
|
|
5574
|
+
if (session.error) setError(session.error);
|
|
5575
|
+
} else if (typeId) {
|
|
5576
|
+
if (Object.keys(s).length) controller.setTextStyle(typeId, s);
|
|
5577
|
+
if (p) controller.setParagraphStyle(typeId, p);
|
|
5578
|
+
}
|
|
5579
|
+
} catch (e) {
|
|
5580
|
+
setError(e instanceof Error ? e.message : String(e));
|
|
5581
|
+
}
|
|
5582
|
+
};
|
|
5583
|
+
return /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: `flex flex-col gap-2 text-xs text-slate-200 ${className ?? ""}`, "data-testid": "type-options", children: [
|
|
5584
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: "flex flex-wrap items-center gap-2", children: [
|
|
5585
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("label", { className: "flex items-center gap-1", children: [
|
|
5586
|
+
"Font",
|
|
5587
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
5588
|
+
"input",
|
|
5589
|
+
{
|
|
5590
|
+
list: "pixerate-type-fonts",
|
|
5591
|
+
"aria-label": "Font family",
|
|
5592
|
+
value: shown.fontFamily,
|
|
5593
|
+
onChange: (e) => e.target.value.trim() && style({ fontFamily: e.target.value }),
|
|
5594
|
+
className: "w-32 rounded border border-slate-700 bg-slate-950 px-1 py-0.5"
|
|
5595
|
+
}
|
|
5596
|
+
),
|
|
5597
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)("datalist", { id: "pixerate-type-fonts", children: fonts.map((f) => /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("option", { value: f }, f)) })
|
|
5598
|
+
] }),
|
|
5599
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("label", { className: "flex items-center gap-1", children: [
|
|
5600
|
+
"Size",
|
|
5601
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
5602
|
+
"input",
|
|
5603
|
+
{
|
|
5604
|
+
type: "number",
|
|
5605
|
+
"aria-label": "Font size",
|
|
5606
|
+
min: 1,
|
|
5607
|
+
max: 2e3,
|
|
5608
|
+
value: Math.round(shown.fontSize * 10) / 10,
|
|
5609
|
+
onChange: (e) => Number(e.target.value) > 0 && style({ fontSize: Number(e.target.value) }),
|
|
5610
|
+
className: "w-16 rounded border border-slate-700 bg-slate-950 px-1 py-0.5"
|
|
5611
|
+
}
|
|
5612
|
+
)
|
|
5613
|
+
] }),
|
|
5614
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)("button", { type: "button", "aria-pressed": shown.fontWeight >= 600, className: `${chip4(shown.fontWeight >= 600)} font-bold`, onClick: () => style({ fontWeight: shown.fontWeight >= 600 ? 400 : 700 }), children: "B" }),
|
|
5615
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)("button", { type: "button", "aria-pressed": shown.italic, className: `${chip4(shown.italic)} italic`, onClick: () => style({ italic: !shown.italic }), children: "I" }),
|
|
5616
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)("input", { type: "color", "aria-label": "Text colour", value: shown.color, onChange: (e) => style({ color: e.target.value }), className: "h-6 w-8 rounded border border-slate-700 bg-transparent" })
|
|
5617
|
+
] }),
|
|
5618
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { className: "flex gap-1", role: "toolbar", "aria-label": "Alignment", children: import_image_editor13.TEXT_ALIGNS.map((a) => /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("button", { type: "button", "aria-pressed": options.align === a, className: chip4(options.align === a), onClick: () => style({ align: a }), children: ALIGN_LABELS[a] }, a)) }),
|
|
5619
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.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." }),
|
|
5620
|
+
missing.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("p", { role: "status", className: "text-amber-400", "data-testid": "type-missing-fonts", children: [
|
|
5621
|
+
"Missing ",
|
|
5622
|
+
missing.length === 1 ? "font" : "fonts",
|
|
5623
|
+
": ",
|
|
5624
|
+
missing.join(", ")
|
|
5625
|
+
] }),
|
|
5626
|
+
error && /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("p", { role: "alert", className: "text-rose-400", children: error })
|
|
5627
|
+
] });
|
|
5628
|
+
};
|
|
5629
|
+
|
|
5630
|
+
// src/image-editor/ImageEditor.tsx
|
|
5631
|
+
var import_jsx_runtime29 = require("react/jsx-runtime");
|
|
5376
5632
|
var ImageEditor = ({
|
|
5377
5633
|
editor: externalEditor,
|
|
5378
5634
|
src,
|
|
@@ -5387,47 +5643,65 @@ var ImageEditor = ({
|
|
|
5387
5643
|
const internalEditor = useImageEditor({ image: src });
|
|
5388
5644
|
const editor = externalEditor || internalEditor;
|
|
5389
5645
|
const { state, controller } = editor;
|
|
5390
|
-
const legacyProcess = (0,
|
|
5391
|
-
const canvasRef = (0,
|
|
5392
|
-
const containerRef = (0,
|
|
5393
|
-
const [activeTab, setActiveTab] = (0,
|
|
5394
|
-
const [activeCropRatio, setActiveCropRatio] = (0,
|
|
5395
|
-
const [selectionOptions, setSelectionOptions] = (0,
|
|
5396
|
-
const selectionOptionsRef = (0,
|
|
5646
|
+
const legacyProcess = (0, import_image_editor14.normalizeProcessVersion)(state.adjustments.process) < import_image_editor14.LATEST_PROCESS_VERSION;
|
|
5647
|
+
const canvasRef = (0, import_react46.useRef)(null);
|
|
5648
|
+
const containerRef = (0, import_react46.useRef)(null);
|
|
5649
|
+
const [activeTab, setActiveTab] = (0, import_react46.useState)("crop");
|
|
5650
|
+
const [activeCropRatio, setActiveCropRatio] = (0, import_react46.useState)(null);
|
|
5651
|
+
const [selectionOptions, setSelectionOptions] = (0, import_react46.useState)(import_image_editor14.DEFAULT_SELECTION_TOOL_OPTIONS);
|
|
5652
|
+
const selectionOptionsRef = (0, import_react46.useRef)(selectionOptions);
|
|
5397
5653
|
selectionOptionsRef.current = selectionOptions;
|
|
5398
|
-
const selectionGestureRef = (0,
|
|
5654
|
+
const selectionGestureRef = (0, import_react46.useRef)(null);
|
|
5399
5655
|
if (!selectionGestureRef.current || selectionGestureRef.current.controller !== controller) {
|
|
5400
|
-
selectionGestureRef.current = new
|
|
5656
|
+
selectionGestureRef.current = new import_image_editor14.SelectionGesture(controller, () => selectionOptionsRef.current);
|
|
5401
5657
|
}
|
|
5402
|
-
const selectionDraftRef = (0,
|
|
5403
|
-
const [selectionError, setSelectionError] = (0,
|
|
5404
|
-
const paintGestureRef = (0,
|
|
5405
|
-
const paintControllerRef = (0,
|
|
5658
|
+
const selectionDraftRef = (0, import_react46.useRef)(null);
|
|
5659
|
+
const [selectionError, setSelectionError] = (0, import_react46.useState)(null);
|
|
5660
|
+
const paintGestureRef = (0, import_react46.useRef)(null);
|
|
5661
|
+
const paintControllerRef = (0, import_react46.useRef)(controller);
|
|
5406
5662
|
if (!paintGestureRef.current || paintControllerRef.current !== controller) {
|
|
5407
|
-
paintGestureRef.current = new
|
|
5663
|
+
paintGestureRef.current = new import_image_editor14.PaintGesture(controller);
|
|
5408
5664
|
paintControllerRef.current = controller;
|
|
5409
5665
|
}
|
|
5410
|
-
const brushCursorRef = (0,
|
|
5411
|
-
const [paintError, setPaintError] = (0,
|
|
5412
|
-
const transformToolRef = (0,
|
|
5413
|
-
const transformControllerRef = (0,
|
|
5666
|
+
const brushCursorRef = (0, import_react46.useRef)(null);
|
|
5667
|
+
const [paintError, setPaintError] = (0, import_react46.useState)(null);
|
|
5668
|
+
const transformToolRef = (0, import_react46.useRef)(null);
|
|
5669
|
+
const transformControllerRef = (0, import_react46.useRef)(controller);
|
|
5414
5670
|
if (!transformToolRef.current || transformControllerRef.current !== controller) {
|
|
5415
5671
|
transformToolRef.current?.cancel();
|
|
5416
|
-
transformToolRef.current = new
|
|
5672
|
+
transformToolRef.current = new import_image_editor14.FreeTransformTool(controller, {
|
|
5417
5673
|
schedule: (run) => typeof requestAnimationFrame !== "undefined" ? requestAnimationFrame(run) : run()
|
|
5418
5674
|
});
|
|
5419
5675
|
transformControllerRef.current = controller;
|
|
5420
5676
|
}
|
|
5421
5677
|
const transformTool = transformToolRef.current;
|
|
5422
|
-
const [, setTransformTick] = (0,
|
|
5423
|
-
const [transformCursor, setTransformCursor] = (0,
|
|
5424
|
-
const [
|
|
5425
|
-
const
|
|
5426
|
-
|
|
5427
|
-
const [
|
|
5428
|
-
const
|
|
5429
|
-
|
|
5430
|
-
const
|
|
5678
|
+
const [, setTransformTick] = (0, import_react46.useState)(0);
|
|
5679
|
+
const [transformCursor, setTransformCursor] = (0, import_react46.useState)("default");
|
|
5680
|
+
const [shapeOptions, setShapeOptions] = (0, import_react46.useState)(import_image_editor14.DEFAULT_SHAPE_TOOL_OPTIONS);
|
|
5681
|
+
const shapeOptionsRef = (0, import_react46.useRef)(shapeOptions);
|
|
5682
|
+
shapeOptionsRef.current = shapeOptions;
|
|
5683
|
+
const [typeOptions, setTypeOptions] = (0, import_react46.useState)(import_image_editor14.DEFAULT_TYPE_TOOL_OPTIONS);
|
|
5684
|
+
const typeOptionsRef = (0, import_react46.useRef)(typeOptions);
|
|
5685
|
+
typeOptionsRef.current = typeOptions;
|
|
5686
|
+
const shapeGestureRef = (0, import_react46.useRef)(null);
|
|
5687
|
+
const typeToolRef = (0, import_react46.useRef)(null);
|
|
5688
|
+
const shapeTypeControllerRef = (0, import_react46.useRef)(controller);
|
|
5689
|
+
if (!shapeGestureRef.current || !typeToolRef.current || shapeTypeControllerRef.current !== controller) {
|
|
5690
|
+
typeToolRef.current?.finish();
|
|
5691
|
+
shapeGestureRef.current = new import_image_editor14.ShapeDrawGesture(controller, () => shapeOptionsRef.current);
|
|
5692
|
+
typeToolRef.current = new import_image_editor14.TypeToolGesture(controller, () => typeOptionsRef.current);
|
|
5693
|
+
shapeTypeControllerRef.current = controller;
|
|
5694
|
+
}
|
|
5695
|
+
const typeInputRef = (0, import_react46.useRef)(null);
|
|
5696
|
+
const [typeSession, setTypeSession] = (0, import_react46.useState)(typeToolRef.current.session);
|
|
5697
|
+
const [shapeTypeError, setShapeTypeError] = (0, import_react46.useState)(null);
|
|
5698
|
+
const [inpaintPrompt, setInpaintPrompt] = (0, import_react46.useState)("");
|
|
5699
|
+
const [inpaintMaskMode, setInpaintMaskMode] = (0, import_react46.useState)("annotations");
|
|
5700
|
+
const [isRemovingBg, setIsRemovingBg] = (0, import_react46.useState)(false);
|
|
5701
|
+
const [isInpainting, setIsInpainting] = (0, import_react46.useState)(false);
|
|
5702
|
+
const [aiError, setAiError] = (0, import_react46.useState)(null);
|
|
5703
|
+
const [aiSuccess, setAiSuccess] = (0, import_react46.useState)(null);
|
|
5704
|
+
const [aiTarget, setAiTarget] = (0, import_react46.useState)("auto");
|
|
5431
5705
|
const aiOptions = aiTarget === "auto" ? {} : { target: aiTarget };
|
|
5432
5706
|
const effectiveOnInpaint = onInpaint || aiHooks?.onInpaint;
|
|
5433
5707
|
const effectiveOnRemoveBg = onRemoveBackground || aiHooks?.onRemoveBackground;
|
|
@@ -5490,18 +5764,18 @@ var ImageEditor = ({
|
|
|
5490
5764
|
setIsInpainting(false);
|
|
5491
5765
|
}
|
|
5492
5766
|
};
|
|
5493
|
-
const [activeColor, setActiveColor] = (0,
|
|
5494
|
-
const [strokeWidth, setStrokeWidth] = (0,
|
|
5495
|
-
const [fontSize, setFontSize] = (0,
|
|
5496
|
-
const [textInput, setTextInput] = (0,
|
|
5497
|
-
const draftAnnotationRef = (0,
|
|
5498
|
-
const draftCropRef = (0,
|
|
5499
|
-
const cropDragInfoRef = (0,
|
|
5500
|
-
const annotationDragInfoRef = (0,
|
|
5501
|
-
const isDrawingRef = (0,
|
|
5502
|
-
const currentPathRef = (0,
|
|
5503
|
-
const dragStartPointRef = (0,
|
|
5504
|
-
const renderCanvas = (0,
|
|
5767
|
+
const [activeColor, setActiveColor] = (0, import_react46.useState)("#ef4444");
|
|
5768
|
+
const [strokeWidth, setStrokeWidth] = (0, import_react46.useState)(3);
|
|
5769
|
+
const [fontSize, setFontSize] = (0, import_react46.useState)(24);
|
|
5770
|
+
const [textInput, setTextInput] = (0, import_react46.useState)("");
|
|
5771
|
+
const draftAnnotationRef = (0, import_react46.useRef)(null);
|
|
5772
|
+
const draftCropRef = (0, import_react46.useRef)(null);
|
|
5773
|
+
const cropDragInfoRef = (0, import_react46.useRef)(null);
|
|
5774
|
+
const annotationDragInfoRef = (0, import_react46.useRef)(null);
|
|
5775
|
+
const isDrawingRef = (0, import_react46.useRef)(false);
|
|
5776
|
+
const currentPathRef = (0, import_react46.useRef)([]);
|
|
5777
|
+
const dragStartPointRef = (0, import_react46.useRef)(null);
|
|
5778
|
+
const renderCanvas = (0, import_react46.useCallback)(
|
|
5505
5779
|
async (draftAnnotation, draftCrop) => {
|
|
5506
5780
|
const canvas = canvasRef.current;
|
|
5507
5781
|
const container = containerRef.current;
|
|
@@ -5518,12 +5792,49 @@ var ImageEditor = ({
|
|
|
5518
5792
|
draftCrop: draftCrop !== void 0 ? draftCrop : draftCropRef.current,
|
|
5519
5793
|
draftSelectionPath: selectionDraftRef.current,
|
|
5520
5794
|
brushCursor: activeTab === "paint" && brushCursorRef.current && controller.getState().activeTool !== "move" && !transformTool.active ? { ...brushCursorRef.current, diameter: controller.getState().paint.brush.size } : null,
|
|
5521
|
-
freeTransform: transformTool.overlay()
|
|
5795
|
+
freeTransform: transformTool.overlay(),
|
|
5796
|
+
textEdit: typeToolRef.current?.session?.alive ? typeToolRef.current.session.overlay() : null
|
|
5522
5797
|
});
|
|
5523
5798
|
},
|
|
5524
5799
|
[controller, activeTab, transformTool]
|
|
5525
5800
|
);
|
|
5526
|
-
(0,
|
|
5801
|
+
(0, import_react46.useEffect)(() => typeSession?.subscribe(() => void renderCanvas()), [typeSession, renderCanvas]);
|
|
5802
|
+
(0, import_react46.useEffect)(() => {
|
|
5803
|
+
if (activeTab === "annotate" && state.activeTool === "type") return;
|
|
5804
|
+
if (typeToolRef.current?.session) {
|
|
5805
|
+
typeToolRef.current.finish();
|
|
5806
|
+
setTypeSession(null);
|
|
5807
|
+
void renderCanvas();
|
|
5808
|
+
}
|
|
5809
|
+
}, [activeTab, state.activeTool, renderCanvas]);
|
|
5810
|
+
const finishTyping = () => {
|
|
5811
|
+
typeToolRef.current?.finish();
|
|
5812
|
+
setTypeSession(null);
|
|
5813
|
+
void renderCanvas();
|
|
5814
|
+
};
|
|
5815
|
+
const handleTypeKeyDown = (e) => {
|
|
5816
|
+
const session = typeToolRef.current?.session;
|
|
5817
|
+
if (!session || e.nativeEvent.isComposing) return;
|
|
5818
|
+
if (e.key === "Escape") {
|
|
5819
|
+
e.preventDefault();
|
|
5820
|
+
finishTyping();
|
|
5821
|
+
return;
|
|
5822
|
+
}
|
|
5823
|
+
if ((e.metaKey || e.ctrlKey) && ["z", "y", "c", "x", "v"].includes(e.key.toLowerCase())) return;
|
|
5824
|
+
if (session.handleKey(e)) {
|
|
5825
|
+
e.preventDefault();
|
|
5826
|
+
setShapeTypeError(session.error);
|
|
5827
|
+
}
|
|
5828
|
+
};
|
|
5829
|
+
const handleTypeInput = (e) => {
|
|
5830
|
+
const el = e.currentTarget;
|
|
5831
|
+
const session = typeToolRef.current?.session;
|
|
5832
|
+
if (session && el.value && !e.nativeEvent.isComposing) {
|
|
5833
|
+
session.insert(el.value);
|
|
5834
|
+
el.value = "";
|
|
5835
|
+
}
|
|
5836
|
+
};
|
|
5837
|
+
(0, import_react46.useEffect)(() => transformTool.subscribe(() => {
|
|
5527
5838
|
setTransformTick((n) => n + 1);
|
|
5528
5839
|
void renderCanvas();
|
|
5529
5840
|
}), [transformTool, renderCanvas]);
|
|
@@ -5534,8 +5845,8 @@ var ImageEditor = ({
|
|
|
5534
5845
|
const sy = rect.height > 0 ? canvas.height / rect.height : 1;
|
|
5535
5846
|
const s = controller.getState();
|
|
5536
5847
|
const cropping = activeTab === "crop";
|
|
5537
|
-
const projection = (0,
|
|
5538
|
-
const pt = (0,
|
|
5848
|
+
const projection = (0, import_image_editor14.getViewportProjection)(s, canvas.width, canvas.height, cropping);
|
|
5849
|
+
const pt = (0, import_image_editor14.canvasToImagePoint)({ x: (e.clientX - rect.left) * sx, y: (e.clientY - rect.top) * sy }, s, canvas.width, canvas.height, cropping);
|
|
5539
5850
|
transformTool.setView(projection.scale);
|
|
5540
5851
|
return { pt, tolerance: 6 / (projection.scale || 1) };
|
|
5541
5852
|
};
|
|
@@ -5566,7 +5877,7 @@ var ImageEditor = ({
|
|
|
5566
5877
|
transformTool.up();
|
|
5567
5878
|
return true;
|
|
5568
5879
|
};
|
|
5569
|
-
(0,
|
|
5880
|
+
(0, import_react46.useEffect)(() => {
|
|
5570
5881
|
if (typeof window === "undefined") return;
|
|
5571
5882
|
const onKey = (e) => {
|
|
5572
5883
|
if (transformTool.key(e)) e.preventDefault();
|
|
@@ -5574,7 +5885,7 @@ var ImageEditor = ({
|
|
|
5574
5885
|
window.addEventListener("keydown", onKey);
|
|
5575
5886
|
return () => window.removeEventListener("keydown", onKey);
|
|
5576
5887
|
}, [transformTool]);
|
|
5577
|
-
(0,
|
|
5888
|
+
(0, import_react46.useEffect)(() => {
|
|
5578
5889
|
const raf = typeof requestAnimationFrame !== "undefined" ? requestAnimationFrame : (cb) => setTimeout(cb, 0);
|
|
5579
5890
|
const caf = typeof cancelAnimationFrame !== "undefined" ? cancelAnimationFrame : (id) => clearTimeout(id);
|
|
5580
5891
|
const animId = raf(() => {
|
|
@@ -5582,12 +5893,12 @@ var ImageEditor = ({
|
|
|
5582
5893
|
});
|
|
5583
5894
|
return () => caf(animId);
|
|
5584
5895
|
}, [renderCanvas, state]);
|
|
5585
|
-
(0,
|
|
5896
|
+
(0, import_react46.useEffect)(() => {
|
|
5586
5897
|
if (activeTab === "crop" && editor.state.activeTool !== "crop") {
|
|
5587
5898
|
editor.setTool("crop");
|
|
5588
5899
|
}
|
|
5589
5900
|
}, [activeTab, editor]);
|
|
5590
|
-
(0,
|
|
5901
|
+
(0, import_react46.useEffect)(() => {
|
|
5591
5902
|
const container = containerRef.current;
|
|
5592
5903
|
if (!container) return;
|
|
5593
5904
|
if (typeof ResizeObserver !== "undefined") {
|
|
@@ -5623,8 +5934,8 @@ var ImageEditor = ({
|
|
|
5623
5934
|
const sy = rect.height > 0 ? canvas.height / rect.height : 1;
|
|
5624
5935
|
const s = controller.getState();
|
|
5625
5936
|
return list.map((ev) => ({
|
|
5626
|
-
...(0,
|
|
5627
|
-
pressure: (0,
|
|
5937
|
+
...(0, import_image_editor14.canvasToImagePoint)({ x: (ev.clientX - rect.left) * sx, y: (ev.clientY - rect.top) * sy }, s, canvas.width, canvas.height, false),
|
|
5938
|
+
pressure: (0, import_image_editor14.pointerPressure)(ev)
|
|
5628
5939
|
}));
|
|
5629
5940
|
};
|
|
5630
5941
|
const handlePaintPointerDown = (e) => {
|
|
@@ -5636,7 +5947,7 @@ var ImageEditor = ({
|
|
|
5636
5947
|
} catch {
|
|
5637
5948
|
}
|
|
5638
5949
|
const [first] = paintSamples(e);
|
|
5639
|
-
setPaintError(paintGestureRef.current.down(first));
|
|
5950
|
+
setPaintError(paintGestureRef.current.down({ ...first, altKey: e.altKey }));
|
|
5640
5951
|
};
|
|
5641
5952
|
const handlePaintPointerMove = (e) => {
|
|
5642
5953
|
if (handleTransformPointerMove(e)) return;
|
|
@@ -5655,10 +5966,10 @@ var ImageEditor = ({
|
|
|
5655
5966
|
if (g.error) setPaintError(g.error);
|
|
5656
5967
|
}
|
|
5657
5968
|
};
|
|
5658
|
-
(0,
|
|
5969
|
+
(0, import_react46.useEffect)(() => {
|
|
5659
5970
|
if (activeTab !== "paint" || typeof window === "undefined") return;
|
|
5660
5971
|
const onKey = (e) => {
|
|
5661
|
-
if ((0,
|
|
5972
|
+
if ((0, import_image_editor14.handlePaintShortcut)(controller, e)) e.preventDefault();
|
|
5662
5973
|
};
|
|
5663
5974
|
window.addEventListener("keydown", onKey);
|
|
5664
5975
|
return () => window.removeEventListener("keydown", onKey);
|
|
@@ -5669,7 +5980,7 @@ var ImageEditor = ({
|
|
|
5669
5980
|
const canvasPt = getCanvasEventPoint(e);
|
|
5670
5981
|
if (activeTab === "select") {
|
|
5671
5982
|
const gesture = selectionGestureRef.current;
|
|
5672
|
-
const imgPt = (0,
|
|
5983
|
+
const imgPt = (0, import_image_editor14.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false);
|
|
5673
5984
|
void gesture.begin(imgPt, e).then(() => setSelectionError(gesture.error));
|
|
5674
5985
|
return;
|
|
5675
5986
|
}
|
|
@@ -5680,8 +5991,8 @@ var ImageEditor = ({
|
|
|
5680
5991
|
width: state.imageDimensions.width,
|
|
5681
5992
|
height: state.imageDimensions.height
|
|
5682
5993
|
};
|
|
5683
|
-
const handle = (0,
|
|
5684
|
-
const startImgPt = (0,
|
|
5994
|
+
const handle = (0, import_image_editor14.hitTestCrop)(canvasPt, state, canvas.width, canvas.height, 14, activeCrop);
|
|
5995
|
+
const startImgPt = (0, import_image_editor14.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, true);
|
|
5685
5996
|
if (handle) {
|
|
5686
5997
|
cropDragInfoRef.current = {
|
|
5687
5998
|
handle,
|
|
@@ -5699,13 +6010,24 @@ var ImageEditor = ({
|
|
|
5699
6010
|
}
|
|
5700
6011
|
return;
|
|
5701
6012
|
}
|
|
6013
|
+
if (activeTab === "annotate" && (state.activeTool === "shape" || state.activeTool === "type")) {
|
|
6014
|
+
const imgPt = (0, import_image_editor14.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false);
|
|
6015
|
+
setShapeTypeError(null);
|
|
6016
|
+
if (state.activeTool === "shape") shapeGestureRef.current.down(imgPt);
|
|
6017
|
+
else {
|
|
6018
|
+
typeToolRef.current.down(imgPt, { shift: e.shiftKey });
|
|
6019
|
+
setTypeSession(typeToolRef.current.session);
|
|
6020
|
+
void renderCanvas();
|
|
6021
|
+
}
|
|
6022
|
+
return;
|
|
6023
|
+
}
|
|
5702
6024
|
if (activeTab === "annotate") {
|
|
5703
|
-
const imgPt = (0,
|
|
6025
|
+
const imgPt = (0, import_image_editor14.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false);
|
|
5704
6026
|
dragStartPointRef.current = imgPt;
|
|
5705
6027
|
if (state.activeTool === "select") {
|
|
5706
6028
|
for (let i = state.annotations.length - 1; i >= 0; i--) {
|
|
5707
6029
|
const ann = state.annotations[i];
|
|
5708
|
-
if ((0,
|
|
6030
|
+
if ((0, import_image_editor14.hitTestAnnotation)(imgPt, ann)) {
|
|
5709
6031
|
editor.selectAnnotation(ann.id);
|
|
5710
6032
|
annotationDragInfoRef.current = {
|
|
5711
6033
|
annId: ann.id,
|
|
@@ -5741,7 +6063,7 @@ var ImageEditor = ({
|
|
|
5741
6063
|
const canvasPt = getCanvasEventPoint(e);
|
|
5742
6064
|
if (activeTab === "select") {
|
|
5743
6065
|
const gesture = selectionGestureRef.current;
|
|
5744
|
-
if (gesture.active && gesture.move((0,
|
|
6066
|
+
if (gesture.active && gesture.move((0, import_image_editor14.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false))) {
|
|
5745
6067
|
selectionDraftRef.current = gesture.draftPath;
|
|
5746
6068
|
renderCanvas();
|
|
5747
6069
|
}
|
|
@@ -5750,7 +6072,7 @@ var ImageEditor = ({
|
|
|
5750
6072
|
if (activeTab === "crop") {
|
|
5751
6073
|
const drag = cropDragInfoRef.current;
|
|
5752
6074
|
if (drag) {
|
|
5753
|
-
const currentImgPt = (0,
|
|
6075
|
+
const currentImgPt = (0, import_image_editor14.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, true);
|
|
5754
6076
|
let newCrop;
|
|
5755
6077
|
if (drag.handle === "new") {
|
|
5756
6078
|
const minX = Math.max(0, Math.min(drag.startImgPt.x, currentImgPt.x));
|
|
@@ -5764,7 +6086,7 @@ var ImageEditor = ({
|
|
|
5764
6086
|
height: Math.round(Math.max(20, maxY - minY))
|
|
5765
6087
|
};
|
|
5766
6088
|
} else {
|
|
5767
|
-
newCrop = (0,
|
|
6089
|
+
newCrop = (0, import_image_editor14.calculateCropDrag)(
|
|
5768
6090
|
drag.startCrop,
|
|
5769
6091
|
drag.handle,
|
|
5770
6092
|
drag.startImgPt,
|
|
@@ -5784,15 +6106,23 @@ var ImageEditor = ({
|
|
|
5784
6106
|
width: state.imageDimensions.width,
|
|
5785
6107
|
height: state.imageDimensions.height
|
|
5786
6108
|
};
|
|
5787
|
-
const handle = (0,
|
|
5788
|
-
canvas.style.cursor = (0,
|
|
6109
|
+
const handle = (0, import_image_editor14.hitTestCrop)(canvasPt, state, canvas.width, canvas.height, 14, activeCrop);
|
|
6110
|
+
canvas.style.cursor = (0, import_image_editor14.getCropCursor)(handle, state.transform);
|
|
6111
|
+
}
|
|
6112
|
+
return;
|
|
6113
|
+
}
|
|
6114
|
+
if (activeTab === "annotate" && state.activeTool === "shape") {
|
|
6115
|
+
const g = shapeGestureRef.current;
|
|
6116
|
+
if (g.active) {
|
|
6117
|
+
g.move((0, import_image_editor14.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false), { shift: e.shiftKey, alt: e.altKey });
|
|
6118
|
+
if (g.error) setShapeTypeError(g.error);
|
|
5789
6119
|
}
|
|
5790
6120
|
return;
|
|
5791
6121
|
}
|
|
5792
6122
|
if (activeTab === "annotate") {
|
|
5793
6123
|
if (annotationDragInfoRef.current) {
|
|
5794
6124
|
const drag = annotationDragInfoRef.current;
|
|
5795
|
-
const currentImgPt2 = (0,
|
|
6125
|
+
const currentImgPt2 = (0, import_image_editor14.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false);
|
|
5796
6126
|
const dx = currentImgPt2.x - drag.startImgPt.x;
|
|
5797
6127
|
const dy = currentImgPt2.y - drag.startImgPt.y;
|
|
5798
6128
|
editor.updateAnnotation(drag.annId, {
|
|
@@ -5804,10 +6134,10 @@ var ImageEditor = ({
|
|
|
5804
6134
|
const startPt = dragStartPointRef.current;
|
|
5805
6135
|
if (!startPt) {
|
|
5806
6136
|
if (state.activeTool === "select") {
|
|
5807
|
-
const imgPt = (0,
|
|
6137
|
+
const imgPt = (0, import_image_editor14.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false);
|
|
5808
6138
|
let hovered = false;
|
|
5809
6139
|
for (let i = state.annotations.length - 1; i >= 0; i--) {
|
|
5810
|
-
if ((0,
|
|
6140
|
+
if ((0, import_image_editor14.hitTestAnnotation)(imgPt, state.annotations[i])) {
|
|
5811
6141
|
hovered = true;
|
|
5812
6142
|
break;
|
|
5813
6143
|
}
|
|
@@ -5818,7 +6148,7 @@ var ImageEditor = ({
|
|
|
5818
6148
|
}
|
|
5819
6149
|
return;
|
|
5820
6150
|
}
|
|
5821
|
-
const currentImgPt = (0,
|
|
6151
|
+
const currentImgPt = (0, import_image_editor14.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false);
|
|
5822
6152
|
if (state.activeTool === "pen" && isDrawingRef.current) {
|
|
5823
6153
|
currentPathRef.current.push(currentImgPt);
|
|
5824
6154
|
const draft = {
|
|
@@ -5898,7 +6228,7 @@ var ImageEditor = ({
|
|
|
5898
6228
|
if (activeTab === "select") {
|
|
5899
6229
|
const gesture = selectionGestureRef.current;
|
|
5900
6230
|
if (gesture.active) {
|
|
5901
|
-
gesture.end((0,
|
|
6231
|
+
gesture.end((0, import_image_editor14.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false), e);
|
|
5902
6232
|
selectionDraftRef.current = null;
|
|
5903
6233
|
renderCanvas();
|
|
5904
6234
|
}
|
|
@@ -5915,6 +6245,19 @@ var ImageEditor = ({
|
|
|
5915
6245
|
}
|
|
5916
6246
|
return;
|
|
5917
6247
|
}
|
|
6248
|
+
if (activeTab === "annotate" && state.activeTool === "shape") {
|
|
6249
|
+
shapeGestureRef.current.up();
|
|
6250
|
+
return;
|
|
6251
|
+
}
|
|
6252
|
+
if (activeTab === "annotate" && state.activeTool === "type") {
|
|
6253
|
+
const tool = typeToolRef.current;
|
|
6254
|
+
tool.up((0, import_image_editor14.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false));
|
|
6255
|
+
setTypeSession(tool.session);
|
|
6256
|
+
if (tool.error) setShapeTypeError(tool.error);
|
|
6257
|
+
void renderCanvas();
|
|
6258
|
+
if (tool.session) setTimeout(() => typeInputRef.current?.focus(), 0);
|
|
6259
|
+
return;
|
|
6260
|
+
}
|
|
5918
6261
|
if (activeTab === "annotate") {
|
|
5919
6262
|
if (annotationDragInfoRef.current) {
|
|
5920
6263
|
annotationDragInfoRef.current = null;
|
|
@@ -5922,7 +6265,7 @@ var ImageEditor = ({
|
|
|
5922
6265
|
}
|
|
5923
6266
|
const startPt = dragStartPointRef.current;
|
|
5924
6267
|
if (startPt) {
|
|
5925
|
-
const currentImgPt = (0,
|
|
6268
|
+
const currentImgPt = (0, import_image_editor14.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false);
|
|
5926
6269
|
if (state.activeTool === "pen" && isDrawingRef.current) {
|
|
5927
6270
|
if (currentPathRef.current.length > 1) {
|
|
5928
6271
|
editor.addAnnotation({
|
|
@@ -6018,15 +6361,15 @@ var ImageEditor = ({
|
|
|
6018
6361
|
link.click();
|
|
6019
6362
|
}
|
|
6020
6363
|
};
|
|
6021
|
-
return /* @__PURE__ */ (0,
|
|
6364
|
+
return /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(
|
|
6022
6365
|
"div",
|
|
6023
6366
|
{
|
|
6024
6367
|
className: `flex flex-col bg-slate-900 border border-slate-800 rounded-xl overflow-hidden shadow-2xl text-slate-100 ${className}`,
|
|
6025
6368
|
style,
|
|
6026
6369
|
children: [
|
|
6027
|
-
/* @__PURE__ */ (0,
|
|
6028
|
-
/* @__PURE__ */ (0,
|
|
6029
|
-
/* @__PURE__ */ (0,
|
|
6370
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.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: [
|
|
6371
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "flex items-center gap-1 bg-slate-900 p-1 rounded-lg border border-slate-800 text-xs", children: [
|
|
6372
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
6030
6373
|
"button",
|
|
6031
6374
|
{
|
|
6032
6375
|
type: "button",
|
|
@@ -6038,7 +6381,7 @@ var ImageEditor = ({
|
|
|
6038
6381
|
children: "Transform & Crop"
|
|
6039
6382
|
}
|
|
6040
6383
|
),
|
|
6041
|
-
/* @__PURE__ */ (0,
|
|
6384
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
6042
6385
|
"button",
|
|
6043
6386
|
{
|
|
6044
6387
|
type: "button",
|
|
@@ -6050,7 +6393,7 @@ var ImageEditor = ({
|
|
|
6050
6393
|
children: "Adjustments"
|
|
6051
6394
|
}
|
|
6052
6395
|
),
|
|
6053
|
-
/* @__PURE__ */ (0,
|
|
6396
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
6054
6397
|
"button",
|
|
6055
6398
|
{
|
|
6056
6399
|
type: "button",
|
|
@@ -6062,7 +6405,7 @@ var ImageEditor = ({
|
|
|
6062
6405
|
children: "Layers"
|
|
6063
6406
|
}
|
|
6064
6407
|
),
|
|
6065
|
-
/* @__PURE__ */ (0,
|
|
6408
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
6066
6409
|
"button",
|
|
6067
6410
|
{
|
|
6068
6411
|
type: "button",
|
|
@@ -6074,7 +6417,7 @@ var ImageEditor = ({
|
|
|
6074
6417
|
children: "Paint"
|
|
6075
6418
|
}
|
|
6076
6419
|
),
|
|
6077
|
-
/* @__PURE__ */ (0,
|
|
6420
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
6078
6421
|
"button",
|
|
6079
6422
|
{
|
|
6080
6423
|
type: "button",
|
|
@@ -6086,7 +6429,7 @@ var ImageEditor = ({
|
|
|
6086
6429
|
children: "Select & Mask"
|
|
6087
6430
|
}
|
|
6088
6431
|
),
|
|
6089
|
-
/* @__PURE__ */ (0,
|
|
6432
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
6090
6433
|
"button",
|
|
6091
6434
|
{
|
|
6092
6435
|
type: "button",
|
|
@@ -6098,7 +6441,7 @@ var ImageEditor = ({
|
|
|
6098
6441
|
children: "Annotations"
|
|
6099
6442
|
}
|
|
6100
6443
|
),
|
|
6101
|
-
/* @__PURE__ */ (0,
|
|
6444
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
6102
6445
|
"button",
|
|
6103
6446
|
{
|
|
6104
6447
|
type: "button",
|
|
@@ -6110,7 +6453,7 @@ var ImageEditor = ({
|
|
|
6110
6453
|
children: "Depth Mask"
|
|
6111
6454
|
}
|
|
6112
6455
|
),
|
|
6113
|
-
/* @__PURE__ */ (0,
|
|
6456
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(
|
|
6114
6457
|
"button",
|
|
6115
6458
|
{
|
|
6116
6459
|
type: "button",
|
|
@@ -6120,14 +6463,14 @@ var ImageEditor = ({
|
|
|
6120
6463
|
},
|
|
6121
6464
|
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"}`,
|
|
6122
6465
|
children: [
|
|
6123
|
-
/* @__PURE__ */ (0,
|
|
6466
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.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_runtime29.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" }) }),
|
|
6124
6467
|
"AI Tools"
|
|
6125
6468
|
]
|
|
6126
6469
|
}
|
|
6127
6470
|
)
|
|
6128
6471
|
] }),
|
|
6129
|
-
/* @__PURE__ */ (0,
|
|
6130
|
-
/* @__PURE__ */ (0,
|
|
6472
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "flex items-center gap-2 text-xs", children: [
|
|
6473
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
6131
6474
|
"button",
|
|
6132
6475
|
{
|
|
6133
6476
|
type: "button",
|
|
@@ -6138,7 +6481,7 @@ var ImageEditor = ({
|
|
|
6138
6481
|
children: "\u21A9"
|
|
6139
6482
|
}
|
|
6140
6483
|
),
|
|
6141
|
-
/* @__PURE__ */ (0,
|
|
6484
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
6142
6485
|
"button",
|
|
6143
6486
|
{
|
|
6144
6487
|
type: "button",
|
|
@@ -6149,7 +6492,7 @@ var ImageEditor = ({
|
|
|
6149
6492
|
children: "\u21AA"
|
|
6150
6493
|
}
|
|
6151
6494
|
),
|
|
6152
|
-
/* @__PURE__ */ (0,
|
|
6495
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
6153
6496
|
"button",
|
|
6154
6497
|
{
|
|
6155
6498
|
type: "button",
|
|
@@ -6158,8 +6501,8 @@ var ImageEditor = ({
|
|
|
6158
6501
|
children: "Reset"
|
|
6159
6502
|
}
|
|
6160
6503
|
),
|
|
6161
|
-
/* @__PURE__ */ (0,
|
|
6162
|
-
/* @__PURE__ */ (0,
|
|
6504
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: "h-4 w-px bg-slate-800 mx-1" }),
|
|
6505
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
6163
6506
|
"button",
|
|
6164
6507
|
{
|
|
6165
6508
|
type: "button",
|
|
@@ -6169,11 +6512,11 @@ var ImageEditor = ({
|
|
|
6169
6512
|
children: "-"
|
|
6170
6513
|
}
|
|
6171
6514
|
),
|
|
6172
|
-
/* @__PURE__ */ (0,
|
|
6515
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("span", { className: "font-mono text-slate-400 w-10 text-center", children: [
|
|
6173
6516
|
Math.round(state.zoom * 100),
|
|
6174
6517
|
"%"
|
|
6175
6518
|
] }),
|
|
6176
|
-
/* @__PURE__ */ (0,
|
|
6519
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
6177
6520
|
"button",
|
|
6178
6521
|
{
|
|
6179
6522
|
type: "button",
|
|
@@ -6183,8 +6526,8 @@ var ImageEditor = ({
|
|
|
6183
6526
|
children: "+"
|
|
6184
6527
|
}
|
|
6185
6528
|
),
|
|
6186
|
-
/* @__PURE__ */ (0,
|
|
6187
|
-
/* @__PURE__ */ (0,
|
|
6529
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: "h-4 w-px bg-slate-800 mx-1" }),
|
|
6530
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
6188
6531
|
"button",
|
|
6189
6532
|
{
|
|
6190
6533
|
type: "button",
|
|
@@ -6195,7 +6538,7 @@ var ImageEditor = ({
|
|
|
6195
6538
|
children: "Hold Compare"
|
|
6196
6539
|
}
|
|
6197
6540
|
),
|
|
6198
|
-
/* @__PURE__ */ (0,
|
|
6541
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
6199
6542
|
"button",
|
|
6200
6543
|
{
|
|
6201
6544
|
type: "button",
|
|
@@ -6206,38 +6549,59 @@ var ImageEditor = ({
|
|
|
6206
6549
|
)
|
|
6207
6550
|
] })
|
|
6208
6551
|
] }),
|
|
6209
|
-
transformTool.active && /* @__PURE__ */ (0,
|
|
6210
|
-
!transformTool.active && transformTool.error && /* @__PURE__ */ (0,
|
|
6211
|
-
/* @__PURE__ */ (0,
|
|
6212
|
-
/* @__PURE__ */ (0,
|
|
6552
|
+
transformTool.active && /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(FreeTransformOptionsBar, { tool: transformTool, className: "border-b border-slate-800 bg-slate-900/95 px-4 py-2" }),
|
|
6553
|
+
!transformTool.active && transformTool.error && /* @__PURE__ */ (0, import_jsx_runtime29.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 }),
|
|
6554
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "flex flex-col md:flex-row flex-1 min-h-[520px] md:h-[560px]", children: [
|
|
6555
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(
|
|
6213
6556
|
"div",
|
|
6214
6557
|
{
|
|
6215
6558
|
ref: containerRef,
|
|
6216
6559
|
className: "relative flex-1 h-[360px] md:h-full min-h-[320px] bg-slate-950 overflow-hidden select-none",
|
|
6217
|
-
children:
|
|
6218
|
-
|
|
6219
|
-
|
|
6220
|
-
|
|
6221
|
-
|
|
6222
|
-
|
|
6223
|
-
|
|
6224
|
-
|
|
6225
|
-
|
|
6226
|
-
|
|
6227
|
-
|
|
6228
|
-
|
|
6229
|
-
|
|
6230
|
-
|
|
6231
|
-
|
|
6232
|
-
|
|
6233
|
-
|
|
6560
|
+
children: [
|
|
6561
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
6562
|
+
"canvas",
|
|
6563
|
+
{
|
|
6564
|
+
ref: canvasRef,
|
|
6565
|
+
onMouseDown: handleMouseDown,
|
|
6566
|
+
onMouseMove: handleMouseMove,
|
|
6567
|
+
onMouseUp: handleMouseUp,
|
|
6568
|
+
onMouseLeave: handleMouseUp,
|
|
6569
|
+
onPointerDown: handlePaintPointerDown,
|
|
6570
|
+
onPointerMove: handlePaintPointerMove,
|
|
6571
|
+
onPointerUp: handlePaintPointerUp,
|
|
6572
|
+
onPointerCancel: () => paintGestureRef.current?.cancel(),
|
|
6573
|
+
"data-testid": "image-editor-canvas",
|
|
6574
|
+
style: transformTool.active ? { cursor: transformCursor } : void 0,
|
|
6575
|
+
className: `absolute inset-0 w-full h-full block ${transformTool.active ? "touch-none" : activeTab === "paint" ? "touch-none cursor-crosshair" : activeTab === "annotate" && state.activeTool === "type" ? "cursor-text" : activeTab === "annotate" && state.activeTool === "shape" ? "cursor-crosshair" : ""}`
|
|
6576
|
+
}
|
|
6577
|
+
),
|
|
6578
|
+
typeSession && /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
6579
|
+
"textarea",
|
|
6580
|
+
{
|
|
6581
|
+
ref: typeInputRef,
|
|
6582
|
+
"aria-label": "Edit text",
|
|
6583
|
+
"data-testid": "type-input",
|
|
6584
|
+
autoCapitalize: "off",
|
|
6585
|
+
autoCorrect: "off",
|
|
6586
|
+
spellCheck: false,
|
|
6587
|
+
onKeyDown: handleTypeKeyDown,
|
|
6588
|
+
onInput: handleTypeInput,
|
|
6589
|
+
onCompositionEnd: (e) => {
|
|
6590
|
+
const session = typeToolRef.current?.session;
|
|
6591
|
+
if (session && e.data) session.insert(e.data);
|
|
6592
|
+
e.currentTarget.value = "";
|
|
6593
|
+
},
|
|
6594
|
+
className: "absolute left-0 top-0 h-px w-px opacity-0"
|
|
6595
|
+
}
|
|
6596
|
+
)
|
|
6597
|
+
]
|
|
6234
6598
|
}
|
|
6235
6599
|
),
|
|
6236
|
-
/* @__PURE__ */ (0,
|
|
6237
|
-
activeTab === "crop" && /* @__PURE__ */ (0,
|
|
6238
|
-
/* @__PURE__ */ (0,
|
|
6239
|
-
/* @__PURE__ */ (0,
|
|
6240
|
-
/* @__PURE__ */ (0,
|
|
6600
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.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: [
|
|
6601
|
+
activeTab === "crop" && /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "flex flex-col gap-4 text-xs", children: [
|
|
6602
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Aspect Ratio Presets" }),
|
|
6603
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "grid grid-cols-3 gap-2", children: [
|
|
6604
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
6241
6605
|
"button",
|
|
6242
6606
|
{
|
|
6243
6607
|
type: "button",
|
|
@@ -6249,7 +6613,7 @@ var ImageEditor = ({
|
|
|
6249
6613
|
children: "Freeform"
|
|
6250
6614
|
}
|
|
6251
6615
|
),
|
|
6252
|
-
/* @__PURE__ */ (0,
|
|
6616
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
6253
6617
|
"button",
|
|
6254
6618
|
{
|
|
6255
6619
|
type: "button",
|
|
@@ -6261,7 +6625,7 @@ var ImageEditor = ({
|
|
|
6261
6625
|
children: "1:1 Square"
|
|
6262
6626
|
}
|
|
6263
6627
|
),
|
|
6264
|
-
/* @__PURE__ */ (0,
|
|
6628
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
6265
6629
|
"button",
|
|
6266
6630
|
{
|
|
6267
6631
|
type: "button",
|
|
@@ -6273,7 +6637,7 @@ var ImageEditor = ({
|
|
|
6273
6637
|
children: "4:3 Standard"
|
|
6274
6638
|
}
|
|
6275
6639
|
),
|
|
6276
|
-
/* @__PURE__ */ (0,
|
|
6640
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
6277
6641
|
"button",
|
|
6278
6642
|
{
|
|
6279
6643
|
type: "button",
|
|
@@ -6285,7 +6649,7 @@ var ImageEditor = ({
|
|
|
6285
6649
|
children: "16:9 Wide"
|
|
6286
6650
|
}
|
|
6287
6651
|
),
|
|
6288
|
-
/* @__PURE__ */ (0,
|
|
6652
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
6289
6653
|
"button",
|
|
6290
6654
|
{
|
|
6291
6655
|
type: "button",
|
|
@@ -6297,7 +6661,7 @@ var ImageEditor = ({
|
|
|
6297
6661
|
children: "3:2 Photo"
|
|
6298
6662
|
}
|
|
6299
6663
|
),
|
|
6300
|
-
/* @__PURE__ */ (0,
|
|
6664
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
6301
6665
|
"button",
|
|
6302
6666
|
{
|
|
6303
6667
|
type: "button",
|
|
@@ -6310,10 +6674,10 @@ var ImageEditor = ({
|
|
|
6310
6674
|
}
|
|
6311
6675
|
)
|
|
6312
6676
|
] }),
|
|
6313
|
-
/* @__PURE__ */ (0,
|
|
6314
|
-
/* @__PURE__ */ (0,
|
|
6315
|
-
/* @__PURE__ */ (0,
|
|
6316
|
-
/* @__PURE__ */ (0,
|
|
6677
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: "h-px bg-slate-800 my-1" }),
|
|
6678
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Orientation & Flips" }),
|
|
6679
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "grid grid-cols-2 gap-2", children: [
|
|
6680
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
6317
6681
|
"button",
|
|
6318
6682
|
{
|
|
6319
6683
|
type: "button",
|
|
@@ -6322,7 +6686,7 @@ var ImageEditor = ({
|
|
|
6322
6686
|
children: "Rotate -90\xB0"
|
|
6323
6687
|
}
|
|
6324
6688
|
),
|
|
6325
|
-
/* @__PURE__ */ (0,
|
|
6689
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
6326
6690
|
"button",
|
|
6327
6691
|
{
|
|
6328
6692
|
type: "button",
|
|
@@ -6331,7 +6695,7 @@ var ImageEditor = ({
|
|
|
6331
6695
|
children: "Rotate +90\xB0"
|
|
6332
6696
|
}
|
|
6333
6697
|
),
|
|
6334
|
-
/* @__PURE__ */ (0,
|
|
6698
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
6335
6699
|
"button",
|
|
6336
6700
|
{
|
|
6337
6701
|
type: "button",
|
|
@@ -6340,7 +6704,7 @@ var ImageEditor = ({
|
|
|
6340
6704
|
children: "Flip Horizontal"
|
|
6341
6705
|
}
|
|
6342
6706
|
),
|
|
6343
|
-
/* @__PURE__ */ (0,
|
|
6707
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
6344
6708
|
"button",
|
|
6345
6709
|
{
|
|
6346
6710
|
type: "button",
|
|
@@ -6351,10 +6715,10 @@ var ImageEditor = ({
|
|
|
6351
6715
|
)
|
|
6352
6716
|
] })
|
|
6353
6717
|
] }),
|
|
6354
|
-
activeTab === "adjust" && /* @__PURE__ */ (0,
|
|
6355
|
-
/* @__PURE__ */ (0,
|
|
6356
|
-
/* @__PURE__ */ (0,
|
|
6357
|
-
/* @__PURE__ */ (0,
|
|
6718
|
+
activeTab === "adjust" && /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "flex flex-col gap-3 text-xs", children: [
|
|
6719
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "flex items-center justify-between", children: [
|
|
6720
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Color Adjustments" }),
|
|
6721
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
6358
6722
|
"button",
|
|
6359
6723
|
{
|
|
6360
6724
|
type: "button",
|
|
@@ -6364,25 +6728,25 @@ var ImageEditor = ({
|
|
|
6364
6728
|
}
|
|
6365
6729
|
)
|
|
6366
6730
|
] }),
|
|
6367
|
-
/* @__PURE__ */ (0,
|
|
6368
|
-
|
|
6369
|
-
/* @__PURE__ */ (0,
|
|
6731
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)(Histogram, { histogram: editor.histogram }),
|
|
6732
|
+
import_image_editor14.IMAGE_ADJUSTMENT_CONTROLS.map((spec) => /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(import_react46.default.Fragment, { children: [
|
|
6733
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
6370
6734
|
ControlSlider,
|
|
6371
6735
|
{
|
|
6372
6736
|
spec,
|
|
6373
|
-
value: (0,
|
|
6737
|
+
value: (0, import_image_editor14.readAdjustmentControls)(state.adjustments)[spec.id],
|
|
6374
6738
|
disabled: spec.requiresProcess !== void 0 && legacyProcess,
|
|
6375
6739
|
onChange: (v) => editor.setAdjustments({ [spec.id]: v })
|
|
6376
6740
|
}
|
|
6377
6741
|
),
|
|
6378
|
-
spec.id === "tint" && legacyProcess && /* @__PURE__ */ (0,
|
|
6742
|
+
spec.id === "tint" && legacyProcess && /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(
|
|
6379
6743
|
"div",
|
|
6380
6744
|
{
|
|
6381
6745
|
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",
|
|
6382
6746
|
"data-testid": "image-editor-process-notice",
|
|
6383
6747
|
children: [
|
|
6384
|
-
/* @__PURE__ */ (0,
|
|
6385
|
-
/* @__PURE__ */ (0,
|
|
6748
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { children: "Legacy rendering (process 1). Tint needs the current process." }),
|
|
6749
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
6386
6750
|
"button",
|
|
6387
6751
|
{
|
|
6388
6752
|
type: "button",
|
|
@@ -6395,7 +6759,7 @@ var ImageEditor = ({
|
|
|
6395
6759
|
}
|
|
6396
6760
|
)
|
|
6397
6761
|
] }, spec.id)),
|
|
6398
|
-
/* @__PURE__ */ (0,
|
|
6762
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: "border-t border-slate-700/60 pt-3", children: /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
6399
6763
|
AdjustmentLayersPanel,
|
|
6400
6764
|
{
|
|
6401
6765
|
controller,
|
|
@@ -6404,9 +6768,9 @@ var ImageEditor = ({
|
|
|
6404
6768
|
}
|
|
6405
6769
|
) })
|
|
6406
6770
|
] }),
|
|
6407
|
-
activeTab === "layers" && /* @__PURE__ */ (0,
|
|
6408
|
-
/* @__PURE__ */ (0,
|
|
6409
|
-
/* @__PURE__ */ (0,
|
|
6771
|
+
activeTab === "layers" && /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "flex flex-col gap-3 text-xs", children: [
|
|
6772
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Layers" }),
|
|
6773
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
6410
6774
|
"button",
|
|
6411
6775
|
{
|
|
6412
6776
|
type: "button",
|
|
@@ -6417,12 +6781,12 @@ var ImageEditor = ({
|
|
|
6417
6781
|
children: "Free Transform"
|
|
6418
6782
|
}
|
|
6419
6783
|
),
|
|
6420
|
-
/* @__PURE__ */ (0,
|
|
6784
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)(LayersPanel, { controller })
|
|
6421
6785
|
] }),
|
|
6422
|
-
activeTab === "paint" && /* @__PURE__ */ (0,
|
|
6423
|
-
/* @__PURE__ */ (0,
|
|
6424
|
-
/* @__PURE__ */ (0,
|
|
6425
|
-
/* @__PURE__ */ (0,
|
|
6786
|
+
activeTab === "paint" && /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "flex flex-col gap-3 text-xs", children: [
|
|
6787
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Paint" }),
|
|
6788
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)(BrushOptionsBar, { controller }),
|
|
6789
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
6426
6790
|
"button",
|
|
6427
6791
|
{
|
|
6428
6792
|
type: "button",
|
|
@@ -6433,12 +6797,29 @@ var ImageEditor = ({
|
|
|
6433
6797
|
children: "Free Transform"
|
|
6434
6798
|
}
|
|
6435
6799
|
),
|
|
6436
|
-
paintError && /* @__PURE__ */ (0,
|
|
6437
|
-
/* @__PURE__ */ (0,
|
|
6800
|
+
paintError && /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("p", { role: "alert", className: "text-rose-400", "data-testid": "paint-error", children: paintError }),
|
|
6801
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: "border-t border-slate-700/60 pt-3", children: /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(LayersPanel, { controller }) })
|
|
6438
6802
|
] }),
|
|
6439
|
-
activeTab === "annotate" && /* @__PURE__ */ (0,
|
|
6440
|
-
/* @__PURE__ */ (0,
|
|
6441
|
-
/* @__PURE__ */ (0,
|
|
6803
|
+
activeTab === "annotate" && /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "flex flex-col gap-3 text-xs", children: [
|
|
6804
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Shape & Type Layers" }),
|
|
6805
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: "grid grid-cols-2 gap-1.5", children: ["shape", "type"].map((t) => /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
6806
|
+
"button",
|
|
6807
|
+
{
|
|
6808
|
+
type: "button",
|
|
6809
|
+
"aria-pressed": state.activeTool === t,
|
|
6810
|
+
onClick: () => editor.setTool(t),
|
|
6811
|
+
className: `py-1.5 px-2 rounded-lg font-medium border transition-colors ${state.activeTool === t ? "bg-indigo-600 border-indigo-500 text-white" : "bg-slate-800 border-slate-700 text-slate-300 hover:bg-slate-700"}`,
|
|
6812
|
+
children: t === "shape" ? "Shape" : "Type"
|
|
6813
|
+
},
|
|
6814
|
+
t
|
|
6815
|
+
)) }),
|
|
6816
|
+
state.activeTool === "shape" && /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(ShapeOptionsBar, { controller, options: shapeOptions, onChange: setShapeOptions }),
|
|
6817
|
+
state.activeTool === "type" && /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(TypeOptionsBar, { controller, options: typeOptions, onChange: setTypeOptions, session: typeSession }),
|
|
6818
|
+
state.activeTool === "type" && typeSession && /* @__PURE__ */ (0, import_jsx_runtime29.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" }),
|
|
6819
|
+
shapeTypeError && /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("p", { role: "alert", className: "text-rose-400", "data-testid": "shape-type-error", children: shapeTypeError }),
|
|
6820
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: "h-px bg-slate-800 my-1" }),
|
|
6821
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Draw & Annotate" }),
|
|
6822
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: "grid grid-cols-3 gap-1.5", children: ["pen", "rect", "circle", "arrow", "line"].map((t) => /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
6442
6823
|
"button",
|
|
6443
6824
|
{
|
|
6444
6825
|
type: "button",
|
|
@@ -6448,9 +6829,9 @@ var ImageEditor = ({
|
|
|
6448
6829
|
},
|
|
6449
6830
|
t
|
|
6450
6831
|
)) }),
|
|
6451
|
-
/* @__PURE__ */ (0,
|
|
6452
|
-
/* @__PURE__ */ (0,
|
|
6453
|
-
/* @__PURE__ */ (0,
|
|
6832
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "flex items-center gap-2 mt-2", children: [
|
|
6833
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)("label", { className: "text-slate-400", children: "Color:" }),
|
|
6834
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
6454
6835
|
"input",
|
|
6455
6836
|
{
|
|
6456
6837
|
type: "color",
|
|
@@ -6459,15 +6840,15 @@ var ImageEditor = ({
|
|
|
6459
6840
|
className: "w-8 h-8 rounded border border-slate-700 cursor-pointer bg-transparent"
|
|
6460
6841
|
}
|
|
6461
6842
|
),
|
|
6462
|
-
/* @__PURE__ */ (0,
|
|
6463
|
-
/* @__PURE__ */ (0,
|
|
6464
|
-
/* @__PURE__ */ (0,
|
|
6465
|
-
/* @__PURE__ */ (0,
|
|
6843
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "flex-1 ml-2", children: [
|
|
6844
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "flex justify-between text-slate-400 mb-0.5", children: [
|
|
6845
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { children: "Width:" }),
|
|
6846
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("span", { className: "font-mono", children: [
|
|
6466
6847
|
strokeWidth,
|
|
6467
6848
|
"px"
|
|
6468
6849
|
] })
|
|
6469
6850
|
] }),
|
|
6470
|
-
/* @__PURE__ */ (0,
|
|
6851
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
6471
6852
|
"input",
|
|
6472
6853
|
{
|
|
6473
6854
|
type: "range",
|
|
@@ -6480,10 +6861,10 @@ var ImageEditor = ({
|
|
|
6480
6861
|
)
|
|
6481
6862
|
] })
|
|
6482
6863
|
] }),
|
|
6483
|
-
/* @__PURE__ */ (0,
|
|
6484
|
-
/* @__PURE__ */ (0,
|
|
6485
|
-
/* @__PURE__ */ (0,
|
|
6486
|
-
/* @__PURE__ */ (0,
|
|
6864
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: "h-px bg-slate-800 my-1" }),
|
|
6865
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Add Text" }),
|
|
6866
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "flex gap-2", children: [
|
|
6867
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
6487
6868
|
"input",
|
|
6488
6869
|
{
|
|
6489
6870
|
type: "text",
|
|
@@ -6494,7 +6875,7 @@ var ImageEditor = ({
|
|
|
6494
6875
|
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"
|
|
6495
6876
|
}
|
|
6496
6877
|
),
|
|
6497
|
-
/* @__PURE__ */ (0,
|
|
6878
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
6498
6879
|
"button",
|
|
6499
6880
|
{
|
|
6500
6881
|
type: "button",
|
|
@@ -6504,14 +6885,14 @@ var ImageEditor = ({
|
|
|
6504
6885
|
}
|
|
6505
6886
|
)
|
|
6506
6887
|
] }),
|
|
6507
|
-
/* @__PURE__ */ (0,
|
|
6508
|
-
/* @__PURE__ */ (0,
|
|
6509
|
-
/* @__PURE__ */ (0,
|
|
6888
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "flex items-center justify-between text-slate-400", children: [
|
|
6889
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { children: "Font Size:" }),
|
|
6890
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("span", { className: "font-mono", children: [
|
|
6510
6891
|
fontSize,
|
|
6511
6892
|
"px"
|
|
6512
6893
|
] })
|
|
6513
6894
|
] }),
|
|
6514
|
-
/* @__PURE__ */ (0,
|
|
6895
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
6515
6896
|
"input",
|
|
6516
6897
|
{
|
|
6517
6898
|
type: "range",
|
|
@@ -6522,14 +6903,14 @@ var ImageEditor = ({
|
|
|
6522
6903
|
className: "w-full accent-indigo-500"
|
|
6523
6904
|
}
|
|
6524
6905
|
),
|
|
6525
|
-
/* @__PURE__ */ (0,
|
|
6526
|
-
/* @__PURE__ */ (0,
|
|
6527
|
-
/* @__PURE__ */ (0,
|
|
6906
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: "h-px bg-slate-800 my-1" }),
|
|
6907
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "flex items-center justify-between", children: [
|
|
6908
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("span", { className: "text-slate-400", children: [
|
|
6528
6909
|
"Layers (",
|
|
6529
6910
|
state.annotations.length,
|
|
6530
6911
|
")"
|
|
6531
6912
|
] }),
|
|
6532
|
-
state.selectedAnnotationId && /* @__PURE__ */ (0,
|
|
6913
|
+
state.selectedAnnotationId && /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
6533
6914
|
"button",
|
|
6534
6915
|
{
|
|
6535
6916
|
type: "button",
|
|
@@ -6538,7 +6919,7 @@ var ImageEditor = ({
|
|
|
6538
6919
|
children: "Delete Selected"
|
|
6539
6920
|
}
|
|
6540
6921
|
),
|
|
6541
|
-
state.annotations.length > 0 && /* @__PURE__ */ (0,
|
|
6922
|
+
state.annotations.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
6542
6923
|
"button",
|
|
6543
6924
|
{
|
|
6544
6925
|
type: "button",
|
|
@@ -6549,10 +6930,10 @@ var ImageEditor = ({
|
|
|
6549
6930
|
)
|
|
6550
6931
|
] })
|
|
6551
6932
|
] }),
|
|
6552
|
-
activeTab === "depth" && /* @__PURE__ */ (0,
|
|
6553
|
-
/* @__PURE__ */ (0,
|
|
6554
|
-
/* @__PURE__ */ (0,
|
|
6555
|
-
/* @__PURE__ */ (0,
|
|
6933
|
+
activeTab === "depth" && /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "flex flex-col gap-3 text-xs", children: [
|
|
6934
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "flex items-center justify-between", children: [
|
|
6935
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Depth Masking" }),
|
|
6936
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
6556
6937
|
"button",
|
|
6557
6938
|
{
|
|
6558
6939
|
type: "button",
|
|
@@ -6562,8 +6943,8 @@ var ImageEditor = ({
|
|
|
6562
6943
|
}
|
|
6563
6944
|
)
|
|
6564
6945
|
] }),
|
|
6565
|
-
/* @__PURE__ */ (0,
|
|
6566
|
-
/* @__PURE__ */ (0,
|
|
6946
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("label", { className: "flex items-center gap-2 cursor-pointer text-slate-300", children: [
|
|
6947
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
6567
6948
|
"input",
|
|
6568
6949
|
{
|
|
6569
6950
|
type: "checkbox",
|
|
@@ -6572,12 +6953,12 @@ var ImageEditor = ({
|
|
|
6572
6953
|
className: "rounded accent-indigo-500"
|
|
6573
6954
|
}
|
|
6574
6955
|
),
|
|
6575
|
-
/* @__PURE__ */ (0,
|
|
6956
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { children: "Enable Depth / Alpha Mask" })
|
|
6576
6957
|
] }),
|
|
6577
|
-
state.depthMask.enabled && /* @__PURE__ */ (0,
|
|
6578
|
-
/* @__PURE__ */ (0,
|
|
6579
|
-
/* @__PURE__ */ (0,
|
|
6580
|
-
/* @__PURE__ */ (0,
|
|
6958
|
+
state.depthMask.enabled && /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(import_jsx_runtime29.Fragment, { children: [
|
|
6959
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { children: [
|
|
6960
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)("label", { className: "text-slate-400 block mb-1", children: "Mask Image URL:" }),
|
|
6961
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
6581
6962
|
"input",
|
|
6582
6963
|
{
|
|
6583
6964
|
type: "text",
|
|
@@ -6588,8 +6969,8 @@ var ImageEditor = ({
|
|
|
6588
6969
|
}
|
|
6589
6970
|
)
|
|
6590
6971
|
] }),
|
|
6591
|
-
/* @__PURE__ */ (0,
|
|
6592
|
-
/* @__PURE__ */ (0,
|
|
6972
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "flex gap-2", children: [
|
|
6973
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
6593
6974
|
"button",
|
|
6594
6975
|
{
|
|
6595
6976
|
type: "button",
|
|
@@ -6598,7 +6979,7 @@ var ImageEditor = ({
|
|
|
6598
6979
|
children: "Threshold Mode"
|
|
6599
6980
|
}
|
|
6600
6981
|
),
|
|
6601
|
-
/* @__PURE__ */ (0,
|
|
6982
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
6602
6983
|
"button",
|
|
6603
6984
|
{
|
|
6604
6985
|
type: "button",
|
|
@@ -6608,12 +6989,12 @@ var ImageEditor = ({
|
|
|
6608
6989
|
}
|
|
6609
6990
|
)
|
|
6610
6991
|
] }),
|
|
6611
|
-
/* @__PURE__ */ (0,
|
|
6612
|
-
/* @__PURE__ */ (0,
|
|
6613
|
-
/* @__PURE__ */ (0,
|
|
6614
|
-
/* @__PURE__ */ (0,
|
|
6992
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { children: [
|
|
6993
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "flex justify-between text-slate-400 mb-1", children: [
|
|
6994
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { children: "Depth Start (Lower):" }),
|
|
6995
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { className: "font-mono", children: state.depthMask.depthRange[0] })
|
|
6615
6996
|
] }),
|
|
6616
|
-
/* @__PURE__ */ (0,
|
|
6997
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
6617
6998
|
"input",
|
|
6618
6999
|
{
|
|
6619
7000
|
type: "range",
|
|
@@ -6627,12 +7008,12 @@ var ImageEditor = ({
|
|
|
6627
7008
|
}
|
|
6628
7009
|
)
|
|
6629
7010
|
] }),
|
|
6630
|
-
/* @__PURE__ */ (0,
|
|
6631
|
-
/* @__PURE__ */ (0,
|
|
6632
|
-
/* @__PURE__ */ (0,
|
|
6633
|
-
/* @__PURE__ */ (0,
|
|
7011
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { children: [
|
|
7012
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "flex justify-between text-slate-400 mb-1", children: [
|
|
7013
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { children: "Depth Stop (Upper):" }),
|
|
7014
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { className: "font-mono", children: state.depthMask.depthRange[1] })
|
|
6634
7015
|
] }),
|
|
6635
|
-
/* @__PURE__ */ (0,
|
|
7016
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
6636
7017
|
"input",
|
|
6637
7018
|
{
|
|
6638
7019
|
type: "range",
|
|
@@ -6646,12 +7027,12 @@ var ImageEditor = ({
|
|
|
6646
7027
|
}
|
|
6647
7028
|
)
|
|
6648
7029
|
] }),
|
|
6649
|
-
/* @__PURE__ */ (0,
|
|
6650
|
-
/* @__PURE__ */ (0,
|
|
6651
|
-
/* @__PURE__ */ (0,
|
|
6652
|
-
/* @__PURE__ */ (0,
|
|
7030
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { children: [
|
|
7031
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "flex justify-between text-slate-400 mb-1", children: [
|
|
7032
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { children: "Softness:" }),
|
|
7033
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { className: "font-mono", children: state.depthMask.softness })
|
|
6653
7034
|
] }),
|
|
6654
|
-
/* @__PURE__ */ (0,
|
|
7035
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
6655
7036
|
"input",
|
|
6656
7037
|
{
|
|
6657
7038
|
type: "range",
|
|
@@ -6663,8 +7044,8 @@ var ImageEditor = ({
|
|
|
6663
7044
|
}
|
|
6664
7045
|
)
|
|
6665
7046
|
] }),
|
|
6666
|
-
/* @__PURE__ */ (0,
|
|
6667
|
-
/* @__PURE__ */ (0,
|
|
7047
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("label", { className: "flex items-center gap-2 cursor-pointer text-slate-300 mt-1", children: [
|
|
7048
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
6668
7049
|
"input",
|
|
6669
7050
|
{
|
|
6670
7051
|
type: "checkbox",
|
|
@@ -6673,12 +7054,12 @@ var ImageEditor = ({
|
|
|
6673
7054
|
className: "rounded accent-indigo-500"
|
|
6674
7055
|
}
|
|
6675
7056
|
),
|
|
6676
|
-
/* @__PURE__ */ (0,
|
|
7057
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { children: "Invert Mask" })
|
|
6677
7058
|
] })
|
|
6678
7059
|
] })
|
|
6679
7060
|
] }),
|
|
6680
|
-
activeTab === "select" && /* @__PURE__ */ (0,
|
|
6681
|
-
/* @__PURE__ */ (0,
|
|
7061
|
+
activeTab === "select" && /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "flex flex-col gap-4 text-xs", children: [
|
|
7062
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
6682
7063
|
SelectionOptionsBar,
|
|
6683
7064
|
{
|
|
6684
7065
|
controller,
|
|
@@ -6688,9 +7069,9 @@ var ImageEditor = ({
|
|
|
6688
7069
|
quickMask: Boolean(state.quickMask)
|
|
6689
7070
|
}
|
|
6690
7071
|
),
|
|
6691
|
-
selectionError && /* @__PURE__ */ (0,
|
|
6692
|
-
/* @__PURE__ */ (0,
|
|
6693
|
-
/* @__PURE__ */ (0,
|
|
7072
|
+
selectionError && /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("p", { role: "alert", className: "text-rose-400", children: selectionError }),
|
|
7073
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "flex gap-1", children: [
|
|
7074
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
6694
7075
|
"button",
|
|
6695
7076
|
{
|
|
6696
7077
|
type: "button",
|
|
@@ -6701,7 +7082,7 @@ var ImageEditor = ({
|
|
|
6701
7082
|
children: "Transform Selection"
|
|
6702
7083
|
}
|
|
6703
7084
|
),
|
|
6704
|
-
/* @__PURE__ */ (0,
|
|
7085
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
6705
7086
|
"button",
|
|
6706
7087
|
{
|
|
6707
7088
|
type: "button",
|
|
@@ -6713,12 +7094,12 @@ var ImageEditor = ({
|
|
|
6713
7094
|
}
|
|
6714
7095
|
)
|
|
6715
7096
|
] }),
|
|
6716
|
-
/* @__PURE__ */ (0,
|
|
7097
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)(RefineEdgePanel, { controller, selection: state.selection ?? null, layers: state.adjustments.layers })
|
|
6717
7098
|
] }),
|
|
6718
|
-
activeTab === "ai" && /* @__PURE__ */ (0,
|
|
6719
|
-
/* @__PURE__ */ (0,
|
|
6720
|
-
/* @__PURE__ */ (0,
|
|
6721
|
-
/* @__PURE__ */ (0,
|
|
7099
|
+
activeTab === "ai" && /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "flex flex-col gap-4 text-xs", children: [
|
|
7100
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("label", { className: "flex items-center justify-between gap-2 text-slate-300", children: [
|
|
7101
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { children: "Results go to" }),
|
|
7102
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(
|
|
6722
7103
|
"select",
|
|
6723
7104
|
{
|
|
6724
7105
|
"aria-label": "AI result target",
|
|
@@ -6726,54 +7107,54 @@ var ImageEditor = ({
|
|
|
6726
7107
|
onChange: (e) => setAiTarget(e.target.value),
|
|
6727
7108
|
className: "bg-slate-800 border border-slate-700 rounded px-1.5 py-1",
|
|
6728
7109
|
children: [
|
|
6729
|
-
/* @__PURE__ */ (0,
|
|
6730
|
-
/* @__PURE__ */ (0,
|
|
6731
|
-
/* @__PURE__ */ (0,
|
|
7110
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)("option", { value: "auto", children: controller.isMultiLayer ? "Auto (new layer)" : "Auto (replace image)" }),
|
|
7111
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)("option", { value: "new-layer", children: "New layer / mask" }),
|
|
7112
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)("option", { value: "replace", children: "Replace image" })
|
|
6732
7113
|
]
|
|
6733
7114
|
}
|
|
6734
7115
|
)
|
|
6735
7116
|
] }),
|
|
6736
|
-
/* @__PURE__ */ (0,
|
|
6737
|
-
/* @__PURE__ */ (0,
|
|
6738
|
-
/* @__PURE__ */ (0,
|
|
6739
|
-
/* @__PURE__ */ (0,
|
|
7117
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "p-3 rounded-lg bg-slate-950/60 border border-slate-800 flex flex-col gap-2.5", children: [
|
|
7118
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "flex items-center justify-between", children: [
|
|
7119
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px] flex items-center gap-1.5", children: [
|
|
7120
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.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_runtime29.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" }) }),
|
|
6740
7121
|
"Background Removal"
|
|
6741
7122
|
] }),
|
|
6742
|
-
isRemovingBg && /* @__PURE__ */ (0,
|
|
7123
|
+
isRemovingBg && /* @__PURE__ */ (0, import_jsx_runtime29.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..." })
|
|
6743
7124
|
] }),
|
|
6744
|
-
/* @__PURE__ */ (0,
|
|
6745
|
-
/* @__PURE__ */ (0,
|
|
7125
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)("p", { className: "text-slate-400 text-[11px] leading-relaxed", children: "Isolate foreground subject with AI alpha transparency segmentation." }),
|
|
7126
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
6746
7127
|
"button",
|
|
6747
7128
|
{
|
|
6748
7129
|
type: "button",
|
|
6749
7130
|
onClick: handleRemoveBackground,
|
|
6750
7131
|
disabled: isRemovingBg || isInpainting,
|
|
6751
7132
|
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",
|
|
6752
|
-
children: isRemovingBg ? /* @__PURE__ */ (0,
|
|
6753
|
-
/* @__PURE__ */ (0,
|
|
7133
|
+
children: isRemovingBg ? /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(import_jsx_runtime29.Fragment, { children: [
|
|
7134
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: "w-3.5 h-3.5 border-2 border-white/30 border-t-white rounded-full animate-spin" }),
|
|
6754
7135
|
"Removing Background..."
|
|
6755
|
-
] }) : /* @__PURE__ */ (0,
|
|
6756
|
-
/* @__PURE__ */ (0,
|
|
7136
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(import_jsx_runtime29.Fragment, { children: [
|
|
7137
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.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_runtime29.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" }) }),
|
|
6757
7138
|
"Remove Background"
|
|
6758
7139
|
] })
|
|
6759
7140
|
}
|
|
6760
7141
|
)
|
|
6761
7142
|
] }),
|
|
6762
|
-
/* @__PURE__ */ (0,
|
|
6763
|
-
/* @__PURE__ */ (0,
|
|
6764
|
-
/* @__PURE__ */ (0,
|
|
6765
|
-
/* @__PURE__ */ (0,
|
|
6766
|
-
/* @__PURE__ */ (0,
|
|
6767
|
-
/* @__PURE__ */ (0,
|
|
7143
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "p-3 rounded-lg bg-slate-950/60 border border-slate-800 flex flex-col gap-2.5", children: [
|
|
7144
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "flex items-center justify-between", children: [
|
|
7145
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px] flex items-center gap-1.5", children: [
|
|
7146
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("svg", { className: "w-3.5 h-3.5 text-purple-400", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: [
|
|
7147
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.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" }),
|
|
7148
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)("path", { d: "m14 7 3 3" })
|
|
6768
7149
|
] }),
|
|
6769
7150
|
"Generative Inpainting"
|
|
6770
7151
|
] }),
|
|
6771
|
-
isInpainting && /* @__PURE__ */ (0,
|
|
7152
|
+
isInpainting && /* @__PURE__ */ (0, import_jsx_runtime29.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..." })
|
|
6772
7153
|
] }),
|
|
6773
|
-
/* @__PURE__ */ (0,
|
|
6774
|
-
/* @__PURE__ */ (0,
|
|
6775
|
-
/* @__PURE__ */ (0,
|
|
6776
|
-
/* @__PURE__ */ (0,
|
|
7154
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)("p", { className: "text-slate-400 text-[11px] leading-relaxed", children: "Replace, modify, or fill selected regions using prompt-guided generative inpainting." }),
|
|
7155
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "flex flex-col gap-1", children: [
|
|
7156
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)("label", { htmlFor: "ai-inpaint-prompt-react", className: "text-slate-300 text-[11px] font-medium", children: "Prompt" }),
|
|
7157
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
6777
7158
|
"textarea",
|
|
6778
7159
|
{
|
|
6779
7160
|
id: "ai-inpaint-prompt-react",
|
|
@@ -6785,10 +7166,10 @@ var ImageEditor = ({
|
|
|
6785
7166
|
}
|
|
6786
7167
|
)
|
|
6787
7168
|
] }),
|
|
6788
|
-
/* @__PURE__ */ (0,
|
|
6789
|
-
/* @__PURE__ */ (0,
|
|
6790
|
-
/* @__PURE__ */ (0,
|
|
6791
|
-
/* @__PURE__ */ (0,
|
|
7169
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "flex flex-col gap-1", children: [
|
|
7170
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { className: "text-slate-300 text-[11px] font-medium", children: "Target Mask Region" }),
|
|
7171
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "grid grid-cols-2 gap-1.5", children: [
|
|
7172
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(
|
|
6792
7173
|
"button",
|
|
6793
7174
|
{
|
|
6794
7175
|
type: "button",
|
|
@@ -6801,7 +7182,7 @@ var ImageEditor = ({
|
|
|
6801
7182
|
]
|
|
6802
7183
|
}
|
|
6803
7184
|
),
|
|
6804
|
-
/* @__PURE__ */ (0,
|
|
7185
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(
|
|
6805
7186
|
"button",
|
|
6806
7187
|
{
|
|
6807
7188
|
type: "button",
|
|
@@ -6816,25 +7197,25 @@ var ImageEditor = ({
|
|
|
6816
7197
|
)
|
|
6817
7198
|
] })
|
|
6818
7199
|
] }),
|
|
6819
|
-
/* @__PURE__ */ (0,
|
|
7200
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
6820
7201
|
"button",
|
|
6821
7202
|
{
|
|
6822
7203
|
type: "button",
|
|
6823
7204
|
onClick: handleInpaint,
|
|
6824
7205
|
disabled: isInpainting || isRemovingBg || !inpaintPrompt.trim(),
|
|
6825
7206
|
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",
|
|
6826
|
-
children: isInpainting ? /* @__PURE__ */ (0,
|
|
6827
|
-
/* @__PURE__ */ (0,
|
|
7207
|
+
children: isInpainting ? /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(import_jsx_runtime29.Fragment, { children: [
|
|
7208
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: "w-3.5 h-3.5 border-2 border-white/30 border-t-white rounded-full animate-spin" }),
|
|
6828
7209
|
"Generating Inpaint..."
|
|
6829
|
-
] }) : /* @__PURE__ */ (0,
|
|
6830
|
-
/* @__PURE__ */ (0,
|
|
7210
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(import_jsx_runtime29.Fragment, { children: [
|
|
7211
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.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_runtime29.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" }) }),
|
|
6831
7212
|
"Apply Inpainting"
|
|
6832
7213
|
] })
|
|
6833
7214
|
}
|
|
6834
7215
|
)
|
|
6835
7216
|
] }),
|
|
6836
|
-
aiError && /* @__PURE__ */ (0,
|
|
6837
|
-
aiSuccess && /* @__PURE__ */ (0,
|
|
7217
|
+
aiError && /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: "p-2.5 rounded-lg bg-rose-950/60 border border-rose-800 text-rose-300 text-[11px]", children: aiError }),
|
|
7218
|
+
aiSuccess && /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: "p-2.5 rounded-lg bg-emerald-950/60 border border-emerald-800 text-emerald-300 text-[11px]", children: aiSuccess })
|
|
6838
7219
|
] })
|
|
6839
7220
|
] })
|
|
6840
7221
|
] })
|
|
@@ -6844,7 +7225,7 @@ var ImageEditor = ({
|
|
|
6844
7225
|
};
|
|
6845
7226
|
|
|
6846
7227
|
// src/review/useReview.ts
|
|
6847
|
-
var
|
|
7228
|
+
var import_react47 = require("react");
|
|
6848
7229
|
var import_editor12 = require("@pixerate/editor");
|
|
6849
7230
|
var EMPTY_COMMENTS = Object.freeze({
|
|
6850
7231
|
threads: [],
|
|
@@ -6863,23 +7244,23 @@ function isCommentStore(value) {
|
|
|
6863
7244
|
}
|
|
6864
7245
|
function useComments(source) {
|
|
6865
7246
|
const store = isCommentStore(source) ? source : (0, import_editor12.getCommentStore)(source);
|
|
6866
|
-
const subscribe = (0,
|
|
7247
|
+
const subscribe = (0, import_react47.useCallback)(
|
|
6867
7248
|
(onChange) => store ? store.subscribe(() => onChange()) : noopUnsubscribe,
|
|
6868
7249
|
[store]
|
|
6869
7250
|
);
|
|
6870
7251
|
const getSnapshot = () => store?.getSnapshot() ?? EMPTY_COMMENTS;
|
|
6871
|
-
const snapshot = (0,
|
|
6872
|
-
return (0,
|
|
7252
|
+
const snapshot = (0, import_react47.useSyncExternalStore)(subscribe, getSnapshot, getSnapshot);
|
|
7253
|
+
return (0, import_react47.useMemo)(() => ({ ...snapshot, store }), [snapshot, store]);
|
|
6873
7254
|
}
|
|
6874
7255
|
function useTrackChanges(editor) {
|
|
6875
7256
|
const store = (0, import_editor12.getTrackChangesStore)(editor ?? null);
|
|
6876
|
-
const subscribe = (0,
|
|
7257
|
+
const subscribe = (0, import_react47.useCallback)(
|
|
6877
7258
|
(onChange) => store ? store.subscribe(() => onChange()) : noopUnsubscribe,
|
|
6878
7259
|
[store]
|
|
6879
7260
|
);
|
|
6880
7261
|
const getSnapshot = () => store?.getSnapshot() ?? EMPTY_TRACK_CHANGES;
|
|
6881
|
-
const snapshot = (0,
|
|
6882
|
-
return (0,
|
|
7262
|
+
const snapshot = (0, import_react47.useSyncExternalStore)(subscribe, getSnapshot, getSnapshot);
|
|
7263
|
+
return (0, import_react47.useMemo)(() => {
|
|
6883
7264
|
const run = (fn) => () => {
|
|
6884
7265
|
if (editor && !editor.isDestroyed) fn(editor);
|
|
6885
7266
|
};
|
|
@@ -6902,9 +7283,9 @@ function useTrackChanges(editor) {
|
|
|
6902
7283
|
}
|
|
6903
7284
|
|
|
6904
7285
|
// src/review/CommentsPanel.tsx
|
|
6905
|
-
var
|
|
7286
|
+
var import_react48 = require("react");
|
|
6906
7287
|
var import_editor13 = require("@pixerate/editor");
|
|
6907
|
-
var
|
|
7288
|
+
var import_jsx_runtime30 = require("react/jsx-runtime");
|
|
6908
7289
|
var buttonClass2 = "rounded px-2 py-1 text-xs text-muted-foreground hover:bg-muted hover:text-foreground disabled:opacity-50";
|
|
6909
7290
|
var primaryButtonClass = "rounded px-2 py-1 text-xs bg-primary/10 text-primary hover:bg-primary/20 disabled:opacity-50";
|
|
6910
7291
|
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";
|
|
@@ -6918,18 +7299,18 @@ var CommentsPanel = ({
|
|
|
6918
7299
|
emptyMessage = "No comments yet. Select text and add a comment."
|
|
6919
7300
|
}) => {
|
|
6920
7301
|
const { threads, activeThreadId, store } = useComments(storeProp ?? editor);
|
|
6921
|
-
const [showResolved, setShowResolved] = (0,
|
|
7302
|
+
const [showResolved, setShowResolved] = (0, import_react48.useState)(showResolvedInitial);
|
|
6922
7303
|
const author = authorProp ?? (0, import_editor13.getCommentAuthor)(editor) ?? { id: "anonymous", name: "Anonymous" };
|
|
6923
7304
|
const visible = threads.filter((t) => showResolved || !t.resolved);
|
|
6924
7305
|
const resolvedCount = threads.filter((t) => t.resolved).length;
|
|
6925
|
-
return /* @__PURE__ */ (0,
|
|
6926
|
-
/* @__PURE__ */ (0,
|
|
6927
|
-
/* @__PURE__ */ (0,
|
|
7306
|
+
return /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("aside", { className, "aria-label": "Comments", children: [
|
|
7307
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "flex items-center justify-between gap-2", children: [
|
|
7308
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("span", { className: "text-xs font-medium text-muted-foreground", children: [
|
|
6928
7309
|
threads.length - resolvedCount,
|
|
6929
7310
|
" open",
|
|
6930
7311
|
resolvedCount > 0 ? ` \xB7 ${resolvedCount} resolved` : ""
|
|
6931
7312
|
] }),
|
|
6932
|
-
resolvedCount > 0 && /* @__PURE__ */ (0,
|
|
7313
|
+
resolvedCount > 0 && /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
6933
7314
|
"button",
|
|
6934
7315
|
{
|
|
6935
7316
|
type: "button",
|
|
@@ -6940,7 +7321,7 @@ var CommentsPanel = ({
|
|
|
6940
7321
|
}
|
|
6941
7322
|
)
|
|
6942
7323
|
] }),
|
|
6943
|
-
visible.length === 0 ? /* @__PURE__ */ (0,
|
|
7324
|
+
visible.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("p", { className: "text-xs text-muted-foreground", children: emptyMessage }) : /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("ul", { className: "flex flex-col gap-2", role: "list", children: visible.map((thread) => /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
6944
7325
|
CommentThreadCard,
|
|
6945
7326
|
{
|
|
6946
7327
|
thread,
|
|
@@ -6962,7 +7343,7 @@ var CommentThreadCard = ({
|
|
|
6962
7343
|
author,
|
|
6963
7344
|
formatTime
|
|
6964
7345
|
}) => {
|
|
6965
|
-
const [draft, setDraft] = (0,
|
|
7346
|
+
const [draft, setDraft] = (0, import_react48.useState)("");
|
|
6966
7347
|
const isDraft = thread.body === "";
|
|
6967
7348
|
const quote = thread.anchor?.quote ?? thread.lastQuote ?? "";
|
|
6968
7349
|
const live = editor && !editor.isDestroyed ? editor : null;
|
|
@@ -6988,7 +7369,7 @@ var CommentThreadCard = ({
|
|
|
6988
7369
|
setDraft("");
|
|
6989
7370
|
};
|
|
6990
7371
|
const stop = (e) => e.stopPropagation();
|
|
6991
|
-
return /* @__PURE__ */ (0,
|
|
7372
|
+
return /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(
|
|
6992
7373
|
"li",
|
|
6993
7374
|
{
|
|
6994
7375
|
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" : ""}`,
|
|
@@ -7004,24 +7385,24 @@ var CommentThreadCard = ({
|
|
|
7004
7385
|
}
|
|
7005
7386
|
},
|
|
7006
7387
|
children: [
|
|
7007
|
-
/* @__PURE__ */ (0,
|
|
7008
|
-
/* @__PURE__ */ (0,
|
|
7009
|
-
/* @__PURE__ */ (0,
|
|
7388
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "flex items-baseline justify-between gap-2", children: [
|
|
7389
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", { className: "font-medium", children: thread.author.name }),
|
|
7390
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", { className: "text-xs text-muted-foreground", children: formatTime(thread.createdAt) })
|
|
7010
7391
|
] }),
|
|
7011
|
-
quote && /* @__PURE__ */ (0,
|
|
7012
|
-
thread.orphaned && /* @__PURE__ */ (0,
|
|
7013
|
-
thread.resolved && /* @__PURE__ */ (0,
|
|
7014
|
-
!isDraft && /* @__PURE__ */ (0,
|
|
7015
|
-
thread.replies.length > 0 && /* @__PURE__ */ (0,
|
|
7016
|
-
/* @__PURE__ */ (0,
|
|
7017
|
-
/* @__PURE__ */ (0,
|
|
7392
|
+
quote && /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("blockquote", { className: "border-l-2 border-border pl-2 text-xs text-muted-foreground line-clamp-2", children: quote }),
|
|
7393
|
+
thread.orphaned && /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", { className: "text-xs text-destructive", children: "The commented text was deleted." }),
|
|
7394
|
+
thread.resolved && /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", { className: "text-xs text-muted-foreground", children: "Resolved" }),
|
|
7395
|
+
!isDraft && /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("p", { className: "whitespace-pre-wrap break-words", children: thread.body }),
|
|
7396
|
+
thread.replies.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime30.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_runtime30.jsxs)("li", { className: "flex flex-col gap-0.5", "data-reply-id": reply.id, children: [
|
|
7397
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("span", { className: "text-xs", children: [
|
|
7398
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", { className: "font-medium", children: reply.author.name }),
|
|
7018
7399
|
" ",
|
|
7019
|
-
/* @__PURE__ */ (0,
|
|
7400
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", { className: "text-muted-foreground", children: formatTime(reply.createdAt) })
|
|
7020
7401
|
] }),
|
|
7021
|
-
/* @__PURE__ */ (0,
|
|
7402
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("p", { className: "whitespace-pre-wrap break-words", children: reply.body })
|
|
7022
7403
|
] }, reply.id)) }),
|
|
7023
|
-
(active || isDraft) && !thread.resolved && /* @__PURE__ */ (0,
|
|
7024
|
-
/* @__PURE__ */ (0,
|
|
7404
|
+
(active || isDraft) && !thread.resolved && /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "flex flex-col gap-1", onClick: stop, children: [
|
|
7405
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
7025
7406
|
"textarea",
|
|
7026
7407
|
{
|
|
7027
7408
|
className: textareaClass,
|
|
@@ -7039,9 +7420,9 @@ var CommentThreadCard = ({
|
|
|
7039
7420
|
}
|
|
7040
7421
|
}
|
|
7041
7422
|
),
|
|
7042
|
-
/* @__PURE__ */ (0,
|
|
7043
|
-
isDraft && /* @__PURE__ */ (0,
|
|
7044
|
-
/* @__PURE__ */ (0,
|
|
7423
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "flex justify-end gap-1", children: [
|
|
7424
|
+
isDraft && /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("button", { type: "button", className: buttonClass2, onClick: remove, children: "Cancel" }),
|
|
7425
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
7045
7426
|
"button",
|
|
7046
7427
|
{
|
|
7047
7428
|
type: "button",
|
|
@@ -7053,9 +7434,9 @@ var CommentThreadCard = ({
|
|
|
7053
7434
|
)
|
|
7054
7435
|
] })
|
|
7055
7436
|
] }),
|
|
7056
|
-
!isDraft && /* @__PURE__ */ (0,
|
|
7057
|
-
/* @__PURE__ */ (0,
|
|
7058
|
-
/* @__PURE__ */ (0,
|
|
7437
|
+
!isDraft && /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "flex justify-end gap-1", onClick: stop, children: [
|
|
7438
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("button", { type: "button", className: buttonClass2, onClick: () => setResolved(!thread.resolved), children: thread.resolved ? "Reopen" : "Resolve" }),
|
|
7439
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
7059
7440
|
"button",
|
|
7060
7441
|
{
|
|
7061
7442
|
type: "button",
|
|
@@ -7071,7 +7452,7 @@ var CommentThreadCard = ({
|
|
|
7071
7452
|
};
|
|
7072
7453
|
|
|
7073
7454
|
// src/review/ReviewToolbar.tsx
|
|
7074
|
-
var
|
|
7455
|
+
var import_jsx_runtime31 = require("react/jsx-runtime");
|
|
7075
7456
|
var defaultDescriptionClass = "max-w-[16rem] truncate px-1 text-xs text-muted-foreground";
|
|
7076
7457
|
var buttonClass3 = "rounded px-2 py-1 text-xs text-foreground hover:bg-muted disabled:opacity-40 disabled:hover:bg-transparent";
|
|
7077
7458
|
var ReviewToolbar = ({
|
|
@@ -7084,8 +7465,8 @@ var ReviewToolbar = ({
|
|
|
7084
7465
|
const count = review.changes.length;
|
|
7085
7466
|
const current = review.currentChange;
|
|
7086
7467
|
const index = current ? review.changes.findIndex((c) => c.id === current.id) + 1 : 0;
|
|
7087
|
-
return /* @__PURE__ */ (0,
|
|
7088
|
-
/* @__PURE__ */ (0,
|
|
7468
|
+
return /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("div", { className, role: "toolbar", "aria-label": "Review", children: [
|
|
7469
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
|
|
7089
7470
|
"button",
|
|
7090
7471
|
{
|
|
7091
7472
|
type: "button",
|
|
@@ -7096,8 +7477,8 @@ var ReviewToolbar = ({
|
|
|
7096
7477
|
children: review.enabled ? "Tracking on" : "Track changes"
|
|
7097
7478
|
}
|
|
7098
7479
|
),
|
|
7099
|
-
/* @__PURE__ */ (0,
|
|
7100
|
-
/* @__PURE__ */ (0,
|
|
7480
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)("span", { className: "mx-1 h-4 w-px bg-border", "aria-hidden": "true" }),
|
|
7481
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
|
|
7101
7482
|
"button",
|
|
7102
7483
|
{
|
|
7103
7484
|
type: "button",
|
|
@@ -7108,8 +7489,8 @@ var ReviewToolbar = ({
|
|
|
7108
7489
|
children: "\u2039"
|
|
7109
7490
|
}
|
|
7110
7491
|
),
|
|
7111
|
-
/* @__PURE__ */ (0,
|
|
7112
|
-
/* @__PURE__ */ (0,
|
|
7492
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.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` }),
|
|
7493
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
|
|
7113
7494
|
"button",
|
|
7114
7495
|
{
|
|
7115
7496
|
type: "button",
|
|
@@ -7120,7 +7501,7 @@ var ReviewToolbar = ({
|
|
|
7120
7501
|
children: "\u203A"
|
|
7121
7502
|
}
|
|
7122
7503
|
),
|
|
7123
|
-
showDescription && current && /* @__PURE__ */ (0,
|
|
7504
|
+
showDescription && current && /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(
|
|
7124
7505
|
"span",
|
|
7125
7506
|
{
|
|
7126
7507
|
className: descriptionClassName,
|
|
@@ -7132,8 +7513,8 @@ var ReviewToolbar = ({
|
|
|
7132
7513
|
]
|
|
7133
7514
|
}
|
|
7134
7515
|
),
|
|
7135
|
-
/* @__PURE__ */ (0,
|
|
7136
|
-
/* @__PURE__ */ (0,
|
|
7516
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)("span", { className: "mx-1 h-4 w-px bg-border", "aria-hidden": "true" }),
|
|
7517
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
|
|
7137
7518
|
"button",
|
|
7138
7519
|
{
|
|
7139
7520
|
type: "button",
|
|
@@ -7143,7 +7524,7 @@ var ReviewToolbar = ({
|
|
|
7143
7524
|
children: "Accept"
|
|
7144
7525
|
}
|
|
7145
7526
|
),
|
|
7146
|
-
/* @__PURE__ */ (0,
|
|
7527
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
|
|
7147
7528
|
"button",
|
|
7148
7529
|
{
|
|
7149
7530
|
type: "button",
|
|
@@ -7153,18 +7534,18 @@ var ReviewToolbar = ({
|
|
|
7153
7534
|
children: "Reject"
|
|
7154
7535
|
}
|
|
7155
7536
|
),
|
|
7156
|
-
/* @__PURE__ */ (0,
|
|
7157
|
-
/* @__PURE__ */ (0,
|
|
7537
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)("button", { type: "button", className: buttonClass3, disabled: count === 0, onClick: review.acceptAll, children: "Accept all" }),
|
|
7538
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)("button", { type: "button", className: buttonClass3, disabled: count === 0, onClick: review.rejectAll, children: "Reject all" })
|
|
7158
7539
|
] });
|
|
7159
7540
|
};
|
|
7160
7541
|
|
|
7161
7542
|
// src/review/CommentButton.tsx
|
|
7162
|
-
var
|
|
7543
|
+
var import_jsx_runtime32 = require("react/jsx-runtime");
|
|
7163
7544
|
var CommentButton = ({
|
|
7164
7545
|
editor,
|
|
7165
7546
|
className = "rounded px-2 py-1 text-xs text-popover-foreground hover:bg-muted",
|
|
7166
7547
|
children = "Comment"
|
|
7167
|
-
}) => /* @__PURE__ */ (0,
|
|
7548
|
+
}) => /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
7168
7549
|
"button",
|
|
7169
7550
|
{
|
|
7170
7551
|
type: "button",
|
|
@@ -7176,13 +7557,13 @@ var CommentButton = ({
|
|
|
7176
7557
|
);
|
|
7177
7558
|
|
|
7178
7559
|
// src/review/useDocumentCompare.ts
|
|
7179
|
-
var
|
|
7560
|
+
var import_react49 = require("react");
|
|
7180
7561
|
var import_editor14 = require("@pixerate/editor");
|
|
7181
7562
|
function useDocumentCompare(editor, options) {
|
|
7182
|
-
const [summary, setSummary] = (0,
|
|
7183
|
-
const defaults = (0,
|
|
7563
|
+
const [summary, setSummary] = (0, import_react49.useState)(null);
|
|
7564
|
+
const defaults = (0, import_react49.useRef)(options);
|
|
7184
7565
|
defaults.current = options;
|
|
7185
|
-
const compare = (0,
|
|
7566
|
+
const compare = (0, import_react49.useCallback)(
|
|
7186
7567
|
(original, revised, overrides) => {
|
|
7187
7568
|
if (!editor || editor.isDestroyed) return null;
|
|
7188
7569
|
const result = (0, import_editor14.applyDocumentComparison)(editor, original, revised, {
|
|
@@ -7194,13 +7575,13 @@ function useDocumentCompare(editor, options) {
|
|
|
7194
7575
|
},
|
|
7195
7576
|
[editor]
|
|
7196
7577
|
);
|
|
7197
|
-
const clear = (0,
|
|
7198
|
-
return (0,
|
|
7578
|
+
const clear = (0, import_react49.useCallback)(() => setSummary(null), []);
|
|
7579
|
+
return (0, import_react49.useMemo)(() => ({ summary, compare, clear }), [summary, compare, clear]);
|
|
7199
7580
|
}
|
|
7200
7581
|
|
|
7201
7582
|
// src/review/TrackedChangesList.tsx
|
|
7202
7583
|
var import_editor15 = require("@pixerate/editor");
|
|
7203
|
-
var
|
|
7584
|
+
var import_jsx_runtime33 = require("react/jsx-runtime");
|
|
7204
7585
|
var buttonClass4 = "rounded px-1.5 py-0.5 text-xs text-foreground hover:bg-muted disabled:opacity-40";
|
|
7205
7586
|
var TrackedChangesList = ({
|
|
7206
7587
|
editor,
|
|
@@ -7211,18 +7592,18 @@ var TrackedChangesList = ({
|
|
|
7211
7592
|
}) => {
|
|
7212
7593
|
const review = useTrackChanges(editor);
|
|
7213
7594
|
if (review.changes.length === 0) {
|
|
7214
|
-
return /* @__PURE__ */ (0,
|
|
7595
|
+
return /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { className, "data-tracked-changes-list": "", children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { className: "pixerate-changes-empty text-xs text-muted-foreground", children: emptyState }) });
|
|
7215
7596
|
}
|
|
7216
|
-
return /* @__PURE__ */ (0,
|
|
7597
|
+
return /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("ul", { className, role: "list", "aria-label": "Tracked changes", "data-tracked-changes-list": "", children: review.changes.map((change) => {
|
|
7217
7598
|
const active = change.id === review.currentChangeId;
|
|
7218
|
-
return /* @__PURE__ */ (0,
|
|
7599
|
+
return /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(
|
|
7219
7600
|
"li",
|
|
7220
7601
|
{
|
|
7221
7602
|
className: active ? `${itemClassName} ${activeItemClassName}` : itemClassName,
|
|
7222
7603
|
"data-change-type": change.type,
|
|
7223
7604
|
"data-change-id": change.id,
|
|
7224
7605
|
children: [
|
|
7225
|
-
/* @__PURE__ */ (0,
|
|
7606
|
+
/* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(
|
|
7226
7607
|
"button",
|
|
7227
7608
|
{
|
|
7228
7609
|
type: "button",
|
|
@@ -7230,14 +7611,14 @@ var TrackedChangesList = ({
|
|
|
7230
7611
|
title: `${change.author.name}: ${change.description}`,
|
|
7231
7612
|
onClick: () => review.select(change.id),
|
|
7232
7613
|
children: [
|
|
7233
|
-
/* @__PURE__ */ (0,
|
|
7614
|
+
/* @__PURE__ */ (0, import_jsx_runtime33.jsx)("span", { className: "font-medium", children: (0, import_editor15.trackedChangeLabel)(change) }),
|
|
7234
7615
|
change.author.name ? ` \xB7 ${change.author.name}` : "",
|
|
7235
|
-
/* @__PURE__ */ (0,
|
|
7616
|
+
/* @__PURE__ */ (0, import_jsx_runtime33.jsx)("span", { className: "block truncate text-muted-foreground", children: change.description })
|
|
7236
7617
|
]
|
|
7237
7618
|
}
|
|
7238
7619
|
),
|
|
7239
|
-
/* @__PURE__ */ (0,
|
|
7240
|
-
/* @__PURE__ */ (0,
|
|
7620
|
+
/* @__PURE__ */ (0, import_jsx_runtime33.jsx)("button", { type: "button", className: buttonClass4, onClick: () => review.accept(change.id), children: "Accept" }),
|
|
7621
|
+
/* @__PURE__ */ (0, import_jsx_runtime33.jsx)("button", { type: "button", className: buttonClass4, onClick: () => review.reject(change.id), children: "Reject" })
|
|
7241
7622
|
]
|
|
7242
7623
|
},
|
|
7243
7624
|
`${change.type}:${change.id}`
|
|
@@ -7246,12 +7627,12 @@ var TrackedChangesList = ({
|
|
|
7246
7627
|
};
|
|
7247
7628
|
|
|
7248
7629
|
// src/commands/useCommandPalette.ts
|
|
7249
|
-
var
|
|
7630
|
+
var import_react50 = require("react");
|
|
7250
7631
|
var import_commands2 = require("@pixerate/editor/commands");
|
|
7251
7632
|
function useCommandPalette(registry, options = {}) {
|
|
7252
|
-
const optionsRef = (0,
|
|
7633
|
+
const optionsRef = (0, import_react50.useRef)(options);
|
|
7253
7634
|
optionsRef.current = options;
|
|
7254
|
-
const controller = (0,
|
|
7635
|
+
const controller = (0, import_react50.useMemo)(
|
|
7255
7636
|
() => (0, import_commands2.createCommandPaletteController)(registry, {
|
|
7256
7637
|
context: () => {
|
|
7257
7638
|
const c = optionsRef.current.context;
|
|
@@ -7272,9 +7653,9 @@ function useCommandPalette(registry, options = {}) {
|
|
|
7272
7653
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
7273
7654
|
[registry]
|
|
7274
7655
|
);
|
|
7275
|
-
const state = (0,
|
|
7656
|
+
const state = (0, import_react50.useSyncExternalStore)(controller.subscribe, controller.getState, controller.getState);
|
|
7276
7657
|
const { hotkey, hotkeyTarget } = options;
|
|
7277
|
-
(0,
|
|
7658
|
+
(0, import_react50.useEffect)(() => {
|
|
7278
7659
|
if (!hotkey) return;
|
|
7279
7660
|
const target = hotkeyTarget ?? (typeof window !== "undefined" ? window : null);
|
|
7280
7661
|
if (!target) return;
|
|
@@ -7302,13 +7683,13 @@ function useCommandPalette(registry, options = {}) {
|
|
|
7302
7683
|
}
|
|
7303
7684
|
|
|
7304
7685
|
// src/commands/CommandPalette.tsx
|
|
7305
|
-
var
|
|
7306
|
-
var
|
|
7686
|
+
var import_react51 = __toESM(require("react"), 1);
|
|
7687
|
+
var import_jsx_runtime34 = require("react/jsx-runtime");
|
|
7307
7688
|
function HighlightedLabel({ item }) {
|
|
7308
|
-
if (item.labelIndices.length === 0) return /* @__PURE__ */ (0,
|
|
7689
|
+
if (item.labelIndices.length === 0) return /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(import_jsx_runtime34.Fragment, { children: item.label });
|
|
7309
7690
|
const marked = new Set(item.labelIndices);
|
|
7310
|
-
return /* @__PURE__ */ (0,
|
|
7311
|
-
(ch, i) => marked.has(i) ? /* @__PURE__ */ (0,
|
|
7691
|
+
return /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(import_jsx_runtime34.Fragment, { children: Array.from(item.label).map(
|
|
7692
|
+
(ch, i) => marked.has(i) ? /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("span", { className: "font-semibold text-foreground", "data-match": "", children: ch }, i) : /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(import_react51.default.Fragment, { children: ch }, i)
|
|
7312
7693
|
) });
|
|
7313
7694
|
}
|
|
7314
7695
|
var CommandPalette = ({
|
|
@@ -7317,22 +7698,22 @@ var CommandPalette = ({
|
|
|
7317
7698
|
emptyMessage = "No matching commands",
|
|
7318
7699
|
className = ""
|
|
7319
7700
|
}) => {
|
|
7320
|
-
const inputRef = (0,
|
|
7321
|
-
const listRef = (0,
|
|
7322
|
-
const baseId = (0,
|
|
7701
|
+
const inputRef = (0, import_react51.useRef)(null);
|
|
7702
|
+
const listRef = (0, import_react51.useRef)(null);
|
|
7703
|
+
const baseId = (0, import_react51.useId)();
|
|
7323
7704
|
const listId = `${baseId}-list`;
|
|
7324
7705
|
const optionId = (index) => `${baseId}-option-${index}`;
|
|
7325
7706
|
const { open, query, items, activeIndex } = palette;
|
|
7326
|
-
(0,
|
|
7707
|
+
(0, import_react51.useEffect)(() => {
|
|
7327
7708
|
if (open) inputRef.current?.focus();
|
|
7328
7709
|
}, [open]);
|
|
7329
|
-
(0,
|
|
7710
|
+
(0, import_react51.useEffect)(() => {
|
|
7330
7711
|
if (!open) return;
|
|
7331
7712
|
const active = listRef.current?.querySelector('[aria-selected="true"]');
|
|
7332
7713
|
active?.scrollIntoView?.({ block: "nearest" });
|
|
7333
7714
|
}, [open, activeIndex]);
|
|
7334
7715
|
if (!open) return null;
|
|
7335
|
-
return /* @__PURE__ */ (0,
|
|
7716
|
+
return /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
7336
7717
|
"div",
|
|
7337
7718
|
{
|
|
7338
7719
|
className: "fixed inset-0 z-50 flex items-start justify-center bg-black/30 px-4 pt-[15vh]",
|
|
@@ -7340,7 +7721,7 @@ var CommandPalette = ({
|
|
|
7340
7721
|
onMouseDown: (e) => {
|
|
7341
7722
|
if (e.target === e.currentTarget) palette.setOpen(false);
|
|
7342
7723
|
},
|
|
7343
|
-
children: /* @__PURE__ */ (0,
|
|
7724
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(
|
|
7344
7725
|
"div",
|
|
7345
7726
|
{
|
|
7346
7727
|
role: "dialog",
|
|
@@ -7349,7 +7730,7 @@ var CommandPalette = ({
|
|
|
7349
7730
|
className: `w-full max-w-lg overflow-hidden rounded-lg border border-border bg-popover text-popover-foreground shadow-xl ${className}`,
|
|
7350
7731
|
style: { background: "var(--popover, var(--background, #fff))" },
|
|
7351
7732
|
children: [
|
|
7352
|
-
/* @__PURE__ */ (0,
|
|
7733
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
7353
7734
|
"input",
|
|
7354
7735
|
{
|
|
7355
7736
|
ref: inputRef,
|
|
@@ -7369,7 +7750,7 @@ var CommandPalette = ({
|
|
|
7369
7750
|
className: "w-full border-b border-border bg-transparent px-3 py-2 text-sm outline-none placeholder:text-muted-foreground"
|
|
7370
7751
|
}
|
|
7371
7752
|
),
|
|
7372
|
-
items.length === 0 ? /* @__PURE__ */ (0,
|
|
7753
|
+
items.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("div", { className: "px-3 py-6 text-center text-sm text-muted-foreground", children: emptyMessage }) : /* @__PURE__ */ (0, import_jsx_runtime34.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_runtime34.jsxs)(
|
|
7373
7754
|
"li",
|
|
7374
7755
|
{
|
|
7375
7756
|
id: optionId(index),
|
|
@@ -7384,12 +7765,12 @@ var CommandPalette = ({
|
|
|
7384
7765
|
onClick: () => palette.run(item.id),
|
|
7385
7766
|
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"}`,
|
|
7386
7767
|
children: [
|
|
7387
|
-
/* @__PURE__ */ (0,
|
|
7388
|
-
/* @__PURE__ */ (0,
|
|
7389
|
-
item.disabledReason && /* @__PURE__ */ (0,
|
|
7768
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("span", { className: "min-w-0 flex-1 truncate", children: [
|
|
7769
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)(HighlightedLabel, { item }),
|
|
7770
|
+
item.disabledReason && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("span", { className: "ml-2 text-xs text-muted-foreground", "data-disabled-reason": "", children: item.disabledReason })
|
|
7390
7771
|
] }),
|
|
7391
|
-
item.group && /* @__PURE__ */ (0,
|
|
7392
|
-
item.shortcut && /* @__PURE__ */ (0,
|
|
7772
|
+
item.group && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("span", { className: "shrink-0 text-xs text-muted-foreground", children: item.group }),
|
|
7773
|
+
item.shortcut && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("kbd", { className: "shrink-0 rounded border border-border px-1.5 font-mono text-[10px] text-muted-foreground", children: item.shortcut })
|
|
7393
7774
|
]
|
|
7394
7775
|
},
|
|
7395
7776
|
item.id
|
|
@@ -7402,12 +7783,12 @@ var CommandPalette = ({
|
|
|
7402
7783
|
};
|
|
7403
7784
|
|
|
7404
7785
|
// src/commands/useCommandShortcuts.ts
|
|
7405
|
-
var
|
|
7786
|
+
var import_react52 = require("react");
|
|
7406
7787
|
function useCommandShortcuts(registry, options = {}) {
|
|
7407
|
-
const optionsRef = (0,
|
|
7788
|
+
const optionsRef = (0, import_react52.useRef)(options);
|
|
7408
7789
|
optionsRef.current = options;
|
|
7409
7790
|
const { enabled = true, target } = options;
|
|
7410
|
-
(0,
|
|
7791
|
+
(0, import_react52.useEffect)(() => {
|
|
7411
7792
|
if (!registry || !enabled) return;
|
|
7412
7793
|
const eventTarget = target ?? (typeof window !== "undefined" ? window : null);
|
|
7413
7794
|
if (!eventTarget) return;
|
|
@@ -7425,14 +7806,14 @@ function useCommandShortcuts(registry, options = {}) {
|
|
|
7425
7806
|
}, [registry, enabled, target]);
|
|
7426
7807
|
}
|
|
7427
7808
|
function useRegisterCommands(registry, specs) {
|
|
7428
|
-
(0,
|
|
7809
|
+
(0, import_react52.useEffect)(() => {
|
|
7429
7810
|
if (!registry || !specs || specs.length === 0) return;
|
|
7430
7811
|
return registry.register(specs);
|
|
7431
7812
|
}, [registry, specs]);
|
|
7432
7813
|
}
|
|
7433
7814
|
|
|
7434
7815
|
// src/persistence/useAutosave.ts
|
|
7435
|
-
var
|
|
7816
|
+
var import_react53 = require("react");
|
|
7436
7817
|
var import_persistence = require("@pixerate/editor/persistence");
|
|
7437
7818
|
var IDLE = {
|
|
7438
7819
|
status: "idle",
|
|
@@ -7443,18 +7824,18 @@ var IDLE = {
|
|
|
7443
7824
|
ready: false
|
|
7444
7825
|
};
|
|
7445
7826
|
function useAutosave(options) {
|
|
7446
|
-
const optionsRef = (0,
|
|
7827
|
+
const optionsRef = (0, import_react53.useRef)(options);
|
|
7447
7828
|
optionsRef.current = options;
|
|
7448
7829
|
const { storage, key, history, dirty } = options;
|
|
7449
7830
|
const recover = options.recover !== false;
|
|
7450
7831
|
const flushOnHide = options.flushOnHide !== false;
|
|
7451
7832
|
const ready = options.ready !== false;
|
|
7452
|
-
const [controller, setController] = (0,
|
|
7453
|
-
const [status, setStatus] = (0,
|
|
7454
|
-
const [recovery, setRecovery] = (0,
|
|
7455
|
-
const [pendingRecovery, setPendingRecovery] = (0,
|
|
7456
|
-
const revisionsRef = (0,
|
|
7457
|
-
(0,
|
|
7833
|
+
const [controller, setController] = (0, import_react53.useState)(null);
|
|
7834
|
+
const [status, setStatus] = (0, import_react53.useState)(IDLE);
|
|
7835
|
+
const [recovery, setRecovery] = (0, import_react53.useState)(null);
|
|
7836
|
+
const [pendingRecovery, setPendingRecovery] = (0, import_react53.useState)(recover);
|
|
7837
|
+
const revisionsRef = (0, import_react53.useRef)(null);
|
|
7838
|
+
(0, import_react53.useEffect)(() => {
|
|
7458
7839
|
const revisions = (0, import_persistence.createRevisionTracker)({ history, dirty });
|
|
7459
7840
|
const o = optionsRef.current;
|
|
7460
7841
|
const instance = (0, import_persistence.createAutosaveController)({
|
|
@@ -7497,10 +7878,10 @@ function useAutosave(options) {
|
|
|
7497
7878
|
if (revisionsRef.current === revisions) revisionsRef.current = null;
|
|
7498
7879
|
};
|
|
7499
7880
|
}, [storage, key, history, dirty, recover]);
|
|
7500
|
-
(0,
|
|
7881
|
+
(0, import_react53.useEffect)(() => {
|
|
7501
7882
|
if (controller && ready && !pendingRecovery) controller.ready();
|
|
7502
7883
|
}, [controller, ready, pendingRecovery]);
|
|
7503
|
-
(0,
|
|
7884
|
+
(0, import_react53.useEffect)(() => {
|
|
7504
7885
|
if (!controller || !flushOnHide || typeof window === "undefined") return;
|
|
7505
7886
|
const flush = () => void controller.flushNow();
|
|
7506
7887
|
const onVisibility = () => {
|
|
@@ -7513,31 +7894,31 @@ function useAutosave(options) {
|
|
|
7513
7894
|
document.removeEventListener("visibilitychange", onVisibility);
|
|
7514
7895
|
};
|
|
7515
7896
|
}, [controller, flushOnHide]);
|
|
7516
|
-
const restore = (0,
|
|
7897
|
+
const restore = (0, import_react53.useCallback)(() => {
|
|
7517
7898
|
const snapshot = recovery?.snapshot;
|
|
7518
7899
|
setRecovery(null);
|
|
7519
7900
|
setPendingRecovery(false);
|
|
7520
7901
|
return snapshot;
|
|
7521
7902
|
}, [recovery]);
|
|
7522
|
-
const discard = (0,
|
|
7903
|
+
const discard = (0, import_react53.useCallback)(async () => {
|
|
7523
7904
|
if (controller) await controller.discardRecovery();
|
|
7524
7905
|
setRecovery(null);
|
|
7525
7906
|
setPendingRecovery(false);
|
|
7526
7907
|
}, [controller]);
|
|
7527
|
-
const flushNow = (0,
|
|
7908
|
+
const flushNow = (0, import_react53.useCallback)(async () => {
|
|
7528
7909
|
await controller?.flushNow();
|
|
7529
7910
|
}, [controller]);
|
|
7530
|
-
const markClean = (0,
|
|
7911
|
+
const markClean = (0, import_react53.useCallback)(async () => {
|
|
7531
7912
|
revisionsRef.current?.markSaved();
|
|
7532
7913
|
await controller?.markClean();
|
|
7533
7914
|
}, [controller]);
|
|
7534
|
-
const notifyChange = (0,
|
|
7915
|
+
const notifyChange = (0, import_react53.useCallback)(() => revisionsRef.current?.bump(), []);
|
|
7535
7916
|
return { status, recovery, pendingRecovery, restore, discard, flushNow, markClean, notifyChange, controller };
|
|
7536
7917
|
}
|
|
7537
7918
|
|
|
7538
7919
|
// src/persistence/RecoveryPrompt.tsx
|
|
7539
7920
|
var import_persistence2 = require("@pixerate/editor/persistence");
|
|
7540
|
-
var
|
|
7921
|
+
var import_jsx_runtime35 = require("react/jsx-runtime");
|
|
7541
7922
|
var RecoveryPrompt = ({
|
|
7542
7923
|
recovery,
|
|
7543
7924
|
onRestore,
|
|
@@ -7549,7 +7930,7 @@ var RecoveryPrompt = ({
|
|
|
7549
7930
|
}) => {
|
|
7550
7931
|
if (!recovery) return null;
|
|
7551
7932
|
const { name } = recovery.meta;
|
|
7552
|
-
return /* @__PURE__ */ (0,
|
|
7933
|
+
return /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)(
|
|
7553
7934
|
"div",
|
|
7554
7935
|
{
|
|
7555
7936
|
role: "alertdialog",
|
|
@@ -7557,15 +7938,15 @@ var RecoveryPrompt = ({
|
|
|
7557
7938
|
"data-recovery-prompt": "",
|
|
7558
7939
|
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}`,
|
|
7559
7940
|
children: [
|
|
7560
|
-
/* @__PURE__ */ (0,
|
|
7941
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("span", { className: "min-w-0 flex-1", children: [
|
|
7561
7942
|
(0, import_persistence2.formatRecoveryMessage)(recovery.meta, formatTime),
|
|
7562
|
-
name ? /* @__PURE__ */ (0,
|
|
7943
|
+
name ? /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("span", { className: "ml-1 text-xs text-muted-foreground", children: [
|
|
7563
7944
|
"(",
|
|
7564
7945
|
name,
|
|
7565
7946
|
")"
|
|
7566
7947
|
] }) : null
|
|
7567
7948
|
] }),
|
|
7568
|
-
/* @__PURE__ */ (0,
|
|
7949
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
|
|
7569
7950
|
"button",
|
|
7570
7951
|
{
|
|
7571
7952
|
type: "button",
|
|
@@ -7575,7 +7956,7 @@ var RecoveryPrompt = ({
|
|
|
7575
7956
|
children: restoreLabel
|
|
7576
7957
|
}
|
|
7577
7958
|
),
|
|
7578
|
-
/* @__PURE__ */ (0,
|
|
7959
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
|
|
7579
7960
|
"button",
|
|
7580
7961
|
{
|
|
7581
7962
|
type: "button",
|
|
@@ -7591,17 +7972,17 @@ var RecoveryPrompt = ({
|
|
|
7591
7972
|
};
|
|
7592
7973
|
|
|
7593
7974
|
// src/generation/useGenerationPlan.ts
|
|
7594
|
-
var
|
|
7975
|
+
var import_react54 = require("react");
|
|
7595
7976
|
var import_generation = require("@pixerate/editor/generation");
|
|
7596
7977
|
function useGenerationPlan(request, capabilities, options = {}) {
|
|
7597
7978
|
const key = JSON.stringify([request, capabilities, options]);
|
|
7598
|
-
return (0,
|
|
7979
|
+
return (0, import_react54.useMemo)(() => (0, import_generation.planGenerationRequest)(request, capabilities, options), [key]);
|
|
7599
7980
|
}
|
|
7600
7981
|
function useJobProgress(options) {
|
|
7601
7982
|
const { startedAt, expectedMs, done, now, intervalMs = 1e3 } = options;
|
|
7602
|
-
const [tick, setTick] = (0,
|
|
7983
|
+
const [tick, setTick] = (0, import_react54.useState)(() => Date.now());
|
|
7603
7984
|
const ticking = !done && now === void 0;
|
|
7604
|
-
(0,
|
|
7985
|
+
(0, import_react54.useEffect)(() => {
|
|
7605
7986
|
if (!ticking) return;
|
|
7606
7987
|
setTick(Date.now());
|
|
7607
7988
|
const id = setInterval(() => setTick(Date.now()), Math.max(16, intervalMs));
|
|
@@ -7611,9 +7992,9 @@ function useJobProgress(options) {
|
|
|
7611
7992
|
}
|
|
7612
7993
|
|
|
7613
7994
|
// src/generation/GenerationSettings.tsx
|
|
7614
|
-
var
|
|
7995
|
+
var import_react55 = require("react");
|
|
7615
7996
|
var import_generation2 = require("@pixerate/editor/generation");
|
|
7616
|
-
var
|
|
7997
|
+
var import_jsx_runtime36 = require("react/jsx-runtime");
|
|
7617
7998
|
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";
|
|
7618
7999
|
function Control({
|
|
7619
8000
|
control,
|
|
@@ -7623,7 +8004,7 @@ function Control({
|
|
|
7623
8004
|
}) {
|
|
7624
8005
|
const shown = value ?? control.defaultValue;
|
|
7625
8006
|
if (control.kind === "checkbox") {
|
|
7626
|
-
return /* @__PURE__ */ (0,
|
|
8007
|
+
return /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
7627
8008
|
"input",
|
|
7628
8009
|
{
|
|
7629
8010
|
id,
|
|
@@ -7635,7 +8016,7 @@ function Control({
|
|
|
7635
8016
|
);
|
|
7636
8017
|
}
|
|
7637
8018
|
if (control.kind === "select") {
|
|
7638
|
-
return /* @__PURE__ */ (0,
|
|
8019
|
+
return /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(
|
|
7639
8020
|
"select",
|
|
7640
8021
|
{
|
|
7641
8022
|
id,
|
|
@@ -7644,14 +8025,14 @@ function Control({
|
|
|
7644
8025
|
value: shown === void 0 ? "" : String(shown),
|
|
7645
8026
|
onChange: (e) => onValue((0, import_generation2.parseControlValue)(control, e.target.value)),
|
|
7646
8027
|
children: [
|
|
7647
|
-
shown === void 0 && /* @__PURE__ */ (0,
|
|
7648
|
-
control.options.map((option) => /* @__PURE__ */ (0,
|
|
8028
|
+
shown === void 0 && /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("option", { value: "", children: "Default" }),
|
|
8029
|
+
control.options.map((option) => /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("option", { value: String(option.value), children: option.label }, String(option.value)))
|
|
7649
8030
|
]
|
|
7650
8031
|
}
|
|
7651
8032
|
);
|
|
7652
8033
|
}
|
|
7653
8034
|
if (control.kind === "textarea") {
|
|
7654
|
-
return /* @__PURE__ */ (0,
|
|
8035
|
+
return /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
7655
8036
|
"textarea",
|
|
7656
8037
|
{
|
|
7657
8038
|
id,
|
|
@@ -7665,8 +8046,8 @@ function Control({
|
|
|
7665
8046
|
);
|
|
7666
8047
|
}
|
|
7667
8048
|
const numeric = typeof shown === "number" ? shown : void 0;
|
|
7668
|
-
return /* @__PURE__ */ (0,
|
|
7669
|
-
/* @__PURE__ */ (0,
|
|
8049
|
+
return /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
8050
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
7670
8051
|
"input",
|
|
7671
8052
|
{
|
|
7672
8053
|
id,
|
|
@@ -7680,7 +8061,7 @@ function Control({
|
|
|
7680
8061
|
onChange: (e) => onValue((0, import_generation2.parseControlValue)(control, e.target.value))
|
|
7681
8062
|
}
|
|
7682
8063
|
),
|
|
7683
|
-
control.kind === "range" && /* @__PURE__ */ (0,
|
|
8064
|
+
control.kind === "range" && /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("span", { className: "w-10 text-right tabular-nums text-muted-foreground", "data-field-value": "", children: numeric ?? "\u2013" })
|
|
7684
8065
|
] });
|
|
7685
8066
|
}
|
|
7686
8067
|
var GenerationSettings = ({
|
|
@@ -7694,17 +8075,17 @@ var GenerationSettings = ({
|
|
|
7694
8075
|
renderReference,
|
|
7695
8076
|
className = ""
|
|
7696
8077
|
}) => {
|
|
7697
|
-
const baseId = (0,
|
|
7698
|
-
const controls = (0,
|
|
8078
|
+
const baseId = (0, import_react55.useId)();
|
|
8079
|
+
const controls = (0, import_react55.useMemo)(() => (0, import_generation2.getGenerationControls)(capabilities), [capabilities]);
|
|
7699
8080
|
const computed = useGenerationPlan(value, capabilities, { strategy });
|
|
7700
8081
|
const plan = planProp ?? computed;
|
|
7701
8082
|
const slots = (0, import_generation2.getReferenceSlots)(capabilities, value);
|
|
7702
|
-
return /* @__PURE__ */ (0,
|
|
8083
|
+
return /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("div", { className: `flex flex-col gap-3 text-sm ${className}`, "data-generation-settings": "", "data-model": capabilities.id, children: [
|
|
7703
8084
|
controls.map((control) => {
|
|
7704
8085
|
const id = `${baseId}-${control.key}`;
|
|
7705
|
-
return /* @__PURE__ */ (0,
|
|
7706
|
-
/* @__PURE__ */ (0,
|
|
7707
|
-
/* @__PURE__ */ (0,
|
|
8086
|
+
return /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("div", { className: "flex flex-col gap-1", "data-control": control.key, children: [
|
|
8087
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)("label", { htmlFor: id, className: "text-xs font-medium text-muted-foreground", title: control.description, children: control.label }),
|
|
8088
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
7708
8089
|
Control,
|
|
7709
8090
|
{
|
|
7710
8091
|
control,
|
|
@@ -7715,23 +8096,23 @@ var GenerationSettings = ({
|
|
|
7715
8096
|
)
|
|
7716
8097
|
] }, control.key);
|
|
7717
8098
|
}),
|
|
7718
|
-
slots.map((slot) => /* @__PURE__ */ (0,
|
|
7719
|
-
/* @__PURE__ */ (0,
|
|
8099
|
+
slots.map((slot) => /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("fieldset", { className: "flex flex-col gap-1", "data-reference-role": slot.role, children: [
|
|
8100
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("legend", { className: "text-xs font-medium text-muted-foreground", title: slot.description, children: [
|
|
7720
8101
|
slot.label,
|
|
7721
8102
|
" ",
|
|
7722
|
-
/* @__PURE__ */ (0,
|
|
8103
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("span", { className: "tabular-nums", "data-reference-count": "", children: [
|
|
7723
8104
|
"(",
|
|
7724
8105
|
slot.references.length,
|
|
7725
8106
|
"/",
|
|
7726
8107
|
slot.max,
|
|
7727
8108
|
")"
|
|
7728
8109
|
] }),
|
|
7729
|
-
slot.min > 0 && /* @__PURE__ */ (0,
|
|
8110
|
+
slot.min > 0 && /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("span", { className: "text-destructive", children: " *" })
|
|
7730
8111
|
] }),
|
|
7731
|
-
/* @__PURE__ */ (0,
|
|
7732
|
-
slot.references.map((ref) => /* @__PURE__ */ (0,
|
|
7733
|
-
renderReference ? renderReference(ref) : /* @__PURE__ */ (0,
|
|
7734
|
-
/* @__PURE__ */ (0,
|
|
8112
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("ul", { className: "flex flex-wrap gap-1", children: [
|
|
8113
|
+
slot.references.map((ref) => /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("li", { className: "flex items-center gap-1 rounded border border-border px-1.5 py-0.5", "data-reference-id": ref.id, children: [
|
|
8114
|
+
renderReference ? renderReference(ref) : /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("span", { className: "max-w-[10rem] truncate", children: ref.id }),
|
|
8115
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
7735
8116
|
"button",
|
|
7736
8117
|
{
|
|
7737
8118
|
type: "button",
|
|
@@ -7742,7 +8123,7 @@ var GenerationSettings = ({
|
|
|
7742
8123
|
}
|
|
7743
8124
|
)
|
|
7744
8125
|
] }, ref.id)),
|
|
7745
|
-
onAddReference && slot.canAdd && /* @__PURE__ */ (0,
|
|
8126
|
+
onAddReference && slot.canAdd && /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("li", { children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
7746
8127
|
"button",
|
|
7747
8128
|
{
|
|
7748
8129
|
type: "button",
|
|
@@ -7753,21 +8134,21 @@ var GenerationSettings = ({
|
|
|
7753
8134
|
) })
|
|
7754
8135
|
] })
|
|
7755
8136
|
] }, slot.role)),
|
|
7756
|
-
showAdjustments && plan.adjustments.length > 0 && /* @__PURE__ */ (0,
|
|
7757
|
-
showAdjustments && plan.errors.length > 0 && /* @__PURE__ */ (0,
|
|
8137
|
+
showAdjustments && plan.adjustments.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime36.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_runtime36.jsx)("li", { "data-adjustment-field": adjustment.field, "data-adjustment-kind": adjustment.kind, children: adjustment.reason }, index)) }),
|
|
8138
|
+
showAdjustments && plan.errors.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime36.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_runtime36.jsx)("li", { "data-error-field": error.field, children: error.message }, index)) })
|
|
7758
8139
|
] });
|
|
7759
8140
|
};
|
|
7760
8141
|
|
|
7761
8142
|
// src/generation/JobProgress.tsx
|
|
7762
|
-
var
|
|
8143
|
+
var import_jsx_runtime37 = require("react/jsx-runtime");
|
|
7763
8144
|
var JobProgress = ({ title, className = "", ...options }) => {
|
|
7764
8145
|
const progress = useJobProgress(options);
|
|
7765
|
-
return /* @__PURE__ */ (0,
|
|
7766
|
-
/* @__PURE__ */ (0,
|
|
7767
|
-
title && /* @__PURE__ */ (0,
|
|
7768
|
-
/* @__PURE__ */ (0,
|
|
8146
|
+
return /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("div", { className: `flex flex-col gap-1 text-sm ${className}`, "data-job-progress": "", "data-done": options.done ? "" : void 0, children: [
|
|
8147
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("div", { className: "flex items-center justify-between gap-2 text-muted-foreground", children: [
|
|
8148
|
+
title && /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("span", { className: "truncate text-foreground", children: title }),
|
|
8149
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsx)("span", { "data-job-progress-label": "", "aria-live": "polite", children: progress.label })
|
|
7769
8150
|
] }),
|
|
7770
|
-
/* @__PURE__ */ (0,
|
|
8151
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
|
|
7771
8152
|
"div",
|
|
7772
8153
|
{
|
|
7773
8154
|
role: "progressbar",
|
|
@@ -7777,7 +8158,7 @@ var JobProgress = ({ title, className = "", ...options }) => {
|
|
|
7777
8158
|
"aria-valuenow": progress.percent,
|
|
7778
8159
|
"aria-valuetext": `${progress.percent}%, ${progress.label}`,
|
|
7779
8160
|
className: "h-1.5 w-full overflow-hidden rounded-full bg-muted",
|
|
7780
|
-
children: /* @__PURE__ */ (0,
|
|
8161
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
|
|
7781
8162
|
"div",
|
|
7782
8163
|
{
|
|
7783
8164
|
className: "h-full rounded-full bg-primary transition-[width] duration-500",
|
|
@@ -7790,9 +8171,9 @@ var JobProgress = ({ title, className = "", ...options }) => {
|
|
|
7790
8171
|
};
|
|
7791
8172
|
|
|
7792
8173
|
// src/generation/AssetMentionChips.tsx
|
|
7793
|
-
var
|
|
8174
|
+
var import_react56 = require("react");
|
|
7794
8175
|
var import_generation3 = require("@pixerate/editor/generation");
|
|
7795
|
-
var
|
|
8176
|
+
var import_jsx_runtime38 = require("react/jsx-runtime");
|
|
7796
8177
|
var AssetMentionChips = ({
|
|
7797
8178
|
content,
|
|
7798
8179
|
onChange,
|
|
@@ -7802,14 +8183,14 @@ var AssetMentionChips = ({
|
|
|
7802
8183
|
renderAsset,
|
|
7803
8184
|
className = ""
|
|
7804
8185
|
}) => {
|
|
7805
|
-
const [open, setOpen] = (0,
|
|
7806
|
-
const rootRef = (0,
|
|
7807
|
-
const chips = (0,
|
|
8186
|
+
const [open, setOpen] = (0, import_react56.useState)(null);
|
|
8187
|
+
const rootRef = (0, import_react56.useRef)(null);
|
|
8188
|
+
const chips = (0, import_react56.useMemo)(
|
|
7808
8189
|
() => (0, import_generation3.describeAssetMentions)((0, import_generation3.findTextMentions)(content), assets, capabilities),
|
|
7809
8190
|
[content, assets, capabilities]
|
|
7810
8191
|
);
|
|
7811
8192
|
const options = roles ?? (capabilities ? (0, import_generation3.getAssetRoleOptions)(capabilities) : (0, import_generation3.defaultAssetRoleOptions)());
|
|
7812
|
-
(0,
|
|
8193
|
+
(0, import_react56.useEffect)(() => {
|
|
7813
8194
|
if (open === null) return;
|
|
7814
8195
|
const onPointer = (event) => {
|
|
7815
8196
|
if (!rootRef.current?.contains(event.target)) setOpen(null);
|
|
@@ -7817,19 +8198,19 @@ var AssetMentionChips = ({
|
|
|
7817
8198
|
document.addEventListener("mousedown", onPointer);
|
|
7818
8199
|
return () => document.removeEventListener("mousedown", onPointer);
|
|
7819
8200
|
}, [open]);
|
|
7820
|
-
const pick = (
|
|
8201
|
+
const pick = (chip5, role) => {
|
|
7821
8202
|
setOpen(null);
|
|
7822
|
-
if (
|
|
7823
|
-
onChange((0, import_generation3.setMentionRoleInText)(content,
|
|
8203
|
+
if (chip5.start === void 0) return;
|
|
8204
|
+
onChange((0, import_generation3.setMentionRoleInText)(content, chip5.start, role));
|
|
7824
8205
|
};
|
|
7825
8206
|
if (chips.length === 0) return null;
|
|
7826
|
-
return /* @__PURE__ */ (0,
|
|
7827
|
-
const error =
|
|
7828
|
-
const warning =
|
|
8207
|
+
return /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("div", { ref: rootRef, className: `flex flex-wrap gap-1.5 ${className}`, "data-asset-mention-chips": "", children: chips.map((chip5) => {
|
|
8208
|
+
const error = chip5.issues.find((issue) => issue.severity === "error");
|
|
8209
|
+
const warning = chip5.issues.find((issue) => issue.severity === "warning");
|
|
7829
8210
|
const problem = error ?? warning;
|
|
7830
|
-
const isOpen = open ===
|
|
7831
|
-
return /* @__PURE__ */ (0,
|
|
7832
|
-
/* @__PURE__ */ (0,
|
|
8211
|
+
const isOpen = open === chip5.index;
|
|
8212
|
+
return /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)("span", { className: "relative inline-flex", "data-asset-chip": chip5.asset.id, children: [
|
|
8213
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(
|
|
7833
8214
|
"button",
|
|
7834
8215
|
{
|
|
7835
8216
|
type: "button",
|
|
@@ -7837,82 +8218,82 @@ var AssetMentionChips = ({
|
|
|
7837
8218
|
"aria-expanded": isOpen,
|
|
7838
8219
|
title: problem?.message,
|
|
7839
8220
|
"data-issue": problem?.code,
|
|
7840
|
-
onClick: () => setOpen(isOpen ? null :
|
|
8221
|
+
onClick: () => setOpen(isOpen ? null : chip5.index),
|
|
7841
8222
|
onKeyDown: (e) => {
|
|
7842
8223
|
if (e.key === "Escape") setOpen(null);
|
|
7843
8224
|
},
|
|
7844
8225
|
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`,
|
|
7845
8226
|
children: [
|
|
7846
|
-
/* @__PURE__ */ (0,
|
|
7847
|
-
/* @__PURE__ */ (0,
|
|
8227
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)("span", { children: renderAsset ? renderAsset(chip5) : `@${chip5.asset.label ?? chip5.handle}` }),
|
|
8228
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
|
|
7848
8229
|
"span",
|
|
7849
8230
|
{
|
|
7850
|
-
className: `rounded px-1 text-[10px] uppercase tracking-wide ${
|
|
7851
|
-
"data-role-badge":
|
|
7852
|
-
children:
|
|
8231
|
+
className: `rounded px-1 text-[10px] uppercase tracking-wide ${chip5.role ? "bg-primary/15" : "opacity-60"}`,
|
|
8232
|
+
"data-role-badge": chip5.role ?? "",
|
|
8233
|
+
children: chip5.roleLabel ?? "No role"
|
|
7853
8234
|
}
|
|
7854
8235
|
)
|
|
7855
8236
|
]
|
|
7856
8237
|
}
|
|
7857
8238
|
),
|
|
7858
|
-
isOpen && /* @__PURE__ */ (0,
|
|
8239
|
+
isOpen && /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(
|
|
7859
8240
|
"div",
|
|
7860
8241
|
{
|
|
7861
8242
|
role: "listbox",
|
|
7862
|
-
"aria-label": `Role for ${
|
|
8243
|
+
"aria-label": `Role for ${chip5.asset.label ?? chip5.handle}`,
|
|
7863
8244
|
className: "absolute left-0 top-full z-50 mt-1 flex min-w-[12rem] flex-col rounded-md border border-border bg-background p-1 text-xs shadow-lg",
|
|
7864
8245
|
"data-role-picker": "",
|
|
7865
8246
|
onKeyDown: (e) => {
|
|
7866
8247
|
if (e.key === "Escape") setOpen(null);
|
|
7867
8248
|
},
|
|
7868
8249
|
children: [
|
|
7869
|
-
options.map((option) => /* @__PURE__ */ (0,
|
|
8250
|
+
options.map((option) => /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(
|
|
7870
8251
|
"button",
|
|
7871
8252
|
{
|
|
7872
8253
|
type: "button",
|
|
7873
8254
|
role: "option",
|
|
7874
|
-
"aria-selected":
|
|
8255
|
+
"aria-selected": chip5.role === option.role,
|
|
7875
8256
|
"data-role-option": option.role,
|
|
7876
8257
|
title: option.description,
|
|
7877
|
-
onClick: () => pick(
|
|
8258
|
+
onClick: () => pick(chip5, option.role),
|
|
7878
8259
|
className: "flex items-center justify-between gap-2 rounded px-2 py-1 text-left hover:bg-muted",
|
|
7879
8260
|
children: [
|
|
7880
|
-
/* @__PURE__ */ (0,
|
|
7881
|
-
option.accepts?.length ? /* @__PURE__ */ (0,
|
|
8261
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)("span", { children: option.label }),
|
|
8262
|
+
option.accepts?.length ? /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("span", { className: "text-[10px] opacity-60", children: option.accepts.join(", ") }) : null
|
|
7882
8263
|
]
|
|
7883
8264
|
},
|
|
7884
8265
|
option.role
|
|
7885
8266
|
)),
|
|
7886
|
-
/* @__PURE__ */ (0,
|
|
8267
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
|
|
7887
8268
|
"button",
|
|
7888
8269
|
{
|
|
7889
8270
|
type: "button",
|
|
7890
8271
|
role: "option",
|
|
7891
|
-
"aria-selected": !
|
|
8272
|
+
"aria-selected": !chip5.role,
|
|
7892
8273
|
"data-role-option": "",
|
|
7893
|
-
onClick: () => pick(
|
|
8274
|
+
onClick: () => pick(chip5, null),
|
|
7894
8275
|
className: "rounded px-2 py-1 text-left opacity-70 hover:bg-muted",
|
|
7895
8276
|
children: "No role"
|
|
7896
8277
|
}
|
|
7897
8278
|
),
|
|
7898
|
-
|
|
8279
|
+
chip5.issues.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("ul", { className: "mt-1 border-t border-border px-2 pt-1 text-[10px]", "data-chip-issues": "", children: chip5.issues.map((issue, i) => /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("li", { className: issue.severity === "error" ? "text-red-500" : "text-amber-500", children: issue.message }, i)) })
|
|
7899
8280
|
]
|
|
7900
8281
|
}
|
|
7901
8282
|
)
|
|
7902
|
-
] }, `${
|
|
8283
|
+
] }, `${chip5.start}-${chip5.index}`);
|
|
7903
8284
|
}) });
|
|
7904
8285
|
};
|
|
7905
8286
|
|
|
7906
8287
|
// src/generation/GenerationHistory.tsx
|
|
7907
|
-
var
|
|
8288
|
+
var import_react57 = require("react");
|
|
7908
8289
|
var import_generation4 = require("@pixerate/editor/generation");
|
|
7909
|
-
var
|
|
8290
|
+
var import_jsx_runtime39 = require("react/jsx-runtime");
|
|
7910
8291
|
function useGenerationRecords(store, filter) {
|
|
7911
|
-
const [records, setRecords] = (0,
|
|
7912
|
-
const [loading, setLoading] = (0,
|
|
7913
|
-
const [error, setError] = (0,
|
|
8292
|
+
const [records, setRecords] = (0, import_react57.useState)([]);
|
|
8293
|
+
const [loading, setLoading] = (0, import_react57.useState)(!!store);
|
|
8294
|
+
const [error, setError] = (0, import_react57.useState)(null);
|
|
7914
8295
|
const filterKey = (0, import_generation4.stableStringify)(filter ?? {});
|
|
7915
|
-
const refresh = (0,
|
|
8296
|
+
const refresh = (0, import_react57.useCallback)(async () => {
|
|
7916
8297
|
if (!store) {
|
|
7917
8298
|
setRecords([]);
|
|
7918
8299
|
setLoading(false);
|
|
@@ -7929,7 +8310,7 @@ function useGenerationRecords(store, filter) {
|
|
|
7929
8310
|
setLoading(false);
|
|
7930
8311
|
}
|
|
7931
8312
|
}, [store, filterKey]);
|
|
7932
|
-
(0,
|
|
8313
|
+
(0, import_react57.useEffect)(() => {
|
|
7933
8314
|
void refresh();
|
|
7934
8315
|
if (!store) return;
|
|
7935
8316
|
return store.subscribe(() => void refresh());
|
|
@@ -7955,21 +8336,21 @@ var GenerationHistory = ({
|
|
|
7955
8336
|
emptyText = "No generations yet.",
|
|
7956
8337
|
className = ""
|
|
7957
8338
|
}) => {
|
|
7958
|
-
const [innerMode, setInnerMode] = (0,
|
|
8339
|
+
const [innerMode, setInnerMode] = (0, import_react57.useState)("exact");
|
|
7959
8340
|
const mode = modeProp ?? innerMode;
|
|
7960
8341
|
const setMode = (next) => {
|
|
7961
8342
|
if (modeProp === void 0) setInnerMode(next);
|
|
7962
8343
|
onModeChange?.(next);
|
|
7963
8344
|
};
|
|
7964
|
-
const options = (0,
|
|
7965
|
-
const results = (0,
|
|
7966
|
-
const models = (0,
|
|
8345
|
+
const options = (0, import_react57.useMemo)(() => ({ templates, capabilities, assets, mode }), [templates, capabilities, assets, mode]);
|
|
8346
|
+
const results = (0, import_react57.useMemo)(() => records.map((record) => (0, import_generation4.recreateRequest)(record, options)), [records, options]);
|
|
8347
|
+
const models = (0, import_react57.useMemo)(
|
|
7967
8348
|
() => capabilities ? Array.isArray(capabilities) ? capabilities : [capabilities] : [],
|
|
7968
8349
|
[capabilities]
|
|
7969
8350
|
);
|
|
7970
|
-
return /* @__PURE__ */ (0,
|
|
7971
|
-
/* @__PURE__ */ (0,
|
|
7972
|
-
/* @__PURE__ */ (0,
|
|
8351
|
+
return /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("div", { className: `flex flex-col gap-2 text-sm ${className}`, "data-generation-history": "", children: [
|
|
8352
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.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_runtime39.jsxs)("label", { className: "inline-flex items-center gap-1", children: [
|
|
8353
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
|
|
7973
8354
|
"input",
|
|
7974
8355
|
{
|
|
7975
8356
|
type: "radio",
|
|
@@ -7982,34 +8363,34 @@ var GenerationHistory = ({
|
|
|
7982
8363
|
),
|
|
7983
8364
|
value === "exact" ? "Exact (recorded versions)" : "Latest templates & settings"
|
|
7984
8365
|
] }, value)) }),
|
|
7985
|
-
records.length === 0 && /* @__PURE__ */ (0,
|
|
7986
|
-
/* @__PURE__ */ (0,
|
|
8366
|
+
records.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("p", { className: "text-xs text-muted-foreground", children: emptyText }),
|
|
8367
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsx)("ul", { className: "flex flex-col gap-2", children: records.map((record, i) => {
|
|
7987
8368
|
const result = results[i];
|
|
7988
8369
|
const model = models.find((m) => m.id === record.provenance.modelId);
|
|
7989
8370
|
const blocked = !result.ok;
|
|
7990
|
-
return /* @__PURE__ */ (0,
|
|
8371
|
+
return /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)(
|
|
7991
8372
|
"li",
|
|
7992
8373
|
{
|
|
7993
8374
|
className: "rounded-md border border-border p-2",
|
|
7994
8375
|
"data-record": record.id,
|
|
7995
8376
|
"data-drift": result.drift.length,
|
|
7996
8377
|
children: [
|
|
7997
|
-
/* @__PURE__ */ (0,
|
|
7998
|
-
/* @__PURE__ */ (0,
|
|
7999
|
-
/* @__PURE__ */ (0,
|
|
8000
|
-
record.kind !== "generate" && /* @__PURE__ */ (0,
|
|
8378
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("div", { className: "flex flex-wrap items-center justify-between gap-2 text-xs", children: [
|
|
8379
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsx)("span", { className: "font-medium", children: model?.name ?? record.provenance.modelId }),
|
|
8380
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("span", { className: "text-muted-foreground", children: [
|
|
8381
|
+
record.kind !== "generate" && /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("span", { "data-kind": "", children: [
|
|
8001
8382
|
record.kind,
|
|
8002
8383
|
" \xB7 "
|
|
8003
8384
|
] }),
|
|
8004
|
-
/* @__PURE__ */ (0,
|
|
8005
|
-
record.seed !== void 0 && /* @__PURE__ */ (0,
|
|
8385
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsx)("time", { dateTime: record.createdAt, children: record.createdAt.replace("T", " ").slice(0, 16) }),
|
|
8386
|
+
record.seed !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)(import_jsx_runtime39.Fragment, { children: [
|
|
8006
8387
|
" \xB7 seed ",
|
|
8007
8388
|
record.seed
|
|
8008
8389
|
] })
|
|
8009
8390
|
] })
|
|
8010
8391
|
] }),
|
|
8011
|
-
/* @__PURE__ */ (0,
|
|
8012
|
-
record.assets.length > 0 && /* @__PURE__ */ (0,
|
|
8392
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsx)("p", { className: "mt-1 line-clamp-3 break-words text-xs", "data-record-prompt": "", children: record.provenance.resolvedPrompt }),
|
|
8393
|
+
record.assets.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("div", { className: "mt-1 flex flex-wrap gap-1", children: record.assets.map((asset) => /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)(
|
|
8013
8394
|
"span",
|
|
8014
8395
|
{
|
|
8015
8396
|
className: "rounded-full bg-muted px-2 py-0.5 text-[10px]",
|
|
@@ -8023,16 +8404,16 @@ var GenerationHistory = ({
|
|
|
8023
8404
|
`${asset.role}:${asset.id}`
|
|
8024
8405
|
)) }),
|
|
8025
8406
|
renderPreview?.(record),
|
|
8026
|
-
result.drift.length > 0 && /* @__PURE__ */ (0,
|
|
8027
|
-
/* @__PURE__ */ (0,
|
|
8407
|
+
result.drift.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime39.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_runtime39.jsxs)("li", { className: severityClass[item.severity], "data-drift-type": item.type, children: [
|
|
8408
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("strong", { children: [
|
|
8028
8409
|
import_generation4.DRIFT_TYPE_LABELS[item.type],
|
|
8029
8410
|
":"
|
|
8030
8411
|
] }),
|
|
8031
8412
|
" ",
|
|
8032
8413
|
item.message
|
|
8033
8414
|
] }, j)) }),
|
|
8034
|
-
/* @__PURE__ */ (0,
|
|
8035
|
-
onRecreate && /* @__PURE__ */ (0,
|
|
8415
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("div", { className: "mt-2 flex gap-2", children: [
|
|
8416
|
+
onRecreate && /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
|
|
8036
8417
|
"button",
|
|
8037
8418
|
{
|
|
8038
8419
|
type: "button",
|
|
@@ -8044,7 +8425,7 @@ var GenerationHistory = ({
|
|
|
8044
8425
|
children: "Recreate"
|
|
8045
8426
|
}
|
|
8046
8427
|
),
|
|
8047
|
-
onVariation && /* @__PURE__ */ (0,
|
|
8428
|
+
onVariation && /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
|
|
8048
8429
|
"button",
|
|
8049
8430
|
{
|
|
8050
8431
|
type: "button",
|
|
@@ -8054,7 +8435,7 @@ var GenerationHistory = ({
|
|
|
8054
8435
|
children: "Variation"
|
|
8055
8436
|
}
|
|
8056
8437
|
),
|
|
8057
|
-
onRemove && /* @__PURE__ */ (0,
|
|
8438
|
+
onRemove && /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
|
|
8058
8439
|
"button",
|
|
8059
8440
|
{
|
|
8060
8441
|
type: "button",
|
|
@@ -8074,19 +8455,19 @@ var GenerationHistory = ({
|
|
|
8074
8455
|
};
|
|
8075
8456
|
|
|
8076
8457
|
// src/find-replace/useFindReplace.ts
|
|
8077
|
-
var
|
|
8458
|
+
var import_react58 = require("react");
|
|
8078
8459
|
var import_editor16 = require("@pixerate/editor");
|
|
8079
8460
|
var noopUnsubscribe2 = () => {
|
|
8080
8461
|
};
|
|
8081
8462
|
function useFindReplace(editor) {
|
|
8082
8463
|
const store = (0, import_editor16.getFindReplaceStore)(editor ?? null);
|
|
8083
|
-
const subscribe = (0,
|
|
8464
|
+
const subscribe = (0, import_react58.useCallback)(
|
|
8084
8465
|
(onChange) => store ? store.subscribe(() => onChange()) : noopUnsubscribe2,
|
|
8085
8466
|
[store]
|
|
8086
8467
|
);
|
|
8087
8468
|
const getSnapshot = () => store?.getSnapshot() ?? import_editor16.EMPTY_FIND_REPLACE_SNAPSHOT;
|
|
8088
|
-
const snapshot = (0,
|
|
8089
|
-
return (0,
|
|
8469
|
+
const snapshot = (0, import_react58.useSyncExternalStore)(subscribe, getSnapshot, getSnapshot);
|
|
8470
|
+
return (0, import_react58.useMemo)(() => {
|
|
8090
8471
|
const run = (fn) => {
|
|
8091
8472
|
if (editor && !editor.isDestroyed && store) fn(editor);
|
|
8092
8473
|
};
|
|
@@ -8110,9 +8491,9 @@ function useFindReplace(editor) {
|
|
|
8110
8491
|
}
|
|
8111
8492
|
|
|
8112
8493
|
// src/find-replace/FindReplaceBar.tsx
|
|
8113
|
-
var
|
|
8494
|
+
var import_react59 = require("react");
|
|
8114
8495
|
var import_editor17 = require("@pixerate/editor");
|
|
8115
|
-
var
|
|
8496
|
+
var import_jsx_runtime40 = require("react/jsx-runtime");
|
|
8116
8497
|
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";
|
|
8117
8498
|
var buttonClass5 = "rounded px-2 py-1 text-xs text-foreground hover:bg-muted disabled:opacity-40 disabled:hover:bg-transparent";
|
|
8118
8499
|
var toggleClass = (on) => `${buttonClass5} font-mono ${on ? "bg-primary/10 text-primary" : "text-muted-foreground"}`;
|
|
@@ -8125,10 +8506,10 @@ var FindReplaceBar = ({
|
|
|
8125
8506
|
onClose
|
|
8126
8507
|
}) => {
|
|
8127
8508
|
const find = useFindReplace(editor);
|
|
8128
|
-
const findInput = (0,
|
|
8129
|
-
const [moreOpen, setMoreOpen] = (0,
|
|
8509
|
+
const findInput = (0, import_react59.useRef)(null);
|
|
8510
|
+
const [moreOpen, setMoreOpen] = (0, import_react59.useState)(false);
|
|
8130
8511
|
const visible = find.available && (alwaysOpen || find.open);
|
|
8131
|
-
(0,
|
|
8512
|
+
(0, import_react59.useEffect)(() => {
|
|
8132
8513
|
if (!visible || find.focusRequest === 0) return;
|
|
8133
8514
|
findInput.current?.focus();
|
|
8134
8515
|
findInput.current?.select();
|
|
@@ -8166,9 +8547,9 @@ var FindReplaceBar = ({
|
|
|
8166
8547
|
if (isMod(e)) find.replaceAll();
|
|
8167
8548
|
else find.replace();
|
|
8168
8549
|
};
|
|
8169
|
-
return /* @__PURE__ */ (0,
|
|
8170
|
-
/* @__PURE__ */ (0,
|
|
8171
|
-
/* @__PURE__ */ (0,
|
|
8550
|
+
return /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)("div", { className, role: "search", "aria-label": "Find and replace", onKeyDown: onBarKeyDown, children: [
|
|
8551
|
+
/* @__PURE__ */ (0, import_jsx_runtime40.jsxs)("div", { className: "flex items-center gap-1", children: [
|
|
8552
|
+
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
|
|
8172
8553
|
"button",
|
|
8173
8554
|
{
|
|
8174
8555
|
type: "button",
|
|
@@ -8179,7 +8560,7 @@ var FindReplaceBar = ({
|
|
|
8179
8560
|
children: showReplace ? "\u25BE" : "\u25B8"
|
|
8180
8561
|
}
|
|
8181
8562
|
),
|
|
8182
|
-
/* @__PURE__ */ (0,
|
|
8563
|
+
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
|
|
8183
8564
|
"input",
|
|
8184
8565
|
{
|
|
8185
8566
|
ref: findInput,
|
|
@@ -8193,7 +8574,7 @@ var FindReplaceBar = ({
|
|
|
8193
8574
|
onKeyDown: onFindKeyDown
|
|
8194
8575
|
}
|
|
8195
8576
|
),
|
|
8196
|
-
import_editor17.FIND_OPTION_TOGGLES.filter((t) => !t.advanced).map((t) => /* @__PURE__ */ (0,
|
|
8577
|
+
import_editor17.FIND_OPTION_TOGGLES.filter((t) => !t.advanced).map((t) => /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
|
|
8197
8578
|
"button",
|
|
8198
8579
|
{
|
|
8199
8580
|
type: "button",
|
|
@@ -8206,7 +8587,7 @@ var FindReplaceBar = ({
|
|
|
8206
8587
|
},
|
|
8207
8588
|
t.key
|
|
8208
8589
|
)),
|
|
8209
|
-
/* @__PURE__ */ (0,
|
|
8590
|
+
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
|
|
8210
8591
|
"span",
|
|
8211
8592
|
{
|
|
8212
8593
|
className: `min-w-[5rem] px-1 text-center text-xs ${find.error ? "text-destructive" : "text-muted-foreground"}`,
|
|
@@ -8216,9 +8597,9 @@ var FindReplaceBar = ({
|
|
|
8216
8597
|
children: status
|
|
8217
8598
|
}
|
|
8218
8599
|
),
|
|
8219
|
-
/* @__PURE__ */ (0,
|
|
8220
|
-
/* @__PURE__ */ (0,
|
|
8221
|
-
showMoreOptions && /* @__PURE__ */ (0,
|
|
8600
|
+
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)("button", { type: "button", className: buttonClass5, "aria-label": "Previous match", disabled: !hasMatches, onClick: find.previous, children: "\u2191" }),
|
|
8601
|
+
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)("button", { type: "button", className: buttonClass5, "aria-label": "Next match", disabled: !hasMatches, onClick: find.next, children: "\u2193" }),
|
|
8602
|
+
showMoreOptions && /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
|
|
8222
8603
|
"button",
|
|
8223
8604
|
{
|
|
8224
8605
|
type: "button",
|
|
@@ -8229,10 +8610,10 @@ var FindReplaceBar = ({
|
|
|
8229
8610
|
children: "\u2026"
|
|
8230
8611
|
}
|
|
8231
8612
|
),
|
|
8232
|
-
/* @__PURE__ */ (0,
|
|
8613
|
+
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)("button", { type: "button", className: buttonClass5, "aria-label": "Close find", onClick: close, children: "\xD7" })
|
|
8233
8614
|
] }),
|
|
8234
|
-
showReplace && /* @__PURE__ */ (0,
|
|
8235
|
-
/* @__PURE__ */ (0,
|
|
8615
|
+
showReplace && /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)("div", { className: "flex items-center gap-1 pl-7", children: [
|
|
8616
|
+
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
|
|
8236
8617
|
"input",
|
|
8237
8618
|
{
|
|
8238
8619
|
type: "text",
|
|
@@ -8244,7 +8625,7 @@ var FindReplaceBar = ({
|
|
|
8244
8625
|
onKeyDown: onReplaceKeyDown
|
|
8245
8626
|
}
|
|
8246
8627
|
),
|
|
8247
|
-
/* @__PURE__ */ (0,
|
|
8628
|
+
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
|
|
8248
8629
|
"button",
|
|
8249
8630
|
{
|
|
8250
8631
|
type: "button",
|
|
@@ -8254,11 +8635,11 @@ var FindReplaceBar = ({
|
|
|
8254
8635
|
children: "Replace"
|
|
8255
8636
|
}
|
|
8256
8637
|
),
|
|
8257
|
-
/* @__PURE__ */ (0,
|
|
8258
|
-
find.lastReplaceCount !== null && /* @__PURE__ */ (0,
|
|
8638
|
+
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)("button", { type: "button", className: buttonClass5, disabled: !hasMatches, onClick: find.replaceAll, children: "Replace all" }),
|
|
8639
|
+
find.lastReplaceCount !== null && /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("span", { className: "px-1 text-xs text-muted-foreground", "aria-live": "polite", children: find.lastReplaceCount === 1 ? "1 replaced" : `${find.lastReplaceCount} replaced` })
|
|
8259
8640
|
] }),
|
|
8260
|
-
showMoreOptions && moreOpen && /* @__PURE__ */ (0,
|
|
8261
|
-
/* @__PURE__ */ (0,
|
|
8641
|
+
showMoreOptions && moreOpen && /* @__PURE__ */ (0, import_jsx_runtime40.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_runtime40.jsxs)("label", { className: "flex items-center gap-1", children: [
|
|
8642
|
+
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
|
|
8262
8643
|
"input",
|
|
8263
8644
|
{
|
|
8264
8645
|
type: "checkbox",
|
|
@@ -8272,12 +8653,12 @@ var FindReplaceBar = ({
|
|
|
8272
8653
|
};
|
|
8273
8654
|
|
|
8274
8655
|
// src/tables/useTableMenu.ts
|
|
8275
|
-
var
|
|
8656
|
+
var import_react60 = require("react");
|
|
8276
8657
|
var import_editor18 = require("@pixerate/editor");
|
|
8277
8658
|
function useTableMenu(editor) {
|
|
8278
|
-
const store = (0,
|
|
8279
|
-
const snapshot = (0,
|
|
8280
|
-
return (0,
|
|
8659
|
+
const store = (0, import_react60.useMemo)(() => (0, import_editor18.createTableStore)(editor), [editor]);
|
|
8660
|
+
const snapshot = (0, import_react60.useSyncExternalStore)(store.subscribe, store.getSnapshot, store.getSnapshot);
|
|
8661
|
+
return (0, import_react60.useMemo)(
|
|
8281
8662
|
() => ({
|
|
8282
8663
|
...snapshot,
|
|
8283
8664
|
run: (action, params) => (0, import_editor18.runTableAction)(editor, action, params, { focus: true }),
|
|
@@ -8288,9 +8669,9 @@ function useTableMenu(editor) {
|
|
|
8288
8669
|
}
|
|
8289
8670
|
|
|
8290
8671
|
// src/tables/TableToolbar.tsx
|
|
8291
|
-
var
|
|
8672
|
+
var import_react61 = __toESM(require("react"), 1);
|
|
8292
8673
|
var import_editor19 = require("@pixerate/editor");
|
|
8293
|
-
var
|
|
8674
|
+
var import_jsx_runtime41 = require("react/jsx-runtime");
|
|
8294
8675
|
var keepSelection2 = (event) => event.preventDefault();
|
|
8295
8676
|
var TableToolbar = ({
|
|
8296
8677
|
editor,
|
|
@@ -8304,14 +8685,14 @@ var TableToolbar = ({
|
|
|
8304
8685
|
}) => {
|
|
8305
8686
|
const table = useTableMenu(editor);
|
|
8306
8687
|
if (!editor || !table.inTable && !showWhenOutside) return null;
|
|
8307
|
-
return /* @__PURE__ */ (0,
|
|
8688
|
+
return /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("div", { className, role: "toolbar", "aria-label": "Table", "data-table-toolbar": "", children: items.map((item, index) => {
|
|
8308
8689
|
const status = table.check(item.action, item.params);
|
|
8309
8690
|
const enabled = status === true;
|
|
8310
8691
|
const active = item.active?.(table);
|
|
8311
8692
|
const separator = index > 0 && items[index - 1].group !== item.group;
|
|
8312
|
-
return /* @__PURE__ */ (0,
|
|
8313
|
-
separator && /* @__PURE__ */ (0,
|
|
8314
|
-
/* @__PURE__ */ (0,
|
|
8693
|
+
return /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)(import_react61.default.Fragment, { children: [
|
|
8694
|
+
separator && /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("span", { className: separatorClassName, "aria-hidden": "true" }),
|
|
8695
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
|
|
8315
8696
|
"button",
|
|
8316
8697
|
{
|
|
8317
8698
|
type: "button",
|
|
@@ -8333,8 +8714,8 @@ var TableToolbar = ({
|
|
|
8333
8714
|
};
|
|
8334
8715
|
|
|
8335
8716
|
// src/tables/InsertTableGrid.tsx
|
|
8336
|
-
var
|
|
8337
|
-
var
|
|
8717
|
+
var import_react62 = require("react");
|
|
8718
|
+
var import_jsx_runtime42 = require("react/jsx-runtime");
|
|
8338
8719
|
var keepSelection3 = (event) => event.preventDefault();
|
|
8339
8720
|
var InsertTableGrid = ({
|
|
8340
8721
|
editor,
|
|
@@ -8347,14 +8728,14 @@ var InsertTableGrid = ({
|
|
|
8347
8728
|
onInsert
|
|
8348
8729
|
}) => {
|
|
8349
8730
|
const table = useTableMenu(editor);
|
|
8350
|
-
const [hover, setHover] = (0,
|
|
8731
|
+
const [hover, setHover] = (0, import_react62.useState)(null);
|
|
8351
8732
|
const status = table.actions.insertTable;
|
|
8352
8733
|
const disabled = !editor || !status.enabled;
|
|
8353
8734
|
const insert = (size) => {
|
|
8354
8735
|
if (table.run("insertTable", { ...size, withHeaderRow })) onInsert?.(size);
|
|
8355
8736
|
setHover(null);
|
|
8356
8737
|
};
|
|
8357
|
-
return /* @__PURE__ */ (0,
|
|
8738
|
+
return /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)(
|
|
8358
8739
|
"div",
|
|
8359
8740
|
{
|
|
8360
8741
|
className,
|
|
@@ -8364,7 +8745,7 @@ var InsertTableGrid = ({
|
|
|
8364
8745
|
"data-insert-table-grid": "",
|
|
8365
8746
|
onMouseLeave: () => setHover(null),
|
|
8366
8747
|
children: [
|
|
8367
|
-
/* @__PURE__ */ (0,
|
|
8748
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
|
|
8368
8749
|
"div",
|
|
8369
8750
|
{
|
|
8370
8751
|
role: "grid",
|
|
@@ -8373,7 +8754,7 @@ var InsertTableGrid = ({
|
|
|
8373
8754
|
children: Array.from({ length: rows * cols }, (_, i) => {
|
|
8374
8755
|
const size = { rows: Math.floor(i / cols) + 1, cols: i % cols + 1 };
|
|
8375
8756
|
const active = !!hover && size.rows <= hover.rows && size.cols <= hover.cols;
|
|
8376
|
-
return /* @__PURE__ */ (0,
|
|
8757
|
+
return /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
|
|
8377
8758
|
"button",
|
|
8378
8759
|
{
|
|
8379
8760
|
type: "button",
|
|
@@ -8393,7 +8774,7 @@ var InsertTableGrid = ({
|
|
|
8393
8774
|
})
|
|
8394
8775
|
}
|
|
8395
8776
|
),
|
|
8396
|
-
/* @__PURE__ */ (0,
|
|
8777
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)("div", { "aria-live": "polite", "data-testid": "insert-table-size", children: disabled ? status.reason : hover ? `${hover.rows} \xD7 ${hover.cols}` : "Insert table" })
|
|
8397
8778
|
]
|
|
8398
8779
|
}
|
|
8399
8780
|
);
|
|
@@ -8401,31 +8782,31 @@ var InsertTableGrid = ({
|
|
|
8401
8782
|
|
|
8402
8783
|
// src/tables/TableBubbleMenu.tsx
|
|
8403
8784
|
var import_editor20 = require("@pixerate/editor");
|
|
8404
|
-
var
|
|
8785
|
+
var import_jsx_runtime43 = require("react/jsx-runtime");
|
|
8405
8786
|
var TableBubbleMenu = ({
|
|
8406
8787
|
editor,
|
|
8407
8788
|
children,
|
|
8408
8789
|
toolbarProps,
|
|
8409
8790
|
pluginKey = "tableBubbleMenu",
|
|
8410
8791
|
...rest
|
|
8411
|
-
}) => /* @__PURE__ */ (0,
|
|
8792
|
+
}) => /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(BubbleMenu, { editor, pluginKey, shouldShow: import_editor20.shouldShowTableBubbleMenu, ...rest, children: children ?? /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(TableToolbar, { editor, ...toolbarProps }) });
|
|
8412
8793
|
|
|
8413
8794
|
// src/chart-node/ChartNodeView.tsx
|
|
8414
8795
|
var import_client = require("react-dom/client");
|
|
8415
8796
|
|
|
8416
8797
|
// src/chart/ChartCanvas.tsx
|
|
8417
|
-
var
|
|
8798
|
+
var import_react64 = require("react");
|
|
8418
8799
|
var import_chart2 = require("@pixerate/editor/chart");
|
|
8419
8800
|
|
|
8420
8801
|
// src/chart/useChartEditor.ts
|
|
8421
|
-
var
|
|
8802
|
+
var import_react63 = require("react");
|
|
8422
8803
|
var import_chart = require("@pixerate/editor/chart");
|
|
8423
8804
|
function useChartState(controller) {
|
|
8424
|
-
return (0,
|
|
8805
|
+
return (0, import_react63.useSyncExternalStore)(controller.subscribe, controller.getState, controller.getState);
|
|
8425
8806
|
}
|
|
8426
8807
|
|
|
8427
8808
|
// src/chart/ChartCanvas.tsx
|
|
8428
|
-
var
|
|
8809
|
+
var import_jsx_runtime44 = require("react/jsx-runtime");
|
|
8429
8810
|
function renderChartMark(mark, fontFamily, interactive) {
|
|
8430
8811
|
const common = {
|
|
8431
8812
|
"data-role": mark.role,
|
|
@@ -8437,9 +8818,9 @@ function renderChartMark(mark, fontFamily, interactive) {
|
|
|
8437
8818
|
};
|
|
8438
8819
|
switch (mark.kind) {
|
|
8439
8820
|
case "rect":
|
|
8440
|
-
return /* @__PURE__ */ (0,
|
|
8821
|
+
return /* @__PURE__ */ (0, import_jsx_runtime44.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);
|
|
8441
8822
|
case "path":
|
|
8442
|
-
return /* @__PURE__ */ (0,
|
|
8823
|
+
return /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
|
|
8443
8824
|
"path",
|
|
8444
8825
|
{
|
|
8445
8826
|
...common,
|
|
@@ -8452,11 +8833,11 @@ function renderChartMark(mark, fontFamily, interactive) {
|
|
|
8452
8833
|
mark.key
|
|
8453
8834
|
);
|
|
8454
8835
|
case "circle":
|
|
8455
|
-
return /* @__PURE__ */ (0,
|
|
8836
|
+
return /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("circle", { ...common, cx: mark.cx, cy: mark.cy, r: mark.r, style: { fill: mark.fill, stroke: mark.stroke, strokeWidth: mark.strokeWidth } }, mark.key);
|
|
8456
8837
|
case "line":
|
|
8457
|
-
return /* @__PURE__ */ (0,
|
|
8838
|
+
return /* @__PURE__ */ (0, import_jsx_runtime44.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);
|
|
8458
8839
|
case "text":
|
|
8459
|
-
return /* @__PURE__ */ (0,
|
|
8840
|
+
return /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
|
|
8460
8841
|
"text",
|
|
8461
8842
|
{
|
|
8462
8843
|
...common,
|
|
@@ -8473,23 +8854,23 @@ function renderChartMark(mark, fontFamily, interactive) {
|
|
|
8473
8854
|
}
|
|
8474
8855
|
}
|
|
8475
8856
|
function ChartPresenceLayer({ presence }) {
|
|
8476
|
-
const { actors } = (0,
|
|
8477
|
-
return /* @__PURE__ */ (0,
|
|
8478
|
-
/* @__PURE__ */ (0,
|
|
8479
|
-
/* @__PURE__ */ (0,
|
|
8480
|
-
/* @__PURE__ */ (0,
|
|
8481
|
-
/* @__PURE__ */ (0,
|
|
8857
|
+
const { actors } = (0, import_react64.useSyncExternalStore)(presence.subscribe, presence.getState, presence.getState);
|
|
8858
|
+
return /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("g", { "data-chart-presence": "", pointerEvents: "none", children: actors.map((a) => /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("g", { transform: `translate(${a.x} ${a.y})`, "data-actor": a.id, children: [
|
|
8859
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.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 }),
|
|
8860
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("g", { transform: "translate(13 16)", children: [
|
|
8861
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.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 } }),
|
|
8862
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsx)("text", { x: 6, y: 9, dominantBaseline: "central", style: { fill: "#ffffff", fontSize: 11, fontWeight: 600, fontFamily: "inherit" }, children: a.message ?? a.name })
|
|
8482
8863
|
] })
|
|
8483
8864
|
] }, a.id)) });
|
|
8484
8865
|
}
|
|
8485
8866
|
function ChartCanvas({ controller, width = 640, height = 400, responsive = true, theme, editable = true, measureText, emptyMessage, className, presence, sceneRef }) {
|
|
8486
8867
|
const state = useChartState(controller);
|
|
8487
|
-
const wrapper = (0,
|
|
8488
|
-
const svg = (0,
|
|
8489
|
-
const drag = (0,
|
|
8490
|
-
const [measured, setMeasured] = (0,
|
|
8491
|
-
const [frozen, setFrozen] = (0,
|
|
8492
|
-
(0,
|
|
8868
|
+
const wrapper = (0, import_react64.useRef)(null);
|
|
8869
|
+
const svg = (0, import_react64.useRef)(null);
|
|
8870
|
+
const drag = (0, import_react64.useRef)(null);
|
|
8871
|
+
const [measured, setMeasured] = (0, import_react64.useState)(null);
|
|
8872
|
+
const [frozen, setFrozen] = (0, import_react64.useState)(null);
|
|
8873
|
+
(0, import_react64.useEffect)(() => {
|
|
8493
8874
|
const el = wrapper.current;
|
|
8494
8875
|
if (!responsive || !el || typeof ResizeObserver === "undefined") return;
|
|
8495
8876
|
const observer = new ResizeObserver(([entry]) => {
|
|
@@ -8500,8 +8881,8 @@ function ChartCanvas({ controller, width = 640, height = 400, responsive = true,
|
|
|
8500
8881
|
return () => observer.disconnect();
|
|
8501
8882
|
}, [responsive]);
|
|
8502
8883
|
const sceneWidth = responsive && measured || width;
|
|
8503
|
-
const fullTheme = (0,
|
|
8504
|
-
const scene = (0,
|
|
8884
|
+
const fullTheme = (0, import_react64.useMemo)(() => ({ ...import_chart2.CSS_VARIABLE_CHART_THEME, ...theme }), [theme]);
|
|
8885
|
+
const scene = (0, import_react64.useMemo)(
|
|
8505
8886
|
() => (0, import_chart2.layoutChart)(state.spec, {
|
|
8506
8887
|
width: sceneWidth,
|
|
8507
8888
|
height,
|
|
@@ -8517,8 +8898,8 @@ function ChartCanvas({ controller, width = 640, height = 400, responsive = true,
|
|
|
8517
8898
|
[state.spec, state.selection, sceneWidth, height, fullTheme, editable, measureText, emptyMessage, frozen]
|
|
8518
8899
|
);
|
|
8519
8900
|
if (sceneRef) sceneRef.current = scene;
|
|
8520
|
-
const byKey = (0,
|
|
8521
|
-
(0,
|
|
8901
|
+
const byKey = (0, import_react64.useMemo)(() => new Map(scene.marks.map((m) => [m.key, m])), [scene]);
|
|
8902
|
+
(0, import_react64.useEffect)(() => () => drag.current?.end(), []);
|
|
8522
8903
|
const scenePoint = (e) => (0, import_chart2.chartClientToScene)(scene, svg.current.getBoundingClientRect(), e.clientX, e.clientY);
|
|
8523
8904
|
const onPointerDown = (e) => {
|
|
8524
8905
|
if (!editable || e.button !== 0) return;
|
|
@@ -8551,7 +8932,7 @@ function ChartCanvas({ controller, width = 640, height = 400, responsive = true,
|
|
|
8551
8932
|
if (editable && (0, import_chart2.handleChartKey)(controller, scene, e)) e.preventDefault();
|
|
8552
8933
|
};
|
|
8553
8934
|
const label = state.spec.title || "Chart";
|
|
8554
|
-
return /* @__PURE__ */ (0,
|
|
8935
|
+
return /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("div", { ref: wrapper, className: `w-full ${className ?? ""}`, "data-chart-canvas": "", children: /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)(
|
|
8555
8936
|
"svg",
|
|
8556
8937
|
{
|
|
8557
8938
|
ref: svg,
|
|
@@ -8569,14 +8950,14 @@ function ChartCanvas({ controller, width = 640, height = 400, responsive = true,
|
|
|
8569
8950
|
onKeyDown,
|
|
8570
8951
|
children: [
|
|
8571
8952
|
scene.marks.map((m) => renderChartMark(m, scene.theme.fontFamily, editable)),
|
|
8572
|
-
presence && /* @__PURE__ */ (0,
|
|
8953
|
+
presence && /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(ChartPresenceLayer, { presence })
|
|
8573
8954
|
]
|
|
8574
8955
|
}
|
|
8575
8956
|
) });
|
|
8576
8957
|
}
|
|
8577
8958
|
|
|
8578
8959
|
// src/chart/ChartDataGrid.tsx
|
|
8579
|
-
var
|
|
8960
|
+
var import_react65 = require("react");
|
|
8580
8961
|
var import_chart3 = require("@pixerate/editor/chart");
|
|
8581
8962
|
|
|
8582
8963
|
// src/chart/styles.ts
|
|
@@ -8589,11 +8970,11 @@ var chartSectionClass = "space-y-2 border-b border-border pb-3 last:border-b-0";
|
|
|
8589
8970
|
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";
|
|
8590
8971
|
|
|
8591
8972
|
// src/chart/ChartDataGrid.tsx
|
|
8592
|
-
var
|
|
8973
|
+
var import_jsx_runtime45 = require("react/jsx-runtime");
|
|
8593
8974
|
function ChartCommitInput({ value, onCommit, onKeyDown, onBlur, ...rest }) {
|
|
8594
|
-
const [draft, setDraft] = (0,
|
|
8595
|
-
const typing = (0,
|
|
8596
|
-
(0,
|
|
8975
|
+
const [draft, setDraft] = (0, import_react65.useState)(value);
|
|
8976
|
+
const typing = (0, import_react65.useRef)(false);
|
|
8977
|
+
(0, import_react65.useEffect)(() => {
|
|
8597
8978
|
if (!typing.current) setDraft(value);
|
|
8598
8979
|
}, [value]);
|
|
8599
8980
|
const commit = () => {
|
|
@@ -8602,7 +8983,7 @@ function ChartCommitInput({ value, onCommit, onKeyDown, onBlur, ...rest }) {
|
|
|
8602
8983
|
if (draft === value) return;
|
|
8603
8984
|
if (onCommit(draft) === false) setDraft(value);
|
|
8604
8985
|
};
|
|
8605
|
-
return /* @__PURE__ */ (0,
|
|
8986
|
+
return /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
|
|
8606
8987
|
"input",
|
|
8607
8988
|
{
|
|
8608
8989
|
...rest,
|
|
@@ -8637,15 +9018,15 @@ function ChartDataGrid({ controller, categoryHeader = "Category", readOnly = fal
|
|
|
8637
9018
|
e.preventDefault();
|
|
8638
9019
|
controller.pasteCells(row, column, text);
|
|
8639
9020
|
};
|
|
8640
|
-
return /* @__PURE__ */ (0,
|
|
8641
|
-
/* @__PURE__ */ (0,
|
|
8642
|
-
/* @__PURE__ */ (0,
|
|
8643
|
-
/* @__PURE__ */ (0,
|
|
9021
|
+
return /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("div", { className: `overflow-auto rounded-md border border-border ${className ?? ""}`, "data-chart-grid": "", children: [
|
|
9022
|
+
/* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("table", { className: "w-full border-collapse text-xs", children: [
|
|
9023
|
+
/* @__PURE__ */ (0, import_jsx_runtime45.jsx)("thead", { className: "bg-muted/50", children: /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("tr", { children: [
|
|
9024
|
+
/* @__PURE__ */ (0, import_jsx_runtime45.jsx)("th", { className: "border-b border-r border-border px-2 py-1 text-left font-medium text-muted-foreground", children: categoryHeader }),
|
|
8644
9025
|
spec.series.map((s, si) => {
|
|
8645
9026
|
const color = (0, import_chart3.chartSeriesColor)(spec, si);
|
|
8646
9027
|
const selected = selection?.kind === "series" && selection.seriesId === s.id;
|
|
8647
|
-
return /* @__PURE__ */ (0,
|
|
8648
|
-
/* @__PURE__ */ (0,
|
|
9028
|
+
return /* @__PURE__ */ (0, import_jsx_runtime45.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_runtime45.jsxs)("div", { className: "flex items-center gap-1", children: [
|
|
9029
|
+
/* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
|
|
8649
9030
|
"input",
|
|
8650
9031
|
{
|
|
8651
9032
|
type: "color",
|
|
@@ -8658,7 +9039,7 @@ function ChartDataGrid({ controller, categoryHeader = "Category", readOnly = fal
|
|
|
8658
9039
|
className: "h-5 w-5 shrink-0 cursor-pointer rounded border-0 bg-transparent p-0"
|
|
8659
9040
|
}
|
|
8660
9041
|
),
|
|
8661
|
-
/* @__PURE__ */ (0,
|
|
9042
|
+
/* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
|
|
8662
9043
|
ChartCommitInput,
|
|
8663
9044
|
{
|
|
8664
9045
|
value: s.name,
|
|
@@ -8668,8 +9049,8 @@ function ChartDataGrid({ controller, categoryHeader = "Category", readOnly = fal
|
|
|
8668
9049
|
className: `${chartInputClass} h-6 min-w-[5rem] border-transparent bg-transparent font-medium ${s.hidden ? "text-muted-foreground line-through" : ""}`
|
|
8669
9050
|
}
|
|
8670
9051
|
),
|
|
8671
|
-
!readOnly && /* @__PURE__ */ (0,
|
|
8672
|
-
/* @__PURE__ */ (0,
|
|
9052
|
+
!readOnly && /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)(import_jsx_runtime45.Fragment, { children: [
|
|
9053
|
+
/* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
|
|
8673
9054
|
"button",
|
|
8674
9055
|
{
|
|
8675
9056
|
type: "button",
|
|
@@ -8682,16 +9063,16 @@ function ChartDataGrid({ controller, categoryHeader = "Category", readOnly = fal
|
|
|
8682
9063
|
children: s.hidden ? "\u25CB" : "\u25CF"
|
|
8683
9064
|
}
|
|
8684
9065
|
),
|
|
8685
|
-
/* @__PURE__ */ (0,
|
|
9066
|
+
/* @__PURE__ */ (0, import_jsx_runtime45.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" })
|
|
8686
9067
|
] })
|
|
8687
9068
|
] }) }, s.id);
|
|
8688
9069
|
}),
|
|
8689
|
-
!readOnly && /* @__PURE__ */ (0,
|
|
9070
|
+
!readOnly && /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("th", { className: "w-8 border-b border-border px-1", children: /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("button", { type: "button", className: chartIconButtonClass, title: "Add series", "aria-label": "Add series", "data-action": "add-series", onClick: () => controller.addSeries(), children: "+" }) })
|
|
8690
9071
|
] }) }),
|
|
8691
|
-
/* @__PURE__ */ (0,
|
|
9072
|
+
/* @__PURE__ */ (0, import_jsx_runtime45.jsx)("tbody", { children: spec.categories.map((category, i) => {
|
|
8692
9073
|
const rowSelected = selection?.kind === "category" && selection.index === i;
|
|
8693
|
-
return /* @__PURE__ */ (0,
|
|
8694
|
-
/* @__PURE__ */ (0,
|
|
9074
|
+
return /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("tr", { "data-category-index": i, className: rowSelected ? "bg-primary/10" : void 0, children: [
|
|
9075
|
+
/* @__PURE__ */ (0, import_jsx_runtime45.jsx)("th", { className: "border-b border-r border-border p-0 text-left font-normal", children: /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
|
|
8695
9076
|
ChartCommitInput,
|
|
8696
9077
|
{
|
|
8697
9078
|
value: category,
|
|
@@ -8705,7 +9086,7 @@ function ChartDataGrid({ controller, categoryHeader = "Category", readOnly = fal
|
|
|
8705
9086
|
spec.series.map((s) => {
|
|
8706
9087
|
const value = s.values[i];
|
|
8707
9088
|
const selected = selection?.kind === "point" && selection.seriesId === s.id && selection.index === i;
|
|
8708
|
-
return /* @__PURE__ */ (0,
|
|
9089
|
+
return /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("td", { className: `border-b border-r border-border p-0 ${selected ? "bg-primary/10" : ""}`, children: /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
|
|
8709
9090
|
ChartCommitInput,
|
|
8710
9091
|
{
|
|
8711
9092
|
value: value === null || value === void 0 ? "" : String(value),
|
|
@@ -8720,38 +9101,38 @@ function ChartDataGrid({ controller, categoryHeader = "Category", readOnly = fal
|
|
|
8720
9101
|
}
|
|
8721
9102
|
) }, s.id);
|
|
8722
9103
|
}),
|
|
8723
|
-
!readOnly && /* @__PURE__ */ (0,
|
|
9104
|
+
!readOnly && /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("td", { className: "border-b border-border px-1", children: /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("button", { type: "button", className: chartIconButtonClass, title: "Delete category", "aria-label": `Delete ${category}`, "data-action": "remove-category", onClick: () => controller.removeCategory(i), children: "\xD7" }) })
|
|
8724
9105
|
] }, i);
|
|
8725
9106
|
}) })
|
|
8726
9107
|
] }),
|
|
8727
|
-
!readOnly && /* @__PURE__ */ (0,
|
|
9108
|
+
!readOnly && /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("div", { className: "p-1", children: /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("button", { type: "button", className: `${chartButtonClass} h-6 border-dashed`, "data-action": "add-category", onClick: () => controller.addCategory(), children: "+ Add category" }) })
|
|
8728
9109
|
] });
|
|
8729
9110
|
}
|
|
8730
9111
|
|
|
8731
9112
|
// src/chart/ChartInspector.tsx
|
|
8732
|
-
var
|
|
9113
|
+
var import_react66 = require("react");
|
|
8733
9114
|
var import_chart4 = require("@pixerate/editor/chart");
|
|
8734
|
-
var
|
|
9115
|
+
var import_jsx_runtime46 = require("react/jsx-runtime");
|
|
8735
9116
|
var cap = (s) => s.charAt(0).toUpperCase() + s.slice(1);
|
|
8736
9117
|
function Field({ label, htmlFor, children }) {
|
|
8737
|
-
return /* @__PURE__ */ (0,
|
|
8738
|
-
/* @__PURE__ */ (0,
|
|
8739
|
-
/* @__PURE__ */ (0,
|
|
9118
|
+
return /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
9119
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsx)("label", { htmlFor, className: `${chartLabelClass} w-20 shrink-0`, children: label }),
|
|
9120
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsx)("div", { className: "min-w-0 flex-1", children })
|
|
8740
9121
|
] });
|
|
8741
9122
|
}
|
|
8742
9123
|
function Toggle({ label, checked, onChange, name }) {
|
|
8743
|
-
return /* @__PURE__ */ (0,
|
|
8744
|
-
/* @__PURE__ */ (0,
|
|
9124
|
+
return /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("label", { className: "flex cursor-pointer items-center gap-2 text-xs text-foreground", children: [
|
|
9125
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsx)("input", { type: "checkbox", className: "h-3.5 w-3.5 accent-primary", checked, "data-option": name, onChange: (e) => onChange(e.currentTarget.checked) }),
|
|
8745
9126
|
label
|
|
8746
9127
|
] });
|
|
8747
9128
|
}
|
|
8748
9129
|
function Select({ id, value, options, onChange, name, labels }) {
|
|
8749
|
-
return /* @__PURE__ */ (0,
|
|
9130
|
+
return /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("select", { id, className: chartInputClass, value, "data-option": name, onChange: (e) => onChange(e.currentTarget.value), children: options.map((o) => /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("option", { value: o, children: labels?.[o] ?? cap(o) }, o)) });
|
|
8750
9131
|
}
|
|
8751
9132
|
function AxisSection({ controller, axis, value, idBase, horizontal, numeric = false, scales = false }) {
|
|
8752
9133
|
const set = (patch) => controller.setAxis(axis, patch);
|
|
8753
9134
|
const setFormat = (patch) => set({ format: { ...value.format, ...patch } });
|
|
8754
|
-
const bound = (key2) => /* @__PURE__ */ (0,
|
|
9135
|
+
const bound = (key2) => /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
|
|
8755
9136
|
ChartCommitInput,
|
|
8756
9137
|
{
|
|
8757
9138
|
id: `${idBase}-${axis}-${key2}`,
|
|
@@ -8766,26 +9147,26 @@ function AxisSection({ controller, axis, value, idBase, horizontal, numeric = fa
|
|
|
8766
9147
|
const name = axis === "x" ? numeric ? "X axis" : "Category axis" : axis === "y" ? "Value axis" : "Secondary axis";
|
|
8767
9148
|
const valueAxis = axis !== "x" || numeric;
|
|
8768
9149
|
const key = axis === "y2" ? "yAxis2" : `${axis}Axis`;
|
|
8769
|
-
return /* @__PURE__ */ (0,
|
|
8770
|
-
/* @__PURE__ */ (0,
|
|
8771
|
-
/* @__PURE__ */ (0,
|
|
9150
|
+
return /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("div", { className: chartSectionClass, "data-section": `axis-${axis}`, children: [
|
|
9151
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("div", { className: "flex items-center justify-between", children: [
|
|
9152
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("h4", { className: "text-xs font-semibold text-foreground", children: [
|
|
8772
9153
|
name,
|
|
8773
|
-
/* @__PURE__ */ (0,
|
|
9154
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("span", { className: "ml-1 font-normal text-muted-foreground", children: [
|
|
8774
9155
|
"(",
|
|
8775
9156
|
axis === "x" ? horizontal ? "left" : "bottom" : axis === "y2" ? horizontal ? "top" : "right" : horizontal ? "bottom" : "left",
|
|
8776
9157
|
")"
|
|
8777
9158
|
] })
|
|
8778
9159
|
] }),
|
|
8779
|
-
/* @__PURE__ */ (0,
|
|
9160
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsx)(Toggle, { label: "Show", name: `${axis}Axis.show`, checked: value.show, onChange: (show) => set({ show }) })
|
|
8780
9161
|
] }),
|
|
8781
|
-
/* @__PURE__ */ (0,
|
|
8782
|
-
/* @__PURE__ */ (0,
|
|
8783
|
-
/* @__PURE__ */ (0,
|
|
8784
|
-
axis === "x" && !numeric && /* @__PURE__ */ (0,
|
|
8785
|
-
scales && /* @__PURE__ */ (0,
|
|
8786
|
-
scales && valueAxis && /* @__PURE__ */ (0,
|
|
9162
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsx)(Field, { label: "Title", htmlFor: `${idBase}-${axis}-title`, children: /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(ChartCommitInput, { id: `${idBase}-${axis}-title`, value: value.title, "data-option": `${axis}Axis.title`, className: chartInputClass, onCommit: (title) => void set({ title }) }) }),
|
|
9163
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("div", { className: "flex flex-wrap gap-x-4 gap-y-1", children: [
|
|
9164
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsx)(Toggle, { label: "Grid lines", name: `${key}.gridlines`, checked: value.gridlines, onChange: (gridlines) => set({ gridlines }) }),
|
|
9165
|
+
axis === "x" && !numeric && /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(Toggle, { label: "Dates", name: "xAxis.kind", checked: value.kind === "date", onChange: (dates) => set({ kind: dates ? "date" : void 0 }) }),
|
|
9166
|
+
scales && /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(Toggle, { label: "Reverse", name: `${key}.reverse`, checked: !!value.reverse, onChange: (reverse) => set({ reverse }) }),
|
|
9167
|
+
scales && valueAxis && /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(Toggle, { label: "Log scale", name: `${key}.scale`, checked: value.scale === "log", onChange: (log) => set({ scale: log ? "log" : "linear" }) })
|
|
8787
9168
|
] }),
|
|
8788
|
-
scales && valueAxis && value.scale === "log" && /* @__PURE__ */ (0,
|
|
9169
|
+
scales && valueAxis && value.scale === "log" && /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(Field, { label: "Log base", htmlFor: `${idBase}-${axis}-log-base`, children: /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
|
|
8789
9170
|
ChartCommitInput,
|
|
8790
9171
|
{
|
|
8791
9172
|
id: `${idBase}-${axis}-log-base`,
|
|
@@ -8796,7 +9177,7 @@ function AxisSection({ controller, axis, value, idBase, horizontal, numeric = fa
|
|
|
8796
9177
|
onCommit: (text) => set({ logBase: text.trim() === "" ? void 0 : Number(text) }).ok
|
|
8797
9178
|
}
|
|
8798
9179
|
) }),
|
|
8799
|
-
valueAxis && value.scale !== "log" && /* @__PURE__ */ (0,
|
|
9180
|
+
valueAxis && value.scale !== "log" && /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(Field, { label: "Step", htmlFor: `${idBase}-${axis}-step`, children: /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
|
|
8800
9181
|
ChartCommitInput,
|
|
8801
9182
|
{
|
|
8802
9183
|
id: `${idBase}-${axis}-step`,
|
|
@@ -8808,14 +9189,14 @@ function AxisSection({ controller, axis, value, idBase, horizontal, numeric = fa
|
|
|
8808
9189
|
onCommit: (text) => set({ step: text.trim() === "" ? null : Number(text) }).ok
|
|
8809
9190
|
}
|
|
8810
9191
|
) }),
|
|
8811
|
-
valueAxis && /* @__PURE__ */ (0,
|
|
8812
|
-
/* @__PURE__ */ (0,
|
|
9192
|
+
valueAxis && /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)(import_jsx_runtime46.Fragment, { children: [
|
|
9193
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsx)(Field, { label: "Min / max", children: /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("div", { className: "flex gap-1", children: [
|
|
8813
9194
|
bound("min"),
|
|
8814
9195
|
bound("max")
|
|
8815
9196
|
] }) }),
|
|
8816
|
-
/* @__PURE__ */ (0,
|
|
8817
|
-
/* @__PURE__ */ (0,
|
|
8818
|
-
/* @__PURE__ */ (0,
|
|
9197
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsx)(Field, { label: "Format", htmlFor: `${idBase}-${axis}-format`, children: /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("div", { className: "flex gap-1", children: [
|
|
9198
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.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 }) }),
|
|
9199
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
|
|
8819
9200
|
ChartCommitInput,
|
|
8820
9201
|
{
|
|
8821
9202
|
value: value.format.decimals === void 0 ? "" : String(value.format.decimals),
|
|
@@ -8834,8 +9215,8 @@ function AxisSection({ controller, axis, value, idBase, horizontal, numeric = fa
|
|
|
8834
9215
|
}
|
|
8835
9216
|
)
|
|
8836
9217
|
] }) }),
|
|
8837
|
-
value.format.style === "currency" && /* @__PURE__ */ (0,
|
|
8838
|
-
/* @__PURE__ */ (0,
|
|
9218
|
+
value.format.style === "currency" && /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(Field, { label: "Currency", htmlFor: `${idBase}-${axis}-currency`, children: /* @__PURE__ */ (0, import_jsx_runtime46.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() }) }) }),
|
|
9219
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsx)(Field, { label: "Code", htmlFor: `${idBase}-${axis}-code`, children: /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
|
|
8839
9220
|
ChartCommitInput,
|
|
8840
9221
|
{
|
|
8841
9222
|
id: `${idBase}-${axis}-code`,
|
|
@@ -8861,15 +9242,15 @@ function ErrorBarFields({ controller, series, which, idBase }) {
|
|
|
8861
9242
|
const values = which === "xErrorBars" ? series.x ?? [] : series.values;
|
|
8862
9243
|
const set = (next) => controller.updateSeries(series.id, { [which]: next });
|
|
8863
9244
|
const patch = (p) => bars && set({ ...bars, ...p });
|
|
8864
|
-
return /* @__PURE__ */ (0,
|
|
8865
|
-
/* @__PURE__ */ (0,
|
|
8866
|
-
/* @__PURE__ */ (0,
|
|
8867
|
-
import_chart4.CHART_ERROR_BAR_TYPES.map((t) => /* @__PURE__ */ (0,
|
|
9245
|
+
return /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("div", { className: "space-y-1.5", "data-section": which === "errorBars" ? "error-bars" : "x-error-bars", children: [
|
|
9246
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsx)(Field, { label: which === "errorBars" ? "Error bars" : "X error bars", htmlFor: `${id}-type`, children: /* @__PURE__ */ (0, import_jsx_runtime46.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: [
|
|
9247
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsx)("option", { value: "", children: "None" }),
|
|
9248
|
+
import_chart4.CHART_ERROR_BAR_TYPES.map((t) => /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("option", { value: t, children: import_chart4.CHART_ERROR_BAR_LABELS[t] }, t))
|
|
8868
9249
|
] }) }),
|
|
8869
|
-
bars && (bars.type === "fixed" || bars.type === "percent" || bars.type === "stddev") && /* @__PURE__ */ (0,
|
|
8870
|
-
bars?.type === "custom" && /* @__PURE__ */ (0,
|
|
8871
|
-
/* @__PURE__ */ (0,
|
|
8872
|
-
/* @__PURE__ */ (0,
|
|
9250
|
+
bars && (bars.type === "fixed" || bars.type === "percent" || bars.type === "stddev") && /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(Field, { label: bars.type === "percent" ? "Percent" : bars.type === "stddev" ? "Deviations" : "Amount", htmlFor: `${id}-value`, children: /* @__PURE__ */ (0, import_jsx_runtime46.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 }) }),
|
|
9251
|
+
bars?.type === "custom" && /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)(import_jsx_runtime46.Fragment, { children: [
|
|
9252
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsx)(Field, { label: "Plus", htmlFor: `${id}-plus`, children: /* @__PURE__ */ (0, import_jsx_runtime46.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 }) }),
|
|
9253
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsx)(Field, { label: "Minus", htmlFor: `${id}-minus`, children: /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
|
|
8873
9254
|
ChartCommitInput,
|
|
8874
9255
|
{
|
|
8875
9256
|
id: `${id}-minus`,
|
|
@@ -8886,15 +9267,15 @@ function ErrorBarFields({ controller, series, which, idBase }) {
|
|
|
8886
9267
|
}
|
|
8887
9268
|
) })
|
|
8888
9269
|
] }),
|
|
8889
|
-
bars && /* @__PURE__ */ (0,
|
|
8890
|
-
/* @__PURE__ */ (0,
|
|
8891
|
-
/* @__PURE__ */ (0,
|
|
9270
|
+
bars && /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
9271
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.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_runtime46.jsx)("option", { value: d, children: d === "both" ? "Both ways" : d === "plus" ? "Plus only" : "Minus only" }, d)) }),
|
|
9272
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsx)(Toggle, { label: "Caps", name: `${key}.cap`, checked: bars.cap !== false, onChange: (cap2) => patch({ cap: cap2 }) })
|
|
8892
9273
|
] })
|
|
8893
9274
|
] });
|
|
8894
9275
|
}
|
|
8895
9276
|
function ChartInspector({ controller, sections, className }) {
|
|
8896
9277
|
const { spec, selectedSeries } = useChartState(controller);
|
|
8897
|
-
const idBase = (0,
|
|
9278
|
+
const idBase = (0, import_react66.useId)();
|
|
8898
9279
|
const show = (section) => !sections || sections.includes(section);
|
|
8899
9280
|
const cartesian = (0, import_chart4.isCartesianChart)(spec.type);
|
|
8900
9281
|
const family = (0, import_chart4.chartFamily)(spec);
|
|
@@ -8906,29 +9287,29 @@ function ChartInspector({ controller, sections, className }) {
|
|
|
8906
9287
|
const hasLines = cartesian && types.some((t) => t === "line" || t === "area");
|
|
8907
9288
|
const seriesIndex = selectedSeries ? spec.series.findIndex((s) => s.id === selectedSeries.id) : -1;
|
|
8908
9289
|
const scales = family === "cartesian" || family === "xy";
|
|
8909
|
-
return /* @__PURE__ */ (0,
|
|
8910
|
-
show("type") && /* @__PURE__ */ (0,
|
|
8911
|
-
show("style") && /* @__PURE__ */ (0,
|
|
8912
|
-
/* @__PURE__ */ (0,
|
|
8913
|
-
/* @__PURE__ */ (0,
|
|
8914
|
-
import_chart4.CHART_LAYOUT_PRESETS.map((p) => /* @__PURE__ */ (0,
|
|
9290
|
+
return /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("div", { className: `space-y-3 text-xs ${className ?? ""}`, "data-chart-inspector": "", children: [
|
|
9291
|
+
show("type") && /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("div", { className: chartSectionClass, "data-section": "type", children: /* @__PURE__ */ (0, import_jsx_runtime46.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_runtime46.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)) }) }),
|
|
9292
|
+
show("style") && /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("div", { className: chartSectionClass, "data-section": "style", children: [
|
|
9293
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsx)(Field, { label: "Layout", htmlFor: `${idBase}-layout`, children: /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("select", { id: `${idBase}-layout`, className: chartInputClass, value: "", "data-option": "preset.layout", onChange: (e) => e.currentTarget.value && controller.applyPreset({ layout: e.currentTarget.value }), children: [
|
|
9294
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsx)("option", { value: "", children: "Quick layout\u2026" }),
|
|
9295
|
+
import_chart4.CHART_LAYOUT_PRESETS.map((p) => /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("option", { value: p.id, title: p.description, children: p.label }, p.id))
|
|
8915
9296
|
] }) }),
|
|
8916
|
-
/* @__PURE__ */ (0,
|
|
8917
|
-
/* @__PURE__ */ (0,
|
|
8918
|
-
import_chart4.CHART_COLOR_SCHEMES.map((c) => /* @__PURE__ */ (0,
|
|
9297
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsx)(Field, { label: "Colours", htmlFor: `${idBase}-colors`, children: /* @__PURE__ */ (0, import_jsx_runtime46.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: [
|
|
9298
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsx)("option", { value: "", children: "Custom" }),
|
|
9299
|
+
import_chart4.CHART_COLOR_SCHEMES.map((c) => /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("option", { value: c.id, title: c.description, children: c.label }, c.id))
|
|
8919
9300
|
] }) }),
|
|
8920
|
-
!colorCheck.ok && /* @__PURE__ */ (0,
|
|
8921
|
-
/* @__PURE__ */ (0,
|
|
9301
|
+
!colorCheck.ok && /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("p", { className: "text-[11px] leading-snug text-amber-600 dark:text-amber-400", "data-chart-color-warning": "", children: colorCheck.issues[0] }),
|
|
9302
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsx)("button", { type: "button", className: chartButtonClass, "data-action": "transpose", onClick: () => controller.transpose(), children: "Switch rows and columns" })
|
|
8922
9303
|
] }),
|
|
8923
|
-
show("titles") && /* @__PURE__ */ (0,
|
|
8924
|
-
/* @__PURE__ */ (0,
|
|
8925
|
-
/* @__PURE__ */ (0,
|
|
9304
|
+
show("titles") && /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("div", { className: chartSectionClass, "data-section": "titles", children: [
|
|
9305
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsx)(Field, { label: "Title", htmlFor: `${idBase}-title`, children: /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(ChartCommitInput, { id: `${idBase}-title`, value: spec.title, "data-option": "title", className: chartInputClass, onCommit: (title) => void controller.setTitle(title) }) }),
|
|
9306
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsx)(Field, { label: "Subtitle", htmlFor: `${idBase}-subtitle`, children: /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(ChartCommitInput, { id: `${idBase}-subtitle`, value: spec.subtitle, "data-option": "subtitle", className: chartInputClass, onCommit: (subtitle) => void controller.setSubtitle(subtitle) }) })
|
|
8926
9307
|
] }),
|
|
8927
|
-
show("options") && /* @__PURE__ */ (0,
|
|
8928
|
-
cartesian && /* @__PURE__ */ (0,
|
|
8929
|
-
hasBars && /* @__PURE__ */ (0,
|
|
8930
|
-
hasLines && /* @__PURE__ */ (0,
|
|
8931
|
-
spec.type === "donut" && /* @__PURE__ */ (0,
|
|
9308
|
+
show("options") && /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("div", { className: chartSectionClass, "data-section": "options", children: [
|
|
9309
|
+
cartesian && /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(Field, { label: "Stacking", htmlFor: `${idBase}-stacking`, children: /* @__PURE__ */ (0, import_jsx_runtime46.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 }) }) }),
|
|
9310
|
+
hasBars && /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(Field, { label: "Bars", children: /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("div", { className: "flex gap-0.5 rounded-md bg-muted p-0.5", children: ["vertical", "horizontal"].map((o) => /* @__PURE__ */ (0, import_jsx_runtime46.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)) }) }),
|
|
9311
|
+
hasLines && /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(Field, { label: "Lines", htmlFor: `${idBase}-curve`, children: /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(Select, { id: `${idBase}-curve`, name: "curve", value: spec.curve, options: import_chart4.CHART_CURVES, onChange: (curve) => controller.update({ curve }) }) }),
|
|
9312
|
+
spec.type === "donut" && /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(Field, { label: "Hole", htmlFor: `${idBase}-hole`, children: /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
|
|
8932
9313
|
"input",
|
|
8933
9314
|
{
|
|
8934
9315
|
id: `${idBase}-hole`,
|
|
@@ -8944,7 +9325,7 @@ function ChartInspector({ controller, sections, className }) {
|
|
|
8944
9325
|
onChange: (e) => controller.update({ innerRadius: Number(e.currentTarget.value) })
|
|
8945
9326
|
}
|
|
8946
9327
|
) }),
|
|
8947
|
-
hasBars && /* @__PURE__ */ (0,
|
|
9328
|
+
hasBars && /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(Field, { label: "Spacing", htmlFor: `${idBase}-gap`, children: /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
|
|
8948
9329
|
"input",
|
|
8949
9330
|
{
|
|
8950
9331
|
id: `${idBase}-gap`,
|
|
@@ -8960,31 +9341,31 @@ function ChartInspector({ controller, sections, className }) {
|
|
|
8960
9341
|
onChange: (e) => controller.update({ gapWidth: Number(e.currentTarget.value) })
|
|
8961
9342
|
}
|
|
8962
9343
|
) }),
|
|
8963
|
-
spec.dataLabels && hasBars && /* @__PURE__ */ (0,
|
|
8964
|
-
spec.type === "histogram" && /* @__PURE__ */ (0,
|
|
8965
|
-
/* @__PURE__ */ (0,
|
|
8966
|
-
spec.type === "waterfall" && /* @__PURE__ */ (0,
|
|
8967
|
-
hasLines && /* @__PURE__ */ (0,
|
|
8968
|
-
/* @__PURE__ */ (0,
|
|
9344
|
+
spec.dataLabels && hasBars && /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(Field, { label: "Labels", htmlFor: `${idBase}-label-position`, children: /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(Select, { id: `${idBase}-label-position`, name: "labelPosition", value: spec.labelPosition, options: import_chart4.CHART_LABEL_POSITIONS, onChange: (labelPosition) => controller.update({ labelPosition }) }) }),
|
|
9345
|
+
spec.type === "histogram" && /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(Field, { label: "Bins", htmlFor: `${idBase}-bins`, children: /* @__PURE__ */ (0, import_jsx_runtime46.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 }) }),
|
|
9346
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("div", { className: "flex flex-wrap gap-x-4 gap-y-1", children: [
|
|
9347
|
+
spec.type === "waterfall" && /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(Toggle, { label: "Total bar", name: "showTotal", checked: spec.showTotal, onChange: (showTotal) => controller.update({ showTotal }) }),
|
|
9348
|
+
hasLines && /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(Toggle, { label: "Points", name: "points", checked: spec.points, onChange: (points) => controller.update({ points }) }),
|
|
9349
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsx)(Toggle, { label: "Data labels", name: "dataLabels", checked: spec.dataLabels, onChange: (dataLabels) => controller.update({ dataLabels }) })
|
|
8969
9350
|
] })
|
|
8970
9351
|
] }),
|
|
8971
|
-
show("legend") && /* @__PURE__ */ (0,
|
|
8972
|
-
/* @__PURE__ */ (0,
|
|
8973
|
-
/* @__PURE__ */ (0,
|
|
8974
|
-
/* @__PURE__ */ (0,
|
|
9352
|
+
show("legend") && /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("div", { className: chartSectionClass, "data-section": "legend", children: [
|
|
9353
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("div", { className: "flex items-center justify-between", children: [
|
|
9354
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsx)("h4", { className: "text-xs font-semibold text-foreground", children: "Legend" }),
|
|
9355
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsx)(Toggle, { label: "Show", name: "legend.show", checked: spec.legend.show, onChange: (v) => controller.setLegend({ show: v }) })
|
|
8975
9356
|
] }),
|
|
8976
|
-
spec.legend.show && /* @__PURE__ */ (0,
|
|
9357
|
+
spec.legend.show && /* @__PURE__ */ (0, import_jsx_runtime46.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_runtime46.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)) })
|
|
8977
9358
|
] }),
|
|
8978
|
-
show("axes") && hasAxes && /* @__PURE__ */ (0,
|
|
8979
|
-
family !== "box" && family !== "histogram" && /* @__PURE__ */ (0,
|
|
8980
|
-
/* @__PURE__ */ (0,
|
|
8981
|
-
usesSecondary && /* @__PURE__ */ (0,
|
|
9359
|
+
show("axes") && hasAxes && /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)(import_jsx_runtime46.Fragment, { children: [
|
|
9360
|
+
family !== "box" && family !== "histogram" && /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(AxisSection, { controller, axis: "x", value: spec.xAxis, idBase, horizontal: spec.orientation === "horizontal", numeric: family === "xy", scales }),
|
|
9361
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsx)(AxisSection, { controller, axis: "y", value: spec.yAxis, idBase, horizontal: spec.orientation === "horizontal", scales }),
|
|
9362
|
+
usesSecondary && /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(AxisSection, { controller, axis: "y2", value: spec.yAxis2, idBase, horizontal: spec.orientation === "horizontal", scales })
|
|
8982
9363
|
] }),
|
|
8983
|
-
show("series") && selectedSeries && /* @__PURE__ */ (0,
|
|
8984
|
-
/* @__PURE__ */ (0,
|
|
8985
|
-
/* @__PURE__ */ (0,
|
|
8986
|
-
/* @__PURE__ */ (0,
|
|
8987
|
-
/* @__PURE__ */ (0,
|
|
9364
|
+
show("series") && selectedSeries && /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("div", { className: chartSectionClass, "data-section": "series", "data-series-id": selectedSeries.id, children: [
|
|
9365
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsx)("h4", { className: "text-xs font-semibold text-foreground", children: "Series" }),
|
|
9366
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsx)(Field, { label: "Name", htmlFor: `${idBase}-series-name`, children: /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(ChartCommitInput, { id: `${idBase}-series-name`, value: selectedSeries.name, "data-option": "series.name", className: chartInputClass, onCommit: (name) => void controller.updateSeries(selectedSeries.id, { name }) }) }),
|
|
9367
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsx)(Field, { label: "Colour", htmlFor: `${idBase}-series-color`, children: /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("div", { className: "flex items-center gap-1", children: [
|
|
9368
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
|
|
8988
9369
|
"input",
|
|
8989
9370
|
{
|
|
8990
9371
|
id: `${idBase}-series-color`,
|
|
@@ -8997,9 +9378,9 @@ function ChartInspector({ controller, sections, className }) {
|
|
|
8997
9378
|
onChange: (e) => controller.updateSeries(selectedSeries.id, { color: e.currentTarget.value })
|
|
8998
9379
|
}
|
|
8999
9380
|
),
|
|
9000
|
-
selectedSeries.color && /* @__PURE__ */ (0,
|
|
9381
|
+
selectedSeries.color && /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("button", { type: "button", className: chartButtonClass, "data-action": "reset-color", onClick: () => controller.updateSeries(selectedSeries.id, { color: null }), children: "Palette" })
|
|
9001
9382
|
] }) }),
|
|
9002
|
-
cartesian && /* @__PURE__ */ (0,
|
|
9383
|
+
cartesian && /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(Field, { label: "Draw as", htmlFor: `${idBase}-series-type`, children: /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)(
|
|
9003
9384
|
"select",
|
|
9004
9385
|
{
|
|
9005
9386
|
id: `${idBase}-series-type`,
|
|
@@ -9008,12 +9389,12 @@ function ChartInspector({ controller, sections, className }) {
|
|
|
9008
9389
|
"data-option": "series.type",
|
|
9009
9390
|
onChange: (e) => controller.updateSeries(selectedSeries.id, { type: e.currentTarget.value || null }),
|
|
9010
9391
|
children: [
|
|
9011
|
-
/* @__PURE__ */ (0,
|
|
9012
|
-
import_chart4.CHART_SERIES_TYPES.map((t) => /* @__PURE__ */ (0,
|
|
9392
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsx)("option", { value: "", children: "Chart type" }),
|
|
9393
|
+
import_chart4.CHART_SERIES_TYPES.map((t) => /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("option", { value: t, children: import_chart4.CHART_TYPE_LABELS[t] }, t))
|
|
9013
9394
|
]
|
|
9014
9395
|
}
|
|
9015
9396
|
) }),
|
|
9016
|
-
(cartesian || family === "xy") && ["line", "area", "scatter"].includes((0, import_chart4.chartSeriesType)(spec, selectedSeries)) && /* @__PURE__ */ (0,
|
|
9397
|
+
(cartesian || family === "xy") && ["line", "area", "scatter"].includes((0, import_chart4.chartSeriesType)(spec, selectedSeries)) && /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(Field, { label: "Marker", htmlFor: `${idBase}-series-marker`, children: /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)(
|
|
9017
9398
|
"select",
|
|
9018
9399
|
{
|
|
9019
9400
|
id: `${idBase}-series-marker`,
|
|
@@ -9022,20 +9403,20 @@ function ChartInspector({ controller, sections, className }) {
|
|
|
9022
9403
|
"data-option": "series.marker",
|
|
9023
9404
|
onChange: (e) => controller.updateSeries(selectedSeries.id, { marker: e.currentTarget.value || null }),
|
|
9024
9405
|
children: [
|
|
9025
|
-
/* @__PURE__ */ (0,
|
|
9026
|
-
import_chart4.CHART_MARKERS.map((m) => /* @__PURE__ */ (0,
|
|
9406
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsx)("option", { value: "", children: "Default" }),
|
|
9407
|
+
import_chart4.CHART_MARKERS.map((m) => /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("option", { value: m, children: cap(m) }, m))
|
|
9027
9408
|
]
|
|
9028
9409
|
}
|
|
9029
9410
|
) }),
|
|
9030
|
-
scales && /* @__PURE__ */ (0,
|
|
9031
|
-
family === "xy" && /* @__PURE__ */ (0,
|
|
9032
|
-
(0, import_chart4.chartSupportsTrendlines)(spec.type, spec.stacking) && /* @__PURE__ */ (0,
|
|
9033
|
-
(selectedSeries.trendlines ?? []).map((t, i) => /* @__PURE__ */ (0,
|
|
9034
|
-
/* @__PURE__ */ (0,
|
|
9035
|
-
/* @__PURE__ */ (0,
|
|
9036
|
-
/* @__PURE__ */ (0,
|
|
9411
|
+
scales && /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(ErrorBarFields, { controller, series: selectedSeries, which: "errorBars", idBase }),
|
|
9412
|
+
family === "xy" && /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(ErrorBarFields, { controller, series: selectedSeries, which: "xErrorBars", idBase }),
|
|
9413
|
+
(0, import_chart4.chartSupportsTrendlines)(spec.type, spec.stacking) && /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("div", { className: "space-y-1", "data-section": "trendlines", children: [
|
|
9414
|
+
(selectedSeries.trendlines ?? []).map((t, i) => /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("div", { className: "flex items-center gap-1", "data-trendline": i, children: [
|
|
9415
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsx)("span", { className: "flex-1 truncate text-muted-foreground", children: (0, import_chart4.chartTrendlineName)(t, selectedSeries.name) }),
|
|
9416
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsx)(Toggle, { label: "R\xB2", name: `trendline.${i}.showR2`, checked: !!t.showR2, onChange: (showR2) => controller.updateTrendline(selectedSeries.id, i, { showR2 }) }),
|
|
9417
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsx)("button", { type: "button", className: chartButtonClass, "aria-label": "Delete trendline", "data-action": "trendline-delete", onClick: () => controller.removeTrendline(selectedSeries.id, i), children: "\xD7" })
|
|
9037
9418
|
] }, i)),
|
|
9038
|
-
/* @__PURE__ */ (0,
|
|
9419
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsxs)(
|
|
9039
9420
|
"select",
|
|
9040
9421
|
{
|
|
9041
9422
|
className: chartInputClass,
|
|
@@ -9044,32 +9425,32 @@ function ChartInspector({ controller, sections, className }) {
|
|
|
9044
9425
|
"data-option": "trendline.add",
|
|
9045
9426
|
onChange: (e) => e.currentTarget.value && controller.addTrendline(selectedSeries.id, { type: e.currentTarget.value }),
|
|
9046
9427
|
children: [
|
|
9047
|
-
/* @__PURE__ */ (0,
|
|
9048
|
-
import_chart4.CHART_TRENDLINE_TYPES.map((t) => /* @__PURE__ */ (0,
|
|
9428
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsx)("option", { value: "", children: "Add trendline\u2026" }),
|
|
9429
|
+
import_chart4.CHART_TRENDLINE_TYPES.map((t) => /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("option", { value: t, children: cap(t.replace("-", " ")) }, t))
|
|
9049
9430
|
]
|
|
9050
9431
|
}
|
|
9051
9432
|
)
|
|
9052
9433
|
] }),
|
|
9053
|
-
/* @__PURE__ */ (0,
|
|
9054
|
-
/* @__PURE__ */ (0,
|
|
9055
|
-
family === "cartesian" && /* @__PURE__ */ (0,
|
|
9056
|
-
/* @__PURE__ */ (0,
|
|
9057
|
-
/* @__PURE__ */ (0,
|
|
9058
|
-
/* @__PURE__ */ (0,
|
|
9059
|
-
/* @__PURE__ */ (0,
|
|
9434
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("div", { className: "flex flex-wrap items-center gap-1", children: [
|
|
9435
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsx)(Toggle, { label: "Hidden", name: "series.hidden", checked: !!selectedSeries.hidden, onChange: (hidden) => controller.updateSeries(selectedSeries.id, { hidden }) }),
|
|
9436
|
+
family === "cartesian" && /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(Toggle, { label: "Secondary axis", name: "series.axis", checked: selectedSeries.axis === "secondary", onChange: (secondary) => controller.updateSeries(selectedSeries.id, { axis: secondary ? "secondary" : null }) }),
|
|
9437
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsx)("span", { className: "flex-1" }),
|
|
9438
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.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" }),
|
|
9439
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.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" }),
|
|
9440
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsx)("button", { type: "button", className: `${chartButtonClass} text-destructive`, "data-action": "series-delete", onClick: () => controller.removeSeries(selectedSeries.id), children: "Delete" })
|
|
9060
9441
|
] })
|
|
9061
9442
|
] })
|
|
9062
9443
|
] });
|
|
9063
9444
|
}
|
|
9064
9445
|
|
|
9065
9446
|
// src/chart-node/ChartNodeView.tsx
|
|
9066
|
-
var
|
|
9447
|
+
var import_jsx_runtime47 = require("react/jsx-runtime");
|
|
9067
9448
|
function ChartNodeView({ state, theme, showDataGrid = true }) {
|
|
9068
9449
|
const { controller, editing, editable, selected, width, height, setEditing } = state;
|
|
9069
9450
|
const open = () => {
|
|
9070
9451
|
if (editable && !editing) setEditing(true);
|
|
9071
9452
|
};
|
|
9072
|
-
return /* @__PURE__ */ (0,
|
|
9453
|
+
return /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)(
|
|
9073
9454
|
"div",
|
|
9074
9455
|
{
|
|
9075
9456
|
className: `not-prose my-2 rounded-md border bg-background p-1 ${selected ? "border-primary ring-1 ring-primary" : "border-border"}`,
|
|
@@ -9082,24 +9463,24 @@ function ChartNodeView({ state, theme, showDataGrid = true }) {
|
|
|
9082
9463
|
}
|
|
9083
9464
|
},
|
|
9084
9465
|
children: [
|
|
9085
|
-
editing && /* @__PURE__ */ (0,
|
|
9086
|
-
/* @__PURE__ */ (0,
|
|
9087
|
-
/* @__PURE__ */ (0,
|
|
9466
|
+
editing && /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: "mb-1 flex items-center justify-between gap-2 px-1", "data-chart-node-toolbar": "", children: [
|
|
9467
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)("span", { className: "text-xs text-muted-foreground", children: "Editing chart" }),
|
|
9468
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)("button", { type: "button", className: chartButtonClass, "data-action": "done", onClick: () => setEditing(false), children: "Done" })
|
|
9088
9469
|
] }),
|
|
9089
|
-
/* @__PURE__ */ (0,
|
|
9470
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
|
|
9090
9471
|
"div",
|
|
9091
9472
|
{
|
|
9092
9473
|
className: editable && !editing ? "cursor-pointer" : void 0,
|
|
9093
9474
|
onClick: open,
|
|
9094
9475
|
title: editable && !editing ? "Click to edit the chart" : void 0,
|
|
9095
9476
|
"data-chart-node-canvas": "",
|
|
9096
|
-
children: /* @__PURE__ */ (0,
|
|
9477
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(ChartCanvas, { controller, width: width ?? 640, height, responsive: width === null, editable: editing, theme })
|
|
9097
9478
|
}
|
|
9098
9479
|
),
|
|
9099
9480
|
editing && // Wraps by the document's width, not the viewport's: side by side when there is room.
|
|
9100
|
-
/* @__PURE__ */ (0,
|
|
9101
|
-
showDataGrid && /* @__PURE__ */ (0,
|
|
9102
|
-
/* @__PURE__ */ (0,
|
|
9481
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: "mt-2 flex flex-wrap items-start gap-2", "data-chart-node-panel": "", children: [
|
|
9482
|
+
showDataGrid && /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("div", { className: "min-w-0 flex-[1_1_20rem] overflow-x-auto", children: /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(ChartDataGrid, { controller }) }),
|
|
9483
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)(ChartInspector, { controller, className: "max-h-96 min-w-0 flex-[1_1_16rem] overflow-y-auto rounded-md border border-border p-3" })
|
|
9103
9484
|
] })
|
|
9104
9485
|
]
|
|
9105
9486
|
}
|
|
@@ -9117,7 +9498,7 @@ function createReactChartNodeView(options = {}) {
|
|
|
9117
9498
|
scheduled = true;
|
|
9118
9499
|
queueMicrotask(() => {
|
|
9119
9500
|
scheduled = false;
|
|
9120
|
-
if (!destroyed) root.render(/* @__PURE__ */ (0,
|
|
9501
|
+
if (!destroyed) root.render(/* @__PURE__ */ (0, import_jsx_runtime47.jsx)(Component, { ...props, state: latest }));
|
|
9121
9502
|
});
|
|
9122
9503
|
};
|
|
9123
9504
|
schedule();
|
|
@@ -9168,6 +9549,7 @@ function createReactChartNodeView(options = {}) {
|
|
|
9168
9549
|
RefineEdgePanel,
|
|
9169
9550
|
ReviewToolbar,
|
|
9170
9551
|
SelectionOptionsBar,
|
|
9552
|
+
ShapeOptionsBar,
|
|
9171
9553
|
SheetTabs,
|
|
9172
9554
|
SpreadsheetConditionalFormatPanel,
|
|
9173
9555
|
SpreadsheetContextMenu,
|
|
@@ -9180,6 +9562,7 @@ function createReactChartNodeView(options = {}) {
|
|
|
9180
9562
|
TableToolbar,
|
|
9181
9563
|
TemplateRenderer,
|
|
9182
9564
|
TrackedChangesList,
|
|
9565
|
+
TypeOptionsBar,
|
|
9183
9566
|
VariableForm,
|
|
9184
9567
|
bindDirtyToHistory,
|
|
9185
9568
|
createDirtyTracker,
|