@pixerate/editor-react 0.64.0 → 0.66.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-M4WLX3IR.js → chunk-LCTQWNTL.js} +468 -194
- package/dist/chunk-LCTQWNTL.js.map +1 -0
- package/dist/image-editor/index.cjs +505 -232
- package/dist/image-editor/index.cjs.map +1 -1
- package/dist/image-editor/index.d.cts +15 -2
- package/dist/image-editor/index.d.ts +15 -2
- package/dist/image-editor/index.js +3 -1
- package/dist/index.cjs +934 -661
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
- package/dist/chunk-M4WLX3IR.js.map +0 -1
package/dist/index.cjs
CHANGED
|
@@ -46,6 +46,7 @@ __export(src_exports, {
|
|
|
46
46
|
ExportDocxButton: () => ExportDocxButton,
|
|
47
47
|
FindReplaceBar: () => FindReplaceBar,
|
|
48
48
|
FormulaHints: () => FormulaHints,
|
|
49
|
+
FreeTransformOptionsBar: () => FreeTransformOptionsBar,
|
|
49
50
|
GenerationHistory: () => GenerationHistory,
|
|
50
51
|
GenerationSettings: () => GenerationSettings,
|
|
51
52
|
Histogram: () => Histogram,
|
|
@@ -3784,8 +3785,8 @@ function useImageEditor(options = {}) {
|
|
|
3784
3785
|
}
|
|
3785
3786
|
|
|
3786
3787
|
// src/image-editor/ImageEditor.tsx
|
|
3787
|
-
var
|
|
3788
|
-
var
|
|
3788
|
+
var import_react44 = __toESM(require("react"), 1);
|
|
3789
|
+
var import_image_editor12 = require("@pixerate/editor/image-editor");
|
|
3789
3790
|
|
|
3790
3791
|
// src/image-editor/ControlSlider.tsx
|
|
3791
3792
|
var import_image_editor2 = require("@pixerate/editor/image-editor");
|
|
@@ -4704,6 +4705,22 @@ var LayersPanel = ({ controller, thumbnailSize = 32, psd = true, psdFileName = "
|
|
|
4704
4705
|
children: (0, import_image_editor7.layerBadge)(layer)
|
|
4705
4706
|
}
|
|
4706
4707
|
),
|
|
4708
|
+
layer.mask && !layer.mask.source && layer.type === "pixel" && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
4709
|
+
"button",
|
|
4710
|
+
{
|
|
4711
|
+
type: "button",
|
|
4712
|
+
"aria-label": `${layer.mask.linked === false ? "Link" : "Unlink"} ${row.label} mask`,
|
|
4713
|
+
"aria-pressed": layer.mask.linked !== false,
|
|
4714
|
+
title: layer.mask.linked === false ? "Mask unlinked: it stays put when the layer moves or transforms. Click to link." : "Mask linked: it moves with the layer. Click to unlink.",
|
|
4715
|
+
"data-testid": "layer-mask-link",
|
|
4716
|
+
className: `shrink-0 text-[10px] leading-none ${layer.mask.linked === false ? "text-slate-600" : "text-slate-300"}`,
|
|
4717
|
+
onClick: (e) => {
|
|
4718
|
+
e.stopPropagation();
|
|
4719
|
+
attempt(() => controller.setLayerMaskProps(layer.id, { linked: layer.mask.linked === false }));
|
|
4720
|
+
},
|
|
4721
|
+
children: layer.mask.linked === false ? "\u26D3\uFE0E\u0338" : "\u26D3\uFE0E"
|
|
4722
|
+
}
|
|
4723
|
+
),
|
|
4707
4724
|
layer.mask && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
4708
4725
|
Thumbnail,
|
|
4709
4726
|
{
|
|
@@ -5215,8 +5232,147 @@ var RefineEdgePanel = ({ controller, selection, layers, className = "" }) => {
|
|
|
5215
5232
|
] });
|
|
5216
5233
|
};
|
|
5217
5234
|
|
|
5218
|
-
// src/image-editor/
|
|
5235
|
+
// src/image-editor/FreeTransformOptionsBar.tsx
|
|
5236
|
+
var import_react43 = require("react");
|
|
5237
|
+
var import_image_editor11 = require("@pixerate/editor/image-editor");
|
|
5219
5238
|
var import_jsx_runtime26 = require("react/jsx-runtime");
|
|
5239
|
+
var chip2 = (on) => `px-2 py-1 rounded text-[11px] ${on ? "bg-indigo-600 text-white" : "bg-slate-800 text-slate-300 hover:text-white"}`;
|
|
5240
|
+
var round = (v, unit) => unit === "px" ? Math.round(v * 10) / 10 : Math.round(v * 100) / 100;
|
|
5241
|
+
var FreeTransformOptionsBar = ({ tool, className }) => {
|
|
5242
|
+
const [, setTick] = (0, import_react43.useState)(0);
|
|
5243
|
+
(0, import_react43.useEffect)(() => tool.subscribe(() => setTick((n) => n + 1)), [tool]);
|
|
5244
|
+
const bar = tool.bar();
|
|
5245
|
+
if (!tool.active || !bar) return null;
|
|
5246
|
+
const warp = tool.warpBar();
|
|
5247
|
+
const warpNumber = (key, raw) => {
|
|
5248
|
+
const v = Number(raw);
|
|
5249
|
+
if (raw.trim() !== "" && Number.isFinite(v) && v !== warp[key]) tool.setWarp({ [key]: Math.max(-100, Math.min(100, v)) });
|
|
5250
|
+
};
|
|
5251
|
+
const apply = (field, raw) => {
|
|
5252
|
+
const v = Number(raw);
|
|
5253
|
+
if (raw.trim() !== "" && Number.isFinite(v) && Math.abs(v - bar[field]) > 1e-9) tool.setField(field, v);
|
|
5254
|
+
};
|
|
5255
|
+
return /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: `flex flex-wrap items-center gap-2 text-xs text-slate-200 ${className ?? ""}`, "data-testid": "free-transform-options", role: "toolbar", "aria-label": "Free Transform options", children: [
|
|
5256
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "flex gap-1", role: "group", "aria-label": "Transform mode", children: import_image_editor11.FREE_TRANSFORM_MODE_OPTIONS.map((m) => /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("button", { type: "button", title: m.title, "aria-pressed": tool.mode === m.id, className: chip2(tool.mode === m.id), onClick: () => tool.setMode(m.id), children: m.label }, m.id)) }),
|
|
5257
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "grid grid-cols-3 gap-px", role: "group", "aria-label": "Reference point", children: import_image_editor11.TRANSFORM_ANCHORS.map((a) => /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("button", { type: "button", "aria-label": `Reference point ${a}`, title: `Reference point: ${a}`, className: "h-2.5 w-2.5 rounded-sm bg-slate-700 hover:bg-indigo-500", onClick: () => tool.setReference(a) }, a)) }),
|
|
5258
|
+
tool.mode === "warp" && /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "flex flex-wrap items-center gap-2", role: "group", "aria-label": "Warp options", children: [
|
|
5259
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("label", { className: "flex items-center gap-1", children: [
|
|
5260
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { className: "text-slate-400", children: "Warp" }),
|
|
5261
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("select", { "aria-label": "Warp style", value: warp.style, onChange: (e) => tool.setWarp({ style: e.target.value }), className: "rounded border border-slate-700 bg-slate-900 px-1 py-0.5", children: import_image_editor11.WARP_STYLE_OPTIONS.map((o) => /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("option", { value: o.id, children: o.label }, o.id)) })
|
|
5262
|
+
] }),
|
|
5263
|
+
["bend", "horizontal", "vertical"].map((k) => /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("label", { className: "flex items-center gap-1", children: [
|
|
5264
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { className: "text-slate-400", children: k === "bend" ? "Bend" : k === "horizontal" ? "H" : "V" }),
|
|
5265
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
5266
|
+
"input",
|
|
5267
|
+
{
|
|
5268
|
+
type: "number",
|
|
5269
|
+
"aria-label": k === "bend" ? "Warp bend in percent" : `Warp ${k} distortion in percent`,
|
|
5270
|
+
defaultValue: warp[k],
|
|
5271
|
+
min: -100,
|
|
5272
|
+
max: 100,
|
|
5273
|
+
disabled: warp.style === "custom",
|
|
5274
|
+
className: "w-14 rounded border border-slate-700 bg-slate-900 px-1 py-0.5 text-right disabled:opacity-40",
|
|
5275
|
+
onBlur: (e) => warpNumber(k, e.currentTarget.value),
|
|
5276
|
+
onKeyDown: (e) => {
|
|
5277
|
+
if (e.key === "Enter") {
|
|
5278
|
+
e.preventDefault();
|
|
5279
|
+
e.stopPropagation();
|
|
5280
|
+
warpNumber(k, e.currentTarget.value);
|
|
5281
|
+
}
|
|
5282
|
+
}
|
|
5283
|
+
},
|
|
5284
|
+
`${k}:${warp[k]}`
|
|
5285
|
+
),
|
|
5286
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { className: "text-slate-500", children: "%" })
|
|
5287
|
+
] }, k)),
|
|
5288
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
5289
|
+
"button",
|
|
5290
|
+
{
|
|
5291
|
+
type: "button",
|
|
5292
|
+
title: "Bend along the vertical axis",
|
|
5293
|
+
"aria-pressed": warp.orientation === "vertical",
|
|
5294
|
+
disabled: warp.style === "custom",
|
|
5295
|
+
className: chip2(warp.orientation === "vertical"),
|
|
5296
|
+
onClick: () => tool.setWarp({ orientation: warp.orientation === "vertical" ? "horizontal" : "vertical" }),
|
|
5297
|
+
children: "Vertical"
|
|
5298
|
+
}
|
|
5299
|
+
),
|
|
5300
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("label", { className: "flex items-center gap-1", children: [
|
|
5301
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { className: "text-slate-400", children: "Grid" }),
|
|
5302
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
5303
|
+
"select",
|
|
5304
|
+
{
|
|
5305
|
+
"aria-label": "Warp grid",
|
|
5306
|
+
value: import_image_editor11.WARP_GRID_OPTIONS.find((g) => g.columns === warp.columns && g.rows === warp.rows)?.id ?? "1x1",
|
|
5307
|
+
onChange: (e) => {
|
|
5308
|
+
const g = import_image_editor11.WARP_GRID_OPTIONS.find((o) => o.id === e.target.value);
|
|
5309
|
+
tool.setWarp({ columns: g.columns, rows: g.rows });
|
|
5310
|
+
},
|
|
5311
|
+
className: "rounded border border-slate-700 bg-slate-900 px-1 py-0.5",
|
|
5312
|
+
children: import_image_editor11.WARP_GRID_OPTIONS.map((g) => /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("option", { value: g.id, children: g.label }, g.id))
|
|
5313
|
+
}
|
|
5314
|
+
)
|
|
5315
|
+
] })
|
|
5316
|
+
] }),
|
|
5317
|
+
tool.mode !== "warp" && import_image_editor11.FREE_TRANSFORM_FIELDS.map((f) => /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("label", { className: "flex items-center gap-1", title: f.title, children: [
|
|
5318
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { className: "text-slate-400", children: f.label }),
|
|
5319
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
5320
|
+
"input",
|
|
5321
|
+
{
|
|
5322
|
+
type: "number",
|
|
5323
|
+
"aria-label": f.title,
|
|
5324
|
+
defaultValue: round(bar[f.id], f.unit),
|
|
5325
|
+
disabled: !bar.affine,
|
|
5326
|
+
step: f.unit === "px" ? 1 : 0.1,
|
|
5327
|
+
className: "w-16 rounded border border-slate-700 bg-slate-900 px-1 py-0.5 text-right disabled:opacity-40",
|
|
5328
|
+
onBlur: (e) => apply(f.id, e.currentTarget.value),
|
|
5329
|
+
onKeyDown: (e) => {
|
|
5330
|
+
if (e.key === "Enter") {
|
|
5331
|
+
e.preventDefault();
|
|
5332
|
+
e.stopPropagation();
|
|
5333
|
+
apply(f.id, e.currentTarget.value);
|
|
5334
|
+
}
|
|
5335
|
+
}
|
|
5336
|
+
},
|
|
5337
|
+
`${f.id}:${round(bar[f.id], f.unit)}`
|
|
5338
|
+
),
|
|
5339
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { className: "text-slate-500", children: f.unit }),
|
|
5340
|
+
f.id === "scaleX" && /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
5341
|
+
"button",
|
|
5342
|
+
{
|
|
5343
|
+
type: "button",
|
|
5344
|
+
"aria-label": "Keep width and height proportional",
|
|
5345
|
+
"aria-pressed": tool.proportional,
|
|
5346
|
+
className: chip2(tool.proportional),
|
|
5347
|
+
onClick: () => {
|
|
5348
|
+
tool.proportional = !tool.proportional;
|
|
5349
|
+
setTick((n) => n + 1);
|
|
5350
|
+
},
|
|
5351
|
+
children: "\u26D3\uFE0E"
|
|
5352
|
+
}
|
|
5353
|
+
)
|
|
5354
|
+
] }, f.id)),
|
|
5355
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("label", { className: "flex items-center gap-1", children: [
|
|
5356
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { className: "text-slate-400", children: "Interpolation" }),
|
|
5357
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
5358
|
+
"select",
|
|
5359
|
+
{
|
|
5360
|
+
"aria-label": "Interpolation",
|
|
5361
|
+
value: tool.interpolation,
|
|
5362
|
+
onChange: (e) => tool.setInterpolation(e.target.value),
|
|
5363
|
+
className: "rounded border border-slate-700 bg-slate-900 px-1 py-0.5",
|
|
5364
|
+
children: import_image_editor11.INTERPOLATIONS.map((i) => /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("option", { value: i, children: i[0].toUpperCase() + i.slice(1) }, i))
|
|
5365
|
+
}
|
|
5366
|
+
)
|
|
5367
|
+
] }),
|
|
5368
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("button", { type: "button", title: "Commit (Enter)", className: "px-2 py-1 rounded bg-emerald-600 text-white hover:bg-emerald-500", onClick: () => tool.commit(), children: "Commit" }),
|
|
5369
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("button", { type: "button", title: "Cancel (Esc)", className: chip2(false), onClick: () => tool.cancel(), children: "Cancel" }),
|
|
5370
|
+
tool.error && /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { role: "alert", className: "text-rose-400", children: tool.error })
|
|
5371
|
+
] });
|
|
5372
|
+
};
|
|
5373
|
+
|
|
5374
|
+
// src/image-editor/ImageEditor.tsx
|
|
5375
|
+
var import_jsx_runtime27 = require("react/jsx-runtime");
|
|
5220
5376
|
var ImageEditor = ({
|
|
5221
5377
|
editor: externalEditor,
|
|
5222
5378
|
src,
|
|
@@ -5231,35 +5387,47 @@ var ImageEditor = ({
|
|
|
5231
5387
|
const internalEditor = useImageEditor({ image: src });
|
|
5232
5388
|
const editor = externalEditor || internalEditor;
|
|
5233
5389
|
const { state, controller } = editor;
|
|
5234
|
-
const legacyProcess = (0,
|
|
5235
|
-
const canvasRef = (0,
|
|
5236
|
-
const containerRef = (0,
|
|
5237
|
-
const [activeTab, setActiveTab] = (0,
|
|
5238
|
-
const [activeCropRatio, setActiveCropRatio] = (0,
|
|
5239
|
-
const [selectionOptions, setSelectionOptions] = (0,
|
|
5240
|
-
const selectionOptionsRef = (0,
|
|
5390
|
+
const legacyProcess = (0, import_image_editor12.normalizeProcessVersion)(state.adjustments.process) < import_image_editor12.LATEST_PROCESS_VERSION;
|
|
5391
|
+
const canvasRef = (0, import_react44.useRef)(null);
|
|
5392
|
+
const containerRef = (0, import_react44.useRef)(null);
|
|
5393
|
+
const [activeTab, setActiveTab] = (0, import_react44.useState)("crop");
|
|
5394
|
+
const [activeCropRatio, setActiveCropRatio] = (0, import_react44.useState)(null);
|
|
5395
|
+
const [selectionOptions, setSelectionOptions] = (0, import_react44.useState)(import_image_editor12.DEFAULT_SELECTION_TOOL_OPTIONS);
|
|
5396
|
+
const selectionOptionsRef = (0, import_react44.useRef)(selectionOptions);
|
|
5241
5397
|
selectionOptionsRef.current = selectionOptions;
|
|
5242
|
-
const selectionGestureRef = (0,
|
|
5398
|
+
const selectionGestureRef = (0, import_react44.useRef)(null);
|
|
5243
5399
|
if (!selectionGestureRef.current || selectionGestureRef.current.controller !== controller) {
|
|
5244
|
-
selectionGestureRef.current = new
|
|
5400
|
+
selectionGestureRef.current = new import_image_editor12.SelectionGesture(controller, () => selectionOptionsRef.current);
|
|
5245
5401
|
}
|
|
5246
|
-
const selectionDraftRef = (0,
|
|
5247
|
-
const [selectionError, setSelectionError] = (0,
|
|
5248
|
-
const paintGestureRef = (0,
|
|
5249
|
-
const paintControllerRef = (0,
|
|
5402
|
+
const selectionDraftRef = (0, import_react44.useRef)(null);
|
|
5403
|
+
const [selectionError, setSelectionError] = (0, import_react44.useState)(null);
|
|
5404
|
+
const paintGestureRef = (0, import_react44.useRef)(null);
|
|
5405
|
+
const paintControllerRef = (0, import_react44.useRef)(controller);
|
|
5250
5406
|
if (!paintGestureRef.current || paintControllerRef.current !== controller) {
|
|
5251
|
-
paintGestureRef.current = new
|
|
5407
|
+
paintGestureRef.current = new import_image_editor12.PaintGesture(controller);
|
|
5252
5408
|
paintControllerRef.current = controller;
|
|
5253
5409
|
}
|
|
5254
|
-
const brushCursorRef = (0,
|
|
5255
|
-
const [paintError, setPaintError] = (0,
|
|
5256
|
-
const
|
|
5257
|
-
const
|
|
5258
|
-
|
|
5259
|
-
|
|
5260
|
-
|
|
5261
|
-
|
|
5262
|
-
|
|
5410
|
+
const brushCursorRef = (0, import_react44.useRef)(null);
|
|
5411
|
+
const [paintError, setPaintError] = (0, import_react44.useState)(null);
|
|
5412
|
+
const transformToolRef = (0, import_react44.useRef)(null);
|
|
5413
|
+
const transformControllerRef = (0, import_react44.useRef)(controller);
|
|
5414
|
+
if (!transformToolRef.current || transformControllerRef.current !== controller) {
|
|
5415
|
+
transformToolRef.current?.cancel();
|
|
5416
|
+
transformToolRef.current = new import_image_editor12.FreeTransformTool(controller, {
|
|
5417
|
+
schedule: (run) => typeof requestAnimationFrame !== "undefined" ? requestAnimationFrame(run) : run()
|
|
5418
|
+
});
|
|
5419
|
+
transformControllerRef.current = controller;
|
|
5420
|
+
}
|
|
5421
|
+
const transformTool = transformToolRef.current;
|
|
5422
|
+
const [, setTransformTick] = (0, import_react44.useState)(0);
|
|
5423
|
+
const [transformCursor, setTransformCursor] = (0, import_react44.useState)("default");
|
|
5424
|
+
const [inpaintPrompt, setInpaintPrompt] = (0, import_react44.useState)("");
|
|
5425
|
+
const [inpaintMaskMode, setInpaintMaskMode] = (0, import_react44.useState)("annotations");
|
|
5426
|
+
const [isRemovingBg, setIsRemovingBg] = (0, import_react44.useState)(false);
|
|
5427
|
+
const [isInpainting, setIsInpainting] = (0, import_react44.useState)(false);
|
|
5428
|
+
const [aiError, setAiError] = (0, import_react44.useState)(null);
|
|
5429
|
+
const [aiSuccess, setAiSuccess] = (0, import_react44.useState)(null);
|
|
5430
|
+
const [aiTarget, setAiTarget] = (0, import_react44.useState)("auto");
|
|
5263
5431
|
const aiOptions = aiTarget === "auto" ? {} : { target: aiTarget };
|
|
5264
5432
|
const effectiveOnInpaint = onInpaint || aiHooks?.onInpaint;
|
|
5265
5433
|
const effectiveOnRemoveBg = onRemoveBackground || aiHooks?.onRemoveBackground;
|
|
@@ -5322,18 +5490,18 @@ var ImageEditor = ({
|
|
|
5322
5490
|
setIsInpainting(false);
|
|
5323
5491
|
}
|
|
5324
5492
|
};
|
|
5325
|
-
const [activeColor, setActiveColor] = (0,
|
|
5326
|
-
const [strokeWidth, setStrokeWidth] = (0,
|
|
5327
|
-
const [fontSize, setFontSize] = (0,
|
|
5328
|
-
const [textInput, setTextInput] = (0,
|
|
5329
|
-
const draftAnnotationRef = (0,
|
|
5330
|
-
const draftCropRef = (0,
|
|
5331
|
-
const cropDragInfoRef = (0,
|
|
5332
|
-
const annotationDragInfoRef = (0,
|
|
5333
|
-
const isDrawingRef = (0,
|
|
5334
|
-
const currentPathRef = (0,
|
|
5335
|
-
const dragStartPointRef = (0,
|
|
5336
|
-
const renderCanvas = (0,
|
|
5493
|
+
const [activeColor, setActiveColor] = (0, import_react44.useState)("#ef4444");
|
|
5494
|
+
const [strokeWidth, setStrokeWidth] = (0, import_react44.useState)(3);
|
|
5495
|
+
const [fontSize, setFontSize] = (0, import_react44.useState)(24);
|
|
5496
|
+
const [textInput, setTextInput] = (0, import_react44.useState)("");
|
|
5497
|
+
const draftAnnotationRef = (0, import_react44.useRef)(null);
|
|
5498
|
+
const draftCropRef = (0, import_react44.useRef)(null);
|
|
5499
|
+
const cropDragInfoRef = (0, import_react44.useRef)(null);
|
|
5500
|
+
const annotationDragInfoRef = (0, import_react44.useRef)(null);
|
|
5501
|
+
const isDrawingRef = (0, import_react44.useRef)(false);
|
|
5502
|
+
const currentPathRef = (0, import_react44.useRef)([]);
|
|
5503
|
+
const dragStartPointRef = (0, import_react44.useRef)(null);
|
|
5504
|
+
const renderCanvas = (0, import_react44.useCallback)(
|
|
5337
5505
|
async (draftAnnotation, draftCrop) => {
|
|
5338
5506
|
const canvas = canvasRef.current;
|
|
5339
5507
|
const container = containerRef.current;
|
|
@@ -5349,12 +5517,64 @@ var ImageEditor = ({
|
|
|
5349
5517
|
draftAnnotation: draftAnnotation !== void 0 ? draftAnnotation : draftAnnotationRef.current,
|
|
5350
5518
|
draftCrop: draftCrop !== void 0 ? draftCrop : draftCropRef.current,
|
|
5351
5519
|
draftSelectionPath: selectionDraftRef.current,
|
|
5352
|
-
brushCursor: activeTab === "paint" && brushCursorRef.current && controller.getState().activeTool !== "move" ? { ...brushCursorRef.current, diameter: controller.getState().paint.brush.size } : null
|
|
5520
|
+
brushCursor: activeTab === "paint" && brushCursorRef.current && controller.getState().activeTool !== "move" && !transformTool.active ? { ...brushCursorRef.current, diameter: controller.getState().paint.brush.size } : null,
|
|
5521
|
+
freeTransform: transformTool.overlay()
|
|
5353
5522
|
});
|
|
5354
5523
|
},
|
|
5355
|
-
[controller, activeTab]
|
|
5524
|
+
[controller, activeTab, transformTool]
|
|
5356
5525
|
);
|
|
5357
|
-
(0,
|
|
5526
|
+
(0, import_react44.useEffect)(() => transformTool.subscribe(() => {
|
|
5527
|
+
setTransformTick((n) => n + 1);
|
|
5528
|
+
void renderCanvas();
|
|
5529
|
+
}), [transformTool, renderCanvas]);
|
|
5530
|
+
const transformPoint = (e) => {
|
|
5531
|
+
const canvas = canvasRef.current;
|
|
5532
|
+
const rect = canvas.getBoundingClientRect();
|
|
5533
|
+
const sx = rect.width > 0 ? canvas.width / rect.width : 1;
|
|
5534
|
+
const sy = rect.height > 0 ? canvas.height / rect.height : 1;
|
|
5535
|
+
const s = controller.getState();
|
|
5536
|
+
const cropping = activeTab === "crop";
|
|
5537
|
+
const projection = (0, import_image_editor12.getViewportProjection)(s, canvas.width, canvas.height, cropping);
|
|
5538
|
+
const pt = (0, import_image_editor12.canvasToImagePoint)({ x: (e.clientX - rect.left) * sx, y: (e.clientY - rect.top) * sy }, s, canvas.width, canvas.height, cropping);
|
|
5539
|
+
transformTool.setView(projection.scale);
|
|
5540
|
+
return { pt, tolerance: 6 / (projection.scale || 1) };
|
|
5541
|
+
};
|
|
5542
|
+
const handleTransformPointerDown = (e) => {
|
|
5543
|
+
if (!transformTool.active) return false;
|
|
5544
|
+
if (e.button !== 0) return true;
|
|
5545
|
+
e.preventDefault();
|
|
5546
|
+
try {
|
|
5547
|
+
e.currentTarget.setPointerCapture?.(e.pointerId);
|
|
5548
|
+
} catch {
|
|
5549
|
+
}
|
|
5550
|
+
const { pt, tolerance } = transformPoint(e);
|
|
5551
|
+
transformTool.down(pt, tolerance);
|
|
5552
|
+
return true;
|
|
5553
|
+
};
|
|
5554
|
+
const handleTransformPointerMove = (e) => {
|
|
5555
|
+
if (!transformTool.active) return false;
|
|
5556
|
+
const { pt, tolerance } = transformPoint(e);
|
|
5557
|
+
if (e.buttons & 1) transformTool.move(pt, e);
|
|
5558
|
+
else {
|
|
5559
|
+
const over = transformTool.hit(pt, tolerance);
|
|
5560
|
+
setTransformCursor(transformTool.cursor(over));
|
|
5561
|
+
}
|
|
5562
|
+
return true;
|
|
5563
|
+
};
|
|
5564
|
+
const handleTransformPointerUp = () => {
|
|
5565
|
+
if (!transformTool.active) return false;
|
|
5566
|
+
transformTool.up();
|
|
5567
|
+
return true;
|
|
5568
|
+
};
|
|
5569
|
+
(0, import_react44.useEffect)(() => {
|
|
5570
|
+
if (typeof window === "undefined") return;
|
|
5571
|
+
const onKey = (e) => {
|
|
5572
|
+
if (transformTool.key(e)) e.preventDefault();
|
|
5573
|
+
};
|
|
5574
|
+
window.addEventListener("keydown", onKey);
|
|
5575
|
+
return () => window.removeEventListener("keydown", onKey);
|
|
5576
|
+
}, [transformTool]);
|
|
5577
|
+
(0, import_react44.useEffect)(() => {
|
|
5358
5578
|
const raf = typeof requestAnimationFrame !== "undefined" ? requestAnimationFrame : (cb) => setTimeout(cb, 0);
|
|
5359
5579
|
const caf = typeof cancelAnimationFrame !== "undefined" ? cancelAnimationFrame : (id) => clearTimeout(id);
|
|
5360
5580
|
const animId = raf(() => {
|
|
@@ -5362,12 +5582,12 @@ var ImageEditor = ({
|
|
|
5362
5582
|
});
|
|
5363
5583
|
return () => caf(animId);
|
|
5364
5584
|
}, [renderCanvas, state]);
|
|
5365
|
-
(0,
|
|
5585
|
+
(0, import_react44.useEffect)(() => {
|
|
5366
5586
|
if (activeTab === "crop" && editor.state.activeTool !== "crop") {
|
|
5367
5587
|
editor.setTool("crop");
|
|
5368
5588
|
}
|
|
5369
5589
|
}, [activeTab, editor]);
|
|
5370
|
-
(0,
|
|
5590
|
+
(0, import_react44.useEffect)(() => {
|
|
5371
5591
|
const container = containerRef.current;
|
|
5372
5592
|
if (!container) return;
|
|
5373
5593
|
if (typeof ResizeObserver !== "undefined") {
|
|
@@ -5403,11 +5623,12 @@ var ImageEditor = ({
|
|
|
5403
5623
|
const sy = rect.height > 0 ? canvas.height / rect.height : 1;
|
|
5404
5624
|
const s = controller.getState();
|
|
5405
5625
|
return list.map((ev) => ({
|
|
5406
|
-
...(0,
|
|
5407
|
-
pressure: (0,
|
|
5626
|
+
...(0, import_image_editor12.canvasToImagePoint)({ x: (ev.clientX - rect.left) * sx, y: (ev.clientY - rect.top) * sy }, s, canvas.width, canvas.height, false),
|
|
5627
|
+
pressure: (0, import_image_editor12.pointerPressure)(ev)
|
|
5408
5628
|
}));
|
|
5409
5629
|
};
|
|
5410
5630
|
const handlePaintPointerDown = (e) => {
|
|
5631
|
+
if (handleTransformPointerDown(e)) return;
|
|
5411
5632
|
if (activeTab !== "paint" || e.button !== 0) return;
|
|
5412
5633
|
e.preventDefault();
|
|
5413
5634
|
try {
|
|
@@ -5418,6 +5639,7 @@ var ImageEditor = ({
|
|
|
5418
5639
|
setPaintError(paintGestureRef.current.down(first));
|
|
5419
5640
|
};
|
|
5420
5641
|
const handlePaintPointerMove = (e) => {
|
|
5642
|
+
if (handleTransformPointerMove(e)) return;
|
|
5421
5643
|
if (activeTab !== "paint") return;
|
|
5422
5644
|
const samples = paintSamples(e);
|
|
5423
5645
|
brushCursorRef.current = samples[samples.length - 1] ?? null;
|
|
@@ -5425,6 +5647,7 @@ var ImageEditor = ({
|
|
|
5425
5647
|
else void renderCanvas();
|
|
5426
5648
|
};
|
|
5427
5649
|
const handlePaintPointerUp = () => {
|
|
5650
|
+
if (handleTransformPointerUp()) return;
|
|
5428
5651
|
if (activeTab !== "paint") return;
|
|
5429
5652
|
const g = paintGestureRef.current;
|
|
5430
5653
|
if (g.active) {
|
|
@@ -5432,21 +5655,21 @@ var ImageEditor = ({
|
|
|
5432
5655
|
if (g.error) setPaintError(g.error);
|
|
5433
5656
|
}
|
|
5434
5657
|
};
|
|
5435
|
-
(0,
|
|
5658
|
+
(0, import_react44.useEffect)(() => {
|
|
5436
5659
|
if (activeTab !== "paint" || typeof window === "undefined") return;
|
|
5437
5660
|
const onKey = (e) => {
|
|
5438
|
-
if ((0,
|
|
5661
|
+
if ((0, import_image_editor12.handlePaintShortcut)(controller, e)) e.preventDefault();
|
|
5439
5662
|
};
|
|
5440
5663
|
window.addEventListener("keydown", onKey);
|
|
5441
5664
|
return () => window.removeEventListener("keydown", onKey);
|
|
5442
5665
|
}, [activeTab, controller]);
|
|
5443
5666
|
const handleMouseDown = (e) => {
|
|
5444
5667
|
const canvas = canvasRef.current;
|
|
5445
|
-
if (!canvas) return;
|
|
5668
|
+
if (!canvas || transformTool.active) return;
|
|
5446
5669
|
const canvasPt = getCanvasEventPoint(e);
|
|
5447
5670
|
if (activeTab === "select") {
|
|
5448
5671
|
const gesture = selectionGestureRef.current;
|
|
5449
|
-
const imgPt = (0,
|
|
5672
|
+
const imgPt = (0, import_image_editor12.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false);
|
|
5450
5673
|
void gesture.begin(imgPt, e).then(() => setSelectionError(gesture.error));
|
|
5451
5674
|
return;
|
|
5452
5675
|
}
|
|
@@ -5457,8 +5680,8 @@ var ImageEditor = ({
|
|
|
5457
5680
|
width: state.imageDimensions.width,
|
|
5458
5681
|
height: state.imageDimensions.height
|
|
5459
5682
|
};
|
|
5460
|
-
const handle = (0,
|
|
5461
|
-
const startImgPt = (0,
|
|
5683
|
+
const handle = (0, import_image_editor12.hitTestCrop)(canvasPt, state, canvas.width, canvas.height, 14, activeCrop);
|
|
5684
|
+
const startImgPt = (0, import_image_editor12.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, true);
|
|
5462
5685
|
if (handle) {
|
|
5463
5686
|
cropDragInfoRef.current = {
|
|
5464
5687
|
handle,
|
|
@@ -5477,12 +5700,12 @@ var ImageEditor = ({
|
|
|
5477
5700
|
return;
|
|
5478
5701
|
}
|
|
5479
5702
|
if (activeTab === "annotate") {
|
|
5480
|
-
const imgPt = (0,
|
|
5703
|
+
const imgPt = (0, import_image_editor12.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false);
|
|
5481
5704
|
dragStartPointRef.current = imgPt;
|
|
5482
5705
|
if (state.activeTool === "select") {
|
|
5483
5706
|
for (let i = state.annotations.length - 1; i >= 0; i--) {
|
|
5484
5707
|
const ann = state.annotations[i];
|
|
5485
|
-
if ((0,
|
|
5708
|
+
if ((0, import_image_editor12.hitTestAnnotation)(imgPt, ann)) {
|
|
5486
5709
|
editor.selectAnnotation(ann.id);
|
|
5487
5710
|
annotationDragInfoRef.current = {
|
|
5488
5711
|
annId: ann.id,
|
|
@@ -5514,11 +5737,11 @@ var ImageEditor = ({
|
|
|
5514
5737
|
};
|
|
5515
5738
|
const handleMouseMove = (e) => {
|
|
5516
5739
|
const canvas = canvasRef.current;
|
|
5517
|
-
if (!canvas) return;
|
|
5740
|
+
if (!canvas || transformTool.active) return;
|
|
5518
5741
|
const canvasPt = getCanvasEventPoint(e);
|
|
5519
5742
|
if (activeTab === "select") {
|
|
5520
5743
|
const gesture = selectionGestureRef.current;
|
|
5521
|
-
if (gesture.active && gesture.move((0,
|
|
5744
|
+
if (gesture.active && gesture.move((0, import_image_editor12.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false))) {
|
|
5522
5745
|
selectionDraftRef.current = gesture.draftPath;
|
|
5523
5746
|
renderCanvas();
|
|
5524
5747
|
}
|
|
@@ -5527,7 +5750,7 @@ var ImageEditor = ({
|
|
|
5527
5750
|
if (activeTab === "crop") {
|
|
5528
5751
|
const drag = cropDragInfoRef.current;
|
|
5529
5752
|
if (drag) {
|
|
5530
|
-
const currentImgPt = (0,
|
|
5753
|
+
const currentImgPt = (0, import_image_editor12.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, true);
|
|
5531
5754
|
let newCrop;
|
|
5532
5755
|
if (drag.handle === "new") {
|
|
5533
5756
|
const minX = Math.max(0, Math.min(drag.startImgPt.x, currentImgPt.x));
|
|
@@ -5541,7 +5764,7 @@ var ImageEditor = ({
|
|
|
5541
5764
|
height: Math.round(Math.max(20, maxY - minY))
|
|
5542
5765
|
};
|
|
5543
5766
|
} else {
|
|
5544
|
-
newCrop = (0,
|
|
5767
|
+
newCrop = (0, import_image_editor12.calculateCropDrag)(
|
|
5545
5768
|
drag.startCrop,
|
|
5546
5769
|
drag.handle,
|
|
5547
5770
|
drag.startImgPt,
|
|
@@ -5561,15 +5784,15 @@ var ImageEditor = ({
|
|
|
5561
5784
|
width: state.imageDimensions.width,
|
|
5562
5785
|
height: state.imageDimensions.height
|
|
5563
5786
|
};
|
|
5564
|
-
const handle = (0,
|
|
5565
|
-
canvas.style.cursor = (0,
|
|
5787
|
+
const handle = (0, import_image_editor12.hitTestCrop)(canvasPt, state, canvas.width, canvas.height, 14, activeCrop);
|
|
5788
|
+
canvas.style.cursor = (0, import_image_editor12.getCropCursor)(handle, state.transform);
|
|
5566
5789
|
}
|
|
5567
5790
|
return;
|
|
5568
5791
|
}
|
|
5569
5792
|
if (activeTab === "annotate") {
|
|
5570
5793
|
if (annotationDragInfoRef.current) {
|
|
5571
5794
|
const drag = annotationDragInfoRef.current;
|
|
5572
|
-
const currentImgPt2 = (0,
|
|
5795
|
+
const currentImgPt2 = (0, import_image_editor12.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false);
|
|
5573
5796
|
const dx = currentImgPt2.x - drag.startImgPt.x;
|
|
5574
5797
|
const dy = currentImgPt2.y - drag.startImgPt.y;
|
|
5575
5798
|
editor.updateAnnotation(drag.annId, {
|
|
@@ -5581,10 +5804,10 @@ var ImageEditor = ({
|
|
|
5581
5804
|
const startPt = dragStartPointRef.current;
|
|
5582
5805
|
if (!startPt) {
|
|
5583
5806
|
if (state.activeTool === "select") {
|
|
5584
|
-
const imgPt = (0,
|
|
5807
|
+
const imgPt = (0, import_image_editor12.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false);
|
|
5585
5808
|
let hovered = false;
|
|
5586
5809
|
for (let i = state.annotations.length - 1; i >= 0; i--) {
|
|
5587
|
-
if ((0,
|
|
5810
|
+
if ((0, import_image_editor12.hitTestAnnotation)(imgPt, state.annotations[i])) {
|
|
5588
5811
|
hovered = true;
|
|
5589
5812
|
break;
|
|
5590
5813
|
}
|
|
@@ -5595,7 +5818,7 @@ var ImageEditor = ({
|
|
|
5595
5818
|
}
|
|
5596
5819
|
return;
|
|
5597
5820
|
}
|
|
5598
|
-
const currentImgPt = (0,
|
|
5821
|
+
const currentImgPt = (0, import_image_editor12.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false);
|
|
5599
5822
|
if (state.activeTool === "pen" && isDrawingRef.current) {
|
|
5600
5823
|
currentPathRef.current.push(currentImgPt);
|
|
5601
5824
|
const draft = {
|
|
@@ -5670,12 +5893,12 @@ var ImageEditor = ({
|
|
|
5670
5893
|
};
|
|
5671
5894
|
const handleMouseUp = (e) => {
|
|
5672
5895
|
const canvas = canvasRef.current;
|
|
5673
|
-
if (!canvas) return;
|
|
5896
|
+
if (!canvas || transformTool.active) return;
|
|
5674
5897
|
const canvasPt = getCanvasEventPoint(e);
|
|
5675
5898
|
if (activeTab === "select") {
|
|
5676
5899
|
const gesture = selectionGestureRef.current;
|
|
5677
5900
|
if (gesture.active) {
|
|
5678
|
-
gesture.end((0,
|
|
5901
|
+
gesture.end((0, import_image_editor12.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false), e);
|
|
5679
5902
|
selectionDraftRef.current = null;
|
|
5680
5903
|
renderCanvas();
|
|
5681
5904
|
}
|
|
@@ -5699,7 +5922,7 @@ var ImageEditor = ({
|
|
|
5699
5922
|
}
|
|
5700
5923
|
const startPt = dragStartPointRef.current;
|
|
5701
5924
|
if (startPt) {
|
|
5702
|
-
const currentImgPt = (0,
|
|
5925
|
+
const currentImgPt = (0, import_image_editor12.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false);
|
|
5703
5926
|
if (state.activeTool === "pen" && isDrawingRef.current) {
|
|
5704
5927
|
if (currentPathRef.current.length > 1) {
|
|
5705
5928
|
editor.addAnnotation({
|
|
@@ -5795,15 +6018,15 @@ var ImageEditor = ({
|
|
|
5795
6018
|
link.click();
|
|
5796
6019
|
}
|
|
5797
6020
|
};
|
|
5798
|
-
return /* @__PURE__ */ (0,
|
|
6021
|
+
return /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(
|
|
5799
6022
|
"div",
|
|
5800
6023
|
{
|
|
5801
6024
|
className: `flex flex-col bg-slate-900 border border-slate-800 rounded-xl overflow-hidden shadow-2xl text-slate-100 ${className}`,
|
|
5802
6025
|
style,
|
|
5803
6026
|
children: [
|
|
5804
|
-
/* @__PURE__ */ (0,
|
|
5805
|
-
/* @__PURE__ */ (0,
|
|
5806
|
-
/* @__PURE__ */ (0,
|
|
6027
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.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: [
|
|
6028
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "flex items-center gap-1 bg-slate-900 p-1 rounded-lg border border-slate-800 text-xs", children: [
|
|
6029
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
5807
6030
|
"button",
|
|
5808
6031
|
{
|
|
5809
6032
|
type: "button",
|
|
@@ -5815,7 +6038,7 @@ var ImageEditor = ({
|
|
|
5815
6038
|
children: "Transform & Crop"
|
|
5816
6039
|
}
|
|
5817
6040
|
),
|
|
5818
|
-
/* @__PURE__ */ (0,
|
|
6041
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
5819
6042
|
"button",
|
|
5820
6043
|
{
|
|
5821
6044
|
type: "button",
|
|
@@ -5827,7 +6050,7 @@ var ImageEditor = ({
|
|
|
5827
6050
|
children: "Adjustments"
|
|
5828
6051
|
}
|
|
5829
6052
|
),
|
|
5830
|
-
/* @__PURE__ */ (0,
|
|
6053
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
5831
6054
|
"button",
|
|
5832
6055
|
{
|
|
5833
6056
|
type: "button",
|
|
@@ -5839,7 +6062,7 @@ var ImageEditor = ({
|
|
|
5839
6062
|
children: "Layers"
|
|
5840
6063
|
}
|
|
5841
6064
|
),
|
|
5842
|
-
/* @__PURE__ */ (0,
|
|
6065
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
5843
6066
|
"button",
|
|
5844
6067
|
{
|
|
5845
6068
|
type: "button",
|
|
@@ -5851,7 +6074,7 @@ var ImageEditor = ({
|
|
|
5851
6074
|
children: "Paint"
|
|
5852
6075
|
}
|
|
5853
6076
|
),
|
|
5854
|
-
/* @__PURE__ */ (0,
|
|
6077
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
5855
6078
|
"button",
|
|
5856
6079
|
{
|
|
5857
6080
|
type: "button",
|
|
@@ -5863,7 +6086,7 @@ var ImageEditor = ({
|
|
|
5863
6086
|
children: "Select & Mask"
|
|
5864
6087
|
}
|
|
5865
6088
|
),
|
|
5866
|
-
/* @__PURE__ */ (0,
|
|
6089
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
5867
6090
|
"button",
|
|
5868
6091
|
{
|
|
5869
6092
|
type: "button",
|
|
@@ -5875,7 +6098,7 @@ var ImageEditor = ({
|
|
|
5875
6098
|
children: "Annotations"
|
|
5876
6099
|
}
|
|
5877
6100
|
),
|
|
5878
|
-
/* @__PURE__ */ (0,
|
|
6101
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
5879
6102
|
"button",
|
|
5880
6103
|
{
|
|
5881
6104
|
type: "button",
|
|
@@ -5887,7 +6110,7 @@ var ImageEditor = ({
|
|
|
5887
6110
|
children: "Depth Mask"
|
|
5888
6111
|
}
|
|
5889
6112
|
),
|
|
5890
|
-
/* @__PURE__ */ (0,
|
|
6113
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(
|
|
5891
6114
|
"button",
|
|
5892
6115
|
{
|
|
5893
6116
|
type: "button",
|
|
@@ -5897,14 +6120,14 @@ var ImageEditor = ({
|
|
|
5897
6120
|
},
|
|
5898
6121
|
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"}`,
|
|
5899
6122
|
children: [
|
|
5900
|
-
/* @__PURE__ */ (0,
|
|
6123
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.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_runtime27.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" }) }),
|
|
5901
6124
|
"AI Tools"
|
|
5902
6125
|
]
|
|
5903
6126
|
}
|
|
5904
6127
|
)
|
|
5905
6128
|
] }),
|
|
5906
|
-
/* @__PURE__ */ (0,
|
|
5907
|
-
/* @__PURE__ */ (0,
|
|
6129
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "flex items-center gap-2 text-xs", children: [
|
|
6130
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
5908
6131
|
"button",
|
|
5909
6132
|
{
|
|
5910
6133
|
type: "button",
|
|
@@ -5915,7 +6138,7 @@ var ImageEditor = ({
|
|
|
5915
6138
|
children: "\u21A9"
|
|
5916
6139
|
}
|
|
5917
6140
|
),
|
|
5918
|
-
/* @__PURE__ */ (0,
|
|
6141
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
5919
6142
|
"button",
|
|
5920
6143
|
{
|
|
5921
6144
|
type: "button",
|
|
@@ -5926,7 +6149,7 @@ var ImageEditor = ({
|
|
|
5926
6149
|
children: "\u21AA"
|
|
5927
6150
|
}
|
|
5928
6151
|
),
|
|
5929
|
-
/* @__PURE__ */ (0,
|
|
6152
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
5930
6153
|
"button",
|
|
5931
6154
|
{
|
|
5932
6155
|
type: "button",
|
|
@@ -5935,8 +6158,8 @@ var ImageEditor = ({
|
|
|
5935
6158
|
children: "Reset"
|
|
5936
6159
|
}
|
|
5937
6160
|
),
|
|
5938
|
-
/* @__PURE__ */ (0,
|
|
5939
|
-
/* @__PURE__ */ (0,
|
|
6161
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: "h-4 w-px bg-slate-800 mx-1" }),
|
|
6162
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
5940
6163
|
"button",
|
|
5941
6164
|
{
|
|
5942
6165
|
type: "button",
|
|
@@ -5946,11 +6169,11 @@ var ImageEditor = ({
|
|
|
5946
6169
|
children: "-"
|
|
5947
6170
|
}
|
|
5948
6171
|
),
|
|
5949
|
-
/* @__PURE__ */ (0,
|
|
6172
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("span", { className: "font-mono text-slate-400 w-10 text-center", children: [
|
|
5950
6173
|
Math.round(state.zoom * 100),
|
|
5951
6174
|
"%"
|
|
5952
6175
|
] }),
|
|
5953
|
-
/* @__PURE__ */ (0,
|
|
6176
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
5954
6177
|
"button",
|
|
5955
6178
|
{
|
|
5956
6179
|
type: "button",
|
|
@@ -5960,8 +6183,8 @@ var ImageEditor = ({
|
|
|
5960
6183
|
children: "+"
|
|
5961
6184
|
}
|
|
5962
6185
|
),
|
|
5963
|
-
/* @__PURE__ */ (0,
|
|
5964
|
-
/* @__PURE__ */ (0,
|
|
6186
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: "h-4 w-px bg-slate-800 mx-1" }),
|
|
6187
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
5965
6188
|
"button",
|
|
5966
6189
|
{
|
|
5967
6190
|
type: "button",
|
|
@@ -5972,7 +6195,7 @@ var ImageEditor = ({
|
|
|
5972
6195
|
children: "Hold Compare"
|
|
5973
6196
|
}
|
|
5974
6197
|
),
|
|
5975
|
-
/* @__PURE__ */ (0,
|
|
6198
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
5976
6199
|
"button",
|
|
5977
6200
|
{
|
|
5978
6201
|
type: "button",
|
|
@@ -5983,13 +6206,15 @@ var ImageEditor = ({
|
|
|
5983
6206
|
)
|
|
5984
6207
|
] })
|
|
5985
6208
|
] }),
|
|
5986
|
-
/* @__PURE__ */ (0,
|
|
5987
|
-
|
|
6209
|
+
transformTool.active && /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(FreeTransformOptionsBar, { tool: transformTool, className: "border-b border-slate-800 bg-slate-900/95 px-4 py-2" }),
|
|
6210
|
+
!transformTool.active && transformTool.error && /* @__PURE__ */ (0, import_jsx_runtime27.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 }),
|
|
6211
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "flex flex-col md:flex-row flex-1 min-h-[520px] md:h-[560px]", children: [
|
|
6212
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
5988
6213
|
"div",
|
|
5989
6214
|
{
|
|
5990
6215
|
ref: containerRef,
|
|
5991
6216
|
className: "relative flex-1 h-[360px] md:h-full min-h-[320px] bg-slate-950 overflow-hidden select-none",
|
|
5992
|
-
children: /* @__PURE__ */ (0,
|
|
6217
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
5993
6218
|
"canvas",
|
|
5994
6219
|
{
|
|
5995
6220
|
ref: canvasRef,
|
|
@@ -6002,16 +6227,17 @@ var ImageEditor = ({
|
|
|
6002
6227
|
onPointerUp: handlePaintPointerUp,
|
|
6003
6228
|
onPointerCancel: () => paintGestureRef.current?.cancel(),
|
|
6004
6229
|
"data-testid": "image-editor-canvas",
|
|
6005
|
-
|
|
6230
|
+
style: transformTool.active ? { cursor: transformCursor } : void 0,
|
|
6231
|
+
className: `absolute inset-0 w-full h-full block ${transformTool.active ? "touch-none" : activeTab === "paint" ? "touch-none cursor-crosshair" : ""}`
|
|
6006
6232
|
}
|
|
6007
6233
|
)
|
|
6008
6234
|
}
|
|
6009
6235
|
),
|
|
6010
|
-
/* @__PURE__ */ (0,
|
|
6011
|
-
activeTab === "crop" && /* @__PURE__ */ (0,
|
|
6012
|
-
/* @__PURE__ */ (0,
|
|
6013
|
-
/* @__PURE__ */ (0,
|
|
6014
|
-
/* @__PURE__ */ (0,
|
|
6236
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.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: [
|
|
6237
|
+
activeTab === "crop" && /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "flex flex-col gap-4 text-xs", children: [
|
|
6238
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Aspect Ratio Presets" }),
|
|
6239
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "grid grid-cols-3 gap-2", children: [
|
|
6240
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
6015
6241
|
"button",
|
|
6016
6242
|
{
|
|
6017
6243
|
type: "button",
|
|
@@ -6023,7 +6249,7 @@ var ImageEditor = ({
|
|
|
6023
6249
|
children: "Freeform"
|
|
6024
6250
|
}
|
|
6025
6251
|
),
|
|
6026
|
-
/* @__PURE__ */ (0,
|
|
6252
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
6027
6253
|
"button",
|
|
6028
6254
|
{
|
|
6029
6255
|
type: "button",
|
|
@@ -6035,7 +6261,7 @@ var ImageEditor = ({
|
|
|
6035
6261
|
children: "1:1 Square"
|
|
6036
6262
|
}
|
|
6037
6263
|
),
|
|
6038
|
-
/* @__PURE__ */ (0,
|
|
6264
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
6039
6265
|
"button",
|
|
6040
6266
|
{
|
|
6041
6267
|
type: "button",
|
|
@@ -6047,7 +6273,7 @@ var ImageEditor = ({
|
|
|
6047
6273
|
children: "4:3 Standard"
|
|
6048
6274
|
}
|
|
6049
6275
|
),
|
|
6050
|
-
/* @__PURE__ */ (0,
|
|
6276
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
6051
6277
|
"button",
|
|
6052
6278
|
{
|
|
6053
6279
|
type: "button",
|
|
@@ -6059,7 +6285,7 @@ var ImageEditor = ({
|
|
|
6059
6285
|
children: "16:9 Wide"
|
|
6060
6286
|
}
|
|
6061
6287
|
),
|
|
6062
|
-
/* @__PURE__ */ (0,
|
|
6288
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
6063
6289
|
"button",
|
|
6064
6290
|
{
|
|
6065
6291
|
type: "button",
|
|
@@ -6071,7 +6297,7 @@ var ImageEditor = ({
|
|
|
6071
6297
|
children: "3:2 Photo"
|
|
6072
6298
|
}
|
|
6073
6299
|
),
|
|
6074
|
-
/* @__PURE__ */ (0,
|
|
6300
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
6075
6301
|
"button",
|
|
6076
6302
|
{
|
|
6077
6303
|
type: "button",
|
|
@@ -6084,10 +6310,10 @@ var ImageEditor = ({
|
|
|
6084
6310
|
}
|
|
6085
6311
|
)
|
|
6086
6312
|
] }),
|
|
6087
|
-
/* @__PURE__ */ (0,
|
|
6088
|
-
/* @__PURE__ */ (0,
|
|
6089
|
-
/* @__PURE__ */ (0,
|
|
6090
|
-
/* @__PURE__ */ (0,
|
|
6313
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: "h-px bg-slate-800 my-1" }),
|
|
6314
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Orientation & Flips" }),
|
|
6315
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "grid grid-cols-2 gap-2", children: [
|
|
6316
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
6091
6317
|
"button",
|
|
6092
6318
|
{
|
|
6093
6319
|
type: "button",
|
|
@@ -6096,7 +6322,7 @@ var ImageEditor = ({
|
|
|
6096
6322
|
children: "Rotate -90\xB0"
|
|
6097
6323
|
}
|
|
6098
6324
|
),
|
|
6099
|
-
/* @__PURE__ */ (0,
|
|
6325
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
6100
6326
|
"button",
|
|
6101
6327
|
{
|
|
6102
6328
|
type: "button",
|
|
@@ -6105,7 +6331,7 @@ var ImageEditor = ({
|
|
|
6105
6331
|
children: "Rotate +90\xB0"
|
|
6106
6332
|
}
|
|
6107
6333
|
),
|
|
6108
|
-
/* @__PURE__ */ (0,
|
|
6334
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
6109
6335
|
"button",
|
|
6110
6336
|
{
|
|
6111
6337
|
type: "button",
|
|
@@ -6114,7 +6340,7 @@ var ImageEditor = ({
|
|
|
6114
6340
|
children: "Flip Horizontal"
|
|
6115
6341
|
}
|
|
6116
6342
|
),
|
|
6117
|
-
/* @__PURE__ */ (0,
|
|
6343
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
6118
6344
|
"button",
|
|
6119
6345
|
{
|
|
6120
6346
|
type: "button",
|
|
@@ -6125,10 +6351,10 @@ var ImageEditor = ({
|
|
|
6125
6351
|
)
|
|
6126
6352
|
] })
|
|
6127
6353
|
] }),
|
|
6128
|
-
activeTab === "adjust" && /* @__PURE__ */ (0,
|
|
6129
|
-
/* @__PURE__ */ (0,
|
|
6130
|
-
/* @__PURE__ */ (0,
|
|
6131
|
-
/* @__PURE__ */ (0,
|
|
6354
|
+
activeTab === "adjust" && /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "flex flex-col gap-3 text-xs", children: [
|
|
6355
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "flex items-center justify-between", children: [
|
|
6356
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Color Adjustments" }),
|
|
6357
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
6132
6358
|
"button",
|
|
6133
6359
|
{
|
|
6134
6360
|
type: "button",
|
|
@@ -6138,25 +6364,25 @@ var ImageEditor = ({
|
|
|
6138
6364
|
}
|
|
6139
6365
|
)
|
|
6140
6366
|
] }),
|
|
6141
|
-
/* @__PURE__ */ (0,
|
|
6142
|
-
|
|
6143
|
-
/* @__PURE__ */ (0,
|
|
6367
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(Histogram, { histogram: editor.histogram }),
|
|
6368
|
+
import_image_editor12.IMAGE_ADJUSTMENT_CONTROLS.map((spec) => /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(import_react44.default.Fragment, { children: [
|
|
6369
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
6144
6370
|
ControlSlider,
|
|
6145
6371
|
{
|
|
6146
6372
|
spec,
|
|
6147
|
-
value: (0,
|
|
6373
|
+
value: (0, import_image_editor12.readAdjustmentControls)(state.adjustments)[spec.id],
|
|
6148
6374
|
disabled: spec.requiresProcess !== void 0 && legacyProcess,
|
|
6149
6375
|
onChange: (v) => editor.setAdjustments({ [spec.id]: v })
|
|
6150
6376
|
}
|
|
6151
6377
|
),
|
|
6152
|
-
spec.id === "tint" && legacyProcess && /* @__PURE__ */ (0,
|
|
6378
|
+
spec.id === "tint" && legacyProcess && /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(
|
|
6153
6379
|
"div",
|
|
6154
6380
|
{
|
|
6155
6381
|
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",
|
|
6156
6382
|
"data-testid": "image-editor-process-notice",
|
|
6157
6383
|
children: [
|
|
6158
|
-
/* @__PURE__ */ (0,
|
|
6159
|
-
/* @__PURE__ */ (0,
|
|
6384
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { children: "Legacy rendering (process 1). Tint needs the current process." }),
|
|
6385
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
6160
6386
|
"button",
|
|
6161
6387
|
{
|
|
6162
6388
|
type: "button",
|
|
@@ -6169,7 +6395,7 @@ var ImageEditor = ({
|
|
|
6169
6395
|
}
|
|
6170
6396
|
)
|
|
6171
6397
|
] }, spec.id)),
|
|
6172
|
-
/* @__PURE__ */ (0,
|
|
6398
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: "border-t border-slate-700/60 pt-3", children: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
6173
6399
|
AdjustmentLayersPanel,
|
|
6174
6400
|
{
|
|
6175
6401
|
controller,
|
|
@@ -6178,19 +6404,41 @@ var ImageEditor = ({
|
|
|
6178
6404
|
}
|
|
6179
6405
|
) })
|
|
6180
6406
|
] }),
|
|
6181
|
-
activeTab === "layers" && /* @__PURE__ */ (0,
|
|
6182
|
-
/* @__PURE__ */ (0,
|
|
6183
|
-
/* @__PURE__ */ (0,
|
|
6407
|
+
activeTab === "layers" && /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "flex flex-col gap-3 text-xs", children: [
|
|
6408
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Layers" }),
|
|
6409
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
6410
|
+
"button",
|
|
6411
|
+
{
|
|
6412
|
+
type: "button",
|
|
6413
|
+
title: "Edit \u203A Free Transform (Ctrl/Cmd+T): the selected pixels, or the whole active layer",
|
|
6414
|
+
className: "px-2 py-1 rounded text-[11px] bg-slate-800 text-slate-300 hover:text-white self-start disabled:opacity-40",
|
|
6415
|
+
disabled: transformTool.active,
|
|
6416
|
+
onClick: () => transformTool.begin(),
|
|
6417
|
+
children: "Free Transform"
|
|
6418
|
+
}
|
|
6419
|
+
),
|
|
6420
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(LayersPanel, { controller })
|
|
6184
6421
|
] }),
|
|
6185
|
-
activeTab === "paint" && /* @__PURE__ */ (0,
|
|
6186
|
-
/* @__PURE__ */ (0,
|
|
6187
|
-
/* @__PURE__ */ (0,
|
|
6188
|
-
|
|
6189
|
-
|
|
6422
|
+
activeTab === "paint" && /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "flex flex-col gap-3 text-xs", children: [
|
|
6423
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Paint" }),
|
|
6424
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(BrushOptionsBar, { controller }),
|
|
6425
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
6426
|
+
"button",
|
|
6427
|
+
{
|
|
6428
|
+
type: "button",
|
|
6429
|
+
title: "Edit \u203A Free Transform (Ctrl/Cmd+T): the selected pixels, or the whole active layer",
|
|
6430
|
+
className: "px-2 py-1 rounded text-[11px] bg-slate-800 text-slate-300 hover:text-white self-start",
|
|
6431
|
+
disabled: transformTool.active,
|
|
6432
|
+
onClick: () => transformTool.begin(),
|
|
6433
|
+
children: "Free Transform"
|
|
6434
|
+
}
|
|
6435
|
+
),
|
|
6436
|
+
paintError && /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("p", { role: "alert", className: "text-rose-400", "data-testid": "paint-error", children: paintError }),
|
|
6437
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: "border-t border-slate-700/60 pt-3", children: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(LayersPanel, { controller }) })
|
|
6190
6438
|
] }),
|
|
6191
|
-
activeTab === "annotate" && /* @__PURE__ */ (0,
|
|
6192
|
-
/* @__PURE__ */ (0,
|
|
6193
|
-
/* @__PURE__ */ (0,
|
|
6439
|
+
activeTab === "annotate" && /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "flex flex-col gap-3 text-xs", children: [
|
|
6440
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Draw & Annotate" }),
|
|
6441
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: "grid grid-cols-3 gap-1.5", children: ["pen", "rect", "circle", "arrow", "line"].map((t) => /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
6194
6442
|
"button",
|
|
6195
6443
|
{
|
|
6196
6444
|
type: "button",
|
|
@@ -6200,9 +6448,9 @@ var ImageEditor = ({
|
|
|
6200
6448
|
},
|
|
6201
6449
|
t
|
|
6202
6450
|
)) }),
|
|
6203
|
-
/* @__PURE__ */ (0,
|
|
6204
|
-
/* @__PURE__ */ (0,
|
|
6205
|
-
/* @__PURE__ */ (0,
|
|
6451
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "flex items-center gap-2 mt-2", children: [
|
|
6452
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("label", { className: "text-slate-400", children: "Color:" }),
|
|
6453
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
6206
6454
|
"input",
|
|
6207
6455
|
{
|
|
6208
6456
|
type: "color",
|
|
@@ -6211,15 +6459,15 @@ var ImageEditor = ({
|
|
|
6211
6459
|
className: "w-8 h-8 rounded border border-slate-700 cursor-pointer bg-transparent"
|
|
6212
6460
|
}
|
|
6213
6461
|
),
|
|
6214
|
-
/* @__PURE__ */ (0,
|
|
6215
|
-
/* @__PURE__ */ (0,
|
|
6216
|
-
/* @__PURE__ */ (0,
|
|
6217
|
-
/* @__PURE__ */ (0,
|
|
6462
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "flex-1 ml-2", children: [
|
|
6463
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "flex justify-between text-slate-400 mb-0.5", children: [
|
|
6464
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { children: "Width:" }),
|
|
6465
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("span", { className: "font-mono", children: [
|
|
6218
6466
|
strokeWidth,
|
|
6219
6467
|
"px"
|
|
6220
6468
|
] })
|
|
6221
6469
|
] }),
|
|
6222
|
-
/* @__PURE__ */ (0,
|
|
6470
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
6223
6471
|
"input",
|
|
6224
6472
|
{
|
|
6225
6473
|
type: "range",
|
|
@@ -6232,10 +6480,10 @@ var ImageEditor = ({
|
|
|
6232
6480
|
)
|
|
6233
6481
|
] })
|
|
6234
6482
|
] }),
|
|
6235
|
-
/* @__PURE__ */ (0,
|
|
6236
|
-
/* @__PURE__ */ (0,
|
|
6237
|
-
/* @__PURE__ */ (0,
|
|
6238
|
-
/* @__PURE__ */ (0,
|
|
6483
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: "h-px bg-slate-800 my-1" }),
|
|
6484
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Add Text" }),
|
|
6485
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "flex gap-2", children: [
|
|
6486
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
6239
6487
|
"input",
|
|
6240
6488
|
{
|
|
6241
6489
|
type: "text",
|
|
@@ -6246,7 +6494,7 @@ var ImageEditor = ({
|
|
|
6246
6494
|
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"
|
|
6247
6495
|
}
|
|
6248
6496
|
),
|
|
6249
|
-
/* @__PURE__ */ (0,
|
|
6497
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
6250
6498
|
"button",
|
|
6251
6499
|
{
|
|
6252
6500
|
type: "button",
|
|
@@ -6256,14 +6504,14 @@ var ImageEditor = ({
|
|
|
6256
6504
|
}
|
|
6257
6505
|
)
|
|
6258
6506
|
] }),
|
|
6259
|
-
/* @__PURE__ */ (0,
|
|
6260
|
-
/* @__PURE__ */ (0,
|
|
6261
|
-
/* @__PURE__ */ (0,
|
|
6507
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "flex items-center justify-between text-slate-400", children: [
|
|
6508
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { children: "Font Size:" }),
|
|
6509
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("span", { className: "font-mono", children: [
|
|
6262
6510
|
fontSize,
|
|
6263
6511
|
"px"
|
|
6264
6512
|
] })
|
|
6265
6513
|
] }),
|
|
6266
|
-
/* @__PURE__ */ (0,
|
|
6514
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
6267
6515
|
"input",
|
|
6268
6516
|
{
|
|
6269
6517
|
type: "range",
|
|
@@ -6274,14 +6522,14 @@ var ImageEditor = ({
|
|
|
6274
6522
|
className: "w-full accent-indigo-500"
|
|
6275
6523
|
}
|
|
6276
6524
|
),
|
|
6277
|
-
/* @__PURE__ */ (0,
|
|
6278
|
-
/* @__PURE__ */ (0,
|
|
6279
|
-
/* @__PURE__ */ (0,
|
|
6525
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: "h-px bg-slate-800 my-1" }),
|
|
6526
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "flex items-center justify-between", children: [
|
|
6527
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("span", { className: "text-slate-400", children: [
|
|
6280
6528
|
"Layers (",
|
|
6281
6529
|
state.annotations.length,
|
|
6282
6530
|
")"
|
|
6283
6531
|
] }),
|
|
6284
|
-
state.selectedAnnotationId && /* @__PURE__ */ (0,
|
|
6532
|
+
state.selectedAnnotationId && /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
6285
6533
|
"button",
|
|
6286
6534
|
{
|
|
6287
6535
|
type: "button",
|
|
@@ -6290,7 +6538,7 @@ var ImageEditor = ({
|
|
|
6290
6538
|
children: "Delete Selected"
|
|
6291
6539
|
}
|
|
6292
6540
|
),
|
|
6293
|
-
state.annotations.length > 0 && /* @__PURE__ */ (0,
|
|
6541
|
+
state.annotations.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
6294
6542
|
"button",
|
|
6295
6543
|
{
|
|
6296
6544
|
type: "button",
|
|
@@ -6301,10 +6549,10 @@ var ImageEditor = ({
|
|
|
6301
6549
|
)
|
|
6302
6550
|
] })
|
|
6303
6551
|
] }),
|
|
6304
|
-
activeTab === "depth" && /* @__PURE__ */ (0,
|
|
6305
|
-
/* @__PURE__ */ (0,
|
|
6306
|
-
/* @__PURE__ */ (0,
|
|
6307
|
-
/* @__PURE__ */ (0,
|
|
6552
|
+
activeTab === "depth" && /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "flex flex-col gap-3 text-xs", children: [
|
|
6553
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "flex items-center justify-between", children: [
|
|
6554
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Depth Masking" }),
|
|
6555
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
6308
6556
|
"button",
|
|
6309
6557
|
{
|
|
6310
6558
|
type: "button",
|
|
@@ -6314,8 +6562,8 @@ var ImageEditor = ({
|
|
|
6314
6562
|
}
|
|
6315
6563
|
)
|
|
6316
6564
|
] }),
|
|
6317
|
-
/* @__PURE__ */ (0,
|
|
6318
|
-
/* @__PURE__ */ (0,
|
|
6565
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("label", { className: "flex items-center gap-2 cursor-pointer text-slate-300", children: [
|
|
6566
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
6319
6567
|
"input",
|
|
6320
6568
|
{
|
|
6321
6569
|
type: "checkbox",
|
|
@@ -6324,12 +6572,12 @@ var ImageEditor = ({
|
|
|
6324
6572
|
className: "rounded accent-indigo-500"
|
|
6325
6573
|
}
|
|
6326
6574
|
),
|
|
6327
|
-
/* @__PURE__ */ (0,
|
|
6575
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { children: "Enable Depth / Alpha Mask" })
|
|
6328
6576
|
] }),
|
|
6329
|
-
state.depthMask.enabled && /* @__PURE__ */ (0,
|
|
6330
|
-
/* @__PURE__ */ (0,
|
|
6331
|
-
/* @__PURE__ */ (0,
|
|
6332
|
-
/* @__PURE__ */ (0,
|
|
6577
|
+
state.depthMask.enabled && /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(import_jsx_runtime27.Fragment, { children: [
|
|
6578
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { children: [
|
|
6579
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("label", { className: "text-slate-400 block mb-1", children: "Mask Image URL:" }),
|
|
6580
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
6333
6581
|
"input",
|
|
6334
6582
|
{
|
|
6335
6583
|
type: "text",
|
|
@@ -6340,8 +6588,8 @@ var ImageEditor = ({
|
|
|
6340
6588
|
}
|
|
6341
6589
|
)
|
|
6342
6590
|
] }),
|
|
6343
|
-
/* @__PURE__ */ (0,
|
|
6344
|
-
/* @__PURE__ */ (0,
|
|
6591
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "flex gap-2", children: [
|
|
6592
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
6345
6593
|
"button",
|
|
6346
6594
|
{
|
|
6347
6595
|
type: "button",
|
|
@@ -6350,7 +6598,7 @@ var ImageEditor = ({
|
|
|
6350
6598
|
children: "Threshold Mode"
|
|
6351
6599
|
}
|
|
6352
6600
|
),
|
|
6353
|
-
/* @__PURE__ */ (0,
|
|
6601
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
6354
6602
|
"button",
|
|
6355
6603
|
{
|
|
6356
6604
|
type: "button",
|
|
@@ -6360,12 +6608,12 @@ var ImageEditor = ({
|
|
|
6360
6608
|
}
|
|
6361
6609
|
)
|
|
6362
6610
|
] }),
|
|
6363
|
-
/* @__PURE__ */ (0,
|
|
6364
|
-
/* @__PURE__ */ (0,
|
|
6365
|
-
/* @__PURE__ */ (0,
|
|
6366
|
-
/* @__PURE__ */ (0,
|
|
6611
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { children: [
|
|
6612
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "flex justify-between text-slate-400 mb-1", children: [
|
|
6613
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { children: "Depth Start (Lower):" }),
|
|
6614
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: "font-mono", children: state.depthMask.depthRange[0] })
|
|
6367
6615
|
] }),
|
|
6368
|
-
/* @__PURE__ */ (0,
|
|
6616
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
6369
6617
|
"input",
|
|
6370
6618
|
{
|
|
6371
6619
|
type: "range",
|
|
@@ -6379,12 +6627,12 @@ var ImageEditor = ({
|
|
|
6379
6627
|
}
|
|
6380
6628
|
)
|
|
6381
6629
|
] }),
|
|
6382
|
-
/* @__PURE__ */ (0,
|
|
6383
|
-
/* @__PURE__ */ (0,
|
|
6384
|
-
/* @__PURE__ */ (0,
|
|
6385
|
-
/* @__PURE__ */ (0,
|
|
6630
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { children: [
|
|
6631
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "flex justify-between text-slate-400 mb-1", children: [
|
|
6632
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { children: "Depth Stop (Upper):" }),
|
|
6633
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: "font-mono", children: state.depthMask.depthRange[1] })
|
|
6386
6634
|
] }),
|
|
6387
|
-
/* @__PURE__ */ (0,
|
|
6635
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
6388
6636
|
"input",
|
|
6389
6637
|
{
|
|
6390
6638
|
type: "range",
|
|
@@ -6398,12 +6646,12 @@ var ImageEditor = ({
|
|
|
6398
6646
|
}
|
|
6399
6647
|
)
|
|
6400
6648
|
] }),
|
|
6401
|
-
/* @__PURE__ */ (0,
|
|
6402
|
-
/* @__PURE__ */ (0,
|
|
6403
|
-
/* @__PURE__ */ (0,
|
|
6404
|
-
/* @__PURE__ */ (0,
|
|
6649
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { children: [
|
|
6650
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "flex justify-between text-slate-400 mb-1", children: [
|
|
6651
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { children: "Softness:" }),
|
|
6652
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: "font-mono", children: state.depthMask.softness })
|
|
6405
6653
|
] }),
|
|
6406
|
-
/* @__PURE__ */ (0,
|
|
6654
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
6407
6655
|
"input",
|
|
6408
6656
|
{
|
|
6409
6657
|
type: "range",
|
|
@@ -6415,8 +6663,8 @@ var ImageEditor = ({
|
|
|
6415
6663
|
}
|
|
6416
6664
|
)
|
|
6417
6665
|
] }),
|
|
6418
|
-
/* @__PURE__ */ (0,
|
|
6419
|
-
/* @__PURE__ */ (0,
|
|
6666
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("label", { className: "flex items-center gap-2 cursor-pointer text-slate-300 mt-1", children: [
|
|
6667
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
6420
6668
|
"input",
|
|
6421
6669
|
{
|
|
6422
6670
|
type: "checkbox",
|
|
@@ -6425,12 +6673,12 @@ var ImageEditor = ({
|
|
|
6425
6673
|
className: "rounded accent-indigo-500"
|
|
6426
6674
|
}
|
|
6427
6675
|
),
|
|
6428
|
-
/* @__PURE__ */ (0,
|
|
6676
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { children: "Invert Mask" })
|
|
6429
6677
|
] })
|
|
6430
6678
|
] })
|
|
6431
6679
|
] }),
|
|
6432
|
-
activeTab === "select" && /* @__PURE__ */ (0,
|
|
6433
|
-
/* @__PURE__ */ (0,
|
|
6680
|
+
activeTab === "select" && /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "flex flex-col gap-4 text-xs", children: [
|
|
6681
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
6434
6682
|
SelectionOptionsBar,
|
|
6435
6683
|
{
|
|
6436
6684
|
controller,
|
|
@@ -6440,13 +6688,37 @@ var ImageEditor = ({
|
|
|
6440
6688
|
quickMask: Boolean(state.quickMask)
|
|
6441
6689
|
}
|
|
6442
6690
|
),
|
|
6443
|
-
selectionError && /* @__PURE__ */ (0,
|
|
6444
|
-
/* @__PURE__ */ (0,
|
|
6691
|
+
selectionError && /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("p", { role: "alert", className: "text-rose-400", children: selectionError }),
|
|
6692
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "flex gap-1", children: [
|
|
6693
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
6694
|
+
"button",
|
|
6695
|
+
{
|
|
6696
|
+
type: "button",
|
|
6697
|
+
title: "Select \u203A Transform Selection: the outline only",
|
|
6698
|
+
className: "px-2 py-1 rounded text-[11px] bg-slate-800 text-slate-300 hover:text-white self-start disabled:opacity-40",
|
|
6699
|
+
disabled: transformTool.active,
|
|
6700
|
+
onClick: () => transformTool.begin({ content: "selection-outline" }),
|
|
6701
|
+
children: "Transform Selection"
|
|
6702
|
+
}
|
|
6703
|
+
),
|
|
6704
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
6705
|
+
"button",
|
|
6706
|
+
{
|
|
6707
|
+
type: "button",
|
|
6708
|
+
title: "Edit \u203A Free Transform: the selected pixels of the active layer",
|
|
6709
|
+
className: "px-2 py-1 rounded text-[11px] bg-slate-800 text-slate-300 hover:text-white self-start disabled:opacity-40",
|
|
6710
|
+
disabled: transformTool.active,
|
|
6711
|
+
onClick: () => transformTool.begin({ content: "selection" }),
|
|
6712
|
+
children: "Free Transform Pixels"
|
|
6713
|
+
}
|
|
6714
|
+
)
|
|
6715
|
+
] }),
|
|
6716
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(RefineEdgePanel, { controller, selection: state.selection ?? null, layers: state.adjustments.layers })
|
|
6445
6717
|
] }),
|
|
6446
|
-
activeTab === "ai" && /* @__PURE__ */ (0,
|
|
6447
|
-
/* @__PURE__ */ (0,
|
|
6448
|
-
/* @__PURE__ */ (0,
|
|
6449
|
-
/* @__PURE__ */ (0,
|
|
6718
|
+
activeTab === "ai" && /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "flex flex-col gap-4 text-xs", children: [
|
|
6719
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("label", { className: "flex items-center justify-between gap-2 text-slate-300", children: [
|
|
6720
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { children: "Results go to" }),
|
|
6721
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(
|
|
6450
6722
|
"select",
|
|
6451
6723
|
{
|
|
6452
6724
|
"aria-label": "AI result target",
|
|
@@ -6454,54 +6726,54 @@ var ImageEditor = ({
|
|
|
6454
6726
|
onChange: (e) => setAiTarget(e.target.value),
|
|
6455
6727
|
className: "bg-slate-800 border border-slate-700 rounded px-1.5 py-1",
|
|
6456
6728
|
children: [
|
|
6457
|
-
/* @__PURE__ */ (0,
|
|
6458
|
-
/* @__PURE__ */ (0,
|
|
6459
|
-
/* @__PURE__ */ (0,
|
|
6729
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("option", { value: "auto", children: controller.isMultiLayer ? "Auto (new layer)" : "Auto (replace image)" }),
|
|
6730
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("option", { value: "new-layer", children: "New layer / mask" }),
|
|
6731
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("option", { value: "replace", children: "Replace image" })
|
|
6460
6732
|
]
|
|
6461
6733
|
}
|
|
6462
6734
|
)
|
|
6463
6735
|
] }),
|
|
6464
|
-
/* @__PURE__ */ (0,
|
|
6465
|
-
/* @__PURE__ */ (0,
|
|
6466
|
-
/* @__PURE__ */ (0,
|
|
6467
|
-
/* @__PURE__ */ (0,
|
|
6736
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "p-3 rounded-lg bg-slate-950/60 border border-slate-800 flex flex-col gap-2.5", children: [
|
|
6737
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "flex items-center justify-between", children: [
|
|
6738
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px] flex items-center gap-1.5", children: [
|
|
6739
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.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_runtime27.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" }) }),
|
|
6468
6740
|
"Background Removal"
|
|
6469
6741
|
] }),
|
|
6470
|
-
isRemovingBg && /* @__PURE__ */ (0,
|
|
6742
|
+
isRemovingBg && /* @__PURE__ */ (0, import_jsx_runtime27.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..." })
|
|
6471
6743
|
] }),
|
|
6472
|
-
/* @__PURE__ */ (0,
|
|
6473
|
-
/* @__PURE__ */ (0,
|
|
6744
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("p", { className: "text-slate-400 text-[11px] leading-relaxed", children: "Isolate foreground subject with AI alpha transparency segmentation." }),
|
|
6745
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
6474
6746
|
"button",
|
|
6475
6747
|
{
|
|
6476
6748
|
type: "button",
|
|
6477
6749
|
onClick: handleRemoveBackground,
|
|
6478
6750
|
disabled: isRemovingBg || isInpainting,
|
|
6479
6751
|
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",
|
|
6480
|
-
children: isRemovingBg ? /* @__PURE__ */ (0,
|
|
6481
|
-
/* @__PURE__ */ (0,
|
|
6752
|
+
children: isRemovingBg ? /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(import_jsx_runtime27.Fragment, { children: [
|
|
6753
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: "w-3.5 h-3.5 border-2 border-white/30 border-t-white rounded-full animate-spin" }),
|
|
6482
6754
|
"Removing Background..."
|
|
6483
|
-
] }) : /* @__PURE__ */ (0,
|
|
6484
|
-
/* @__PURE__ */ (0,
|
|
6755
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(import_jsx_runtime27.Fragment, { children: [
|
|
6756
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.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_runtime27.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" }) }),
|
|
6485
6757
|
"Remove Background"
|
|
6486
6758
|
] })
|
|
6487
6759
|
}
|
|
6488
6760
|
)
|
|
6489
6761
|
] }),
|
|
6490
|
-
/* @__PURE__ */ (0,
|
|
6491
|
-
/* @__PURE__ */ (0,
|
|
6492
|
-
/* @__PURE__ */ (0,
|
|
6493
|
-
/* @__PURE__ */ (0,
|
|
6494
|
-
/* @__PURE__ */ (0,
|
|
6495
|
-
/* @__PURE__ */ (0,
|
|
6762
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "p-3 rounded-lg bg-slate-950/60 border border-slate-800 flex flex-col gap-2.5", children: [
|
|
6763
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "flex items-center justify-between", children: [
|
|
6764
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px] flex items-center gap-1.5", children: [
|
|
6765
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("svg", { className: "w-3.5 h-3.5 text-purple-400", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: [
|
|
6766
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.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" }),
|
|
6767
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("path", { d: "m14 7 3 3" })
|
|
6496
6768
|
] }),
|
|
6497
6769
|
"Generative Inpainting"
|
|
6498
6770
|
] }),
|
|
6499
|
-
isInpainting && /* @__PURE__ */ (0,
|
|
6771
|
+
isInpainting && /* @__PURE__ */ (0, import_jsx_runtime27.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..." })
|
|
6500
6772
|
] }),
|
|
6501
|
-
/* @__PURE__ */ (0,
|
|
6502
|
-
/* @__PURE__ */ (0,
|
|
6503
|
-
/* @__PURE__ */ (0,
|
|
6504
|
-
/* @__PURE__ */ (0,
|
|
6773
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("p", { className: "text-slate-400 text-[11px] leading-relaxed", children: "Replace, modify, or fill selected regions using prompt-guided generative inpainting." }),
|
|
6774
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "flex flex-col gap-1", children: [
|
|
6775
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("label", { htmlFor: "ai-inpaint-prompt-react", className: "text-slate-300 text-[11px] font-medium", children: "Prompt" }),
|
|
6776
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
6505
6777
|
"textarea",
|
|
6506
6778
|
{
|
|
6507
6779
|
id: "ai-inpaint-prompt-react",
|
|
@@ -6513,10 +6785,10 @@ var ImageEditor = ({
|
|
|
6513
6785
|
}
|
|
6514
6786
|
)
|
|
6515
6787
|
] }),
|
|
6516
|
-
/* @__PURE__ */ (0,
|
|
6517
|
-
/* @__PURE__ */ (0,
|
|
6518
|
-
/* @__PURE__ */ (0,
|
|
6519
|
-
/* @__PURE__ */ (0,
|
|
6788
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "flex flex-col gap-1", children: [
|
|
6789
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: "text-slate-300 text-[11px] font-medium", children: "Target Mask Region" }),
|
|
6790
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "grid grid-cols-2 gap-1.5", children: [
|
|
6791
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(
|
|
6520
6792
|
"button",
|
|
6521
6793
|
{
|
|
6522
6794
|
type: "button",
|
|
@@ -6529,7 +6801,7 @@ var ImageEditor = ({
|
|
|
6529
6801
|
]
|
|
6530
6802
|
}
|
|
6531
6803
|
),
|
|
6532
|
-
/* @__PURE__ */ (0,
|
|
6804
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(
|
|
6533
6805
|
"button",
|
|
6534
6806
|
{
|
|
6535
6807
|
type: "button",
|
|
@@ -6544,25 +6816,25 @@ var ImageEditor = ({
|
|
|
6544
6816
|
)
|
|
6545
6817
|
] })
|
|
6546
6818
|
] }),
|
|
6547
|
-
/* @__PURE__ */ (0,
|
|
6819
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
6548
6820
|
"button",
|
|
6549
6821
|
{
|
|
6550
6822
|
type: "button",
|
|
6551
6823
|
onClick: handleInpaint,
|
|
6552
6824
|
disabled: isInpainting || isRemovingBg || !inpaintPrompt.trim(),
|
|
6553
6825
|
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",
|
|
6554
|
-
children: isInpainting ? /* @__PURE__ */ (0,
|
|
6555
|
-
/* @__PURE__ */ (0,
|
|
6826
|
+
children: isInpainting ? /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(import_jsx_runtime27.Fragment, { children: [
|
|
6827
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: "w-3.5 h-3.5 border-2 border-white/30 border-t-white rounded-full animate-spin" }),
|
|
6556
6828
|
"Generating Inpaint..."
|
|
6557
|
-
] }) : /* @__PURE__ */ (0,
|
|
6558
|
-
/* @__PURE__ */ (0,
|
|
6829
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(import_jsx_runtime27.Fragment, { children: [
|
|
6830
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.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_runtime27.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" }) }),
|
|
6559
6831
|
"Apply Inpainting"
|
|
6560
6832
|
] })
|
|
6561
6833
|
}
|
|
6562
6834
|
)
|
|
6563
6835
|
] }),
|
|
6564
|
-
aiError && /* @__PURE__ */ (0,
|
|
6565
|
-
aiSuccess && /* @__PURE__ */ (0,
|
|
6836
|
+
aiError && /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: "p-2.5 rounded-lg bg-rose-950/60 border border-rose-800 text-rose-300 text-[11px]", children: aiError }),
|
|
6837
|
+
aiSuccess && /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: "p-2.5 rounded-lg bg-emerald-950/60 border border-emerald-800 text-emerald-300 text-[11px]", children: aiSuccess })
|
|
6566
6838
|
] })
|
|
6567
6839
|
] })
|
|
6568
6840
|
] })
|
|
@@ -6572,7 +6844,7 @@ var ImageEditor = ({
|
|
|
6572
6844
|
};
|
|
6573
6845
|
|
|
6574
6846
|
// src/review/useReview.ts
|
|
6575
|
-
var
|
|
6847
|
+
var import_react45 = require("react");
|
|
6576
6848
|
var import_editor12 = require("@pixerate/editor");
|
|
6577
6849
|
var EMPTY_COMMENTS = Object.freeze({
|
|
6578
6850
|
threads: [],
|
|
@@ -6591,23 +6863,23 @@ function isCommentStore(value) {
|
|
|
6591
6863
|
}
|
|
6592
6864
|
function useComments(source) {
|
|
6593
6865
|
const store = isCommentStore(source) ? source : (0, import_editor12.getCommentStore)(source);
|
|
6594
|
-
const subscribe = (0,
|
|
6866
|
+
const subscribe = (0, import_react45.useCallback)(
|
|
6595
6867
|
(onChange) => store ? store.subscribe(() => onChange()) : noopUnsubscribe,
|
|
6596
6868
|
[store]
|
|
6597
6869
|
);
|
|
6598
6870
|
const getSnapshot = () => store?.getSnapshot() ?? EMPTY_COMMENTS;
|
|
6599
|
-
const snapshot = (0,
|
|
6600
|
-
return (0,
|
|
6871
|
+
const snapshot = (0, import_react45.useSyncExternalStore)(subscribe, getSnapshot, getSnapshot);
|
|
6872
|
+
return (0, import_react45.useMemo)(() => ({ ...snapshot, store }), [snapshot, store]);
|
|
6601
6873
|
}
|
|
6602
6874
|
function useTrackChanges(editor) {
|
|
6603
6875
|
const store = (0, import_editor12.getTrackChangesStore)(editor ?? null);
|
|
6604
|
-
const subscribe = (0,
|
|
6876
|
+
const subscribe = (0, import_react45.useCallback)(
|
|
6605
6877
|
(onChange) => store ? store.subscribe(() => onChange()) : noopUnsubscribe,
|
|
6606
6878
|
[store]
|
|
6607
6879
|
);
|
|
6608
6880
|
const getSnapshot = () => store?.getSnapshot() ?? EMPTY_TRACK_CHANGES;
|
|
6609
|
-
const snapshot = (0,
|
|
6610
|
-
return (0,
|
|
6881
|
+
const snapshot = (0, import_react45.useSyncExternalStore)(subscribe, getSnapshot, getSnapshot);
|
|
6882
|
+
return (0, import_react45.useMemo)(() => {
|
|
6611
6883
|
const run = (fn) => () => {
|
|
6612
6884
|
if (editor && !editor.isDestroyed) fn(editor);
|
|
6613
6885
|
};
|
|
@@ -6630,9 +6902,9 @@ function useTrackChanges(editor) {
|
|
|
6630
6902
|
}
|
|
6631
6903
|
|
|
6632
6904
|
// src/review/CommentsPanel.tsx
|
|
6633
|
-
var
|
|
6905
|
+
var import_react46 = require("react");
|
|
6634
6906
|
var import_editor13 = require("@pixerate/editor");
|
|
6635
|
-
var
|
|
6907
|
+
var import_jsx_runtime28 = require("react/jsx-runtime");
|
|
6636
6908
|
var buttonClass2 = "rounded px-2 py-1 text-xs text-muted-foreground hover:bg-muted hover:text-foreground disabled:opacity-50";
|
|
6637
6909
|
var primaryButtonClass = "rounded px-2 py-1 text-xs bg-primary/10 text-primary hover:bg-primary/20 disabled:opacity-50";
|
|
6638
6910
|
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";
|
|
@@ -6646,18 +6918,18 @@ var CommentsPanel = ({
|
|
|
6646
6918
|
emptyMessage = "No comments yet. Select text and add a comment."
|
|
6647
6919
|
}) => {
|
|
6648
6920
|
const { threads, activeThreadId, store } = useComments(storeProp ?? editor);
|
|
6649
|
-
const [showResolved, setShowResolved] = (0,
|
|
6921
|
+
const [showResolved, setShowResolved] = (0, import_react46.useState)(showResolvedInitial);
|
|
6650
6922
|
const author = authorProp ?? (0, import_editor13.getCommentAuthor)(editor) ?? { id: "anonymous", name: "Anonymous" };
|
|
6651
6923
|
const visible = threads.filter((t) => showResolved || !t.resolved);
|
|
6652
6924
|
const resolvedCount = threads.filter((t) => t.resolved).length;
|
|
6653
|
-
return /* @__PURE__ */ (0,
|
|
6654
|
-
/* @__PURE__ */ (0,
|
|
6655
|
-
/* @__PURE__ */ (0,
|
|
6925
|
+
return /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("aside", { className, "aria-label": "Comments", children: [
|
|
6926
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: "flex items-center justify-between gap-2", children: [
|
|
6927
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("span", { className: "text-xs font-medium text-muted-foreground", children: [
|
|
6656
6928
|
threads.length - resolvedCount,
|
|
6657
6929
|
" open",
|
|
6658
6930
|
resolvedCount > 0 ? ` \xB7 ${resolvedCount} resolved` : ""
|
|
6659
6931
|
] }),
|
|
6660
|
-
resolvedCount > 0 && /* @__PURE__ */ (0,
|
|
6932
|
+
resolvedCount > 0 && /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
6661
6933
|
"button",
|
|
6662
6934
|
{
|
|
6663
6935
|
type: "button",
|
|
@@ -6668,7 +6940,7 @@ var CommentsPanel = ({
|
|
|
6668
6940
|
}
|
|
6669
6941
|
)
|
|
6670
6942
|
] }),
|
|
6671
|
-
visible.length === 0 ? /* @__PURE__ */ (0,
|
|
6943
|
+
visible.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("p", { className: "text-xs text-muted-foreground", children: emptyMessage }) : /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("ul", { className: "flex flex-col gap-2", role: "list", children: visible.map((thread) => /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
6672
6944
|
CommentThreadCard,
|
|
6673
6945
|
{
|
|
6674
6946
|
thread,
|
|
@@ -6690,7 +6962,7 @@ var CommentThreadCard = ({
|
|
|
6690
6962
|
author,
|
|
6691
6963
|
formatTime
|
|
6692
6964
|
}) => {
|
|
6693
|
-
const [draft, setDraft] = (0,
|
|
6965
|
+
const [draft, setDraft] = (0, import_react46.useState)("");
|
|
6694
6966
|
const isDraft = thread.body === "";
|
|
6695
6967
|
const quote = thread.anchor?.quote ?? thread.lastQuote ?? "";
|
|
6696
6968
|
const live = editor && !editor.isDestroyed ? editor : null;
|
|
@@ -6716,7 +6988,7 @@ var CommentThreadCard = ({
|
|
|
6716
6988
|
setDraft("");
|
|
6717
6989
|
};
|
|
6718
6990
|
const stop = (e) => e.stopPropagation();
|
|
6719
|
-
return /* @__PURE__ */ (0,
|
|
6991
|
+
return /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(
|
|
6720
6992
|
"li",
|
|
6721
6993
|
{
|
|
6722
6994
|
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" : ""}`,
|
|
@@ -6732,24 +7004,24 @@ var CommentThreadCard = ({
|
|
|
6732
7004
|
}
|
|
6733
7005
|
},
|
|
6734
7006
|
children: [
|
|
6735
|
-
/* @__PURE__ */ (0,
|
|
6736
|
-
/* @__PURE__ */ (0,
|
|
6737
|
-
/* @__PURE__ */ (0,
|
|
7007
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: "flex items-baseline justify-between gap-2", children: [
|
|
7008
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", { className: "font-medium", children: thread.author.name }),
|
|
7009
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", { className: "text-xs text-muted-foreground", children: formatTime(thread.createdAt) })
|
|
6738
7010
|
] }),
|
|
6739
|
-
quote && /* @__PURE__ */ (0,
|
|
6740
|
-
thread.orphaned && /* @__PURE__ */ (0,
|
|
6741
|
-
thread.resolved && /* @__PURE__ */ (0,
|
|
6742
|
-
!isDraft && /* @__PURE__ */ (0,
|
|
6743
|
-
thread.replies.length > 0 && /* @__PURE__ */ (0,
|
|
6744
|
-
/* @__PURE__ */ (0,
|
|
6745
|
-
/* @__PURE__ */ (0,
|
|
7011
|
+
quote && /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("blockquote", { className: "border-l-2 border-border pl-2 text-xs text-muted-foreground line-clamp-2", children: quote }),
|
|
7012
|
+
thread.orphaned && /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", { className: "text-xs text-destructive", children: "The commented text was deleted." }),
|
|
7013
|
+
thread.resolved && /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", { className: "text-xs text-muted-foreground", children: "Resolved" }),
|
|
7014
|
+
!isDraft && /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("p", { className: "whitespace-pre-wrap break-words", children: thread.body }),
|
|
7015
|
+
thread.replies.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime28.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_runtime28.jsxs)("li", { className: "flex flex-col gap-0.5", "data-reply-id": reply.id, children: [
|
|
7016
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("span", { className: "text-xs", children: [
|
|
7017
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", { className: "font-medium", children: reply.author.name }),
|
|
6746
7018
|
" ",
|
|
6747
|
-
/* @__PURE__ */ (0,
|
|
7019
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", { className: "text-muted-foreground", children: formatTime(reply.createdAt) })
|
|
6748
7020
|
] }),
|
|
6749
|
-
/* @__PURE__ */ (0,
|
|
7021
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)("p", { className: "whitespace-pre-wrap break-words", children: reply.body })
|
|
6750
7022
|
] }, reply.id)) }),
|
|
6751
|
-
(active || isDraft) && !thread.resolved && /* @__PURE__ */ (0,
|
|
6752
|
-
/* @__PURE__ */ (0,
|
|
7023
|
+
(active || isDraft) && !thread.resolved && /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: "flex flex-col gap-1", onClick: stop, children: [
|
|
7024
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
6753
7025
|
"textarea",
|
|
6754
7026
|
{
|
|
6755
7027
|
className: textareaClass,
|
|
@@ -6767,9 +7039,9 @@ var CommentThreadCard = ({
|
|
|
6767
7039
|
}
|
|
6768
7040
|
}
|
|
6769
7041
|
),
|
|
6770
|
-
/* @__PURE__ */ (0,
|
|
6771
|
-
isDraft && /* @__PURE__ */ (0,
|
|
6772
|
-
/* @__PURE__ */ (0,
|
|
7042
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: "flex justify-end gap-1", children: [
|
|
7043
|
+
isDraft && /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("button", { type: "button", className: buttonClass2, onClick: remove, children: "Cancel" }),
|
|
7044
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
6773
7045
|
"button",
|
|
6774
7046
|
{
|
|
6775
7047
|
type: "button",
|
|
@@ -6781,9 +7053,9 @@ var CommentThreadCard = ({
|
|
|
6781
7053
|
)
|
|
6782
7054
|
] })
|
|
6783
7055
|
] }),
|
|
6784
|
-
!isDraft && /* @__PURE__ */ (0,
|
|
6785
|
-
/* @__PURE__ */ (0,
|
|
6786
|
-
/* @__PURE__ */ (0,
|
|
7056
|
+
!isDraft && /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: "flex justify-end gap-1", onClick: stop, children: [
|
|
7057
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)("button", { type: "button", className: buttonClass2, onClick: () => setResolved(!thread.resolved), children: thread.resolved ? "Reopen" : "Resolve" }),
|
|
7058
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
6787
7059
|
"button",
|
|
6788
7060
|
{
|
|
6789
7061
|
type: "button",
|
|
@@ -6799,7 +7071,7 @@ var CommentThreadCard = ({
|
|
|
6799
7071
|
};
|
|
6800
7072
|
|
|
6801
7073
|
// src/review/ReviewToolbar.tsx
|
|
6802
|
-
var
|
|
7074
|
+
var import_jsx_runtime29 = require("react/jsx-runtime");
|
|
6803
7075
|
var defaultDescriptionClass = "max-w-[16rem] truncate px-1 text-xs text-muted-foreground";
|
|
6804
7076
|
var buttonClass3 = "rounded px-2 py-1 text-xs text-foreground hover:bg-muted disabled:opacity-40 disabled:hover:bg-transparent";
|
|
6805
7077
|
var ReviewToolbar = ({
|
|
@@ -6812,8 +7084,8 @@ var ReviewToolbar = ({
|
|
|
6812
7084
|
const count = review.changes.length;
|
|
6813
7085
|
const current = review.currentChange;
|
|
6814
7086
|
const index = current ? review.changes.findIndex((c) => c.id === current.id) + 1 : 0;
|
|
6815
|
-
return /* @__PURE__ */ (0,
|
|
6816
|
-
/* @__PURE__ */ (0,
|
|
7087
|
+
return /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className, role: "toolbar", "aria-label": "Review", children: [
|
|
7088
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
6817
7089
|
"button",
|
|
6818
7090
|
{
|
|
6819
7091
|
type: "button",
|
|
@@ -6824,8 +7096,8 @@ var ReviewToolbar = ({
|
|
|
6824
7096
|
children: review.enabled ? "Tracking on" : "Track changes"
|
|
6825
7097
|
}
|
|
6826
7098
|
),
|
|
6827
|
-
/* @__PURE__ */ (0,
|
|
6828
|
-
/* @__PURE__ */ (0,
|
|
7099
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { className: "mx-1 h-4 w-px bg-border", "aria-hidden": "true" }),
|
|
7100
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
6829
7101
|
"button",
|
|
6830
7102
|
{
|
|
6831
7103
|
type: "button",
|
|
@@ -6836,8 +7108,8 @@ var ReviewToolbar = ({
|
|
|
6836
7108
|
children: "\u2039"
|
|
6837
7109
|
}
|
|
6838
7110
|
),
|
|
6839
|
-
/* @__PURE__ */ (0,
|
|
6840
|
-
/* @__PURE__ */ (0,
|
|
7111
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.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` }),
|
|
7112
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
6841
7113
|
"button",
|
|
6842
7114
|
{
|
|
6843
7115
|
type: "button",
|
|
@@ -6848,7 +7120,7 @@ var ReviewToolbar = ({
|
|
|
6848
7120
|
children: "\u203A"
|
|
6849
7121
|
}
|
|
6850
7122
|
),
|
|
6851
|
-
showDescription && current && /* @__PURE__ */ (0,
|
|
7123
|
+
showDescription && current && /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(
|
|
6852
7124
|
"span",
|
|
6853
7125
|
{
|
|
6854
7126
|
className: descriptionClassName,
|
|
@@ -6860,8 +7132,8 @@ var ReviewToolbar = ({
|
|
|
6860
7132
|
]
|
|
6861
7133
|
}
|
|
6862
7134
|
),
|
|
6863
|
-
/* @__PURE__ */ (0,
|
|
6864
|
-
/* @__PURE__ */ (0,
|
|
7135
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { className: "mx-1 h-4 w-px bg-border", "aria-hidden": "true" }),
|
|
7136
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
6865
7137
|
"button",
|
|
6866
7138
|
{
|
|
6867
7139
|
type: "button",
|
|
@@ -6871,7 +7143,7 @@ var ReviewToolbar = ({
|
|
|
6871
7143
|
children: "Accept"
|
|
6872
7144
|
}
|
|
6873
7145
|
),
|
|
6874
|
-
/* @__PURE__ */ (0,
|
|
7146
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
6875
7147
|
"button",
|
|
6876
7148
|
{
|
|
6877
7149
|
type: "button",
|
|
@@ -6881,18 +7153,18 @@ var ReviewToolbar = ({
|
|
|
6881
7153
|
children: "Reject"
|
|
6882
7154
|
}
|
|
6883
7155
|
),
|
|
6884
|
-
/* @__PURE__ */ (0,
|
|
6885
|
-
/* @__PURE__ */ (0,
|
|
7156
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)("button", { type: "button", className: buttonClass3, disabled: count === 0, onClick: review.acceptAll, children: "Accept all" }),
|
|
7157
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)("button", { type: "button", className: buttonClass3, disabled: count === 0, onClick: review.rejectAll, children: "Reject all" })
|
|
6886
7158
|
] });
|
|
6887
7159
|
};
|
|
6888
7160
|
|
|
6889
7161
|
// src/review/CommentButton.tsx
|
|
6890
|
-
var
|
|
7162
|
+
var import_jsx_runtime30 = require("react/jsx-runtime");
|
|
6891
7163
|
var CommentButton = ({
|
|
6892
7164
|
editor,
|
|
6893
7165
|
className = "rounded px-2 py-1 text-xs text-popover-foreground hover:bg-muted",
|
|
6894
7166
|
children = "Comment"
|
|
6895
|
-
}) => /* @__PURE__ */ (0,
|
|
7167
|
+
}) => /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
6896
7168
|
"button",
|
|
6897
7169
|
{
|
|
6898
7170
|
type: "button",
|
|
@@ -6904,13 +7176,13 @@ var CommentButton = ({
|
|
|
6904
7176
|
);
|
|
6905
7177
|
|
|
6906
7178
|
// src/review/useDocumentCompare.ts
|
|
6907
|
-
var
|
|
7179
|
+
var import_react47 = require("react");
|
|
6908
7180
|
var import_editor14 = require("@pixerate/editor");
|
|
6909
7181
|
function useDocumentCompare(editor, options) {
|
|
6910
|
-
const [summary, setSummary] = (0,
|
|
6911
|
-
const defaults = (0,
|
|
7182
|
+
const [summary, setSummary] = (0, import_react47.useState)(null);
|
|
7183
|
+
const defaults = (0, import_react47.useRef)(options);
|
|
6912
7184
|
defaults.current = options;
|
|
6913
|
-
const compare = (0,
|
|
7185
|
+
const compare = (0, import_react47.useCallback)(
|
|
6914
7186
|
(original, revised, overrides) => {
|
|
6915
7187
|
if (!editor || editor.isDestroyed) return null;
|
|
6916
7188
|
const result = (0, import_editor14.applyDocumentComparison)(editor, original, revised, {
|
|
@@ -6922,13 +7194,13 @@ function useDocumentCompare(editor, options) {
|
|
|
6922
7194
|
},
|
|
6923
7195
|
[editor]
|
|
6924
7196
|
);
|
|
6925
|
-
const clear = (0,
|
|
6926
|
-
return (0,
|
|
7197
|
+
const clear = (0, import_react47.useCallback)(() => setSummary(null), []);
|
|
7198
|
+
return (0, import_react47.useMemo)(() => ({ summary, compare, clear }), [summary, compare, clear]);
|
|
6927
7199
|
}
|
|
6928
7200
|
|
|
6929
7201
|
// src/review/TrackedChangesList.tsx
|
|
6930
7202
|
var import_editor15 = require("@pixerate/editor");
|
|
6931
|
-
var
|
|
7203
|
+
var import_jsx_runtime31 = require("react/jsx-runtime");
|
|
6932
7204
|
var buttonClass4 = "rounded px-1.5 py-0.5 text-xs text-foreground hover:bg-muted disabled:opacity-40";
|
|
6933
7205
|
var TrackedChangesList = ({
|
|
6934
7206
|
editor,
|
|
@@ -6939,18 +7211,18 @@ var TrackedChangesList = ({
|
|
|
6939
7211
|
}) => {
|
|
6940
7212
|
const review = useTrackChanges(editor);
|
|
6941
7213
|
if (review.changes.length === 0) {
|
|
6942
|
-
return /* @__PURE__ */ (0,
|
|
7214
|
+
return /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("div", { className, "data-tracked-changes-list": "", children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("div", { className: "pixerate-changes-empty text-xs text-muted-foreground", children: emptyState }) });
|
|
6943
7215
|
}
|
|
6944
|
-
return /* @__PURE__ */ (0,
|
|
7216
|
+
return /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("ul", { className, role: "list", "aria-label": "Tracked changes", "data-tracked-changes-list": "", children: review.changes.map((change) => {
|
|
6945
7217
|
const active = change.id === review.currentChangeId;
|
|
6946
|
-
return /* @__PURE__ */ (0,
|
|
7218
|
+
return /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(
|
|
6947
7219
|
"li",
|
|
6948
7220
|
{
|
|
6949
7221
|
className: active ? `${itemClassName} ${activeItemClassName}` : itemClassName,
|
|
6950
7222
|
"data-change-type": change.type,
|
|
6951
7223
|
"data-change-id": change.id,
|
|
6952
7224
|
children: [
|
|
6953
|
-
/* @__PURE__ */ (0,
|
|
7225
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(
|
|
6954
7226
|
"button",
|
|
6955
7227
|
{
|
|
6956
7228
|
type: "button",
|
|
@@ -6958,14 +7230,14 @@ var TrackedChangesList = ({
|
|
|
6958
7230
|
title: `${change.author.name}: ${change.description}`,
|
|
6959
7231
|
onClick: () => review.select(change.id),
|
|
6960
7232
|
children: [
|
|
6961
|
-
/* @__PURE__ */ (0,
|
|
7233
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)("span", { className: "font-medium", children: (0, import_editor15.trackedChangeLabel)(change) }),
|
|
6962
7234
|
change.author.name ? ` \xB7 ${change.author.name}` : "",
|
|
6963
|
-
/* @__PURE__ */ (0,
|
|
7235
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)("span", { className: "block truncate text-muted-foreground", children: change.description })
|
|
6964
7236
|
]
|
|
6965
7237
|
}
|
|
6966
7238
|
),
|
|
6967
|
-
/* @__PURE__ */ (0,
|
|
6968
|
-
/* @__PURE__ */ (0,
|
|
7239
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)("button", { type: "button", className: buttonClass4, onClick: () => review.accept(change.id), children: "Accept" }),
|
|
7240
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)("button", { type: "button", className: buttonClass4, onClick: () => review.reject(change.id), children: "Reject" })
|
|
6969
7241
|
]
|
|
6970
7242
|
},
|
|
6971
7243
|
`${change.type}:${change.id}`
|
|
@@ -6974,12 +7246,12 @@ var TrackedChangesList = ({
|
|
|
6974
7246
|
};
|
|
6975
7247
|
|
|
6976
7248
|
// src/commands/useCommandPalette.ts
|
|
6977
|
-
var
|
|
7249
|
+
var import_react48 = require("react");
|
|
6978
7250
|
var import_commands2 = require("@pixerate/editor/commands");
|
|
6979
7251
|
function useCommandPalette(registry, options = {}) {
|
|
6980
|
-
const optionsRef = (0,
|
|
7252
|
+
const optionsRef = (0, import_react48.useRef)(options);
|
|
6981
7253
|
optionsRef.current = options;
|
|
6982
|
-
const controller = (0,
|
|
7254
|
+
const controller = (0, import_react48.useMemo)(
|
|
6983
7255
|
() => (0, import_commands2.createCommandPaletteController)(registry, {
|
|
6984
7256
|
context: () => {
|
|
6985
7257
|
const c = optionsRef.current.context;
|
|
@@ -7000,9 +7272,9 @@ function useCommandPalette(registry, options = {}) {
|
|
|
7000
7272
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
7001
7273
|
[registry]
|
|
7002
7274
|
);
|
|
7003
|
-
const state = (0,
|
|
7275
|
+
const state = (0, import_react48.useSyncExternalStore)(controller.subscribe, controller.getState, controller.getState);
|
|
7004
7276
|
const { hotkey, hotkeyTarget } = options;
|
|
7005
|
-
(0,
|
|
7277
|
+
(0, import_react48.useEffect)(() => {
|
|
7006
7278
|
if (!hotkey) return;
|
|
7007
7279
|
const target = hotkeyTarget ?? (typeof window !== "undefined" ? window : null);
|
|
7008
7280
|
if (!target) return;
|
|
@@ -7030,13 +7302,13 @@ function useCommandPalette(registry, options = {}) {
|
|
|
7030
7302
|
}
|
|
7031
7303
|
|
|
7032
7304
|
// src/commands/CommandPalette.tsx
|
|
7033
|
-
var
|
|
7034
|
-
var
|
|
7305
|
+
var import_react49 = __toESM(require("react"), 1);
|
|
7306
|
+
var import_jsx_runtime32 = require("react/jsx-runtime");
|
|
7035
7307
|
function HighlightedLabel({ item }) {
|
|
7036
|
-
if (item.labelIndices.length === 0) return /* @__PURE__ */ (0,
|
|
7308
|
+
if (item.labelIndices.length === 0) return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_jsx_runtime32.Fragment, { children: item.label });
|
|
7037
7309
|
const marked = new Set(item.labelIndices);
|
|
7038
|
-
return /* @__PURE__ */ (0,
|
|
7039
|
-
(ch, i) => marked.has(i) ? /* @__PURE__ */ (0,
|
|
7310
|
+
return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_jsx_runtime32.Fragment, { children: Array.from(item.label).map(
|
|
7311
|
+
(ch, i) => marked.has(i) ? /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("span", { className: "font-semibold text-foreground", "data-match": "", children: ch }, i) : /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_react49.default.Fragment, { children: ch }, i)
|
|
7040
7312
|
) });
|
|
7041
7313
|
}
|
|
7042
7314
|
var CommandPalette = ({
|
|
@@ -7045,22 +7317,22 @@ var CommandPalette = ({
|
|
|
7045
7317
|
emptyMessage = "No matching commands",
|
|
7046
7318
|
className = ""
|
|
7047
7319
|
}) => {
|
|
7048
|
-
const inputRef = (0,
|
|
7049
|
-
const listRef = (0,
|
|
7050
|
-
const baseId = (0,
|
|
7320
|
+
const inputRef = (0, import_react49.useRef)(null);
|
|
7321
|
+
const listRef = (0, import_react49.useRef)(null);
|
|
7322
|
+
const baseId = (0, import_react49.useId)();
|
|
7051
7323
|
const listId = `${baseId}-list`;
|
|
7052
7324
|
const optionId = (index) => `${baseId}-option-${index}`;
|
|
7053
7325
|
const { open, query, items, activeIndex } = palette;
|
|
7054
|
-
(0,
|
|
7326
|
+
(0, import_react49.useEffect)(() => {
|
|
7055
7327
|
if (open) inputRef.current?.focus();
|
|
7056
7328
|
}, [open]);
|
|
7057
|
-
(0,
|
|
7329
|
+
(0, import_react49.useEffect)(() => {
|
|
7058
7330
|
if (!open) return;
|
|
7059
7331
|
const active = listRef.current?.querySelector('[aria-selected="true"]');
|
|
7060
7332
|
active?.scrollIntoView?.({ block: "nearest" });
|
|
7061
7333
|
}, [open, activeIndex]);
|
|
7062
7334
|
if (!open) return null;
|
|
7063
|
-
return /* @__PURE__ */ (0,
|
|
7335
|
+
return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
7064
7336
|
"div",
|
|
7065
7337
|
{
|
|
7066
7338
|
className: "fixed inset-0 z-50 flex items-start justify-center bg-black/30 px-4 pt-[15vh]",
|
|
@@ -7068,7 +7340,7 @@ var CommandPalette = ({
|
|
|
7068
7340
|
onMouseDown: (e) => {
|
|
7069
7341
|
if (e.target === e.currentTarget) palette.setOpen(false);
|
|
7070
7342
|
},
|
|
7071
|
-
children: /* @__PURE__ */ (0,
|
|
7343
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(
|
|
7072
7344
|
"div",
|
|
7073
7345
|
{
|
|
7074
7346
|
role: "dialog",
|
|
@@ -7077,7 +7349,7 @@ var CommandPalette = ({
|
|
|
7077
7349
|
className: `w-full max-w-lg overflow-hidden rounded-lg border border-border bg-popover text-popover-foreground shadow-xl ${className}`,
|
|
7078
7350
|
style: { background: "var(--popover, var(--background, #fff))" },
|
|
7079
7351
|
children: [
|
|
7080
|
-
/* @__PURE__ */ (0,
|
|
7352
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
7081
7353
|
"input",
|
|
7082
7354
|
{
|
|
7083
7355
|
ref: inputRef,
|
|
@@ -7097,7 +7369,7 @@ var CommandPalette = ({
|
|
|
7097
7369
|
className: "w-full border-b border-border bg-transparent px-3 py-2 text-sm outline-none placeholder:text-muted-foreground"
|
|
7098
7370
|
}
|
|
7099
7371
|
),
|
|
7100
|
-
items.length === 0 ? /* @__PURE__ */ (0,
|
|
7372
|
+
items.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { className: "px-3 py-6 text-center text-sm text-muted-foreground", children: emptyMessage }) : /* @__PURE__ */ (0, import_jsx_runtime32.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_runtime32.jsxs)(
|
|
7101
7373
|
"li",
|
|
7102
7374
|
{
|
|
7103
7375
|
id: optionId(index),
|
|
@@ -7112,12 +7384,12 @@ var CommandPalette = ({
|
|
|
7112
7384
|
onClick: () => palette.run(item.id),
|
|
7113
7385
|
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"}`,
|
|
7114
7386
|
children: [
|
|
7115
|
-
/* @__PURE__ */ (0,
|
|
7116
|
-
/* @__PURE__ */ (0,
|
|
7117
|
-
item.disabledReason && /* @__PURE__ */ (0,
|
|
7387
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("span", { className: "min-w-0 flex-1 truncate", children: [
|
|
7388
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)(HighlightedLabel, { item }),
|
|
7389
|
+
item.disabledReason && /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("span", { className: "ml-2 text-xs text-muted-foreground", "data-disabled-reason": "", children: item.disabledReason })
|
|
7118
7390
|
] }),
|
|
7119
|
-
item.group && /* @__PURE__ */ (0,
|
|
7120
|
-
item.shortcut && /* @__PURE__ */ (0,
|
|
7391
|
+
item.group && /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("span", { className: "shrink-0 text-xs text-muted-foreground", children: item.group }),
|
|
7392
|
+
item.shortcut && /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("kbd", { className: "shrink-0 rounded border border-border px-1.5 font-mono text-[10px] text-muted-foreground", children: item.shortcut })
|
|
7121
7393
|
]
|
|
7122
7394
|
},
|
|
7123
7395
|
item.id
|
|
@@ -7130,12 +7402,12 @@ var CommandPalette = ({
|
|
|
7130
7402
|
};
|
|
7131
7403
|
|
|
7132
7404
|
// src/commands/useCommandShortcuts.ts
|
|
7133
|
-
var
|
|
7405
|
+
var import_react50 = require("react");
|
|
7134
7406
|
function useCommandShortcuts(registry, options = {}) {
|
|
7135
|
-
const optionsRef = (0,
|
|
7407
|
+
const optionsRef = (0, import_react50.useRef)(options);
|
|
7136
7408
|
optionsRef.current = options;
|
|
7137
7409
|
const { enabled = true, target } = options;
|
|
7138
|
-
(0,
|
|
7410
|
+
(0, import_react50.useEffect)(() => {
|
|
7139
7411
|
if (!registry || !enabled) return;
|
|
7140
7412
|
const eventTarget = target ?? (typeof window !== "undefined" ? window : null);
|
|
7141
7413
|
if (!eventTarget) return;
|
|
@@ -7153,14 +7425,14 @@ function useCommandShortcuts(registry, options = {}) {
|
|
|
7153
7425
|
}, [registry, enabled, target]);
|
|
7154
7426
|
}
|
|
7155
7427
|
function useRegisterCommands(registry, specs) {
|
|
7156
|
-
(0,
|
|
7428
|
+
(0, import_react50.useEffect)(() => {
|
|
7157
7429
|
if (!registry || !specs || specs.length === 0) return;
|
|
7158
7430
|
return registry.register(specs);
|
|
7159
7431
|
}, [registry, specs]);
|
|
7160
7432
|
}
|
|
7161
7433
|
|
|
7162
7434
|
// src/persistence/useAutosave.ts
|
|
7163
|
-
var
|
|
7435
|
+
var import_react51 = require("react");
|
|
7164
7436
|
var import_persistence = require("@pixerate/editor/persistence");
|
|
7165
7437
|
var IDLE = {
|
|
7166
7438
|
status: "idle",
|
|
@@ -7171,18 +7443,18 @@ var IDLE = {
|
|
|
7171
7443
|
ready: false
|
|
7172
7444
|
};
|
|
7173
7445
|
function useAutosave(options) {
|
|
7174
|
-
const optionsRef = (0,
|
|
7446
|
+
const optionsRef = (0, import_react51.useRef)(options);
|
|
7175
7447
|
optionsRef.current = options;
|
|
7176
7448
|
const { storage, key, history, dirty } = options;
|
|
7177
7449
|
const recover = options.recover !== false;
|
|
7178
7450
|
const flushOnHide = options.flushOnHide !== false;
|
|
7179
7451
|
const ready = options.ready !== false;
|
|
7180
|
-
const [controller, setController] = (0,
|
|
7181
|
-
const [status, setStatus] = (0,
|
|
7182
|
-
const [recovery, setRecovery] = (0,
|
|
7183
|
-
const [pendingRecovery, setPendingRecovery] = (0,
|
|
7184
|
-
const revisionsRef = (0,
|
|
7185
|
-
(0,
|
|
7452
|
+
const [controller, setController] = (0, import_react51.useState)(null);
|
|
7453
|
+
const [status, setStatus] = (0, import_react51.useState)(IDLE);
|
|
7454
|
+
const [recovery, setRecovery] = (0, import_react51.useState)(null);
|
|
7455
|
+
const [pendingRecovery, setPendingRecovery] = (0, import_react51.useState)(recover);
|
|
7456
|
+
const revisionsRef = (0, import_react51.useRef)(null);
|
|
7457
|
+
(0, import_react51.useEffect)(() => {
|
|
7186
7458
|
const revisions = (0, import_persistence.createRevisionTracker)({ history, dirty });
|
|
7187
7459
|
const o = optionsRef.current;
|
|
7188
7460
|
const instance = (0, import_persistence.createAutosaveController)({
|
|
@@ -7225,10 +7497,10 @@ function useAutosave(options) {
|
|
|
7225
7497
|
if (revisionsRef.current === revisions) revisionsRef.current = null;
|
|
7226
7498
|
};
|
|
7227
7499
|
}, [storage, key, history, dirty, recover]);
|
|
7228
|
-
(0,
|
|
7500
|
+
(0, import_react51.useEffect)(() => {
|
|
7229
7501
|
if (controller && ready && !pendingRecovery) controller.ready();
|
|
7230
7502
|
}, [controller, ready, pendingRecovery]);
|
|
7231
|
-
(0,
|
|
7503
|
+
(0, import_react51.useEffect)(() => {
|
|
7232
7504
|
if (!controller || !flushOnHide || typeof window === "undefined") return;
|
|
7233
7505
|
const flush = () => void controller.flushNow();
|
|
7234
7506
|
const onVisibility = () => {
|
|
@@ -7241,31 +7513,31 @@ function useAutosave(options) {
|
|
|
7241
7513
|
document.removeEventListener("visibilitychange", onVisibility);
|
|
7242
7514
|
};
|
|
7243
7515
|
}, [controller, flushOnHide]);
|
|
7244
|
-
const restore = (0,
|
|
7516
|
+
const restore = (0, import_react51.useCallback)(() => {
|
|
7245
7517
|
const snapshot = recovery?.snapshot;
|
|
7246
7518
|
setRecovery(null);
|
|
7247
7519
|
setPendingRecovery(false);
|
|
7248
7520
|
return snapshot;
|
|
7249
7521
|
}, [recovery]);
|
|
7250
|
-
const discard = (0,
|
|
7522
|
+
const discard = (0, import_react51.useCallback)(async () => {
|
|
7251
7523
|
if (controller) await controller.discardRecovery();
|
|
7252
7524
|
setRecovery(null);
|
|
7253
7525
|
setPendingRecovery(false);
|
|
7254
7526
|
}, [controller]);
|
|
7255
|
-
const flushNow = (0,
|
|
7527
|
+
const flushNow = (0, import_react51.useCallback)(async () => {
|
|
7256
7528
|
await controller?.flushNow();
|
|
7257
7529
|
}, [controller]);
|
|
7258
|
-
const markClean = (0,
|
|
7530
|
+
const markClean = (0, import_react51.useCallback)(async () => {
|
|
7259
7531
|
revisionsRef.current?.markSaved();
|
|
7260
7532
|
await controller?.markClean();
|
|
7261
7533
|
}, [controller]);
|
|
7262
|
-
const notifyChange = (0,
|
|
7534
|
+
const notifyChange = (0, import_react51.useCallback)(() => revisionsRef.current?.bump(), []);
|
|
7263
7535
|
return { status, recovery, pendingRecovery, restore, discard, flushNow, markClean, notifyChange, controller };
|
|
7264
7536
|
}
|
|
7265
7537
|
|
|
7266
7538
|
// src/persistence/RecoveryPrompt.tsx
|
|
7267
7539
|
var import_persistence2 = require("@pixerate/editor/persistence");
|
|
7268
|
-
var
|
|
7540
|
+
var import_jsx_runtime33 = require("react/jsx-runtime");
|
|
7269
7541
|
var RecoveryPrompt = ({
|
|
7270
7542
|
recovery,
|
|
7271
7543
|
onRestore,
|
|
@@ -7277,7 +7549,7 @@ var RecoveryPrompt = ({
|
|
|
7277
7549
|
}) => {
|
|
7278
7550
|
if (!recovery) return null;
|
|
7279
7551
|
const { name } = recovery.meta;
|
|
7280
|
-
return /* @__PURE__ */ (0,
|
|
7552
|
+
return /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(
|
|
7281
7553
|
"div",
|
|
7282
7554
|
{
|
|
7283
7555
|
role: "alertdialog",
|
|
@@ -7285,15 +7557,15 @@ var RecoveryPrompt = ({
|
|
|
7285
7557
|
"data-recovery-prompt": "",
|
|
7286
7558
|
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}`,
|
|
7287
7559
|
children: [
|
|
7288
|
-
/* @__PURE__ */ (0,
|
|
7560
|
+
/* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("span", { className: "min-w-0 flex-1", children: [
|
|
7289
7561
|
(0, import_persistence2.formatRecoveryMessage)(recovery.meta, formatTime),
|
|
7290
|
-
name ? /* @__PURE__ */ (0,
|
|
7562
|
+
name ? /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("span", { className: "ml-1 text-xs text-muted-foreground", children: [
|
|
7291
7563
|
"(",
|
|
7292
7564
|
name,
|
|
7293
7565
|
")"
|
|
7294
7566
|
] }) : null
|
|
7295
7567
|
] }),
|
|
7296
|
-
/* @__PURE__ */ (0,
|
|
7568
|
+
/* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
|
|
7297
7569
|
"button",
|
|
7298
7570
|
{
|
|
7299
7571
|
type: "button",
|
|
@@ -7303,7 +7575,7 @@ var RecoveryPrompt = ({
|
|
|
7303
7575
|
children: restoreLabel
|
|
7304
7576
|
}
|
|
7305
7577
|
),
|
|
7306
|
-
/* @__PURE__ */ (0,
|
|
7578
|
+
/* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
|
|
7307
7579
|
"button",
|
|
7308
7580
|
{
|
|
7309
7581
|
type: "button",
|
|
@@ -7319,17 +7591,17 @@ var RecoveryPrompt = ({
|
|
|
7319
7591
|
};
|
|
7320
7592
|
|
|
7321
7593
|
// src/generation/useGenerationPlan.ts
|
|
7322
|
-
var
|
|
7594
|
+
var import_react52 = require("react");
|
|
7323
7595
|
var import_generation = require("@pixerate/editor/generation");
|
|
7324
7596
|
function useGenerationPlan(request, capabilities, options = {}) {
|
|
7325
7597
|
const key = JSON.stringify([request, capabilities, options]);
|
|
7326
|
-
return (0,
|
|
7598
|
+
return (0, import_react52.useMemo)(() => (0, import_generation.planGenerationRequest)(request, capabilities, options), [key]);
|
|
7327
7599
|
}
|
|
7328
7600
|
function useJobProgress(options) {
|
|
7329
7601
|
const { startedAt, expectedMs, done, now, intervalMs = 1e3 } = options;
|
|
7330
|
-
const [tick, setTick] = (0,
|
|
7602
|
+
const [tick, setTick] = (0, import_react52.useState)(() => Date.now());
|
|
7331
7603
|
const ticking = !done && now === void 0;
|
|
7332
|
-
(0,
|
|
7604
|
+
(0, import_react52.useEffect)(() => {
|
|
7333
7605
|
if (!ticking) return;
|
|
7334
7606
|
setTick(Date.now());
|
|
7335
7607
|
const id = setInterval(() => setTick(Date.now()), Math.max(16, intervalMs));
|
|
@@ -7339,9 +7611,9 @@ function useJobProgress(options) {
|
|
|
7339
7611
|
}
|
|
7340
7612
|
|
|
7341
7613
|
// src/generation/GenerationSettings.tsx
|
|
7342
|
-
var
|
|
7614
|
+
var import_react53 = require("react");
|
|
7343
7615
|
var import_generation2 = require("@pixerate/editor/generation");
|
|
7344
|
-
var
|
|
7616
|
+
var import_jsx_runtime34 = require("react/jsx-runtime");
|
|
7345
7617
|
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";
|
|
7346
7618
|
function Control({
|
|
7347
7619
|
control,
|
|
@@ -7351,7 +7623,7 @@ function Control({
|
|
|
7351
7623
|
}) {
|
|
7352
7624
|
const shown = value ?? control.defaultValue;
|
|
7353
7625
|
if (control.kind === "checkbox") {
|
|
7354
|
-
return /* @__PURE__ */ (0,
|
|
7626
|
+
return /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
7355
7627
|
"input",
|
|
7356
7628
|
{
|
|
7357
7629
|
id,
|
|
@@ -7363,7 +7635,7 @@ function Control({
|
|
|
7363
7635
|
);
|
|
7364
7636
|
}
|
|
7365
7637
|
if (control.kind === "select") {
|
|
7366
|
-
return /* @__PURE__ */ (0,
|
|
7638
|
+
return /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(
|
|
7367
7639
|
"select",
|
|
7368
7640
|
{
|
|
7369
7641
|
id,
|
|
@@ -7372,14 +7644,14 @@ function Control({
|
|
|
7372
7644
|
value: shown === void 0 ? "" : String(shown),
|
|
7373
7645
|
onChange: (e) => onValue((0, import_generation2.parseControlValue)(control, e.target.value)),
|
|
7374
7646
|
children: [
|
|
7375
|
-
shown === void 0 && /* @__PURE__ */ (0,
|
|
7376
|
-
control.options.map((option) => /* @__PURE__ */ (0,
|
|
7647
|
+
shown === void 0 && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("option", { value: "", children: "Default" }),
|
|
7648
|
+
control.options.map((option) => /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("option", { value: String(option.value), children: option.label }, String(option.value)))
|
|
7377
7649
|
]
|
|
7378
7650
|
}
|
|
7379
7651
|
);
|
|
7380
7652
|
}
|
|
7381
7653
|
if (control.kind === "textarea") {
|
|
7382
|
-
return /* @__PURE__ */ (0,
|
|
7654
|
+
return /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
7383
7655
|
"textarea",
|
|
7384
7656
|
{
|
|
7385
7657
|
id,
|
|
@@ -7393,8 +7665,8 @@ function Control({
|
|
|
7393
7665
|
);
|
|
7394
7666
|
}
|
|
7395
7667
|
const numeric = typeof shown === "number" ? shown : void 0;
|
|
7396
|
-
return /* @__PURE__ */ (0,
|
|
7397
|
-
/* @__PURE__ */ (0,
|
|
7668
|
+
return /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
7669
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
7398
7670
|
"input",
|
|
7399
7671
|
{
|
|
7400
7672
|
id,
|
|
@@ -7408,7 +7680,7 @@ function Control({
|
|
|
7408
7680
|
onChange: (e) => onValue((0, import_generation2.parseControlValue)(control, e.target.value))
|
|
7409
7681
|
}
|
|
7410
7682
|
),
|
|
7411
|
-
control.kind === "range" && /* @__PURE__ */ (0,
|
|
7683
|
+
control.kind === "range" && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("span", { className: "w-10 text-right tabular-nums text-muted-foreground", "data-field-value": "", children: numeric ?? "\u2013" })
|
|
7412
7684
|
] });
|
|
7413
7685
|
}
|
|
7414
7686
|
var GenerationSettings = ({
|
|
@@ -7422,17 +7694,17 @@ var GenerationSettings = ({
|
|
|
7422
7694
|
renderReference,
|
|
7423
7695
|
className = ""
|
|
7424
7696
|
}) => {
|
|
7425
|
-
const baseId = (0,
|
|
7426
|
-
const controls = (0,
|
|
7697
|
+
const baseId = (0, import_react53.useId)();
|
|
7698
|
+
const controls = (0, import_react53.useMemo)(() => (0, import_generation2.getGenerationControls)(capabilities), [capabilities]);
|
|
7427
7699
|
const computed = useGenerationPlan(value, capabilities, { strategy });
|
|
7428
7700
|
const plan = planProp ?? computed;
|
|
7429
7701
|
const slots = (0, import_generation2.getReferenceSlots)(capabilities, value);
|
|
7430
|
-
return /* @__PURE__ */ (0,
|
|
7702
|
+
return /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("div", { className: `flex flex-col gap-3 text-sm ${className}`, "data-generation-settings": "", "data-model": capabilities.id, children: [
|
|
7431
7703
|
controls.map((control) => {
|
|
7432
7704
|
const id = `${baseId}-${control.key}`;
|
|
7433
|
-
return /* @__PURE__ */ (0,
|
|
7434
|
-
/* @__PURE__ */ (0,
|
|
7435
|
-
/* @__PURE__ */ (0,
|
|
7705
|
+
return /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("div", { className: "flex flex-col gap-1", "data-control": control.key, children: [
|
|
7706
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)("label", { htmlFor: id, className: "text-xs font-medium text-muted-foreground", title: control.description, children: control.label }),
|
|
7707
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
7436
7708
|
Control,
|
|
7437
7709
|
{
|
|
7438
7710
|
control,
|
|
@@ -7443,23 +7715,23 @@ var GenerationSettings = ({
|
|
|
7443
7715
|
)
|
|
7444
7716
|
] }, control.key);
|
|
7445
7717
|
}),
|
|
7446
|
-
slots.map((slot) => /* @__PURE__ */ (0,
|
|
7447
|
-
/* @__PURE__ */ (0,
|
|
7718
|
+
slots.map((slot) => /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("fieldset", { className: "flex flex-col gap-1", "data-reference-role": slot.role, children: [
|
|
7719
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("legend", { className: "text-xs font-medium text-muted-foreground", title: slot.description, children: [
|
|
7448
7720
|
slot.label,
|
|
7449
7721
|
" ",
|
|
7450
|
-
/* @__PURE__ */ (0,
|
|
7722
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("span", { className: "tabular-nums", "data-reference-count": "", children: [
|
|
7451
7723
|
"(",
|
|
7452
7724
|
slot.references.length,
|
|
7453
7725
|
"/",
|
|
7454
7726
|
slot.max,
|
|
7455
7727
|
")"
|
|
7456
7728
|
] }),
|
|
7457
|
-
slot.min > 0 && /* @__PURE__ */ (0,
|
|
7729
|
+
slot.min > 0 && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("span", { className: "text-destructive", children: " *" })
|
|
7458
7730
|
] }),
|
|
7459
|
-
/* @__PURE__ */ (0,
|
|
7460
|
-
slot.references.map((ref) => /* @__PURE__ */ (0,
|
|
7461
|
-
renderReference ? renderReference(ref) : /* @__PURE__ */ (0,
|
|
7462
|
-
/* @__PURE__ */ (0,
|
|
7731
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("ul", { className: "flex flex-wrap gap-1", children: [
|
|
7732
|
+
slot.references.map((ref) => /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("li", { className: "flex items-center gap-1 rounded border border-border px-1.5 py-0.5", "data-reference-id": ref.id, children: [
|
|
7733
|
+
renderReference ? renderReference(ref) : /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("span", { className: "max-w-[10rem] truncate", children: ref.id }),
|
|
7734
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
7463
7735
|
"button",
|
|
7464
7736
|
{
|
|
7465
7737
|
type: "button",
|
|
@@ -7470,7 +7742,7 @@ var GenerationSettings = ({
|
|
|
7470
7742
|
}
|
|
7471
7743
|
)
|
|
7472
7744
|
] }, ref.id)),
|
|
7473
|
-
onAddReference && slot.canAdd && /* @__PURE__ */ (0,
|
|
7745
|
+
onAddReference && slot.canAdd && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("li", { children: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
7474
7746
|
"button",
|
|
7475
7747
|
{
|
|
7476
7748
|
type: "button",
|
|
@@ -7481,21 +7753,21 @@ var GenerationSettings = ({
|
|
|
7481
7753
|
) })
|
|
7482
7754
|
] })
|
|
7483
7755
|
] }, slot.role)),
|
|
7484
|
-
showAdjustments && plan.adjustments.length > 0 && /* @__PURE__ */ (0,
|
|
7485
|
-
showAdjustments && plan.errors.length > 0 && /* @__PURE__ */ (0,
|
|
7756
|
+
showAdjustments && plan.adjustments.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime34.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_runtime34.jsx)("li", { "data-adjustment-field": adjustment.field, "data-adjustment-kind": adjustment.kind, children: adjustment.reason }, index)) }),
|
|
7757
|
+
showAdjustments && plan.errors.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime34.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_runtime34.jsx)("li", { "data-error-field": error.field, children: error.message }, index)) })
|
|
7486
7758
|
] });
|
|
7487
7759
|
};
|
|
7488
7760
|
|
|
7489
7761
|
// src/generation/JobProgress.tsx
|
|
7490
|
-
var
|
|
7762
|
+
var import_jsx_runtime35 = require("react/jsx-runtime");
|
|
7491
7763
|
var JobProgress = ({ title, className = "", ...options }) => {
|
|
7492
7764
|
const progress = useJobProgress(options);
|
|
7493
|
-
return /* @__PURE__ */ (0,
|
|
7494
|
-
/* @__PURE__ */ (0,
|
|
7495
|
-
title && /* @__PURE__ */ (0,
|
|
7496
|
-
/* @__PURE__ */ (0,
|
|
7765
|
+
return /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("div", { className: `flex flex-col gap-1 text-sm ${className}`, "data-job-progress": "", "data-done": options.done ? "" : void 0, children: [
|
|
7766
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("div", { className: "flex items-center justify-between gap-2 text-muted-foreground", children: [
|
|
7767
|
+
title && /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("span", { className: "truncate text-foreground", children: title }),
|
|
7768
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsx)("span", { "data-job-progress-label": "", "aria-live": "polite", children: progress.label })
|
|
7497
7769
|
] }),
|
|
7498
|
-
/* @__PURE__ */ (0,
|
|
7770
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
|
|
7499
7771
|
"div",
|
|
7500
7772
|
{
|
|
7501
7773
|
role: "progressbar",
|
|
@@ -7505,7 +7777,7 @@ var JobProgress = ({ title, className = "", ...options }) => {
|
|
|
7505
7777
|
"aria-valuenow": progress.percent,
|
|
7506
7778
|
"aria-valuetext": `${progress.percent}%, ${progress.label}`,
|
|
7507
7779
|
className: "h-1.5 w-full overflow-hidden rounded-full bg-muted",
|
|
7508
|
-
children: /* @__PURE__ */ (0,
|
|
7780
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
|
|
7509
7781
|
"div",
|
|
7510
7782
|
{
|
|
7511
7783
|
className: "h-full rounded-full bg-primary transition-[width] duration-500",
|
|
@@ -7518,9 +7790,9 @@ var JobProgress = ({ title, className = "", ...options }) => {
|
|
|
7518
7790
|
};
|
|
7519
7791
|
|
|
7520
7792
|
// src/generation/AssetMentionChips.tsx
|
|
7521
|
-
var
|
|
7793
|
+
var import_react54 = require("react");
|
|
7522
7794
|
var import_generation3 = require("@pixerate/editor/generation");
|
|
7523
|
-
var
|
|
7795
|
+
var import_jsx_runtime36 = require("react/jsx-runtime");
|
|
7524
7796
|
var AssetMentionChips = ({
|
|
7525
7797
|
content,
|
|
7526
7798
|
onChange,
|
|
@@ -7530,14 +7802,14 @@ var AssetMentionChips = ({
|
|
|
7530
7802
|
renderAsset,
|
|
7531
7803
|
className = ""
|
|
7532
7804
|
}) => {
|
|
7533
|
-
const [open, setOpen] = (0,
|
|
7534
|
-
const rootRef = (0,
|
|
7535
|
-
const chips = (0,
|
|
7805
|
+
const [open, setOpen] = (0, import_react54.useState)(null);
|
|
7806
|
+
const rootRef = (0, import_react54.useRef)(null);
|
|
7807
|
+
const chips = (0, import_react54.useMemo)(
|
|
7536
7808
|
() => (0, import_generation3.describeAssetMentions)((0, import_generation3.findTextMentions)(content), assets, capabilities),
|
|
7537
7809
|
[content, assets, capabilities]
|
|
7538
7810
|
);
|
|
7539
7811
|
const options = roles ?? (capabilities ? (0, import_generation3.getAssetRoleOptions)(capabilities) : (0, import_generation3.defaultAssetRoleOptions)());
|
|
7540
|
-
(0,
|
|
7812
|
+
(0, import_react54.useEffect)(() => {
|
|
7541
7813
|
if (open === null) return;
|
|
7542
7814
|
const onPointer = (event) => {
|
|
7543
7815
|
if (!rootRef.current?.contains(event.target)) setOpen(null);
|
|
@@ -7545,19 +7817,19 @@ var AssetMentionChips = ({
|
|
|
7545
7817
|
document.addEventListener("mousedown", onPointer);
|
|
7546
7818
|
return () => document.removeEventListener("mousedown", onPointer);
|
|
7547
7819
|
}, [open]);
|
|
7548
|
-
const pick = (
|
|
7820
|
+
const pick = (chip3, role) => {
|
|
7549
7821
|
setOpen(null);
|
|
7550
|
-
if (
|
|
7551
|
-
onChange((0, import_generation3.setMentionRoleInText)(content,
|
|
7822
|
+
if (chip3.start === void 0) return;
|
|
7823
|
+
onChange((0, import_generation3.setMentionRoleInText)(content, chip3.start, role));
|
|
7552
7824
|
};
|
|
7553
7825
|
if (chips.length === 0) return null;
|
|
7554
|
-
return /* @__PURE__ */ (0,
|
|
7555
|
-
const error =
|
|
7556
|
-
const warning =
|
|
7826
|
+
return /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("div", { ref: rootRef, className: `flex flex-wrap gap-1.5 ${className}`, "data-asset-mention-chips": "", children: chips.map((chip3) => {
|
|
7827
|
+
const error = chip3.issues.find((issue) => issue.severity === "error");
|
|
7828
|
+
const warning = chip3.issues.find((issue) => issue.severity === "warning");
|
|
7557
7829
|
const problem = error ?? warning;
|
|
7558
|
-
const isOpen = open ===
|
|
7559
|
-
return /* @__PURE__ */ (0,
|
|
7560
|
-
/* @__PURE__ */ (0,
|
|
7830
|
+
const isOpen = open === chip3.index;
|
|
7831
|
+
return /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("span", { className: "relative inline-flex", "data-asset-chip": chip3.asset.id, children: [
|
|
7832
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(
|
|
7561
7833
|
"button",
|
|
7562
7834
|
{
|
|
7563
7835
|
type: "button",
|
|
@@ -7565,82 +7837,82 @@ var AssetMentionChips = ({
|
|
|
7565
7837
|
"aria-expanded": isOpen,
|
|
7566
7838
|
title: problem?.message,
|
|
7567
7839
|
"data-issue": problem?.code,
|
|
7568
|
-
onClick: () => setOpen(isOpen ? null :
|
|
7840
|
+
onClick: () => setOpen(isOpen ? null : chip3.index),
|
|
7569
7841
|
onKeyDown: (e) => {
|
|
7570
7842
|
if (e.key === "Escape") setOpen(null);
|
|
7571
7843
|
},
|
|
7572
7844
|
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`,
|
|
7573
7845
|
children: [
|
|
7574
|
-
/* @__PURE__ */ (0,
|
|
7575
|
-
/* @__PURE__ */ (0,
|
|
7846
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)("span", { children: renderAsset ? renderAsset(chip3) : `@${chip3.asset.label ?? chip3.handle}` }),
|
|
7847
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
7576
7848
|
"span",
|
|
7577
7849
|
{
|
|
7578
|
-
className: `rounded px-1 text-[10px] uppercase tracking-wide ${
|
|
7579
|
-
"data-role-badge":
|
|
7580
|
-
children:
|
|
7850
|
+
className: `rounded px-1 text-[10px] uppercase tracking-wide ${chip3.role ? "bg-primary/15" : "opacity-60"}`,
|
|
7851
|
+
"data-role-badge": chip3.role ?? "",
|
|
7852
|
+
children: chip3.roleLabel ?? "No role"
|
|
7581
7853
|
}
|
|
7582
7854
|
)
|
|
7583
7855
|
]
|
|
7584
7856
|
}
|
|
7585
7857
|
),
|
|
7586
|
-
isOpen && /* @__PURE__ */ (0,
|
|
7858
|
+
isOpen && /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(
|
|
7587
7859
|
"div",
|
|
7588
7860
|
{
|
|
7589
7861
|
role: "listbox",
|
|
7590
|
-
"aria-label": `Role for ${
|
|
7862
|
+
"aria-label": `Role for ${chip3.asset.label ?? chip3.handle}`,
|
|
7591
7863
|
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",
|
|
7592
7864
|
"data-role-picker": "",
|
|
7593
7865
|
onKeyDown: (e) => {
|
|
7594
7866
|
if (e.key === "Escape") setOpen(null);
|
|
7595
7867
|
},
|
|
7596
7868
|
children: [
|
|
7597
|
-
options.map((option) => /* @__PURE__ */ (0,
|
|
7869
|
+
options.map((option) => /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(
|
|
7598
7870
|
"button",
|
|
7599
7871
|
{
|
|
7600
7872
|
type: "button",
|
|
7601
7873
|
role: "option",
|
|
7602
|
-
"aria-selected":
|
|
7874
|
+
"aria-selected": chip3.role === option.role,
|
|
7603
7875
|
"data-role-option": option.role,
|
|
7604
7876
|
title: option.description,
|
|
7605
|
-
onClick: () => pick(
|
|
7877
|
+
onClick: () => pick(chip3, option.role),
|
|
7606
7878
|
className: "flex items-center justify-between gap-2 rounded px-2 py-1 text-left hover:bg-muted",
|
|
7607
7879
|
children: [
|
|
7608
|
-
/* @__PURE__ */ (0,
|
|
7609
|
-
option.accepts?.length ? /* @__PURE__ */ (0,
|
|
7880
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)("span", { children: option.label }),
|
|
7881
|
+
option.accepts?.length ? /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("span", { className: "text-[10px] opacity-60", children: option.accepts.join(", ") }) : null
|
|
7610
7882
|
]
|
|
7611
7883
|
},
|
|
7612
7884
|
option.role
|
|
7613
7885
|
)),
|
|
7614
|
-
/* @__PURE__ */ (0,
|
|
7886
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
7615
7887
|
"button",
|
|
7616
7888
|
{
|
|
7617
7889
|
type: "button",
|
|
7618
7890
|
role: "option",
|
|
7619
|
-
"aria-selected": !
|
|
7891
|
+
"aria-selected": !chip3.role,
|
|
7620
7892
|
"data-role-option": "",
|
|
7621
|
-
onClick: () => pick(
|
|
7893
|
+
onClick: () => pick(chip3, null),
|
|
7622
7894
|
className: "rounded px-2 py-1 text-left opacity-70 hover:bg-muted",
|
|
7623
7895
|
children: "No role"
|
|
7624
7896
|
}
|
|
7625
7897
|
),
|
|
7626
|
-
|
|
7898
|
+
chip3.issues.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("ul", { className: "mt-1 border-t border-border px-2 pt-1 text-[10px]", "data-chip-issues": "", children: chip3.issues.map((issue, i) => /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("li", { className: issue.severity === "error" ? "text-red-500" : "text-amber-500", children: issue.message }, i)) })
|
|
7627
7899
|
]
|
|
7628
7900
|
}
|
|
7629
7901
|
)
|
|
7630
|
-
] }, `${
|
|
7902
|
+
] }, `${chip3.start}-${chip3.index}`);
|
|
7631
7903
|
}) });
|
|
7632
7904
|
};
|
|
7633
7905
|
|
|
7634
7906
|
// src/generation/GenerationHistory.tsx
|
|
7635
|
-
var
|
|
7907
|
+
var import_react55 = require("react");
|
|
7636
7908
|
var import_generation4 = require("@pixerate/editor/generation");
|
|
7637
|
-
var
|
|
7909
|
+
var import_jsx_runtime37 = require("react/jsx-runtime");
|
|
7638
7910
|
function useGenerationRecords(store, filter) {
|
|
7639
|
-
const [records, setRecords] = (0,
|
|
7640
|
-
const [loading, setLoading] = (0,
|
|
7641
|
-
const [error, setError] = (0,
|
|
7911
|
+
const [records, setRecords] = (0, import_react55.useState)([]);
|
|
7912
|
+
const [loading, setLoading] = (0, import_react55.useState)(!!store);
|
|
7913
|
+
const [error, setError] = (0, import_react55.useState)(null);
|
|
7642
7914
|
const filterKey = (0, import_generation4.stableStringify)(filter ?? {});
|
|
7643
|
-
const refresh = (0,
|
|
7915
|
+
const refresh = (0, import_react55.useCallback)(async () => {
|
|
7644
7916
|
if (!store) {
|
|
7645
7917
|
setRecords([]);
|
|
7646
7918
|
setLoading(false);
|
|
@@ -7657,7 +7929,7 @@ function useGenerationRecords(store, filter) {
|
|
|
7657
7929
|
setLoading(false);
|
|
7658
7930
|
}
|
|
7659
7931
|
}, [store, filterKey]);
|
|
7660
|
-
(0,
|
|
7932
|
+
(0, import_react55.useEffect)(() => {
|
|
7661
7933
|
void refresh();
|
|
7662
7934
|
if (!store) return;
|
|
7663
7935
|
return store.subscribe(() => void refresh());
|
|
@@ -7683,21 +7955,21 @@ var GenerationHistory = ({
|
|
|
7683
7955
|
emptyText = "No generations yet.",
|
|
7684
7956
|
className = ""
|
|
7685
7957
|
}) => {
|
|
7686
|
-
const [innerMode, setInnerMode] = (0,
|
|
7958
|
+
const [innerMode, setInnerMode] = (0, import_react55.useState)("exact");
|
|
7687
7959
|
const mode = modeProp ?? innerMode;
|
|
7688
7960
|
const setMode = (next) => {
|
|
7689
7961
|
if (modeProp === void 0) setInnerMode(next);
|
|
7690
7962
|
onModeChange?.(next);
|
|
7691
7963
|
};
|
|
7692
|
-
const options = (0,
|
|
7693
|
-
const results = (0,
|
|
7694
|
-
const models = (0,
|
|
7964
|
+
const options = (0, import_react55.useMemo)(() => ({ templates, capabilities, assets, mode }), [templates, capabilities, assets, mode]);
|
|
7965
|
+
const results = (0, import_react55.useMemo)(() => records.map((record) => (0, import_generation4.recreateRequest)(record, options)), [records, options]);
|
|
7966
|
+
const models = (0, import_react55.useMemo)(
|
|
7695
7967
|
() => capabilities ? Array.isArray(capabilities) ? capabilities : [capabilities] : [],
|
|
7696
7968
|
[capabilities]
|
|
7697
7969
|
);
|
|
7698
|
-
return /* @__PURE__ */ (0,
|
|
7699
|
-
/* @__PURE__ */ (0,
|
|
7700
|
-
/* @__PURE__ */ (0,
|
|
7970
|
+
return /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("div", { className: `flex flex-col gap-2 text-sm ${className}`, "data-generation-history": "", children: [
|
|
7971
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.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_runtime37.jsxs)("label", { className: "inline-flex items-center gap-1", children: [
|
|
7972
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
|
|
7701
7973
|
"input",
|
|
7702
7974
|
{
|
|
7703
7975
|
type: "radio",
|
|
@@ -7710,34 +7982,34 @@ var GenerationHistory = ({
|
|
|
7710
7982
|
),
|
|
7711
7983
|
value === "exact" ? "Exact (recorded versions)" : "Latest templates & settings"
|
|
7712
7984
|
] }, value)) }),
|
|
7713
|
-
records.length === 0 && /* @__PURE__ */ (0,
|
|
7714
|
-
/* @__PURE__ */ (0,
|
|
7985
|
+
records.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("p", { className: "text-xs text-muted-foreground", children: emptyText }),
|
|
7986
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsx)("ul", { className: "flex flex-col gap-2", children: records.map((record, i) => {
|
|
7715
7987
|
const result = results[i];
|
|
7716
7988
|
const model = models.find((m) => m.id === record.provenance.modelId);
|
|
7717
7989
|
const blocked = !result.ok;
|
|
7718
|
-
return /* @__PURE__ */ (0,
|
|
7990
|
+
return /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)(
|
|
7719
7991
|
"li",
|
|
7720
7992
|
{
|
|
7721
7993
|
className: "rounded-md border border-border p-2",
|
|
7722
7994
|
"data-record": record.id,
|
|
7723
7995
|
"data-drift": result.drift.length,
|
|
7724
7996
|
children: [
|
|
7725
|
-
/* @__PURE__ */ (0,
|
|
7726
|
-
/* @__PURE__ */ (0,
|
|
7727
|
-
/* @__PURE__ */ (0,
|
|
7728
|
-
record.kind !== "generate" && /* @__PURE__ */ (0,
|
|
7997
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("div", { className: "flex flex-wrap items-center justify-between gap-2 text-xs", children: [
|
|
7998
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsx)("span", { className: "font-medium", children: model?.name ?? record.provenance.modelId }),
|
|
7999
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("span", { className: "text-muted-foreground", children: [
|
|
8000
|
+
record.kind !== "generate" && /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("span", { "data-kind": "", children: [
|
|
7729
8001
|
record.kind,
|
|
7730
8002
|
" \xB7 "
|
|
7731
8003
|
] }),
|
|
7732
|
-
/* @__PURE__ */ (0,
|
|
7733
|
-
record.seed !== void 0 && /* @__PURE__ */ (0,
|
|
8004
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsx)("time", { dateTime: record.createdAt, children: record.createdAt.replace("T", " ").slice(0, 16) }),
|
|
8005
|
+
record.seed !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)(import_jsx_runtime37.Fragment, { children: [
|
|
7734
8006
|
" \xB7 seed ",
|
|
7735
8007
|
record.seed
|
|
7736
8008
|
] })
|
|
7737
8009
|
] })
|
|
7738
8010
|
] }),
|
|
7739
|
-
/* @__PURE__ */ (0,
|
|
7740
|
-
record.assets.length > 0 && /* @__PURE__ */ (0,
|
|
8011
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsx)("p", { className: "mt-1 line-clamp-3 break-words text-xs", "data-record-prompt": "", children: record.provenance.resolvedPrompt }),
|
|
8012
|
+
record.assets.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("div", { className: "mt-1 flex flex-wrap gap-1", children: record.assets.map((asset) => /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)(
|
|
7741
8013
|
"span",
|
|
7742
8014
|
{
|
|
7743
8015
|
className: "rounded-full bg-muted px-2 py-0.5 text-[10px]",
|
|
@@ -7751,16 +8023,16 @@ var GenerationHistory = ({
|
|
|
7751
8023
|
`${asset.role}:${asset.id}`
|
|
7752
8024
|
)) }),
|
|
7753
8025
|
renderPreview?.(record),
|
|
7754
|
-
result.drift.length > 0 && /* @__PURE__ */ (0,
|
|
7755
|
-
/* @__PURE__ */ (0,
|
|
8026
|
+
result.drift.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime37.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_runtime37.jsxs)("li", { className: severityClass[item.severity], "data-drift-type": item.type, children: [
|
|
8027
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("strong", { children: [
|
|
7756
8028
|
import_generation4.DRIFT_TYPE_LABELS[item.type],
|
|
7757
8029
|
":"
|
|
7758
8030
|
] }),
|
|
7759
8031
|
" ",
|
|
7760
8032
|
item.message
|
|
7761
8033
|
] }, j)) }),
|
|
7762
|
-
/* @__PURE__ */ (0,
|
|
7763
|
-
onRecreate && /* @__PURE__ */ (0,
|
|
8034
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("div", { className: "mt-2 flex gap-2", children: [
|
|
8035
|
+
onRecreate && /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
|
|
7764
8036
|
"button",
|
|
7765
8037
|
{
|
|
7766
8038
|
type: "button",
|
|
@@ -7772,7 +8044,7 @@ var GenerationHistory = ({
|
|
|
7772
8044
|
children: "Recreate"
|
|
7773
8045
|
}
|
|
7774
8046
|
),
|
|
7775
|
-
onVariation && /* @__PURE__ */ (0,
|
|
8047
|
+
onVariation && /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
|
|
7776
8048
|
"button",
|
|
7777
8049
|
{
|
|
7778
8050
|
type: "button",
|
|
@@ -7782,7 +8054,7 @@ var GenerationHistory = ({
|
|
|
7782
8054
|
children: "Variation"
|
|
7783
8055
|
}
|
|
7784
8056
|
),
|
|
7785
|
-
onRemove && /* @__PURE__ */ (0,
|
|
8057
|
+
onRemove && /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
|
|
7786
8058
|
"button",
|
|
7787
8059
|
{
|
|
7788
8060
|
type: "button",
|
|
@@ -7802,19 +8074,19 @@ var GenerationHistory = ({
|
|
|
7802
8074
|
};
|
|
7803
8075
|
|
|
7804
8076
|
// src/find-replace/useFindReplace.ts
|
|
7805
|
-
var
|
|
8077
|
+
var import_react56 = require("react");
|
|
7806
8078
|
var import_editor16 = require("@pixerate/editor");
|
|
7807
8079
|
var noopUnsubscribe2 = () => {
|
|
7808
8080
|
};
|
|
7809
8081
|
function useFindReplace(editor) {
|
|
7810
8082
|
const store = (0, import_editor16.getFindReplaceStore)(editor ?? null);
|
|
7811
|
-
const subscribe = (0,
|
|
8083
|
+
const subscribe = (0, import_react56.useCallback)(
|
|
7812
8084
|
(onChange) => store ? store.subscribe(() => onChange()) : noopUnsubscribe2,
|
|
7813
8085
|
[store]
|
|
7814
8086
|
);
|
|
7815
8087
|
const getSnapshot = () => store?.getSnapshot() ?? import_editor16.EMPTY_FIND_REPLACE_SNAPSHOT;
|
|
7816
|
-
const snapshot = (0,
|
|
7817
|
-
return (0,
|
|
8088
|
+
const snapshot = (0, import_react56.useSyncExternalStore)(subscribe, getSnapshot, getSnapshot);
|
|
8089
|
+
return (0, import_react56.useMemo)(() => {
|
|
7818
8090
|
const run = (fn) => {
|
|
7819
8091
|
if (editor && !editor.isDestroyed && store) fn(editor);
|
|
7820
8092
|
};
|
|
@@ -7838,9 +8110,9 @@ function useFindReplace(editor) {
|
|
|
7838
8110
|
}
|
|
7839
8111
|
|
|
7840
8112
|
// src/find-replace/FindReplaceBar.tsx
|
|
7841
|
-
var
|
|
8113
|
+
var import_react57 = require("react");
|
|
7842
8114
|
var import_editor17 = require("@pixerate/editor");
|
|
7843
|
-
var
|
|
8115
|
+
var import_jsx_runtime38 = require("react/jsx-runtime");
|
|
7844
8116
|
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";
|
|
7845
8117
|
var buttonClass5 = "rounded px-2 py-1 text-xs text-foreground hover:bg-muted disabled:opacity-40 disabled:hover:bg-transparent";
|
|
7846
8118
|
var toggleClass = (on) => `${buttonClass5} font-mono ${on ? "bg-primary/10 text-primary" : "text-muted-foreground"}`;
|
|
@@ -7853,10 +8125,10 @@ var FindReplaceBar = ({
|
|
|
7853
8125
|
onClose
|
|
7854
8126
|
}) => {
|
|
7855
8127
|
const find = useFindReplace(editor);
|
|
7856
|
-
const findInput = (0,
|
|
7857
|
-
const [moreOpen, setMoreOpen] = (0,
|
|
8128
|
+
const findInput = (0, import_react57.useRef)(null);
|
|
8129
|
+
const [moreOpen, setMoreOpen] = (0, import_react57.useState)(false);
|
|
7858
8130
|
const visible = find.available && (alwaysOpen || find.open);
|
|
7859
|
-
(0,
|
|
8131
|
+
(0, import_react57.useEffect)(() => {
|
|
7860
8132
|
if (!visible || find.focusRequest === 0) return;
|
|
7861
8133
|
findInput.current?.focus();
|
|
7862
8134
|
findInput.current?.select();
|
|
@@ -7894,9 +8166,9 @@ var FindReplaceBar = ({
|
|
|
7894
8166
|
if (isMod(e)) find.replaceAll();
|
|
7895
8167
|
else find.replace();
|
|
7896
8168
|
};
|
|
7897
|
-
return /* @__PURE__ */ (0,
|
|
7898
|
-
/* @__PURE__ */ (0,
|
|
7899
|
-
/* @__PURE__ */ (0,
|
|
8169
|
+
return /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)("div", { className, role: "search", "aria-label": "Find and replace", onKeyDown: onBarKeyDown, children: [
|
|
8170
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsxs)("div", { className: "flex items-center gap-1", children: [
|
|
8171
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
|
|
7900
8172
|
"button",
|
|
7901
8173
|
{
|
|
7902
8174
|
type: "button",
|
|
@@ -7907,7 +8179,7 @@ var FindReplaceBar = ({
|
|
|
7907
8179
|
children: showReplace ? "\u25BE" : "\u25B8"
|
|
7908
8180
|
}
|
|
7909
8181
|
),
|
|
7910
|
-
/* @__PURE__ */ (0,
|
|
8182
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
|
|
7911
8183
|
"input",
|
|
7912
8184
|
{
|
|
7913
8185
|
ref: findInput,
|
|
@@ -7921,7 +8193,7 @@ var FindReplaceBar = ({
|
|
|
7921
8193
|
onKeyDown: onFindKeyDown
|
|
7922
8194
|
}
|
|
7923
8195
|
),
|
|
7924
|
-
import_editor17.FIND_OPTION_TOGGLES.filter((t) => !t.advanced).map((t) => /* @__PURE__ */ (0,
|
|
8196
|
+
import_editor17.FIND_OPTION_TOGGLES.filter((t) => !t.advanced).map((t) => /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
|
|
7925
8197
|
"button",
|
|
7926
8198
|
{
|
|
7927
8199
|
type: "button",
|
|
@@ -7934,7 +8206,7 @@ var FindReplaceBar = ({
|
|
|
7934
8206
|
},
|
|
7935
8207
|
t.key
|
|
7936
8208
|
)),
|
|
7937
|
-
/* @__PURE__ */ (0,
|
|
8209
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
|
|
7938
8210
|
"span",
|
|
7939
8211
|
{
|
|
7940
8212
|
className: `min-w-[5rem] px-1 text-center text-xs ${find.error ? "text-destructive" : "text-muted-foreground"}`,
|
|
@@ -7944,9 +8216,9 @@ var FindReplaceBar = ({
|
|
|
7944
8216
|
children: status
|
|
7945
8217
|
}
|
|
7946
8218
|
),
|
|
7947
|
-
/* @__PURE__ */ (0,
|
|
7948
|
-
/* @__PURE__ */ (0,
|
|
7949
|
-
showMoreOptions && /* @__PURE__ */ (0,
|
|
8219
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)("button", { type: "button", className: buttonClass5, "aria-label": "Previous match", disabled: !hasMatches, onClick: find.previous, children: "\u2191" }),
|
|
8220
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)("button", { type: "button", className: buttonClass5, "aria-label": "Next match", disabled: !hasMatches, onClick: find.next, children: "\u2193" }),
|
|
8221
|
+
showMoreOptions && /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
|
|
7950
8222
|
"button",
|
|
7951
8223
|
{
|
|
7952
8224
|
type: "button",
|
|
@@ -7957,10 +8229,10 @@ var FindReplaceBar = ({
|
|
|
7957
8229
|
children: "\u2026"
|
|
7958
8230
|
}
|
|
7959
8231
|
),
|
|
7960
|
-
/* @__PURE__ */ (0,
|
|
8232
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)("button", { type: "button", className: buttonClass5, "aria-label": "Close find", onClick: close, children: "\xD7" })
|
|
7961
8233
|
] }),
|
|
7962
|
-
showReplace && /* @__PURE__ */ (0,
|
|
7963
|
-
/* @__PURE__ */ (0,
|
|
8234
|
+
showReplace && /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)("div", { className: "flex items-center gap-1 pl-7", children: [
|
|
8235
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
|
|
7964
8236
|
"input",
|
|
7965
8237
|
{
|
|
7966
8238
|
type: "text",
|
|
@@ -7972,7 +8244,7 @@ var FindReplaceBar = ({
|
|
|
7972
8244
|
onKeyDown: onReplaceKeyDown
|
|
7973
8245
|
}
|
|
7974
8246
|
),
|
|
7975
|
-
/* @__PURE__ */ (0,
|
|
8247
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
|
|
7976
8248
|
"button",
|
|
7977
8249
|
{
|
|
7978
8250
|
type: "button",
|
|
@@ -7982,11 +8254,11 @@ var FindReplaceBar = ({
|
|
|
7982
8254
|
children: "Replace"
|
|
7983
8255
|
}
|
|
7984
8256
|
),
|
|
7985
|
-
/* @__PURE__ */ (0,
|
|
7986
|
-
find.lastReplaceCount !== null && /* @__PURE__ */ (0,
|
|
8257
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)("button", { type: "button", className: buttonClass5, disabled: !hasMatches, onClick: find.replaceAll, children: "Replace all" }),
|
|
8258
|
+
find.lastReplaceCount !== null && /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("span", { className: "px-1 text-xs text-muted-foreground", "aria-live": "polite", children: find.lastReplaceCount === 1 ? "1 replaced" : `${find.lastReplaceCount} replaced` })
|
|
7987
8259
|
] }),
|
|
7988
|
-
showMoreOptions && moreOpen && /* @__PURE__ */ (0,
|
|
7989
|
-
/* @__PURE__ */ (0,
|
|
8260
|
+
showMoreOptions && moreOpen && /* @__PURE__ */ (0, import_jsx_runtime38.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_runtime38.jsxs)("label", { className: "flex items-center gap-1", children: [
|
|
8261
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
|
|
7990
8262
|
"input",
|
|
7991
8263
|
{
|
|
7992
8264
|
type: "checkbox",
|
|
@@ -8000,12 +8272,12 @@ var FindReplaceBar = ({
|
|
|
8000
8272
|
};
|
|
8001
8273
|
|
|
8002
8274
|
// src/tables/useTableMenu.ts
|
|
8003
|
-
var
|
|
8275
|
+
var import_react58 = require("react");
|
|
8004
8276
|
var import_editor18 = require("@pixerate/editor");
|
|
8005
8277
|
function useTableMenu(editor) {
|
|
8006
|
-
const store = (0,
|
|
8007
|
-
const snapshot = (0,
|
|
8008
|
-
return (0,
|
|
8278
|
+
const store = (0, import_react58.useMemo)(() => (0, import_editor18.createTableStore)(editor), [editor]);
|
|
8279
|
+
const snapshot = (0, import_react58.useSyncExternalStore)(store.subscribe, store.getSnapshot, store.getSnapshot);
|
|
8280
|
+
return (0, import_react58.useMemo)(
|
|
8009
8281
|
() => ({
|
|
8010
8282
|
...snapshot,
|
|
8011
8283
|
run: (action, params) => (0, import_editor18.runTableAction)(editor, action, params, { focus: true }),
|
|
@@ -8016,9 +8288,9 @@ function useTableMenu(editor) {
|
|
|
8016
8288
|
}
|
|
8017
8289
|
|
|
8018
8290
|
// src/tables/TableToolbar.tsx
|
|
8019
|
-
var
|
|
8291
|
+
var import_react59 = __toESM(require("react"), 1);
|
|
8020
8292
|
var import_editor19 = require("@pixerate/editor");
|
|
8021
|
-
var
|
|
8293
|
+
var import_jsx_runtime39 = require("react/jsx-runtime");
|
|
8022
8294
|
var keepSelection2 = (event) => event.preventDefault();
|
|
8023
8295
|
var TableToolbar = ({
|
|
8024
8296
|
editor,
|
|
@@ -8032,14 +8304,14 @@ var TableToolbar = ({
|
|
|
8032
8304
|
}) => {
|
|
8033
8305
|
const table = useTableMenu(editor);
|
|
8034
8306
|
if (!editor || !table.inTable && !showWhenOutside) return null;
|
|
8035
|
-
return /* @__PURE__ */ (0,
|
|
8307
|
+
return /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("div", { className, role: "toolbar", "aria-label": "Table", "data-table-toolbar": "", children: items.map((item, index) => {
|
|
8036
8308
|
const status = table.check(item.action, item.params);
|
|
8037
8309
|
const enabled = status === true;
|
|
8038
8310
|
const active = item.active?.(table);
|
|
8039
8311
|
const separator = index > 0 && items[index - 1].group !== item.group;
|
|
8040
|
-
return /* @__PURE__ */ (0,
|
|
8041
|
-
separator && /* @__PURE__ */ (0,
|
|
8042
|
-
/* @__PURE__ */ (0,
|
|
8312
|
+
return /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)(import_react59.default.Fragment, { children: [
|
|
8313
|
+
separator && /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("span", { className: separatorClassName, "aria-hidden": "true" }),
|
|
8314
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
|
|
8043
8315
|
"button",
|
|
8044
8316
|
{
|
|
8045
8317
|
type: "button",
|
|
@@ -8061,8 +8333,8 @@ var TableToolbar = ({
|
|
|
8061
8333
|
};
|
|
8062
8334
|
|
|
8063
8335
|
// src/tables/InsertTableGrid.tsx
|
|
8064
|
-
var
|
|
8065
|
-
var
|
|
8336
|
+
var import_react60 = require("react");
|
|
8337
|
+
var import_jsx_runtime40 = require("react/jsx-runtime");
|
|
8066
8338
|
var keepSelection3 = (event) => event.preventDefault();
|
|
8067
8339
|
var InsertTableGrid = ({
|
|
8068
8340
|
editor,
|
|
@@ -8075,14 +8347,14 @@ var InsertTableGrid = ({
|
|
|
8075
8347
|
onInsert
|
|
8076
8348
|
}) => {
|
|
8077
8349
|
const table = useTableMenu(editor);
|
|
8078
|
-
const [hover, setHover] = (0,
|
|
8350
|
+
const [hover, setHover] = (0, import_react60.useState)(null);
|
|
8079
8351
|
const status = table.actions.insertTable;
|
|
8080
8352
|
const disabled = !editor || !status.enabled;
|
|
8081
8353
|
const insert = (size) => {
|
|
8082
8354
|
if (table.run("insertTable", { ...size, withHeaderRow })) onInsert?.(size);
|
|
8083
8355
|
setHover(null);
|
|
8084
8356
|
};
|
|
8085
|
-
return /* @__PURE__ */ (0,
|
|
8357
|
+
return /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(
|
|
8086
8358
|
"div",
|
|
8087
8359
|
{
|
|
8088
8360
|
className,
|
|
@@ -8092,7 +8364,7 @@ var InsertTableGrid = ({
|
|
|
8092
8364
|
"data-insert-table-grid": "",
|
|
8093
8365
|
onMouseLeave: () => setHover(null),
|
|
8094
8366
|
children: [
|
|
8095
|
-
/* @__PURE__ */ (0,
|
|
8367
|
+
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
|
|
8096
8368
|
"div",
|
|
8097
8369
|
{
|
|
8098
8370
|
role: "grid",
|
|
@@ -8101,7 +8373,7 @@ var InsertTableGrid = ({
|
|
|
8101
8373
|
children: Array.from({ length: rows * cols }, (_, i) => {
|
|
8102
8374
|
const size = { rows: Math.floor(i / cols) + 1, cols: i % cols + 1 };
|
|
8103
8375
|
const active = !!hover && size.rows <= hover.rows && size.cols <= hover.cols;
|
|
8104
|
-
return /* @__PURE__ */ (0,
|
|
8376
|
+
return /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
|
|
8105
8377
|
"button",
|
|
8106
8378
|
{
|
|
8107
8379
|
type: "button",
|
|
@@ -8121,7 +8393,7 @@ var InsertTableGrid = ({
|
|
|
8121
8393
|
})
|
|
8122
8394
|
}
|
|
8123
8395
|
),
|
|
8124
|
-
/* @__PURE__ */ (0,
|
|
8396
|
+
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)("div", { "aria-live": "polite", "data-testid": "insert-table-size", children: disabled ? status.reason : hover ? `${hover.rows} \xD7 ${hover.cols}` : "Insert table" })
|
|
8125
8397
|
]
|
|
8126
8398
|
}
|
|
8127
8399
|
);
|
|
@@ -8129,31 +8401,31 @@ var InsertTableGrid = ({
|
|
|
8129
8401
|
|
|
8130
8402
|
// src/tables/TableBubbleMenu.tsx
|
|
8131
8403
|
var import_editor20 = require("@pixerate/editor");
|
|
8132
|
-
var
|
|
8404
|
+
var import_jsx_runtime41 = require("react/jsx-runtime");
|
|
8133
8405
|
var TableBubbleMenu = ({
|
|
8134
8406
|
editor,
|
|
8135
8407
|
children,
|
|
8136
8408
|
toolbarProps,
|
|
8137
8409
|
pluginKey = "tableBubbleMenu",
|
|
8138
8410
|
...rest
|
|
8139
|
-
}) => /* @__PURE__ */ (0,
|
|
8411
|
+
}) => /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(BubbleMenu, { editor, pluginKey, shouldShow: import_editor20.shouldShowTableBubbleMenu, ...rest, children: children ?? /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(TableToolbar, { editor, ...toolbarProps }) });
|
|
8140
8412
|
|
|
8141
8413
|
// src/chart-node/ChartNodeView.tsx
|
|
8142
8414
|
var import_client = require("react-dom/client");
|
|
8143
8415
|
|
|
8144
8416
|
// src/chart/ChartCanvas.tsx
|
|
8145
|
-
var
|
|
8417
|
+
var import_react62 = require("react");
|
|
8146
8418
|
var import_chart2 = require("@pixerate/editor/chart");
|
|
8147
8419
|
|
|
8148
8420
|
// src/chart/useChartEditor.ts
|
|
8149
|
-
var
|
|
8421
|
+
var import_react61 = require("react");
|
|
8150
8422
|
var import_chart = require("@pixerate/editor/chart");
|
|
8151
8423
|
function useChartState(controller) {
|
|
8152
|
-
return (0,
|
|
8424
|
+
return (0, import_react61.useSyncExternalStore)(controller.subscribe, controller.getState, controller.getState);
|
|
8153
8425
|
}
|
|
8154
8426
|
|
|
8155
8427
|
// src/chart/ChartCanvas.tsx
|
|
8156
|
-
var
|
|
8428
|
+
var import_jsx_runtime42 = require("react/jsx-runtime");
|
|
8157
8429
|
function renderChartMark(mark, fontFamily, interactive) {
|
|
8158
8430
|
const common = {
|
|
8159
8431
|
"data-role": mark.role,
|
|
@@ -8165,9 +8437,9 @@ function renderChartMark(mark, fontFamily, interactive) {
|
|
|
8165
8437
|
};
|
|
8166
8438
|
switch (mark.kind) {
|
|
8167
8439
|
case "rect":
|
|
8168
|
-
return /* @__PURE__ */ (0,
|
|
8440
|
+
return /* @__PURE__ */ (0, import_jsx_runtime42.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);
|
|
8169
8441
|
case "path":
|
|
8170
|
-
return /* @__PURE__ */ (0,
|
|
8442
|
+
return /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
|
|
8171
8443
|
"path",
|
|
8172
8444
|
{
|
|
8173
8445
|
...common,
|
|
@@ -8180,11 +8452,11 @@ function renderChartMark(mark, fontFamily, interactive) {
|
|
|
8180
8452
|
mark.key
|
|
8181
8453
|
);
|
|
8182
8454
|
case "circle":
|
|
8183
|
-
return /* @__PURE__ */ (0,
|
|
8455
|
+
return /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("circle", { ...common, cx: mark.cx, cy: mark.cy, r: mark.r, style: { fill: mark.fill, stroke: mark.stroke, strokeWidth: mark.strokeWidth } }, mark.key);
|
|
8184
8456
|
case "line":
|
|
8185
|
-
return /* @__PURE__ */ (0,
|
|
8457
|
+
return /* @__PURE__ */ (0, import_jsx_runtime42.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);
|
|
8186
8458
|
case "text":
|
|
8187
|
-
return /* @__PURE__ */ (0,
|
|
8459
|
+
return /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
|
|
8188
8460
|
"text",
|
|
8189
8461
|
{
|
|
8190
8462
|
...common,
|
|
@@ -8201,23 +8473,23 @@ function renderChartMark(mark, fontFamily, interactive) {
|
|
|
8201
8473
|
}
|
|
8202
8474
|
}
|
|
8203
8475
|
function ChartPresenceLayer({ presence }) {
|
|
8204
|
-
const { actors } = (0,
|
|
8205
|
-
return /* @__PURE__ */ (0,
|
|
8206
|
-
/* @__PURE__ */ (0,
|
|
8207
|
-
/* @__PURE__ */ (0,
|
|
8208
|
-
/* @__PURE__ */ (0,
|
|
8209
|
-
/* @__PURE__ */ (0,
|
|
8476
|
+
const { actors } = (0, import_react62.useSyncExternalStore)(presence.subscribe, presence.getState, presence.getState);
|
|
8477
|
+
return /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("g", { "data-chart-presence": "", pointerEvents: "none", children: actors.map((a) => /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("g", { transform: `translate(${a.x} ${a.y})`, "data-actor": a.id, children: [
|
|
8478
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.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 }),
|
|
8479
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("g", { transform: "translate(13 16)", children: [
|
|
8480
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.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 } }),
|
|
8481
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)("text", { x: 6, y: 9, dominantBaseline: "central", style: { fill: "#ffffff", fontSize: 11, fontWeight: 600, fontFamily: "inherit" }, children: a.message ?? a.name })
|
|
8210
8482
|
] })
|
|
8211
8483
|
] }, a.id)) });
|
|
8212
8484
|
}
|
|
8213
8485
|
function ChartCanvas({ controller, width = 640, height = 400, responsive = true, theme, editable = true, measureText, emptyMessage, className, presence, sceneRef }) {
|
|
8214
8486
|
const state = useChartState(controller);
|
|
8215
|
-
const wrapper = (0,
|
|
8216
|
-
const svg = (0,
|
|
8217
|
-
const drag = (0,
|
|
8218
|
-
const [measured, setMeasured] = (0,
|
|
8219
|
-
const [frozen, setFrozen] = (0,
|
|
8220
|
-
(0,
|
|
8487
|
+
const wrapper = (0, import_react62.useRef)(null);
|
|
8488
|
+
const svg = (0, import_react62.useRef)(null);
|
|
8489
|
+
const drag = (0, import_react62.useRef)(null);
|
|
8490
|
+
const [measured, setMeasured] = (0, import_react62.useState)(null);
|
|
8491
|
+
const [frozen, setFrozen] = (0, import_react62.useState)(null);
|
|
8492
|
+
(0, import_react62.useEffect)(() => {
|
|
8221
8493
|
const el = wrapper.current;
|
|
8222
8494
|
if (!responsive || !el || typeof ResizeObserver === "undefined") return;
|
|
8223
8495
|
const observer = new ResizeObserver(([entry]) => {
|
|
@@ -8228,8 +8500,8 @@ function ChartCanvas({ controller, width = 640, height = 400, responsive = true,
|
|
|
8228
8500
|
return () => observer.disconnect();
|
|
8229
8501
|
}, [responsive]);
|
|
8230
8502
|
const sceneWidth = responsive && measured || width;
|
|
8231
|
-
const fullTheme = (0,
|
|
8232
|
-
const scene = (0,
|
|
8503
|
+
const fullTheme = (0, import_react62.useMemo)(() => ({ ...import_chart2.CSS_VARIABLE_CHART_THEME, ...theme }), [theme]);
|
|
8504
|
+
const scene = (0, import_react62.useMemo)(
|
|
8233
8505
|
() => (0, import_chart2.layoutChart)(state.spec, {
|
|
8234
8506
|
width: sceneWidth,
|
|
8235
8507
|
height,
|
|
@@ -8245,8 +8517,8 @@ function ChartCanvas({ controller, width = 640, height = 400, responsive = true,
|
|
|
8245
8517
|
[state.spec, state.selection, sceneWidth, height, fullTheme, editable, measureText, emptyMessage, frozen]
|
|
8246
8518
|
);
|
|
8247
8519
|
if (sceneRef) sceneRef.current = scene;
|
|
8248
|
-
const byKey = (0,
|
|
8249
|
-
(0,
|
|
8520
|
+
const byKey = (0, import_react62.useMemo)(() => new Map(scene.marks.map((m) => [m.key, m])), [scene]);
|
|
8521
|
+
(0, import_react62.useEffect)(() => () => drag.current?.end(), []);
|
|
8250
8522
|
const scenePoint = (e) => (0, import_chart2.chartClientToScene)(scene, svg.current.getBoundingClientRect(), e.clientX, e.clientY);
|
|
8251
8523
|
const onPointerDown = (e) => {
|
|
8252
8524
|
if (!editable || e.button !== 0) return;
|
|
@@ -8279,7 +8551,7 @@ function ChartCanvas({ controller, width = 640, height = 400, responsive = true,
|
|
|
8279
8551
|
if (editable && (0, import_chart2.handleChartKey)(controller, scene, e)) e.preventDefault();
|
|
8280
8552
|
};
|
|
8281
8553
|
const label = state.spec.title || "Chart";
|
|
8282
|
-
return /* @__PURE__ */ (0,
|
|
8554
|
+
return /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("div", { ref: wrapper, className: `w-full ${className ?? ""}`, "data-chart-canvas": "", children: /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)(
|
|
8283
8555
|
"svg",
|
|
8284
8556
|
{
|
|
8285
8557
|
ref: svg,
|
|
@@ -8297,14 +8569,14 @@ function ChartCanvas({ controller, width = 640, height = 400, responsive = true,
|
|
|
8297
8569
|
onKeyDown,
|
|
8298
8570
|
children: [
|
|
8299
8571
|
scene.marks.map((m) => renderChartMark(m, scene.theme.fontFamily, editable)),
|
|
8300
|
-
presence && /* @__PURE__ */ (0,
|
|
8572
|
+
presence && /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(ChartPresenceLayer, { presence })
|
|
8301
8573
|
]
|
|
8302
8574
|
}
|
|
8303
8575
|
) });
|
|
8304
8576
|
}
|
|
8305
8577
|
|
|
8306
8578
|
// src/chart/ChartDataGrid.tsx
|
|
8307
|
-
var
|
|
8579
|
+
var import_react63 = require("react");
|
|
8308
8580
|
var import_chart3 = require("@pixerate/editor/chart");
|
|
8309
8581
|
|
|
8310
8582
|
// src/chart/styles.ts
|
|
@@ -8317,11 +8589,11 @@ var chartSectionClass = "space-y-2 border-b border-border pb-3 last:border-b-0";
|
|
|
8317
8589
|
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";
|
|
8318
8590
|
|
|
8319
8591
|
// src/chart/ChartDataGrid.tsx
|
|
8320
|
-
var
|
|
8592
|
+
var import_jsx_runtime43 = require("react/jsx-runtime");
|
|
8321
8593
|
function ChartCommitInput({ value, onCommit, onKeyDown, onBlur, ...rest }) {
|
|
8322
|
-
const [draft, setDraft] = (0,
|
|
8323
|
-
const typing = (0,
|
|
8324
|
-
(0,
|
|
8594
|
+
const [draft, setDraft] = (0, import_react63.useState)(value);
|
|
8595
|
+
const typing = (0, import_react63.useRef)(false);
|
|
8596
|
+
(0, import_react63.useEffect)(() => {
|
|
8325
8597
|
if (!typing.current) setDraft(value);
|
|
8326
8598
|
}, [value]);
|
|
8327
8599
|
const commit = () => {
|
|
@@ -8330,7 +8602,7 @@ function ChartCommitInput({ value, onCommit, onKeyDown, onBlur, ...rest }) {
|
|
|
8330
8602
|
if (draft === value) return;
|
|
8331
8603
|
if (onCommit(draft) === false) setDraft(value);
|
|
8332
8604
|
};
|
|
8333
|
-
return /* @__PURE__ */ (0,
|
|
8605
|
+
return /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
|
|
8334
8606
|
"input",
|
|
8335
8607
|
{
|
|
8336
8608
|
...rest,
|
|
@@ -8365,15 +8637,15 @@ function ChartDataGrid({ controller, categoryHeader = "Category", readOnly = fal
|
|
|
8365
8637
|
e.preventDefault();
|
|
8366
8638
|
controller.pasteCells(row, column, text);
|
|
8367
8639
|
};
|
|
8368
|
-
return /* @__PURE__ */ (0,
|
|
8369
|
-
/* @__PURE__ */ (0,
|
|
8370
|
-
/* @__PURE__ */ (0,
|
|
8371
|
-
/* @__PURE__ */ (0,
|
|
8640
|
+
return /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("div", { className: `overflow-auto rounded-md border border-border ${className ?? ""}`, "data-chart-grid": "", children: [
|
|
8641
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("table", { className: "w-full border-collapse text-xs", children: [
|
|
8642
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)("thead", { className: "bg-muted/50", children: /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("tr", { children: [
|
|
8643
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)("th", { className: "border-b border-r border-border px-2 py-1 text-left font-medium text-muted-foreground", children: categoryHeader }),
|
|
8372
8644
|
spec.series.map((s, si) => {
|
|
8373
8645
|
const color = (0, import_chart3.chartSeriesColor)(spec, si);
|
|
8374
8646
|
const selected = selection?.kind === "series" && selection.seriesId === s.id;
|
|
8375
|
-
return /* @__PURE__ */ (0,
|
|
8376
|
-
/* @__PURE__ */ (0,
|
|
8647
|
+
return /* @__PURE__ */ (0, import_jsx_runtime43.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_runtime43.jsxs)("div", { className: "flex items-center gap-1", children: [
|
|
8648
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
|
|
8377
8649
|
"input",
|
|
8378
8650
|
{
|
|
8379
8651
|
type: "color",
|
|
@@ -8386,7 +8658,7 @@ function ChartDataGrid({ controller, categoryHeader = "Category", readOnly = fal
|
|
|
8386
8658
|
className: "h-5 w-5 shrink-0 cursor-pointer rounded border-0 bg-transparent p-0"
|
|
8387
8659
|
}
|
|
8388
8660
|
),
|
|
8389
|
-
/* @__PURE__ */ (0,
|
|
8661
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
|
|
8390
8662
|
ChartCommitInput,
|
|
8391
8663
|
{
|
|
8392
8664
|
value: s.name,
|
|
@@ -8396,8 +8668,8 @@ function ChartDataGrid({ controller, categoryHeader = "Category", readOnly = fal
|
|
|
8396
8668
|
className: `${chartInputClass} h-6 min-w-[5rem] border-transparent bg-transparent font-medium ${s.hidden ? "text-muted-foreground line-through" : ""}`
|
|
8397
8669
|
}
|
|
8398
8670
|
),
|
|
8399
|
-
!readOnly && /* @__PURE__ */ (0,
|
|
8400
|
-
/* @__PURE__ */ (0,
|
|
8671
|
+
!readOnly && /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)(import_jsx_runtime43.Fragment, { children: [
|
|
8672
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
|
|
8401
8673
|
"button",
|
|
8402
8674
|
{
|
|
8403
8675
|
type: "button",
|
|
@@ -8410,16 +8682,16 @@ function ChartDataGrid({ controller, categoryHeader = "Category", readOnly = fal
|
|
|
8410
8682
|
children: s.hidden ? "\u25CB" : "\u25CF"
|
|
8411
8683
|
}
|
|
8412
8684
|
),
|
|
8413
|
-
/* @__PURE__ */ (0,
|
|
8685
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.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" })
|
|
8414
8686
|
] })
|
|
8415
8687
|
] }) }, s.id);
|
|
8416
8688
|
}),
|
|
8417
|
-
!readOnly && /* @__PURE__ */ (0,
|
|
8689
|
+
!readOnly && /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("th", { className: "w-8 border-b border-border px-1", children: /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("button", { type: "button", className: chartIconButtonClass, title: "Add series", "aria-label": "Add series", "data-action": "add-series", onClick: () => controller.addSeries(), children: "+" }) })
|
|
8418
8690
|
] }) }),
|
|
8419
|
-
/* @__PURE__ */ (0,
|
|
8691
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)("tbody", { children: spec.categories.map((category, i) => {
|
|
8420
8692
|
const rowSelected = selection?.kind === "category" && selection.index === i;
|
|
8421
|
-
return /* @__PURE__ */ (0,
|
|
8422
|
-
/* @__PURE__ */ (0,
|
|
8693
|
+
return /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("tr", { "data-category-index": i, className: rowSelected ? "bg-primary/10" : void 0, children: [
|
|
8694
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)("th", { className: "border-b border-r border-border p-0 text-left font-normal", children: /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
|
|
8423
8695
|
ChartCommitInput,
|
|
8424
8696
|
{
|
|
8425
8697
|
value: category,
|
|
@@ -8433,7 +8705,7 @@ function ChartDataGrid({ controller, categoryHeader = "Category", readOnly = fal
|
|
|
8433
8705
|
spec.series.map((s) => {
|
|
8434
8706
|
const value = s.values[i];
|
|
8435
8707
|
const selected = selection?.kind === "point" && selection.seriesId === s.id && selection.index === i;
|
|
8436
|
-
return /* @__PURE__ */ (0,
|
|
8708
|
+
return /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("td", { className: `border-b border-r border-border p-0 ${selected ? "bg-primary/10" : ""}`, children: /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
|
|
8437
8709
|
ChartCommitInput,
|
|
8438
8710
|
{
|
|
8439
8711
|
value: value === null || value === void 0 ? "" : String(value),
|
|
@@ -8448,38 +8720,38 @@ function ChartDataGrid({ controller, categoryHeader = "Category", readOnly = fal
|
|
|
8448
8720
|
}
|
|
8449
8721
|
) }, s.id);
|
|
8450
8722
|
}),
|
|
8451
|
-
!readOnly && /* @__PURE__ */ (0,
|
|
8723
|
+
!readOnly && /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("td", { className: "border-b border-border px-1", children: /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("button", { type: "button", className: chartIconButtonClass, title: "Delete category", "aria-label": `Delete ${category}`, "data-action": "remove-category", onClick: () => controller.removeCategory(i), children: "\xD7" }) })
|
|
8452
8724
|
] }, i);
|
|
8453
8725
|
}) })
|
|
8454
8726
|
] }),
|
|
8455
|
-
!readOnly && /* @__PURE__ */ (0,
|
|
8727
|
+
!readOnly && /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("div", { className: "p-1", children: /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("button", { type: "button", className: `${chartButtonClass} h-6 border-dashed`, "data-action": "add-category", onClick: () => controller.addCategory(), children: "+ Add category" }) })
|
|
8456
8728
|
] });
|
|
8457
8729
|
}
|
|
8458
8730
|
|
|
8459
8731
|
// src/chart/ChartInspector.tsx
|
|
8460
|
-
var
|
|
8732
|
+
var import_react64 = require("react");
|
|
8461
8733
|
var import_chart4 = require("@pixerate/editor/chart");
|
|
8462
|
-
var
|
|
8734
|
+
var import_jsx_runtime44 = require("react/jsx-runtime");
|
|
8463
8735
|
var cap = (s) => s.charAt(0).toUpperCase() + s.slice(1);
|
|
8464
8736
|
function Field({ label, htmlFor, children }) {
|
|
8465
|
-
return /* @__PURE__ */ (0,
|
|
8466
|
-
/* @__PURE__ */ (0,
|
|
8467
|
-
/* @__PURE__ */ (0,
|
|
8737
|
+
return /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
8738
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsx)("label", { htmlFor, className: `${chartLabelClass} w-20 shrink-0`, children: label }),
|
|
8739
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsx)("div", { className: "min-w-0 flex-1", children })
|
|
8468
8740
|
] });
|
|
8469
8741
|
}
|
|
8470
8742
|
function Toggle({ label, checked, onChange, name }) {
|
|
8471
|
-
return /* @__PURE__ */ (0,
|
|
8472
|
-
/* @__PURE__ */ (0,
|
|
8743
|
+
return /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("label", { className: "flex cursor-pointer items-center gap-2 text-xs text-foreground", children: [
|
|
8744
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsx)("input", { type: "checkbox", className: "h-3.5 w-3.5 accent-primary", checked, "data-option": name, onChange: (e) => onChange(e.currentTarget.checked) }),
|
|
8473
8745
|
label
|
|
8474
8746
|
] });
|
|
8475
8747
|
}
|
|
8476
8748
|
function Select({ id, value, options, onChange, name, labels }) {
|
|
8477
|
-
return /* @__PURE__ */ (0,
|
|
8749
|
+
return /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("select", { id, className: chartInputClass, value, "data-option": name, onChange: (e) => onChange(e.currentTarget.value), children: options.map((o) => /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("option", { value: o, children: labels?.[o] ?? cap(o) }, o)) });
|
|
8478
8750
|
}
|
|
8479
8751
|
function AxisSection({ controller, axis, value, idBase, horizontal, numeric = false, scales = false }) {
|
|
8480
8752
|
const set = (patch) => controller.setAxis(axis, patch);
|
|
8481
8753
|
const setFormat = (patch) => set({ format: { ...value.format, ...patch } });
|
|
8482
|
-
const bound = (key2) => /* @__PURE__ */ (0,
|
|
8754
|
+
const bound = (key2) => /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
|
|
8483
8755
|
ChartCommitInput,
|
|
8484
8756
|
{
|
|
8485
8757
|
id: `${idBase}-${axis}-${key2}`,
|
|
@@ -8494,26 +8766,26 @@ function AxisSection({ controller, axis, value, idBase, horizontal, numeric = fa
|
|
|
8494
8766
|
const name = axis === "x" ? numeric ? "X axis" : "Category axis" : axis === "y" ? "Value axis" : "Secondary axis";
|
|
8495
8767
|
const valueAxis = axis !== "x" || numeric;
|
|
8496
8768
|
const key = axis === "y2" ? "yAxis2" : `${axis}Axis`;
|
|
8497
|
-
return /* @__PURE__ */ (0,
|
|
8498
|
-
/* @__PURE__ */ (0,
|
|
8499
|
-
/* @__PURE__ */ (0,
|
|
8769
|
+
return /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("div", { className: chartSectionClass, "data-section": `axis-${axis}`, children: [
|
|
8770
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("div", { className: "flex items-center justify-between", children: [
|
|
8771
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("h4", { className: "text-xs font-semibold text-foreground", children: [
|
|
8500
8772
|
name,
|
|
8501
|
-
/* @__PURE__ */ (0,
|
|
8773
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("span", { className: "ml-1 font-normal text-muted-foreground", children: [
|
|
8502
8774
|
"(",
|
|
8503
8775
|
axis === "x" ? horizontal ? "left" : "bottom" : axis === "y2" ? horizontal ? "top" : "right" : horizontal ? "bottom" : "left",
|
|
8504
8776
|
")"
|
|
8505
8777
|
] })
|
|
8506
8778
|
] }),
|
|
8507
|
-
/* @__PURE__ */ (0,
|
|
8779
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsx)(Toggle, { label: "Show", name: `${axis}Axis.show`, checked: value.show, onChange: (show) => set({ show }) })
|
|
8508
8780
|
] }),
|
|
8509
|
-
/* @__PURE__ */ (0,
|
|
8510
|
-
/* @__PURE__ */ (0,
|
|
8511
|
-
/* @__PURE__ */ (0,
|
|
8512
|
-
axis === "x" && !numeric && /* @__PURE__ */ (0,
|
|
8513
|
-
scales && /* @__PURE__ */ (0,
|
|
8514
|
-
scales && valueAxis && /* @__PURE__ */ (0,
|
|
8781
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsx)(Field, { label: "Title", htmlFor: `${idBase}-${axis}-title`, children: /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(ChartCommitInput, { id: `${idBase}-${axis}-title`, value: value.title, "data-option": `${axis}Axis.title`, className: chartInputClass, onCommit: (title) => void set({ title }) }) }),
|
|
8782
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("div", { className: "flex flex-wrap gap-x-4 gap-y-1", children: [
|
|
8783
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsx)(Toggle, { label: "Grid lines", name: `${key}.gridlines`, checked: value.gridlines, onChange: (gridlines) => set({ gridlines }) }),
|
|
8784
|
+
axis === "x" && !numeric && /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(Toggle, { label: "Dates", name: "xAxis.kind", checked: value.kind === "date", onChange: (dates) => set({ kind: dates ? "date" : void 0 }) }),
|
|
8785
|
+
scales && /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(Toggle, { label: "Reverse", name: `${key}.reverse`, checked: !!value.reverse, onChange: (reverse) => set({ reverse }) }),
|
|
8786
|
+
scales && valueAxis && /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(Toggle, { label: "Log scale", name: `${key}.scale`, checked: value.scale === "log", onChange: (log) => set({ scale: log ? "log" : "linear" }) })
|
|
8515
8787
|
] }),
|
|
8516
|
-
scales && valueAxis && value.scale === "log" && /* @__PURE__ */ (0,
|
|
8788
|
+
scales && valueAxis && value.scale === "log" && /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(Field, { label: "Log base", htmlFor: `${idBase}-${axis}-log-base`, children: /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
|
|
8517
8789
|
ChartCommitInput,
|
|
8518
8790
|
{
|
|
8519
8791
|
id: `${idBase}-${axis}-log-base`,
|
|
@@ -8524,7 +8796,7 @@ function AxisSection({ controller, axis, value, idBase, horizontal, numeric = fa
|
|
|
8524
8796
|
onCommit: (text) => set({ logBase: text.trim() === "" ? void 0 : Number(text) }).ok
|
|
8525
8797
|
}
|
|
8526
8798
|
) }),
|
|
8527
|
-
valueAxis && value.scale !== "log" && /* @__PURE__ */ (0,
|
|
8799
|
+
valueAxis && value.scale !== "log" && /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(Field, { label: "Step", htmlFor: `${idBase}-${axis}-step`, children: /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
|
|
8528
8800
|
ChartCommitInput,
|
|
8529
8801
|
{
|
|
8530
8802
|
id: `${idBase}-${axis}-step`,
|
|
@@ -8536,14 +8808,14 @@ function AxisSection({ controller, axis, value, idBase, horizontal, numeric = fa
|
|
|
8536
8808
|
onCommit: (text) => set({ step: text.trim() === "" ? null : Number(text) }).ok
|
|
8537
8809
|
}
|
|
8538
8810
|
) }),
|
|
8539
|
-
valueAxis && /* @__PURE__ */ (0,
|
|
8540
|
-
/* @__PURE__ */ (0,
|
|
8811
|
+
valueAxis && /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)(import_jsx_runtime44.Fragment, { children: [
|
|
8812
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsx)(Field, { label: "Min / max", children: /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("div", { className: "flex gap-1", children: [
|
|
8541
8813
|
bound("min"),
|
|
8542
8814
|
bound("max")
|
|
8543
8815
|
] }) }),
|
|
8544
|
-
/* @__PURE__ */ (0,
|
|
8545
|
-
/* @__PURE__ */ (0,
|
|
8546
|
-
/* @__PURE__ */ (0,
|
|
8816
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsx)(Field, { label: "Format", htmlFor: `${idBase}-${axis}-format`, children: /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("div", { className: "flex gap-1", children: [
|
|
8817
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.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 }) }),
|
|
8818
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
|
|
8547
8819
|
ChartCommitInput,
|
|
8548
8820
|
{
|
|
8549
8821
|
value: value.format.decimals === void 0 ? "" : String(value.format.decimals),
|
|
@@ -8562,8 +8834,8 @@ function AxisSection({ controller, axis, value, idBase, horizontal, numeric = fa
|
|
|
8562
8834
|
}
|
|
8563
8835
|
)
|
|
8564
8836
|
] }) }),
|
|
8565
|
-
value.format.style === "currency" && /* @__PURE__ */ (0,
|
|
8566
|
-
/* @__PURE__ */ (0,
|
|
8837
|
+
value.format.style === "currency" && /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(Field, { label: "Currency", htmlFor: `${idBase}-${axis}-currency`, children: /* @__PURE__ */ (0, import_jsx_runtime44.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() }) }) }),
|
|
8838
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsx)(Field, { label: "Code", htmlFor: `${idBase}-${axis}-code`, children: /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
|
|
8567
8839
|
ChartCommitInput,
|
|
8568
8840
|
{
|
|
8569
8841
|
id: `${idBase}-${axis}-code`,
|
|
@@ -8589,15 +8861,15 @@ function ErrorBarFields({ controller, series, which, idBase }) {
|
|
|
8589
8861
|
const values = which === "xErrorBars" ? series.x ?? [] : series.values;
|
|
8590
8862
|
const set = (next) => controller.updateSeries(series.id, { [which]: next });
|
|
8591
8863
|
const patch = (p) => bars && set({ ...bars, ...p });
|
|
8592
|
-
return /* @__PURE__ */ (0,
|
|
8593
|
-
/* @__PURE__ */ (0,
|
|
8594
|
-
/* @__PURE__ */ (0,
|
|
8595
|
-
import_chart4.CHART_ERROR_BAR_TYPES.map((t) => /* @__PURE__ */ (0,
|
|
8864
|
+
return /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("div", { className: "space-y-1.5", "data-section": which === "errorBars" ? "error-bars" : "x-error-bars", children: [
|
|
8865
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsx)(Field, { label: which === "errorBars" ? "Error bars" : "X error bars", htmlFor: `${id}-type`, children: /* @__PURE__ */ (0, import_jsx_runtime44.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: [
|
|
8866
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsx)("option", { value: "", children: "None" }),
|
|
8867
|
+
import_chart4.CHART_ERROR_BAR_TYPES.map((t) => /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("option", { value: t, children: import_chart4.CHART_ERROR_BAR_LABELS[t] }, t))
|
|
8596
8868
|
] }) }),
|
|
8597
|
-
bars && (bars.type === "fixed" || bars.type === "percent" || bars.type === "stddev") && /* @__PURE__ */ (0,
|
|
8598
|
-
bars?.type === "custom" && /* @__PURE__ */ (0,
|
|
8599
|
-
/* @__PURE__ */ (0,
|
|
8600
|
-
/* @__PURE__ */ (0,
|
|
8869
|
+
bars && (bars.type === "fixed" || bars.type === "percent" || bars.type === "stddev") && /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(Field, { label: bars.type === "percent" ? "Percent" : bars.type === "stddev" ? "Deviations" : "Amount", htmlFor: `${id}-value`, children: /* @__PURE__ */ (0, import_jsx_runtime44.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 }) }),
|
|
8870
|
+
bars?.type === "custom" && /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)(import_jsx_runtime44.Fragment, { children: [
|
|
8871
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsx)(Field, { label: "Plus", htmlFor: `${id}-plus`, children: /* @__PURE__ */ (0, import_jsx_runtime44.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 }) }),
|
|
8872
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsx)(Field, { label: "Minus", htmlFor: `${id}-minus`, children: /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
|
|
8601
8873
|
ChartCommitInput,
|
|
8602
8874
|
{
|
|
8603
8875
|
id: `${id}-minus`,
|
|
@@ -8614,15 +8886,15 @@ function ErrorBarFields({ controller, series, which, idBase }) {
|
|
|
8614
8886
|
}
|
|
8615
8887
|
) })
|
|
8616
8888
|
] }),
|
|
8617
|
-
bars && /* @__PURE__ */ (0,
|
|
8618
|
-
/* @__PURE__ */ (0,
|
|
8619
|
-
/* @__PURE__ */ (0,
|
|
8889
|
+
bars && /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
8890
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.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_runtime44.jsx)("option", { value: d, children: d === "both" ? "Both ways" : d === "plus" ? "Plus only" : "Minus only" }, d)) }),
|
|
8891
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsx)(Toggle, { label: "Caps", name: `${key}.cap`, checked: bars.cap !== false, onChange: (cap2) => patch({ cap: cap2 }) })
|
|
8620
8892
|
] })
|
|
8621
8893
|
] });
|
|
8622
8894
|
}
|
|
8623
8895
|
function ChartInspector({ controller, sections, className }) {
|
|
8624
8896
|
const { spec, selectedSeries } = useChartState(controller);
|
|
8625
|
-
const idBase = (0,
|
|
8897
|
+
const idBase = (0, import_react64.useId)();
|
|
8626
8898
|
const show = (section) => !sections || sections.includes(section);
|
|
8627
8899
|
const cartesian = (0, import_chart4.isCartesianChart)(spec.type);
|
|
8628
8900
|
const family = (0, import_chart4.chartFamily)(spec);
|
|
@@ -8634,29 +8906,29 @@ function ChartInspector({ controller, sections, className }) {
|
|
|
8634
8906
|
const hasLines = cartesian && types.some((t) => t === "line" || t === "area");
|
|
8635
8907
|
const seriesIndex = selectedSeries ? spec.series.findIndex((s) => s.id === selectedSeries.id) : -1;
|
|
8636
8908
|
const scales = family === "cartesian" || family === "xy";
|
|
8637
|
-
return /* @__PURE__ */ (0,
|
|
8638
|
-
show("type") && /* @__PURE__ */ (0,
|
|
8639
|
-
show("style") && /* @__PURE__ */ (0,
|
|
8640
|
-
/* @__PURE__ */ (0,
|
|
8641
|
-
/* @__PURE__ */ (0,
|
|
8642
|
-
import_chart4.CHART_LAYOUT_PRESETS.map((p) => /* @__PURE__ */ (0,
|
|
8909
|
+
return /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("div", { className: `space-y-3 text-xs ${className ?? ""}`, "data-chart-inspector": "", children: [
|
|
8910
|
+
show("type") && /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("div", { className: chartSectionClass, "data-section": "type", children: /* @__PURE__ */ (0, import_jsx_runtime44.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_runtime44.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)) }) }),
|
|
8911
|
+
show("style") && /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("div", { className: chartSectionClass, "data-section": "style", children: [
|
|
8912
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsx)(Field, { label: "Layout", htmlFor: `${idBase}-layout`, children: /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("select", { id: `${idBase}-layout`, className: chartInputClass, value: "", "data-option": "preset.layout", onChange: (e) => e.currentTarget.value && controller.applyPreset({ layout: e.currentTarget.value }), children: [
|
|
8913
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsx)("option", { value: "", children: "Quick layout\u2026" }),
|
|
8914
|
+
import_chart4.CHART_LAYOUT_PRESETS.map((p) => /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("option", { value: p.id, title: p.description, children: p.label }, p.id))
|
|
8643
8915
|
] }) }),
|
|
8644
|
-
/* @__PURE__ */ (0,
|
|
8645
|
-
/* @__PURE__ */ (0,
|
|
8646
|
-
import_chart4.CHART_COLOR_SCHEMES.map((c) => /* @__PURE__ */ (0,
|
|
8916
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsx)(Field, { label: "Colours", htmlFor: `${idBase}-colors`, children: /* @__PURE__ */ (0, import_jsx_runtime44.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: [
|
|
8917
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsx)("option", { value: "", children: "Custom" }),
|
|
8918
|
+
import_chart4.CHART_COLOR_SCHEMES.map((c) => /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("option", { value: c.id, title: c.description, children: c.label }, c.id))
|
|
8647
8919
|
] }) }),
|
|
8648
|
-
!colorCheck.ok && /* @__PURE__ */ (0,
|
|
8649
|
-
/* @__PURE__ */ (0,
|
|
8920
|
+
!colorCheck.ok && /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("p", { className: "text-[11px] leading-snug text-amber-600 dark:text-amber-400", "data-chart-color-warning": "", children: colorCheck.issues[0] }),
|
|
8921
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsx)("button", { type: "button", className: chartButtonClass, "data-action": "transpose", onClick: () => controller.transpose(), children: "Switch rows and columns" })
|
|
8650
8922
|
] }),
|
|
8651
|
-
show("titles") && /* @__PURE__ */ (0,
|
|
8652
|
-
/* @__PURE__ */ (0,
|
|
8653
|
-
/* @__PURE__ */ (0,
|
|
8923
|
+
show("titles") && /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("div", { className: chartSectionClass, "data-section": "titles", children: [
|
|
8924
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsx)(Field, { label: "Title", htmlFor: `${idBase}-title`, children: /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(ChartCommitInput, { id: `${idBase}-title`, value: spec.title, "data-option": "title", className: chartInputClass, onCommit: (title) => void controller.setTitle(title) }) }),
|
|
8925
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsx)(Field, { label: "Subtitle", htmlFor: `${idBase}-subtitle`, children: /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(ChartCommitInput, { id: `${idBase}-subtitle`, value: spec.subtitle, "data-option": "subtitle", className: chartInputClass, onCommit: (subtitle) => void controller.setSubtitle(subtitle) }) })
|
|
8654
8926
|
] }),
|
|
8655
|
-
show("options") && /* @__PURE__ */ (0,
|
|
8656
|
-
cartesian && /* @__PURE__ */ (0,
|
|
8657
|
-
hasBars && /* @__PURE__ */ (0,
|
|
8658
|
-
hasLines && /* @__PURE__ */ (0,
|
|
8659
|
-
spec.type === "donut" && /* @__PURE__ */ (0,
|
|
8927
|
+
show("options") && /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("div", { className: chartSectionClass, "data-section": "options", children: [
|
|
8928
|
+
cartesian && /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(Field, { label: "Stacking", htmlFor: `${idBase}-stacking`, children: /* @__PURE__ */ (0, import_jsx_runtime44.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 }) }) }),
|
|
8929
|
+
hasBars && /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(Field, { label: "Bars", children: /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("div", { className: "flex gap-0.5 rounded-md bg-muted p-0.5", children: ["vertical", "horizontal"].map((o) => /* @__PURE__ */ (0, import_jsx_runtime44.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)) }) }),
|
|
8930
|
+
hasLines && /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(Field, { label: "Lines", htmlFor: `${idBase}-curve`, children: /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(Select, { id: `${idBase}-curve`, name: "curve", value: spec.curve, options: import_chart4.CHART_CURVES, onChange: (curve) => controller.update({ curve }) }) }),
|
|
8931
|
+
spec.type === "donut" && /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(Field, { label: "Hole", htmlFor: `${idBase}-hole`, children: /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
|
|
8660
8932
|
"input",
|
|
8661
8933
|
{
|
|
8662
8934
|
id: `${idBase}-hole`,
|
|
@@ -8672,7 +8944,7 @@ function ChartInspector({ controller, sections, className }) {
|
|
|
8672
8944
|
onChange: (e) => controller.update({ innerRadius: Number(e.currentTarget.value) })
|
|
8673
8945
|
}
|
|
8674
8946
|
) }),
|
|
8675
|
-
hasBars && /* @__PURE__ */ (0,
|
|
8947
|
+
hasBars && /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(Field, { label: "Spacing", htmlFor: `${idBase}-gap`, children: /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
|
|
8676
8948
|
"input",
|
|
8677
8949
|
{
|
|
8678
8950
|
id: `${idBase}-gap`,
|
|
@@ -8688,31 +8960,31 @@ function ChartInspector({ controller, sections, className }) {
|
|
|
8688
8960
|
onChange: (e) => controller.update({ gapWidth: Number(e.currentTarget.value) })
|
|
8689
8961
|
}
|
|
8690
8962
|
) }),
|
|
8691
|
-
spec.dataLabels && hasBars && /* @__PURE__ */ (0,
|
|
8692
|
-
spec.type === "histogram" && /* @__PURE__ */ (0,
|
|
8693
|
-
/* @__PURE__ */ (0,
|
|
8694
|
-
spec.type === "waterfall" && /* @__PURE__ */ (0,
|
|
8695
|
-
hasLines && /* @__PURE__ */ (0,
|
|
8696
|
-
/* @__PURE__ */ (0,
|
|
8963
|
+
spec.dataLabels && hasBars && /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(Field, { label: "Labels", htmlFor: `${idBase}-label-position`, children: /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(Select, { id: `${idBase}-label-position`, name: "labelPosition", value: spec.labelPosition, options: import_chart4.CHART_LABEL_POSITIONS, onChange: (labelPosition) => controller.update({ labelPosition }) }) }),
|
|
8964
|
+
spec.type === "histogram" && /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(Field, { label: "Bins", htmlFor: `${idBase}-bins`, children: /* @__PURE__ */ (0, import_jsx_runtime44.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 }) }),
|
|
8965
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("div", { className: "flex flex-wrap gap-x-4 gap-y-1", children: [
|
|
8966
|
+
spec.type === "waterfall" && /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(Toggle, { label: "Total bar", name: "showTotal", checked: spec.showTotal, onChange: (showTotal) => controller.update({ showTotal }) }),
|
|
8967
|
+
hasLines && /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(Toggle, { label: "Points", name: "points", checked: spec.points, onChange: (points) => controller.update({ points }) }),
|
|
8968
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsx)(Toggle, { label: "Data labels", name: "dataLabels", checked: spec.dataLabels, onChange: (dataLabels) => controller.update({ dataLabels }) })
|
|
8697
8969
|
] })
|
|
8698
8970
|
] }),
|
|
8699
|
-
show("legend") && /* @__PURE__ */ (0,
|
|
8700
|
-
/* @__PURE__ */ (0,
|
|
8701
|
-
/* @__PURE__ */ (0,
|
|
8702
|
-
/* @__PURE__ */ (0,
|
|
8971
|
+
show("legend") && /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("div", { className: chartSectionClass, "data-section": "legend", children: [
|
|
8972
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("div", { className: "flex items-center justify-between", children: [
|
|
8973
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsx)("h4", { className: "text-xs font-semibold text-foreground", children: "Legend" }),
|
|
8974
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsx)(Toggle, { label: "Show", name: "legend.show", checked: spec.legend.show, onChange: (v) => controller.setLegend({ show: v }) })
|
|
8703
8975
|
] }),
|
|
8704
|
-
spec.legend.show && /* @__PURE__ */ (0,
|
|
8976
|
+
spec.legend.show && /* @__PURE__ */ (0, import_jsx_runtime44.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_runtime44.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)) })
|
|
8705
8977
|
] }),
|
|
8706
|
-
show("axes") && hasAxes && /* @__PURE__ */ (0,
|
|
8707
|
-
family !== "box" && family !== "histogram" && /* @__PURE__ */ (0,
|
|
8708
|
-
/* @__PURE__ */ (0,
|
|
8709
|
-
usesSecondary && /* @__PURE__ */ (0,
|
|
8978
|
+
show("axes") && hasAxes && /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)(import_jsx_runtime44.Fragment, { children: [
|
|
8979
|
+
family !== "box" && family !== "histogram" && /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(AxisSection, { controller, axis: "x", value: spec.xAxis, idBase, horizontal: spec.orientation === "horizontal", numeric: family === "xy", scales }),
|
|
8980
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsx)(AxisSection, { controller, axis: "y", value: spec.yAxis, idBase, horizontal: spec.orientation === "horizontal", scales }),
|
|
8981
|
+
usesSecondary && /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(AxisSection, { controller, axis: "y2", value: spec.yAxis2, idBase, horizontal: spec.orientation === "horizontal", scales })
|
|
8710
8982
|
] }),
|
|
8711
|
-
show("series") && selectedSeries && /* @__PURE__ */ (0,
|
|
8712
|
-
/* @__PURE__ */ (0,
|
|
8713
|
-
/* @__PURE__ */ (0,
|
|
8714
|
-
/* @__PURE__ */ (0,
|
|
8715
|
-
/* @__PURE__ */ (0,
|
|
8983
|
+
show("series") && selectedSeries && /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("div", { className: chartSectionClass, "data-section": "series", "data-series-id": selectedSeries.id, children: [
|
|
8984
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsx)("h4", { className: "text-xs font-semibold text-foreground", children: "Series" }),
|
|
8985
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsx)(Field, { label: "Name", htmlFor: `${idBase}-series-name`, children: /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(ChartCommitInput, { id: `${idBase}-series-name`, value: selectedSeries.name, "data-option": "series.name", className: chartInputClass, onCommit: (name) => void controller.updateSeries(selectedSeries.id, { name }) }) }),
|
|
8986
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsx)(Field, { label: "Colour", htmlFor: `${idBase}-series-color`, children: /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("div", { className: "flex items-center gap-1", children: [
|
|
8987
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
|
|
8716
8988
|
"input",
|
|
8717
8989
|
{
|
|
8718
8990
|
id: `${idBase}-series-color`,
|
|
@@ -8725,9 +8997,9 @@ function ChartInspector({ controller, sections, className }) {
|
|
|
8725
8997
|
onChange: (e) => controller.updateSeries(selectedSeries.id, { color: e.currentTarget.value })
|
|
8726
8998
|
}
|
|
8727
8999
|
),
|
|
8728
|
-
selectedSeries.color && /* @__PURE__ */ (0,
|
|
9000
|
+
selectedSeries.color && /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("button", { type: "button", className: chartButtonClass, "data-action": "reset-color", onClick: () => controller.updateSeries(selectedSeries.id, { color: null }), children: "Palette" })
|
|
8729
9001
|
] }) }),
|
|
8730
|
-
cartesian && /* @__PURE__ */ (0,
|
|
9002
|
+
cartesian && /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(Field, { label: "Draw as", htmlFor: `${idBase}-series-type`, children: /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)(
|
|
8731
9003
|
"select",
|
|
8732
9004
|
{
|
|
8733
9005
|
id: `${idBase}-series-type`,
|
|
@@ -8736,12 +9008,12 @@ function ChartInspector({ controller, sections, className }) {
|
|
|
8736
9008
|
"data-option": "series.type",
|
|
8737
9009
|
onChange: (e) => controller.updateSeries(selectedSeries.id, { type: e.currentTarget.value || null }),
|
|
8738
9010
|
children: [
|
|
8739
|
-
/* @__PURE__ */ (0,
|
|
8740
|
-
import_chart4.CHART_SERIES_TYPES.map((t) => /* @__PURE__ */ (0,
|
|
9011
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsx)("option", { value: "", children: "Chart type" }),
|
|
9012
|
+
import_chart4.CHART_SERIES_TYPES.map((t) => /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("option", { value: t, children: import_chart4.CHART_TYPE_LABELS[t] }, t))
|
|
8741
9013
|
]
|
|
8742
9014
|
}
|
|
8743
9015
|
) }),
|
|
8744
|
-
(cartesian || family === "xy") && ["line", "area", "scatter"].includes((0, import_chart4.chartSeriesType)(spec, selectedSeries)) && /* @__PURE__ */ (0,
|
|
9016
|
+
(cartesian || family === "xy") && ["line", "area", "scatter"].includes((0, import_chart4.chartSeriesType)(spec, selectedSeries)) && /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(Field, { label: "Marker", htmlFor: `${idBase}-series-marker`, children: /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)(
|
|
8745
9017
|
"select",
|
|
8746
9018
|
{
|
|
8747
9019
|
id: `${idBase}-series-marker`,
|
|
@@ -8750,20 +9022,20 @@ function ChartInspector({ controller, sections, className }) {
|
|
|
8750
9022
|
"data-option": "series.marker",
|
|
8751
9023
|
onChange: (e) => controller.updateSeries(selectedSeries.id, { marker: e.currentTarget.value || null }),
|
|
8752
9024
|
children: [
|
|
8753
|
-
/* @__PURE__ */ (0,
|
|
8754
|
-
import_chart4.CHART_MARKERS.map((m) => /* @__PURE__ */ (0,
|
|
9025
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsx)("option", { value: "", children: "Default" }),
|
|
9026
|
+
import_chart4.CHART_MARKERS.map((m) => /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("option", { value: m, children: cap(m) }, m))
|
|
8755
9027
|
]
|
|
8756
9028
|
}
|
|
8757
9029
|
) }),
|
|
8758
|
-
scales && /* @__PURE__ */ (0,
|
|
8759
|
-
family === "xy" && /* @__PURE__ */ (0,
|
|
8760
|
-
(0, import_chart4.chartSupportsTrendlines)(spec.type, spec.stacking) && /* @__PURE__ */ (0,
|
|
8761
|
-
(selectedSeries.trendlines ?? []).map((t, i) => /* @__PURE__ */ (0,
|
|
8762
|
-
/* @__PURE__ */ (0,
|
|
8763
|
-
/* @__PURE__ */ (0,
|
|
8764
|
-
/* @__PURE__ */ (0,
|
|
9030
|
+
scales && /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(ErrorBarFields, { controller, series: selectedSeries, which: "errorBars", idBase }),
|
|
9031
|
+
family === "xy" && /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(ErrorBarFields, { controller, series: selectedSeries, which: "xErrorBars", idBase }),
|
|
9032
|
+
(0, import_chart4.chartSupportsTrendlines)(spec.type, spec.stacking) && /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("div", { className: "space-y-1", "data-section": "trendlines", children: [
|
|
9033
|
+
(selectedSeries.trendlines ?? []).map((t, i) => /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("div", { className: "flex items-center gap-1", "data-trendline": i, children: [
|
|
9034
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsx)("span", { className: "flex-1 truncate text-muted-foreground", children: (0, import_chart4.chartTrendlineName)(t, selectedSeries.name) }),
|
|
9035
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsx)(Toggle, { label: "R\xB2", name: `trendline.${i}.showR2`, checked: !!t.showR2, onChange: (showR2) => controller.updateTrendline(selectedSeries.id, i, { showR2 }) }),
|
|
9036
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsx)("button", { type: "button", className: chartButtonClass, "aria-label": "Delete trendline", "data-action": "trendline-delete", onClick: () => controller.removeTrendline(selectedSeries.id, i), children: "\xD7" })
|
|
8765
9037
|
] }, i)),
|
|
8766
|
-
/* @__PURE__ */ (0,
|
|
9038
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsxs)(
|
|
8767
9039
|
"select",
|
|
8768
9040
|
{
|
|
8769
9041
|
className: chartInputClass,
|
|
@@ -8772,32 +9044,32 @@ function ChartInspector({ controller, sections, className }) {
|
|
|
8772
9044
|
"data-option": "trendline.add",
|
|
8773
9045
|
onChange: (e) => e.currentTarget.value && controller.addTrendline(selectedSeries.id, { type: e.currentTarget.value }),
|
|
8774
9046
|
children: [
|
|
8775
|
-
/* @__PURE__ */ (0,
|
|
8776
|
-
import_chart4.CHART_TRENDLINE_TYPES.map((t) => /* @__PURE__ */ (0,
|
|
9047
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsx)("option", { value: "", children: "Add trendline\u2026" }),
|
|
9048
|
+
import_chart4.CHART_TRENDLINE_TYPES.map((t) => /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("option", { value: t, children: cap(t.replace("-", " ")) }, t))
|
|
8777
9049
|
]
|
|
8778
9050
|
}
|
|
8779
9051
|
)
|
|
8780
9052
|
] }),
|
|
8781
|
-
/* @__PURE__ */ (0,
|
|
8782
|
-
/* @__PURE__ */ (0,
|
|
8783
|
-
family === "cartesian" && /* @__PURE__ */ (0,
|
|
8784
|
-
/* @__PURE__ */ (0,
|
|
8785
|
-
/* @__PURE__ */ (0,
|
|
8786
|
-
/* @__PURE__ */ (0,
|
|
8787
|
-
/* @__PURE__ */ (0,
|
|
9053
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("div", { className: "flex flex-wrap items-center gap-1", children: [
|
|
9054
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsx)(Toggle, { label: "Hidden", name: "series.hidden", checked: !!selectedSeries.hidden, onChange: (hidden) => controller.updateSeries(selectedSeries.id, { hidden }) }),
|
|
9055
|
+
family === "cartesian" && /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(Toggle, { label: "Secondary axis", name: "series.axis", checked: selectedSeries.axis === "secondary", onChange: (secondary) => controller.updateSeries(selectedSeries.id, { axis: secondary ? "secondary" : null }) }),
|
|
9056
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsx)("span", { className: "flex-1" }),
|
|
9057
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.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" }),
|
|
9058
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.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" }),
|
|
9059
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsx)("button", { type: "button", className: `${chartButtonClass} text-destructive`, "data-action": "series-delete", onClick: () => controller.removeSeries(selectedSeries.id), children: "Delete" })
|
|
8788
9060
|
] })
|
|
8789
9061
|
] })
|
|
8790
9062
|
] });
|
|
8791
9063
|
}
|
|
8792
9064
|
|
|
8793
9065
|
// src/chart-node/ChartNodeView.tsx
|
|
8794
|
-
var
|
|
9066
|
+
var import_jsx_runtime45 = require("react/jsx-runtime");
|
|
8795
9067
|
function ChartNodeView({ state, theme, showDataGrid = true }) {
|
|
8796
9068
|
const { controller, editing, editable, selected, width, height, setEditing } = state;
|
|
8797
9069
|
const open = () => {
|
|
8798
9070
|
if (editable && !editing) setEditing(true);
|
|
8799
9071
|
};
|
|
8800
|
-
return /* @__PURE__ */ (0,
|
|
9072
|
+
return /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)(
|
|
8801
9073
|
"div",
|
|
8802
9074
|
{
|
|
8803
9075
|
className: `not-prose my-2 rounded-md border bg-background p-1 ${selected ? "border-primary ring-1 ring-primary" : "border-border"}`,
|
|
@@ -8810,24 +9082,24 @@ function ChartNodeView({ state, theme, showDataGrid = true }) {
|
|
|
8810
9082
|
}
|
|
8811
9083
|
},
|
|
8812
9084
|
children: [
|
|
8813
|
-
editing && /* @__PURE__ */ (0,
|
|
8814
|
-
/* @__PURE__ */ (0,
|
|
8815
|
-
/* @__PURE__ */ (0,
|
|
9085
|
+
editing && /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("div", { className: "mb-1 flex items-center justify-between gap-2 px-1", "data-chart-node-toolbar": "", children: [
|
|
9086
|
+
/* @__PURE__ */ (0, import_jsx_runtime45.jsx)("span", { className: "text-xs text-muted-foreground", children: "Editing chart" }),
|
|
9087
|
+
/* @__PURE__ */ (0, import_jsx_runtime45.jsx)("button", { type: "button", className: chartButtonClass, "data-action": "done", onClick: () => setEditing(false), children: "Done" })
|
|
8816
9088
|
] }),
|
|
8817
|
-
/* @__PURE__ */ (0,
|
|
9089
|
+
/* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
|
|
8818
9090
|
"div",
|
|
8819
9091
|
{
|
|
8820
9092
|
className: editable && !editing ? "cursor-pointer" : void 0,
|
|
8821
9093
|
onClick: open,
|
|
8822
9094
|
title: editable && !editing ? "Click to edit the chart" : void 0,
|
|
8823
9095
|
"data-chart-node-canvas": "",
|
|
8824
|
-
children: /* @__PURE__ */ (0,
|
|
9096
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(ChartCanvas, { controller, width: width ?? 640, height, responsive: width === null, editable: editing, theme })
|
|
8825
9097
|
}
|
|
8826
9098
|
),
|
|
8827
9099
|
editing && // Wraps by the document's width, not the viewport's: side by side when there is room.
|
|
8828
|
-
/* @__PURE__ */ (0,
|
|
8829
|
-
showDataGrid && /* @__PURE__ */ (0,
|
|
8830
|
-
/* @__PURE__ */ (0,
|
|
9100
|
+
/* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("div", { className: "mt-2 flex flex-wrap items-start gap-2", "data-chart-node-panel": "", children: [
|
|
9101
|
+
showDataGrid && /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("div", { className: "min-w-0 flex-[1_1_20rem] overflow-x-auto", children: /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(ChartDataGrid, { controller }) }),
|
|
9102
|
+
/* @__PURE__ */ (0, import_jsx_runtime45.jsx)(ChartInspector, { controller, className: "max-h-96 min-w-0 flex-[1_1_16rem] overflow-y-auto rounded-md border border-border p-3" })
|
|
8831
9103
|
] })
|
|
8832
9104
|
]
|
|
8833
9105
|
}
|
|
@@ -8845,7 +9117,7 @@ function createReactChartNodeView(options = {}) {
|
|
|
8845
9117
|
scheduled = true;
|
|
8846
9118
|
queueMicrotask(() => {
|
|
8847
9119
|
scheduled = false;
|
|
8848
|
-
if (!destroyed) root.render(/* @__PURE__ */ (0,
|
|
9120
|
+
if (!destroyed) root.render(/* @__PURE__ */ (0, import_jsx_runtime45.jsx)(Component, { ...props, state: latest }));
|
|
8849
9121
|
});
|
|
8850
9122
|
};
|
|
8851
9123
|
schedule();
|
|
@@ -8879,6 +9151,7 @@ function createReactChartNodeView(options = {}) {
|
|
|
8879
9151
|
ExportDocxButton,
|
|
8880
9152
|
FindReplaceBar,
|
|
8881
9153
|
FormulaHints,
|
|
9154
|
+
FreeTransformOptionsBar,
|
|
8882
9155
|
GenerationHistory,
|
|
8883
9156
|
GenerationSettings,
|
|
8884
9157
|
Histogram,
|