@pixerate/editor-react 0.62.0 → 0.64.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-OSOGA2OJ.js → chunk-M4WLX3IR.js} +628 -365
- package/dist/chunk-M4WLX3IR.js.map +1 -0
- package/dist/image-editor/index.cjs +661 -398
- package/dist/image-editor/index.cjs.map +1 -1
- package/dist/image-editor/index.d.cts +23 -5
- package/dist/image-editor/index.d.ts +23 -5
- package/dist/image-editor/index.js +3 -1
- package/dist/index.cjs +1079 -816
- 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 +4 -4
- package/dist/chunk-OSOGA2OJ.js.map +0 -1
package/dist/index.cjs
CHANGED
|
@@ -53,6 +53,7 @@ __export(src_exports, {
|
|
|
53
53
|
ImageEditor: () => ImageEditor,
|
|
54
54
|
InsertTableGrid: () => InsertTableGrid,
|
|
55
55
|
JobProgress: () => JobProgress,
|
|
56
|
+
LayerEffectsPanel: () => LayerEffectsPanel,
|
|
56
57
|
LayersPanel: () => LayersPanel,
|
|
57
58
|
MergePreview: () => MergePreview,
|
|
58
59
|
NameManager: () => NameManager,
|
|
@@ -2003,17 +2004,17 @@ var SpreadsheetValidationDialog = ({ prompt, onResolve }) => {
|
|
|
2003
2004
|
style === "warning" && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { className: "mt-2", children: "Continue?" })
|
|
2004
2005
|
] })
|
|
2005
2006
|
] }),
|
|
2006
|
-
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "mt-4 flex justify-end gap-2", children: buttons.map((
|
|
2007
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "mt-4 flex justify-end gap-2", children: buttons.map((button3, i) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
2007
2008
|
"button",
|
|
2008
2009
|
{
|
|
2009
2010
|
ref: i === 0 ? firstButton : void 0,
|
|
2010
2011
|
type: "button",
|
|
2011
|
-
"data-action":
|
|
2012
|
+
"data-action": button3.action,
|
|
2012
2013
|
className: `rounded border border-border px-3 py-1 ${i === 0 ? "bg-primary text-primary-foreground" : "hover:bg-muted"}`,
|
|
2013
|
-
onClick: () => onResolve(
|
|
2014
|
-
children:
|
|
2014
|
+
onClick: () => onResolve(button3.action),
|
|
2015
|
+
children: button3.label
|
|
2015
2016
|
},
|
|
2016
|
-
|
|
2017
|
+
button3.action
|
|
2017
2018
|
)) })
|
|
2018
2019
|
]
|
|
2019
2020
|
}
|
|
@@ -3783,8 +3784,8 @@ function useImageEditor(options = {}) {
|
|
|
3783
3784
|
}
|
|
3784
3785
|
|
|
3785
3786
|
// src/image-editor/ImageEditor.tsx
|
|
3786
|
-
var
|
|
3787
|
-
var
|
|
3787
|
+
var import_react43 = __toESM(require("react"), 1);
|
|
3788
|
+
var import_image_editor11 = require("@pixerate/editor/image-editor");
|
|
3788
3789
|
|
|
3789
3790
|
// src/image-editor/ControlSlider.tsx
|
|
3790
3791
|
var import_image_editor2 = require("@pixerate/editor/image-editor");
|
|
@@ -4216,9 +4217,198 @@ var AdjustmentLayersPanel = ({ controller, layers: layersProp, histogram }) => {
|
|
|
4216
4217
|
};
|
|
4217
4218
|
|
|
4218
4219
|
// src/image-editor/LayersPanel.tsx
|
|
4220
|
+
var import_react39 = require("react");
|
|
4221
|
+
|
|
4222
|
+
// src/image-editor/LayerEffectsPanel.tsx
|
|
4219
4223
|
var import_react38 = require("react");
|
|
4220
4224
|
var import_image_editor6 = require("@pixerate/editor/image-editor");
|
|
4221
4225
|
var import_jsx_runtime21 = require("react/jsx-runtime");
|
|
4226
|
+
var button = "px-1.5 py-0.5 rounded text-[10px] bg-slate-800 text-slate-300 hover:text-white disabled:opacity-40";
|
|
4227
|
+
var LayerEffectsPanel = ({ controller, layerId, className }) => {
|
|
4228
|
+
const [, setTick] = (0, import_react38.useState)(0);
|
|
4229
|
+
(0, import_react38.useEffect)(() => controller.subscribe(() => setTick((n) => n + 1)), [controller]);
|
|
4230
|
+
const [open, setOpen] = (0, import_react38.useState)(null);
|
|
4231
|
+
const [error, setError] = (0, import_react38.useState)(null);
|
|
4232
|
+
const commitNext = (0, import_react38.useRef)(true);
|
|
4233
|
+
const layer = layerId ? controller.getLayer(layerId) : controller.getActiveLayer();
|
|
4234
|
+
const model = (0, import_image_editor6.layerEffectsPanel)(layer);
|
|
4235
|
+
const id = layer?.id;
|
|
4236
|
+
const attempt = (fn) => {
|
|
4237
|
+
try {
|
|
4238
|
+
setError(null);
|
|
4239
|
+
fn();
|
|
4240
|
+
} catch (err) {
|
|
4241
|
+
setError(err instanceof Error ? err.message : String(err));
|
|
4242
|
+
}
|
|
4243
|
+
};
|
|
4244
|
+
const sliderEvents = {
|
|
4245
|
+
onPointerDown: () => commitNext.current = true,
|
|
4246
|
+
onPointerUp: () => commitNext.current = true,
|
|
4247
|
+
onKeyDown: () => commitNext.current = true
|
|
4248
|
+
};
|
|
4249
|
+
if (!model.available || !id) {
|
|
4250
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: `text-xs text-slate-500 ${className ?? ""}`, "data-testid": "layer-effects", children: model.reason });
|
|
4251
|
+
}
|
|
4252
|
+
const effects = controller.getLayerEffects(id);
|
|
4253
|
+
const patterns = controller.getDocumentPatterns();
|
|
4254
|
+
const change = (effectId, control, value, drag = false) => attempt(() => {
|
|
4255
|
+
const effect = controller.getLayerEffects(id).items.find((e) => e.id === effectId);
|
|
4256
|
+
controller.updateLayerEffect(id, effectId, (0, import_image_editor6.effectControlChange)(effect, control.key, value, patterns), drag ? commitNext.current : true);
|
|
4257
|
+
if (drag) commitNext.current = false;
|
|
4258
|
+
});
|
|
4259
|
+
const renderControl = (effectId, c) => {
|
|
4260
|
+
const label = `${c.label}`;
|
|
4261
|
+
switch (c.type) {
|
|
4262
|
+
case "range": {
|
|
4263
|
+
const k = c.percent ? 100 : 1;
|
|
4264
|
+
const shown = Math.round(c.value * k * 100) / 100;
|
|
4265
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("label", { className: "flex flex-col gap-0.5", children: [
|
|
4266
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("span", { className: "text-slate-400", children: [
|
|
4267
|
+
label,
|
|
4268
|
+
" ",
|
|
4269
|
+
shown,
|
|
4270
|
+
c.unit
|
|
4271
|
+
] }),
|
|
4272
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
4273
|
+
"input",
|
|
4274
|
+
{
|
|
4275
|
+
type: "range",
|
|
4276
|
+
"aria-label": label,
|
|
4277
|
+
min: c.min * k,
|
|
4278
|
+
max: c.max * k,
|
|
4279
|
+
step: c.step * k,
|
|
4280
|
+
value: shown,
|
|
4281
|
+
disabled: model.readOnly,
|
|
4282
|
+
...sliderEvents,
|
|
4283
|
+
onChange: (e) => change(effectId, c, Number(e.target.value) / k, true),
|
|
4284
|
+
className: "accent-indigo-500"
|
|
4285
|
+
}
|
|
4286
|
+
)
|
|
4287
|
+
] }, c.key);
|
|
4288
|
+
}
|
|
4289
|
+
case "color":
|
|
4290
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("label", { className: "flex items-center gap-1.5 text-slate-300", children: [
|
|
4291
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("input", { type: "color", "aria-label": label, value: c.value, disabled: model.readOnly, onChange: (e) => change(effectId, c, e.target.value) }),
|
|
4292
|
+
label
|
|
4293
|
+
] }, c.key);
|
|
4294
|
+
case "checkbox":
|
|
4295
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("label", { className: "flex items-center gap-1.5 text-slate-300", children: [
|
|
4296
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("input", { type: "checkbox", "aria-label": label, checked: c.value, disabled: model.readOnly, onChange: (e) => change(effectId, c, e.target.checked), className: "accent-indigo-500" }),
|
|
4297
|
+
label
|
|
4298
|
+
] }, c.key);
|
|
4299
|
+
case "select":
|
|
4300
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("label", { className: "flex flex-col gap-0.5", children: [
|
|
4301
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "text-slate-400", children: label }),
|
|
4302
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
4303
|
+
"select",
|
|
4304
|
+
{
|
|
4305
|
+
"aria-label": label,
|
|
4306
|
+
value: c.value,
|
|
4307
|
+
disabled: model.readOnly,
|
|
4308
|
+
onChange: (e) => change(effectId, c, e.target.value),
|
|
4309
|
+
className: "bg-slate-800 border border-slate-700 rounded px-1.5 py-1",
|
|
4310
|
+
children: c.options.map((o) => /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("option", { value: o.value, children: o.label }, o.value))
|
|
4311
|
+
}
|
|
4312
|
+
)
|
|
4313
|
+
] }, c.key);
|
|
4314
|
+
}
|
|
4315
|
+
};
|
|
4316
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: `flex flex-col gap-1.5 text-xs text-slate-200 ${className ?? ""}`, "data-testid": "layer-effects", "aria-label": "Layer effects", role: "group", children: [
|
|
4317
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "flex flex-wrap items-center gap-2", children: [
|
|
4318
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "font-semibold text-slate-300", children: "fx Effects" }),
|
|
4319
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("label", { className: "flex items-center gap-1 text-slate-300", children: [
|
|
4320
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
4321
|
+
"input",
|
|
4322
|
+
{
|
|
4323
|
+
type: "checkbox",
|
|
4324
|
+
"aria-label": "Effects on",
|
|
4325
|
+
checked: model.enabled,
|
|
4326
|
+
disabled: model.readOnly,
|
|
4327
|
+
onChange: (e) => attempt(() => controller.setLayerEffectsEnabled(id, e.target.checked)),
|
|
4328
|
+
className: "accent-indigo-500"
|
|
4329
|
+
}
|
|
4330
|
+
),
|
|
4331
|
+
"On"
|
|
4332
|
+
] }),
|
|
4333
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("label", { className: "flex items-center gap-1 text-slate-400", children: [
|
|
4334
|
+
"Scale",
|
|
4335
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
4336
|
+
"input",
|
|
4337
|
+
{
|
|
4338
|
+
type: "number",
|
|
4339
|
+
"aria-label": "Scale effects",
|
|
4340
|
+
min: 1,
|
|
4341
|
+
max: 1e3,
|
|
4342
|
+
step: 1,
|
|
4343
|
+
value: Math.round(model.scale * 100),
|
|
4344
|
+
disabled: model.readOnly,
|
|
4345
|
+
onChange: (e) => {
|
|
4346
|
+
const v = Number(e.target.value);
|
|
4347
|
+
if (v >= 1 && v <= 1e3) attempt(() => controller.setLayerEffectsEnabled(id, model.enabled, v / 100));
|
|
4348
|
+
},
|
|
4349
|
+
className: "w-14 bg-slate-800 border border-slate-700 rounded px-1"
|
|
4350
|
+
}
|
|
4351
|
+
),
|
|
4352
|
+
"%"
|
|
4353
|
+
] }),
|
|
4354
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
|
|
4355
|
+
"select",
|
|
4356
|
+
{
|
|
4357
|
+
"aria-label": "Add effect",
|
|
4358
|
+
value: "",
|
|
4359
|
+
disabled: model.readOnly,
|
|
4360
|
+
onChange: (e) => {
|
|
4361
|
+
const kind = e.target.value;
|
|
4362
|
+
if (!kind) return;
|
|
4363
|
+
attempt(() => setOpen(controller.addLayerEffect(id, kind).effect.id));
|
|
4364
|
+
},
|
|
4365
|
+
className: "bg-slate-800 border border-slate-700 rounded px-1.5 py-1",
|
|
4366
|
+
children: [
|
|
4367
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("option", { value: "", children: "Add effect\u2026" }),
|
|
4368
|
+
import_image_editor6.LAYER_EFFECT_MENU.map((m) => /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("option", { value: m.kind, children: m.label }, m.kind))
|
|
4369
|
+
]
|
|
4370
|
+
}
|
|
4371
|
+
)
|
|
4372
|
+
] }),
|
|
4373
|
+
model.readOnly && model.reason && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("p", { className: "text-slate-500", children: model.reason }),
|
|
4374
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("ul", { className: "flex flex-col gap-1", "aria-label": "Effects", children: model.rows.map((row) => {
|
|
4375
|
+
const effect = effects.items.find((e) => e.id === row.id);
|
|
4376
|
+
const expanded = open === row.id;
|
|
4377
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("li", { "data-effect-id": row.id, className: "rounded bg-slate-900/60 ring-1 ring-slate-800", children: [
|
|
4378
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "flex items-center gap-1.5 px-1.5 py-1", children: [
|
|
4379
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
4380
|
+
"input",
|
|
4381
|
+
{
|
|
4382
|
+
type: "checkbox",
|
|
4383
|
+
"aria-label": `${row.label} on`,
|
|
4384
|
+
checked: row.enabled,
|
|
4385
|
+
disabled: model.readOnly,
|
|
4386
|
+
onChange: (e) => attempt(() => controller.updateLayerEffect(id, row.id, { enabled: e.target.checked })),
|
|
4387
|
+
className: "accent-indigo-500"
|
|
4388
|
+
}
|
|
4389
|
+
),
|
|
4390
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
4391
|
+
"button",
|
|
4392
|
+
{
|
|
4393
|
+
type: "button",
|
|
4394
|
+
"aria-expanded": expanded,
|
|
4395
|
+
className: `flex-1 text-left ${row.enabled && model.enabled ? "" : "text-slate-500"}`,
|
|
4396
|
+
onClick: () => setOpen(expanded ? null : row.id),
|
|
4397
|
+
children: row.label
|
|
4398
|
+
}
|
|
4399
|
+
),
|
|
4400
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("button", { type: "button", className: button, "aria-label": `Remove ${row.label}`, disabled: model.readOnly, onClick: () => attempt(() => controller.removeLayerEffect(id, row.id)), children: "\u2715" })
|
|
4401
|
+
] }),
|
|
4402
|
+
expanded && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "grid grid-cols-2 gap-x-2 gap-y-1 px-1.5 pb-1.5", "data-testid": "effect-settings", children: (0, import_image_editor6.layerEffectControls)(effect, patterns).map((c) => renderControl(row.id, c)) })
|
|
4403
|
+
] }, row.id);
|
|
4404
|
+
}) }),
|
|
4405
|
+
error && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("p", { role: "alert", className: "text-rose-400", children: error })
|
|
4406
|
+
] });
|
|
4407
|
+
};
|
|
4408
|
+
|
|
4409
|
+
// src/image-editor/LayersPanel.tsx
|
|
4410
|
+
var import_image_editor7 = require("@pixerate/editor/image-editor");
|
|
4411
|
+
var import_jsx_runtime22 = require("react/jsx-runtime");
|
|
4222
4412
|
var iconButton = "px-1.5 py-0.5 rounded text-[10px] bg-slate-800 text-slate-300 hover:text-white disabled:opacity-40";
|
|
4223
4413
|
var rowClass = (active) => `flex items-center gap-1.5 px-1.5 py-1 rounded cursor-pointer select-none ${active ? "bg-indigo-600/30 ring-1 ring-indigo-500" : "hover:bg-slate-800"}`;
|
|
4224
4414
|
var Thumbnail = ({
|
|
@@ -4229,8 +4419,8 @@ var Thumbnail = ({
|
|
|
4229
4419
|
selected,
|
|
4230
4420
|
testId
|
|
4231
4421
|
}) => {
|
|
4232
|
-
const ref = (0,
|
|
4233
|
-
(0,
|
|
4422
|
+
const ref = (0, import_react39.useRef)(null);
|
|
4423
|
+
(0, import_react39.useEffect)(() => {
|
|
4234
4424
|
const canvas = ref.current;
|
|
4235
4425
|
const ctx = canvas?.getContext("2d");
|
|
4236
4426
|
if (!canvas || !ctx || !pixels || typeof ctx.createImageData !== "function") return;
|
|
@@ -4240,7 +4430,7 @@ var Thumbnail = ({
|
|
|
4240
4430
|
img.data.set(pixels.data);
|
|
4241
4431
|
ctx.putImageData(img, 0, 0);
|
|
4242
4432
|
}, [pixels]);
|
|
4243
|
-
return /* @__PURE__ */ (0,
|
|
4433
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
4244
4434
|
"canvas",
|
|
4245
4435
|
{
|
|
4246
4436
|
ref,
|
|
@@ -4253,15 +4443,15 @@ var Thumbnail = ({
|
|
|
4253
4443
|
}
|
|
4254
4444
|
);
|
|
4255
4445
|
};
|
|
4256
|
-
var LayersPanel = ({ controller, thumbnailSize = 32, psd = true, psdFileName = "image", className }) => {
|
|
4257
|
-
const [, setTick] = (0,
|
|
4258
|
-
(0,
|
|
4259
|
-
const [error, setError] = (0,
|
|
4260
|
-
const [renaming, setRenaming] = (0,
|
|
4261
|
-
const [menu, setMenu] = (0,
|
|
4262
|
-
const [drag, setDrag] = (0,
|
|
4263
|
-
const [psdNotes, setPsdNotes] = (0,
|
|
4264
|
-
const fileInput = (0,
|
|
4446
|
+
var LayersPanel = ({ controller, thumbnailSize = 32, psd = true, psdFileName = "image", effects = true, className }) => {
|
|
4447
|
+
const [, setTick] = (0, import_react39.useState)(0);
|
|
4448
|
+
(0, import_react39.useEffect)(() => controller.subscribe(() => setTick((n) => n + 1)), [controller]);
|
|
4449
|
+
const [error, setError] = (0, import_react39.useState)(null);
|
|
4450
|
+
const [renaming, setRenaming] = (0, import_react39.useState)(null);
|
|
4451
|
+
const [menu, setMenu] = (0, import_react39.useState)(null);
|
|
4452
|
+
const [drag, setDrag] = (0, import_react39.useState)(null);
|
|
4453
|
+
const [psdNotes, setPsdNotes] = (0, import_react39.useState)([]);
|
|
4454
|
+
const fileInput = (0, import_react39.useRef)(null);
|
|
4265
4455
|
const psdTask = async (fn) => {
|
|
4266
4456
|
try {
|
|
4267
4457
|
setError(null);
|
|
@@ -4270,9 +4460,9 @@ var LayersPanel = ({ controller, thumbnailSize = 32, psd = true, psdFileName = "
|
|
|
4270
4460
|
setError(err instanceof Error ? err.message : String(err));
|
|
4271
4461
|
}
|
|
4272
4462
|
};
|
|
4273
|
-
const commitNext = (0,
|
|
4463
|
+
const commitNext = (0, import_react39.useRef)(true);
|
|
4274
4464
|
const state = controller.getState();
|
|
4275
|
-
const rows = (0,
|
|
4465
|
+
const rows = (0, import_image_editor7.layerPanelRows)(state.layers, state.activeLayerId);
|
|
4276
4466
|
const active = controller.getActiveLayer();
|
|
4277
4467
|
const attempt = (fn) => {
|
|
4278
4468
|
try {
|
|
@@ -4284,7 +4474,7 @@ var LayersPanel = ({ controller, thumbnailSize = 32, psd = true, psdFileName = "
|
|
|
4284
4474
|
};
|
|
4285
4475
|
const run = async (action) => {
|
|
4286
4476
|
setMenu(null);
|
|
4287
|
-
setError(await (0,
|
|
4477
|
+
setError(await (0, import_image_editor7.runLayerMenuAction)(controller, action));
|
|
4288
4478
|
};
|
|
4289
4479
|
const prop = (key, value) => attempt(() => {
|
|
4290
4480
|
controller.setLayerProperties(active.id, { [key]: value }, commitNext.current);
|
|
@@ -4302,20 +4492,20 @@ var LayersPanel = ({ controller, thumbnailSize = 32, psd = true, psdFileName = "
|
|
|
4302
4492
|
if (!id) return;
|
|
4303
4493
|
const rect = e.currentTarget.getBoundingClientRect();
|
|
4304
4494
|
const fraction = rect.height ? (e.clientY - rect.top) / rect.height : 0.5;
|
|
4305
|
-
const placement = (0,
|
|
4495
|
+
const placement = (0, import_image_editor7.dropPlacement)(state.layers, id, row.layer.id, (0, import_image_editor7.dropZone)(fraction, row.layer.type === "group"));
|
|
4306
4496
|
if (placement) attempt(() => controller.moveLayer(id, placement));
|
|
4307
4497
|
};
|
|
4308
4498
|
const thumb = (layer) => layer.type === "pixel" ? controller.getLayerThumbnail(layer.id, { maxSide: 64 }) : null;
|
|
4309
4499
|
const maskThumb = (layer) => layer.mask && !layer.mask.source ? controller.getLayerThumbnail(layer.id, { maxSide: 64, mask: true }) : null;
|
|
4310
4500
|
const locked = (layer) => Boolean(layer.locks?.all || layer.locks?.pixels || layer.locks?.position || layer.locks?.transparency);
|
|
4311
|
-
return /* @__PURE__ */ (0,
|
|
4312
|
-
/* @__PURE__ */ (0,
|
|
4313
|
-
/* @__PURE__ */ (0,
|
|
4314
|
-
/* @__PURE__ */ (0,
|
|
4315
|
-
/* @__PURE__ */ (0,
|
|
4316
|
-
/* @__PURE__ */ (0,
|
|
4317
|
-
/* @__PURE__ */ (0,
|
|
4318
|
-
/* @__PURE__ */ (0,
|
|
4501
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: `flex flex-col gap-2 text-xs text-slate-200 ${className ?? ""}`, "data-testid": "layers-panel", onClick: () => menu && setMenu(null), children: [
|
|
4502
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "flex flex-wrap items-center gap-1", role: "toolbar", "aria-label": "Layer actions", children: [
|
|
4503
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("button", { type: "button", className: iconButton, onClick: () => run("new-layer"), children: "New Layer" }),
|
|
4504
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("button", { type: "button", className: iconButton, onClick: () => run("new-group"), children: "New Group" }),
|
|
4505
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("button", { type: "button", className: iconButton, disabled: !active, onClick: () => run("duplicate"), children: "Duplicate" }),
|
|
4506
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("button", { type: "button", className: iconButton, disabled: !active, onClick: () => run("add-mask"), children: "Add Mask" }),
|
|
4507
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("button", { type: "button", className: iconButton, disabled: !active, onClick: () => run("delete"), children: "Delete" }),
|
|
4508
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
4319
4509
|
"button",
|
|
4320
4510
|
{
|
|
4321
4511
|
type: "button",
|
|
@@ -4330,39 +4520,39 @@ var LayersPanel = ({ controller, thumbnailSize = 32, psd = true, psdFileName = "
|
|
|
4330
4520
|
children: "\u22EF"
|
|
4331
4521
|
}
|
|
4332
4522
|
),
|
|
4333
|
-
psd && /* @__PURE__ */ (0,
|
|
4334
|
-
/* @__PURE__ */ (0,
|
|
4335
|
-
/* @__PURE__ */ (0,
|
|
4336
|
-
/* @__PURE__ */ (0,
|
|
4523
|
+
psd && /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(import_jsx_runtime22.Fragment, { children: [
|
|
4524
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("button", { type: "button", className: iconButton, onClick: () => fileInput.current?.click(), children: "Open PSD\u2026" }),
|
|
4525
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("button", { type: "button", className: iconButton, onClick: () => psdTask(async () => (await (0, import_image_editor7.downloadPsd)(controller, psdFileName)).warnings), children: "Export PSD" }),
|
|
4526
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
4337
4527
|
"input",
|
|
4338
4528
|
{
|
|
4339
4529
|
ref: fileInput,
|
|
4340
4530
|
type: "file",
|
|
4341
|
-
accept:
|
|
4531
|
+
accept: import_image_editor7.PSD_FILE_ACCEPT,
|
|
4342
4532
|
className: "hidden",
|
|
4343
4533
|
"data-testid": "psd-file-input",
|
|
4344
4534
|
"aria-label": "Open a PSD file",
|
|
4345
4535
|
onChange: (e) => {
|
|
4346
4536
|
const file = e.currentTarget.files?.[0];
|
|
4347
4537
|
e.currentTarget.value = "";
|
|
4348
|
-
if (file) psdTask(() => (0,
|
|
4538
|
+
if (file) psdTask(() => (0, import_image_editor7.openPsdFile)(controller, file));
|
|
4349
4539
|
}
|
|
4350
4540
|
}
|
|
4351
4541
|
)
|
|
4352
4542
|
] })
|
|
4353
4543
|
] }),
|
|
4354
|
-
psdNotes.length > 0 && /* @__PURE__ */ (0,
|
|
4355
|
-
psdNotes.map((n) => /* @__PURE__ */ (0,
|
|
4356
|
-
/* @__PURE__ */ (0,
|
|
4544
|
+
psdNotes.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("ul", { className: "rounded bg-amber-900/30 text-amber-200 px-2 py-1 space-y-0.5", "data-testid": "psd-warnings", "aria-label": "PSD warnings", children: [
|
|
4545
|
+
psdNotes.map((n) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("li", { children: n }, n)),
|
|
4546
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("li", { children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("button", { type: "button", className: "underline", onClick: () => setPsdNotes([]), children: "Dismiss" }) })
|
|
4357
4547
|
] }),
|
|
4358
|
-
active && /* @__PURE__ */ (0,
|
|
4359
|
-
/* @__PURE__ */ (0,
|
|
4360
|
-
/* @__PURE__ */ (0,
|
|
4548
|
+
active && /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "grid grid-cols-2 gap-x-2 gap-y-1 items-center", "data-testid": "layer-properties", children: [
|
|
4549
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("label", { className: "flex flex-col gap-0.5", children: [
|
|
4550
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("span", { className: "text-slate-400", children: [
|
|
4361
4551
|
"Opacity ",
|
|
4362
4552
|
Math.round(active.opacity * 100),
|
|
4363
4553
|
"%"
|
|
4364
4554
|
] }),
|
|
4365
|
-
/* @__PURE__ */ (0,
|
|
4555
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
4366
4556
|
"input",
|
|
4367
4557
|
{
|
|
4368
4558
|
type: "range",
|
|
@@ -4376,13 +4566,13 @@ var LayersPanel = ({ controller, thumbnailSize = 32, psd = true, psdFileName = "
|
|
|
4376
4566
|
}
|
|
4377
4567
|
)
|
|
4378
4568
|
] }),
|
|
4379
|
-
/* @__PURE__ */ (0,
|
|
4380
|
-
/* @__PURE__ */ (0,
|
|
4569
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("label", { className: "flex flex-col gap-0.5", children: [
|
|
4570
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("span", { className: "text-slate-400", children: [
|
|
4381
4571
|
"Fill ",
|
|
4382
4572
|
Math.round(((active.type === "pixel" ? active.fillOpacity : void 0) ?? 1) * 100),
|
|
4383
4573
|
"%"
|
|
4384
4574
|
] }),
|
|
4385
|
-
/* @__PURE__ */ (0,
|
|
4575
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
4386
4576
|
"input",
|
|
4387
4577
|
{
|
|
4388
4578
|
type: "range",
|
|
@@ -4397,7 +4587,7 @@ var LayersPanel = ({ controller, thumbnailSize = 32, psd = true, psdFileName = "
|
|
|
4397
4587
|
}
|
|
4398
4588
|
)
|
|
4399
4589
|
] }),
|
|
4400
|
-
/* @__PURE__ */ (0,
|
|
4590
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
|
|
4401
4591
|
"select",
|
|
4402
4592
|
{
|
|
4403
4593
|
"aria-label": "Layer blend mode",
|
|
@@ -4405,13 +4595,13 @@ var LayersPanel = ({ controller, thumbnailSize = 32, psd = true, psdFileName = "
|
|
|
4405
4595
|
value: active.blend,
|
|
4406
4596
|
onChange: (e) => attempt(() => controller.setLayerProperties(active.id, { blend: e.target.value })),
|
|
4407
4597
|
children: [
|
|
4408
|
-
active.type === "group" && /* @__PURE__ */ (0,
|
|
4409
|
-
|
|
4598
|
+
active.type === "group" && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("option", { value: "pass-through", children: "Pass Through" }),
|
|
4599
|
+
import_image_editor7.BLEND_MODES.map((m) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("option", { value: m.id, children: m.label }, m.id))
|
|
4410
4600
|
]
|
|
4411
4601
|
}
|
|
4412
4602
|
),
|
|
4413
|
-
/* @__PURE__ */ (0,
|
|
4414
|
-
/* @__PURE__ */ (0,
|
|
4603
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("label", { className: "flex items-center gap-1.5 text-slate-300", children: [
|
|
4604
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
4415
4605
|
"input",
|
|
4416
4606
|
{
|
|
4417
4607
|
type: "checkbox",
|
|
@@ -4423,8 +4613,8 @@ var LayersPanel = ({ controller, thumbnailSize = 32, psd = true, psdFileName = "
|
|
|
4423
4613
|
),
|
|
4424
4614
|
"Clip to below"
|
|
4425
4615
|
] }),
|
|
4426
|
-
/* @__PURE__ */ (0,
|
|
4427
|
-
/* @__PURE__ */ (0,
|
|
4616
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { className: "col-span-2 flex flex-wrap gap-2 text-slate-400", role: "group", "aria-label": "Layer locks", children: ["pixels", "transparency", "position", "all"].map((k) => /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("label", { className: "flex items-center gap-1", children: [
|
|
4617
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
4428
4618
|
"input",
|
|
4429
4619
|
{
|
|
4430
4620
|
type: "checkbox",
|
|
@@ -4437,9 +4627,10 @@ var LayersPanel = ({ controller, thumbnailSize = 32, psd = true, psdFileName = "
|
|
|
4437
4627
|
k
|
|
4438
4628
|
] }, k)) })
|
|
4439
4629
|
] }),
|
|
4440
|
-
/* @__PURE__ */ (0,
|
|
4630
|
+
effects && active && active.type !== "adjustment" && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(LayerEffectsPanel, { controller, className: "border-t border-slate-800 pt-1.5" }),
|
|
4631
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("ul", { className: "flex flex-col gap-0.5", role: "tree", "aria-label": "Layers", children: rows.map((row) => {
|
|
4441
4632
|
const { layer } = row;
|
|
4442
|
-
return /* @__PURE__ */ (0,
|
|
4633
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
|
|
4443
4634
|
"li",
|
|
4444
4635
|
{
|
|
4445
4636
|
role: "treeitem",
|
|
@@ -4469,7 +4660,7 @@ var LayersPanel = ({ controller, thumbnailSize = 32, psd = true, psdFileName = "
|
|
|
4469
4660
|
className: rowClass(row.active),
|
|
4470
4661
|
style: { paddingLeft: 6 + row.depth * 14 },
|
|
4471
4662
|
children: [
|
|
4472
|
-
/* @__PURE__ */ (0,
|
|
4663
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
4473
4664
|
"button",
|
|
4474
4665
|
{
|
|
4475
4666
|
type: "button",
|
|
@@ -4483,7 +4674,7 @@ var LayersPanel = ({ controller, thumbnailSize = 32, psd = true, psdFileName = "
|
|
|
4483
4674
|
children: layer.visible ? "\u25CF" : "\u25CB"
|
|
4484
4675
|
}
|
|
4485
4676
|
),
|
|
4486
|
-
layer.type === "group" && /* @__PURE__ */ (0,
|
|
4677
|
+
layer.type === "group" && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
4487
4678
|
"button",
|
|
4488
4679
|
{
|
|
4489
4680
|
type: "button",
|
|
@@ -4496,8 +4687,8 @@ var LayersPanel = ({ controller, thumbnailSize = 32, psd = true, psdFileName = "
|
|
|
4496
4687
|
children: layer.collapsed ? "\u25B8" : "\u25BE"
|
|
4497
4688
|
}
|
|
4498
4689
|
),
|
|
4499
|
-
row.clipped && /* @__PURE__ */ (0,
|
|
4500
|
-
layer.type === "pixel" ? /* @__PURE__ */ (0,
|
|
4690
|
+
row.clipped && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "text-slate-500", "aria-label": "Clipped", children: "\u21B3" }),
|
|
4691
|
+
layer.type === "pixel" ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
4501
4692
|
Thumbnail,
|
|
4502
4693
|
{
|
|
4503
4694
|
pixels: thumb(layer),
|
|
@@ -4505,15 +4696,15 @@ var LayersPanel = ({ controller, thumbnailSize = 32, psd = true, psdFileName = "
|
|
|
4505
4696
|
label: `${row.label} pixels`,
|
|
4506
4697
|
selected: row.active && state.activeTarget === "pixels" && Boolean(layer.mask)
|
|
4507
4698
|
}
|
|
4508
|
-
) : /* @__PURE__ */ (0,
|
|
4699
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
4509
4700
|
"span",
|
|
4510
4701
|
{
|
|
4511
4702
|
className: "shrink-0 grid place-items-center rounded bg-slate-800 text-[9px] text-slate-400 ring-1 ring-slate-700",
|
|
4512
4703
|
style: { width: thumbnailSize, height: thumbnailSize },
|
|
4513
|
-
children: (0,
|
|
4704
|
+
children: (0, import_image_editor7.layerBadge)(layer)
|
|
4514
4705
|
}
|
|
4515
4706
|
),
|
|
4516
|
-
layer.mask && /* @__PURE__ */ (0,
|
|
4707
|
+
layer.mask && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
4517
4708
|
Thumbnail,
|
|
4518
4709
|
{
|
|
4519
4710
|
pixels: maskThumb(layer),
|
|
@@ -4528,7 +4719,7 @@ var LayersPanel = ({ controller, thumbnailSize = 32, psd = true, psdFileName = "
|
|
|
4528
4719
|
}
|
|
4529
4720
|
}
|
|
4530
4721
|
),
|
|
4531
|
-
renaming === layer.id ? /* @__PURE__ */ (0,
|
|
4722
|
+
renaming === layer.id ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
4532
4723
|
"input",
|
|
4533
4724
|
{
|
|
4534
4725
|
autoFocus: true,
|
|
@@ -4545,7 +4736,7 @@ var LayersPanel = ({ controller, thumbnailSize = 32, psd = true, psdFileName = "
|
|
|
4545
4736
|
if (e.key === "Escape") setRenaming(null);
|
|
4546
4737
|
}
|
|
4547
4738
|
}
|
|
4548
|
-
) : /* @__PURE__ */ (0,
|
|
4739
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
4549
4740
|
"span",
|
|
4550
4741
|
{
|
|
4551
4742
|
className: `flex-1 min-w-0 truncate ${layer.visible ? "" : "text-slate-500"}`,
|
|
@@ -4556,15 +4747,30 @@ var LayersPanel = ({ controller, thumbnailSize = 32, psd = true, psdFileName = "
|
|
|
4556
4747
|
children: row.label
|
|
4557
4748
|
}
|
|
4558
4749
|
),
|
|
4559
|
-
|
|
4560
|
-
|
|
4750
|
+
(0, import_image_editor7.layerEffectsBadge)(layer) && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
4751
|
+
"button",
|
|
4752
|
+
{
|
|
4753
|
+
type: "button",
|
|
4754
|
+
"data-testid": "layer-fx-badge",
|
|
4755
|
+
"aria-label": (0, import_image_editor7.layerEffectsBadge)(layer) === "on" ? `Turn effects off for ${row.label}` : `Turn effects on for ${row.label}`,
|
|
4756
|
+
"aria-pressed": (0, import_image_editor7.layerEffectsBadge)(layer) === "on",
|
|
4757
|
+
className: `text-[9px] italic font-semibold ${(0, import_image_editor7.layerEffectsBadge)(layer) === "on" ? "text-indigo-300" : "text-slate-600 line-through"}`,
|
|
4758
|
+
onClick: (e) => {
|
|
4759
|
+
e.stopPropagation();
|
|
4760
|
+
attempt(() => controller.setLayerEffectsEnabled(layer.id, (0, import_image_editor7.layerEffectsBadge)(layer) !== "on"));
|
|
4761
|
+
},
|
|
4762
|
+
children: "fx"
|
|
4763
|
+
}
|
|
4764
|
+
),
|
|
4765
|
+
locked(layer) && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { "aria-label": "Locked", className: "text-slate-400", children: "\u{1F512}" }),
|
|
4766
|
+
layer.blend !== "normal" && layer.blend !== "pass-through" && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "text-[9px] text-slate-500", children: layer.blend })
|
|
4561
4767
|
]
|
|
4562
4768
|
},
|
|
4563
4769
|
layer.id
|
|
4564
4770
|
);
|
|
4565
4771
|
}) }),
|
|
4566
|
-
error && /* @__PURE__ */ (0,
|
|
4567
|
-
menu && /* @__PURE__ */ (0,
|
|
4772
|
+
error && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("p", { role: "alert", className: "text-rose-400", children: error }),
|
|
4773
|
+
menu && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
4568
4774
|
"div",
|
|
4569
4775
|
{
|
|
4570
4776
|
role: "menu",
|
|
@@ -4573,7 +4779,7 @@ var LayersPanel = ({ controller, thumbnailSize = 32, psd = true, psdFileName = "
|
|
|
4573
4779
|
style: { left: menu.x, top: menu.y },
|
|
4574
4780
|
onClick: (e) => e.stopPropagation(),
|
|
4575
4781
|
onKeyDown: (e) => e.key === "Escape" && setMenu(null),
|
|
4576
|
-
children: (0,
|
|
4782
|
+
children: (0, import_image_editor7.layerMenu)(controller).map((item) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
4577
4783
|
"button",
|
|
4578
4784
|
{
|
|
4579
4785
|
type: "button",
|
|
@@ -4591,16 +4797,16 @@ var LayersPanel = ({ controller, thumbnailSize = 32, psd = true, psdFileName = "
|
|
|
4591
4797
|
};
|
|
4592
4798
|
|
|
4593
4799
|
// src/image-editor/BrushOptionsBar.tsx
|
|
4594
|
-
var
|
|
4595
|
-
var
|
|
4596
|
-
var
|
|
4800
|
+
var import_react40 = require("react");
|
|
4801
|
+
var import_image_editor8 = require("@pixerate/editor/image-editor");
|
|
4802
|
+
var import_jsx_runtime23 = require("react/jsx-runtime");
|
|
4597
4803
|
var chip = (on) => `px-2 py-1 rounded text-[11px] ${on ? "bg-indigo-600 text-white" : "bg-slate-800 text-slate-300 hover:text-white"}`;
|
|
4598
4804
|
var BrushOptionsBar = ({ controller, className }) => {
|
|
4599
|
-
const [, setTick] = (0,
|
|
4600
|
-
(0,
|
|
4601
|
-
const [error, setError] = (0,
|
|
4805
|
+
const [, setTick] = (0, import_react40.useState)(0);
|
|
4806
|
+
(0, import_react40.useEffect)(() => controller.subscribe(() => setTick((n) => n + 1)), [controller]);
|
|
4807
|
+
const [error, setError] = (0, import_react40.useState)(null);
|
|
4602
4808
|
const state = controller.getState();
|
|
4603
|
-
const { brush, foreground, background } = state.paint;
|
|
4809
|
+
const { brush, foreground, background, mixer, mixerLoad } = state.paint;
|
|
4604
4810
|
const attempt = (fn) => {
|
|
4605
4811
|
try {
|
|
4606
4812
|
setError(null);
|
|
@@ -4609,8 +4815,8 @@ var BrushOptionsBar = ({ controller, className }) => {
|
|
|
4609
4815
|
setError(err instanceof Error ? err.message : String(err));
|
|
4610
4816
|
}
|
|
4611
4817
|
};
|
|
4612
|
-
return /* @__PURE__ */ (0,
|
|
4613
|
-
/* @__PURE__ */ (0,
|
|
4818
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: `flex flex-col gap-2 text-xs text-slate-200 ${className ?? ""}`, "data-testid": "brush-options", children: [
|
|
4819
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "flex gap-1", role: "toolbar", "aria-label": "Paint tools", children: import_image_editor8.PAINT_TOOLS.map((t) => /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
4614
4820
|
"button",
|
|
4615
4821
|
{
|
|
4616
4822
|
type: "button",
|
|
@@ -4622,9 +4828,9 @@ var BrushOptionsBar = ({ controller, className }) => {
|
|
|
4622
4828
|
},
|
|
4623
4829
|
t.id
|
|
4624
4830
|
)) }),
|
|
4625
|
-
/* @__PURE__ */ (0,
|
|
4626
|
-
/* @__PURE__ */ (0,
|
|
4627
|
-
/* @__PURE__ */ (0,
|
|
4831
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex items-center gap-2", role: "group", "aria-label": "Colours", children: [
|
|
4832
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("label", { className: "flex items-center gap-1", children: [
|
|
4833
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
4628
4834
|
"input",
|
|
4629
4835
|
{
|
|
4630
4836
|
type: "color",
|
|
@@ -4634,10 +4840,10 @@ var BrushOptionsBar = ({ controller, className }) => {
|
|
|
4634
4840
|
className: "h-6 w-8 rounded border border-slate-700 bg-transparent"
|
|
4635
4841
|
}
|
|
4636
4842
|
),
|
|
4637
|
-
/* @__PURE__ */ (0,
|
|
4843
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "text-slate-400", children: "FG" })
|
|
4638
4844
|
] }),
|
|
4639
|
-
/* @__PURE__ */ (0,
|
|
4640
|
-
/* @__PURE__ */ (0,
|
|
4845
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("label", { className: "flex items-center gap-1", children: [
|
|
4846
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
4641
4847
|
"input",
|
|
4642
4848
|
{
|
|
4643
4849
|
type: "color",
|
|
@@ -4647,12 +4853,12 @@ var BrushOptionsBar = ({ controller, className }) => {
|
|
|
4647
4853
|
className: "h-6 w-8 rounded border border-slate-700 bg-transparent"
|
|
4648
4854
|
}
|
|
4649
4855
|
),
|
|
4650
|
-
/* @__PURE__ */ (0,
|
|
4856
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "text-slate-400", children: "BG" })
|
|
4651
4857
|
] }),
|
|
4652
|
-
/* @__PURE__ */ (0,
|
|
4653
|
-
/* @__PURE__ */ (0,
|
|
4858
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("button", { type: "button", title: "Swap colours (X)", className: chip(false), onClick: () => controller.swapPaintColors(), children: "Swap" }),
|
|
4859
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("button", { type: "button", title: "Default colours (D)", className: chip(false), onClick: () => controller.resetPaintColors(), children: "Default" })
|
|
4654
4860
|
] }),
|
|
4655
|
-
|
|
4861
|
+
import_image_editor8.BRUSH_OPTION_CONTROLS.map((spec) => /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
4656
4862
|
ControlSlider,
|
|
4657
4863
|
{
|
|
4658
4864
|
spec,
|
|
@@ -4661,9 +4867,65 @@ var BrushOptionsBar = ({ controller, className }) => {
|
|
|
4661
4867
|
},
|
|
4662
4868
|
spec.id
|
|
4663
4869
|
)),
|
|
4664
|
-
/* @__PURE__ */ (0,
|
|
4665
|
-
/* @__PURE__ */ (0,
|
|
4666
|
-
/* @__PURE__ */ (0,
|
|
4870
|
+
state.activeTool === "mixer" && /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex flex-col gap-2 border-t border-slate-800 pt-2", role: "group", "aria-label": "Mixer Brush", "data-testid": "mixer-options", children: [
|
|
4871
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
4872
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
4873
|
+
"span",
|
|
4874
|
+
{
|
|
4875
|
+
"aria-label": "Brush load",
|
|
4876
|
+
title: mixerLoad.reservoir ? `Loaded ${(0, import_image_editor8.rgbUnitToHex)(mixerLoad.reservoir)}, ${Math.round(mixerLoad.amount * 100)}% left` : "Unloaded",
|
|
4877
|
+
className: "h-6 w-6 rounded border border-slate-700",
|
|
4878
|
+
style: { background: mixerLoad.reservoir ? (0, import_image_editor8.rgbUnitToHex)(mixerLoad.reservoir) : "transparent" }
|
|
4879
|
+
}
|
|
4880
|
+
),
|
|
4881
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("button", { type: "button", title: "Fill the reservoir with the foreground colour", className: chip(false), onClick: () => controller.loadMixerBrush(), children: "Load brush" }),
|
|
4882
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("button", { type: "button", title: "Empty the picked-up colour", className: chip(false), onClick: () => controller.cleanMixerBrush(), children: "Clean brush" })
|
|
4883
|
+
] }),
|
|
4884
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "flex gap-1", role: "group", "aria-label": "Mixing", children: import_image_editor8.MIXER_MIXING_OPTIONS.map((m) => /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
4885
|
+
"button",
|
|
4886
|
+
{
|
|
4887
|
+
type: "button",
|
|
4888
|
+
"aria-pressed": mixer.mixing === m.id,
|
|
4889
|
+
title: m.title,
|
|
4890
|
+
className: chip(mixer.mixing === m.id),
|
|
4891
|
+
onClick: () => controller.setPaintOptions({ mixer: { mixing: m.id } }),
|
|
4892
|
+
children: m.label
|
|
4893
|
+
},
|
|
4894
|
+
m.id
|
|
4895
|
+
)) }),
|
|
4896
|
+
import_image_editor8.MIXER_OPTION_CONTROLS.map((spec) => /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(ControlSlider, { spec, value: mixer[spec.id], onChange: (v) => controller.setPaintOptions({ mixer: { [spec.id]: v } }) }, spec.id)),
|
|
4897
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex flex-wrap gap-3 text-slate-300", children: [
|
|
4898
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("label", { className: "flex items-center gap-1.5", children: [
|
|
4899
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
4900
|
+
"input",
|
|
4901
|
+
{
|
|
4902
|
+
type: "checkbox",
|
|
4903
|
+
"aria-label": "Load the brush after each stroke",
|
|
4904
|
+
checked: mixer.loadEachStroke,
|
|
4905
|
+
onChange: (e) => controller.setPaintOptions({ mixer: { loadEachStroke: e.target.checked } }),
|
|
4906
|
+
className: "accent-indigo-500"
|
|
4907
|
+
}
|
|
4908
|
+
),
|
|
4909
|
+
"Load each stroke"
|
|
4910
|
+
] }),
|
|
4911
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("label", { className: "flex items-center gap-1.5", children: [
|
|
4912
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
4913
|
+
"input",
|
|
4914
|
+
{
|
|
4915
|
+
type: "checkbox",
|
|
4916
|
+
"aria-label": "Clean the brush after each stroke",
|
|
4917
|
+
checked: mixer.cleanEachStroke,
|
|
4918
|
+
onChange: (e) => controller.setPaintOptions({ mixer: { cleanEachStroke: e.target.checked } }),
|
|
4919
|
+
className: "accent-indigo-500"
|
|
4920
|
+
}
|
|
4921
|
+
),
|
|
4922
|
+
"Clean each stroke"
|
|
4923
|
+
] })
|
|
4924
|
+
] })
|
|
4925
|
+
] }),
|
|
4926
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex flex-wrap gap-3 text-slate-300", role: "group", "aria-label": "Pressure", children: [
|
|
4927
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("label", { className: "flex items-center gap-1.5", children: [
|
|
4928
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
4667
4929
|
"input",
|
|
4668
4930
|
{
|
|
4669
4931
|
type: "checkbox",
|
|
@@ -4675,8 +4937,8 @@ var BrushOptionsBar = ({ controller, className }) => {
|
|
|
4675
4937
|
),
|
|
4676
4938
|
"Pressure size"
|
|
4677
4939
|
] }),
|
|
4678
|
-
/* @__PURE__ */ (0,
|
|
4679
|
-
/* @__PURE__ */ (0,
|
|
4940
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("label", { className: "flex items-center gap-1.5", children: [
|
|
4941
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
4680
4942
|
"input",
|
|
4681
4943
|
{
|
|
4682
4944
|
type: "checkbox",
|
|
@@ -4689,18 +4951,18 @@ var BrushOptionsBar = ({ controller, className }) => {
|
|
|
4689
4951
|
"Pressure opacity"
|
|
4690
4952
|
] })
|
|
4691
4953
|
] }),
|
|
4692
|
-
/* @__PURE__ */ (0,
|
|
4693
|
-
/* @__PURE__ */ (0,
|
|
4694
|
-
/* @__PURE__ */ (0,
|
|
4954
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex gap-1", children: [
|
|
4955
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("button", { type: "button", className: chip(false), onClick: () => attempt(() => controller.fillPixels()), children: "Fill" }),
|
|
4956
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("button", { type: "button", className: chip(false), onClick: () => attempt(() => controller.clearPixels()), children: "Clear" })
|
|
4695
4957
|
] }),
|
|
4696
|
-
error && /* @__PURE__ */ (0,
|
|
4958
|
+
error && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("p", { role: "alert", className: "text-rose-400", children: error })
|
|
4697
4959
|
] });
|
|
4698
4960
|
};
|
|
4699
4961
|
|
|
4700
4962
|
// src/image-editor/SelectionOptionsBar.tsx
|
|
4701
|
-
var
|
|
4702
|
-
var
|
|
4703
|
-
var
|
|
4963
|
+
var import_react41 = require("react");
|
|
4964
|
+
var import_image_editor9 = require("@pixerate/editor/image-editor");
|
|
4965
|
+
var import_jsx_runtime24 = require("react/jsx-runtime");
|
|
4704
4966
|
var MODIFY_OPS = [
|
|
4705
4967
|
{ op: "grow", label: "Grow" },
|
|
4706
4968
|
{ op: "shrink", label: "Shrink" },
|
|
@@ -4717,20 +4979,20 @@ var SelectionOptionsBar = ({
|
|
|
4717
4979
|
quickMask,
|
|
4718
4980
|
className = ""
|
|
4719
4981
|
}) => {
|
|
4720
|
-
const [radius, setRadius] = (0,
|
|
4982
|
+
const [radius, setRadius] = (0, import_react41.useState)(2);
|
|
4721
4983
|
const set = (patch) => onOptionsChange({ ...options, ...patch });
|
|
4722
4984
|
const sel = selection === void 0 ? controller.getSelection() : selection;
|
|
4723
4985
|
const qm = quickMask ?? Boolean(controller.getState().quickMask);
|
|
4724
|
-
return /* @__PURE__ */ (0,
|
|
4725
|
-
/* @__PURE__ */ (0,
|
|
4726
|
-
/* @__PURE__ */ (0,
|
|
4727
|
-
options.tool === "wand" && /* @__PURE__ */ (0,
|
|
4728
|
-
/* @__PURE__ */ (0,
|
|
4729
|
-
/* @__PURE__ */ (0,
|
|
4730
|
-
/* @__PURE__ */ (0,
|
|
4731
|
-
/* @__PURE__ */ (0,
|
|
4986
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { "data-testid": "selection-options-bar", className: `flex flex-col gap-3 text-xs ${className}`, children: [
|
|
4987
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { role: "group", "aria-label": "Selection tool", className: "flex flex-wrap gap-1", children: import_image_editor9.SELECTION_TOOLS.map((t) => /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("button", { type: "button", "aria-pressed": options.tool === t.id, className: btn(options.tool === t.id), onClick: () => set({ tool: t.id }), children: t.label }, t.id)) }),
|
|
4988
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { role: "group", "aria-label": "Selection mode", className: "flex flex-wrap gap-1", children: import_image_editor9.SELECTION_MODES.map((m) => /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("button", { type: "button", "aria-pressed": options.mode === m, className: btn(options.mode === m), onClick: () => set({ mode: m }), children: import_image_editor9.SELECTION_MODE_LABELS[m] }, m)) }),
|
|
4989
|
+
options.tool === "wand" && /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "flex flex-col gap-2", children: [
|
|
4990
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("label", { className: "flex flex-col gap-1", children: [
|
|
4991
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("span", { className: "flex justify-between text-slate-400", children: [
|
|
4992
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { children: "Tolerance" }),
|
|
4993
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { className: "font-mono", children: options.tolerance })
|
|
4732
4994
|
] }),
|
|
4733
|
-
/* @__PURE__ */ (0,
|
|
4995
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
4734
4996
|
"input",
|
|
4735
4997
|
{
|
|
4736
4998
|
type: "range",
|
|
@@ -4744,17 +5006,17 @@ var SelectionOptionsBar = ({
|
|
|
4744
5006
|
}
|
|
4745
5007
|
)
|
|
4746
5008
|
] }),
|
|
4747
|
-
/* @__PURE__ */ (0,
|
|
4748
|
-
/* @__PURE__ */ (0,
|
|
5009
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("label", { className: "flex items-center gap-2 text-slate-300", children: [
|
|
5010
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)("input", { type: "checkbox", checked: options.contiguous, onChange: (e) => set({ contiguous: e.target.checked }) }),
|
|
4749
5011
|
"Contiguous"
|
|
4750
5012
|
] }),
|
|
4751
|
-
/* @__PURE__ */ (0,
|
|
4752
|
-
/* @__PURE__ */ (0,
|
|
5013
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("label", { className: "flex items-center gap-2 text-slate-300", children: [
|
|
5014
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)("input", { type: "checkbox", checked: options.sampleMerged, onChange: (e) => set({ sampleMerged: e.target.checked }) }),
|
|
4753
5015
|
"Sample adjusted image"
|
|
4754
5016
|
] }),
|
|
4755
|
-
/* @__PURE__ */ (0,
|
|
5017
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("label", { className: "flex items-center gap-2 text-slate-300", children: [
|
|
4756
5018
|
"Sample",
|
|
4757
|
-
/* @__PURE__ */ (0,
|
|
5019
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(
|
|
4758
5020
|
"select",
|
|
4759
5021
|
{
|
|
4760
5022
|
"aria-label": "Sample from",
|
|
@@ -4762,27 +5024,27 @@ var SelectionOptionsBar = ({
|
|
|
4762
5024
|
onChange: (e) => set({ sample: e.target.value }),
|
|
4763
5025
|
className: "bg-slate-800 border border-slate-700 rounded px-1 py-0.5",
|
|
4764
5026
|
children: [
|
|
4765
|
-
/* @__PURE__ */ (0,
|
|
4766
|
-
/* @__PURE__ */ (0,
|
|
5027
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)("option", { value: "composite", children: "All layers" }),
|
|
5028
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)("option", { value: "active-layer", children: "Active layer" })
|
|
4767
5029
|
]
|
|
4768
5030
|
}
|
|
4769
5031
|
)
|
|
4770
5032
|
] })
|
|
4771
5033
|
] }),
|
|
4772
|
-
/* @__PURE__ */ (0,
|
|
4773
|
-
/* @__PURE__ */ (0,
|
|
5034
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("label", { className: "flex items-center gap-2 text-slate-300", children: [
|
|
5035
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)("input", { type: "checkbox", checked: options.antiAlias, onChange: (e) => set({ antiAlias: e.target.checked }) }),
|
|
4774
5036
|
"Anti-alias"
|
|
4775
5037
|
] }),
|
|
4776
|
-
/* @__PURE__ */ (0,
|
|
4777
|
-
/* @__PURE__ */ (0,
|
|
4778
|
-
/* @__PURE__ */ (0,
|
|
4779
|
-
/* @__PURE__ */ (0,
|
|
4780
|
-
/* @__PURE__ */ (0,
|
|
5038
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "flex flex-wrap gap-1", children: [
|
|
5039
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)("button", { type: "button", className: btn(false), onClick: () => controller.selectAll(), children: "Select All" }),
|
|
5040
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)("button", { type: "button", className: btn(false), disabled: !sel, onClick: () => controller.deselect(), children: "Deselect" }),
|
|
5041
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)("button", { type: "button", className: btn(false), onClick: () => controller.invertSelection(), children: "Inverse" }),
|
|
5042
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)("button", { type: "button", "aria-pressed": qm, className: btn(qm), onClick: () => controller.setQuickMask(!qm), children: "Quick Mask" })
|
|
4781
5043
|
] }),
|
|
4782
|
-
/* @__PURE__ */ (0,
|
|
4783
|
-
/* @__PURE__ */ (0,
|
|
5044
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "flex flex-wrap items-center gap-1", children: [
|
|
5045
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("label", { className: "flex items-center gap-1 text-slate-400", children: [
|
|
4784
5046
|
"Radius",
|
|
4785
|
-
/* @__PURE__ */ (0,
|
|
5047
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
4786
5048
|
"input",
|
|
4787
5049
|
{
|
|
4788
5050
|
type: "number",
|
|
@@ -4796,24 +5058,24 @@ var SelectionOptionsBar = ({
|
|
|
4796
5058
|
}
|
|
4797
5059
|
)
|
|
4798
5060
|
] }),
|
|
4799
|
-
MODIFY_OPS.map(({ op, label }) => /* @__PURE__ */ (0,
|
|
5061
|
+
MODIFY_OPS.map(({ op, label }) => /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("button", { type: "button", className: btn(false), disabled: !sel, onClick: () => controller.modifySelection(op, radius), children: label }, op))
|
|
4800
5062
|
] }),
|
|
4801
|
-
/* @__PURE__ */ (0,
|
|
5063
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)("p", { "data-testid": "selection-status", className: "text-slate-400", children: (0, import_image_editor9.describeSelection)(sel) })
|
|
4802
5064
|
] });
|
|
4803
5065
|
};
|
|
4804
5066
|
|
|
4805
5067
|
// src/image-editor/RefineEdgePanel.tsx
|
|
4806
|
-
var
|
|
4807
|
-
var
|
|
4808
|
-
var
|
|
5068
|
+
var import_react42 = require("react");
|
|
5069
|
+
var import_image_editor10 = require("@pixerate/editor/image-editor");
|
|
5070
|
+
var import_jsx_runtime25 = require("react/jsx-runtime");
|
|
4809
5071
|
var DEFAULT_PARAMS = { radius: 8, smartRadius: false, smooth: 0, feather: 0, contrast: 0, shiftEdge: 0 };
|
|
4810
|
-
var
|
|
5072
|
+
var button2 = "px-2 py-1 rounded-md border border-slate-800 bg-slate-950 text-[11px] text-slate-200 hover:text-white disabled:opacity-40";
|
|
4811
5073
|
var RefineEdgePanel = ({ controller, selection, layers, className = "" }) => {
|
|
4812
|
-
const [params, setParams] = (0,
|
|
4813
|
-
const [busy, setBusy] = (0,
|
|
4814
|
-
const [error, setError] = (0,
|
|
4815
|
-
const [layerId, setLayerId] = (0,
|
|
4816
|
-
const [newKind, setNewKind] = (0,
|
|
5074
|
+
const [params, setParams] = (0, import_react42.useState)(DEFAULT_PARAMS);
|
|
5075
|
+
const [busy, setBusy] = (0, import_react42.useState)(false);
|
|
5076
|
+
const [error, setError] = (0, import_react42.useState)(null);
|
|
5077
|
+
const [layerId, setLayerId] = (0, import_react42.useState)("");
|
|
5078
|
+
const [newKind, setNewKind] = (0, import_react42.useState)("hueSaturation");
|
|
4817
5079
|
const sel = selection === void 0 ? controller.getSelection() : selection;
|
|
4818
5080
|
const list = layers ?? controller.getAdjustmentLayers();
|
|
4819
5081
|
const target = list.find((l) => l.id === layerId) ?? list[list.length - 1];
|
|
@@ -4828,17 +5090,17 @@ var RefineEdgePanel = ({ controller, selection, layers, className = "" }) => {
|
|
|
4828
5090
|
setBusy(false);
|
|
4829
5091
|
}
|
|
4830
5092
|
};
|
|
4831
|
-
return /* @__PURE__ */ (0,
|
|
4832
|
-
/* @__PURE__ */ (0,
|
|
4833
|
-
|
|
4834
|
-
/* @__PURE__ */ (0,
|
|
4835
|
-
/* @__PURE__ */ (0,
|
|
4836
|
-
/* @__PURE__ */ (0,
|
|
5093
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { "data-testid": "refine-edge-panel", className: `flex flex-col gap-3 text-xs ${className}`, children: [
|
|
5094
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Refine Edge" }),
|
|
5095
|
+
import_image_editor10.REFINE_EDGE_CONTROLS.map((c) => /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("label", { className: "flex flex-col gap-1", children: [
|
|
5096
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("span", { className: "flex justify-between text-slate-400", children: [
|
|
5097
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { children: c.label }),
|
|
5098
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("span", { className: "font-mono", children: [
|
|
4837
5099
|
params[c.id],
|
|
4838
5100
|
c.unit
|
|
4839
5101
|
] })
|
|
4840
5102
|
] }),
|
|
4841
|
-
/* @__PURE__ */ (0,
|
|
5103
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
4842
5104
|
"input",
|
|
4843
5105
|
{
|
|
4844
5106
|
type: "range",
|
|
@@ -4852,67 +5114,67 @@ var RefineEdgePanel = ({ controller, selection, layers, className = "" }) => {
|
|
|
4852
5114
|
}
|
|
4853
5115
|
)
|
|
4854
5116
|
] }, c.id)),
|
|
4855
|
-
/* @__PURE__ */ (0,
|
|
4856
|
-
/* @__PURE__ */ (0,
|
|
5117
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("label", { className: "flex items-center gap-2 text-slate-300", children: [
|
|
5118
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("input", { type: "checkbox", checked: params.smartRadius, onChange: (e) => setParams({ ...params, smartRadius: e.target.checked }) }),
|
|
4857
5119
|
"Smart Radius"
|
|
4858
5120
|
] }),
|
|
4859
|
-
/* @__PURE__ */ (0,
|
|
4860
|
-
/* @__PURE__ */ (0,
|
|
4861
|
-
/* @__PURE__ */ (0,
|
|
5121
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "flex gap-1", children: [
|
|
5122
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("button", { type: "button", className: button2, disabled: !sel || busy, onClick: refine, children: "Refine Edge" }),
|
|
5123
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("button", { type: "button", className: button2, onClick: () => setParams(DEFAULT_PARAMS), children: "Reset" })
|
|
4862
5124
|
] }),
|
|
4863
|
-
error && /* @__PURE__ */ (0,
|
|
4864
|
-
/* @__PURE__ */ (0,
|
|
4865
|
-
/* @__PURE__ */ (0,
|
|
4866
|
-
/* @__PURE__ */ (0,
|
|
5125
|
+
error && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("p", { role: "alert", className: "text-rose-400", children: error }),
|
|
5126
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px] mt-2", children: "Layer Mask" }),
|
|
5127
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "flex gap-1 items-center", children: [
|
|
5128
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
4867
5129
|
"select",
|
|
4868
5130
|
{
|
|
4869
5131
|
"aria-label": "New masked layer kind",
|
|
4870
5132
|
value: newKind,
|
|
4871
5133
|
onChange: (e) => setNewKind(e.target.value),
|
|
4872
5134
|
className: "flex-1 bg-slate-950 border border-slate-800 rounded px-1 py-1 text-slate-200",
|
|
4873
|
-
children:
|
|
5135
|
+
children: import_image_editor10.ADJUSTMENT_KINDS.map((k) => /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("option", { value: k.kind, children: k.label }, k.kind))
|
|
4874
5136
|
}
|
|
4875
5137
|
),
|
|
4876
|
-
/* @__PURE__ */ (0,
|
|
5138
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
4877
5139
|
"button",
|
|
4878
5140
|
{
|
|
4879
5141
|
type: "button",
|
|
4880
|
-
className:
|
|
5142
|
+
className: button2,
|
|
4881
5143
|
disabled: !sel,
|
|
4882
|
-
onClick: () => sel && setLayerId(controller.addAdjustmentLayer({ kind: newKind, mask: (0,
|
|
5144
|
+
onClick: () => sel && setLayerId(controller.addAdjustmentLayer({ kind: newKind, mask: (0, import_image_editor10.layerMaskFromSelection)(sel) })),
|
|
4883
5145
|
children: "New Masked Layer"
|
|
4884
5146
|
}
|
|
4885
5147
|
)
|
|
4886
5148
|
] }),
|
|
4887
|
-
list.length > 0 && target && /* @__PURE__ */ (0,
|
|
4888
|
-
/* @__PURE__ */ (0,
|
|
5149
|
+
list.length > 0 && target && /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "flex flex-col gap-2", children: [
|
|
5150
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
4889
5151
|
"select",
|
|
4890
5152
|
{
|
|
4891
5153
|
"aria-label": "Mask layer",
|
|
4892
5154
|
value: target.id,
|
|
4893
5155
|
onChange: (e) => setLayerId(e.target.value),
|
|
4894
5156
|
className: "bg-slate-950 border border-slate-800 rounded px-1 py-1 text-slate-200",
|
|
4895
|
-
children: list.map((l) => /* @__PURE__ */ (0,
|
|
4896
|
-
l.name || (0,
|
|
5157
|
+
children: list.map((l) => /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("option", { value: l.id, children: [
|
|
5158
|
+
l.name || (0, import_image_editor10.adjustmentKindLabel)(l.kind),
|
|
4897
5159
|
l.mask ? " (masked)" : ""
|
|
4898
5160
|
] }, l.id))
|
|
4899
5161
|
}
|
|
4900
5162
|
),
|
|
4901
|
-
/* @__PURE__ */ (0,
|
|
4902
|
-
/* @__PURE__ */ (0,
|
|
4903
|
-
/* @__PURE__ */ (0,
|
|
4904
|
-
/* @__PURE__ */ (0,
|
|
5163
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "flex flex-wrap gap-1", children: [
|
|
5164
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("button", { type: "button", className: button2, disabled: !sel, onClick: () => controller.applySelectionAsLayerMask(target.id), children: "Mask with Selection" }),
|
|
5165
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("button", { type: "button", className: button2, disabled: !target.mask, onClick: () => controller.selectionFromLayerMask(target.id), children: "Load as Selection" }),
|
|
5166
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("button", { type: "button", className: button2, disabled: !target.mask, onClick: () => controller.setAdjustmentLayerMask(target.id, null), children: "Remove Mask" })
|
|
4905
5167
|
] }),
|
|
4906
|
-
target.mask && /* @__PURE__ */ (0,
|
|
4907
|
-
/* @__PURE__ */ (0,
|
|
4908
|
-
/* @__PURE__ */ (0,
|
|
4909
|
-
/* @__PURE__ */ (0,
|
|
4910
|
-
/* @__PURE__ */ (0,
|
|
5168
|
+
target.mask && /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(import_jsx_runtime25.Fragment, { children: [
|
|
5169
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("label", { className: "flex flex-col gap-1", children: [
|
|
5170
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("span", { className: "flex justify-between text-slate-400", children: [
|
|
5171
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { children: "Density" }),
|
|
5172
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("span", { className: "font-mono", children: [
|
|
4911
5173
|
Math.round((target.mask.density ?? 1) * 100),
|
|
4912
5174
|
"%"
|
|
4913
5175
|
] })
|
|
4914
5176
|
] }),
|
|
4915
|
-
/* @__PURE__ */ (0,
|
|
5177
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
4916
5178
|
"input",
|
|
4917
5179
|
{
|
|
4918
5180
|
type: "range",
|
|
@@ -4926,15 +5188,15 @@ var RefineEdgePanel = ({ controller, selection, layers, className = "" }) => {
|
|
|
4926
5188
|
}
|
|
4927
5189
|
)
|
|
4928
5190
|
] }),
|
|
4929
|
-
/* @__PURE__ */ (0,
|
|
4930
|
-
/* @__PURE__ */ (0,
|
|
4931
|
-
/* @__PURE__ */ (0,
|
|
4932
|
-
/* @__PURE__ */ (0,
|
|
5191
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("label", { className: "flex flex-col gap-1", children: [
|
|
5192
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("span", { className: "flex justify-between text-slate-400", children: [
|
|
5193
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { children: "Mask Feather" }),
|
|
5194
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("span", { className: "font-mono", children: [
|
|
4933
5195
|
target.mask.feather ?? 0,
|
|
4934
5196
|
"px"
|
|
4935
5197
|
] })
|
|
4936
5198
|
] }),
|
|
4937
|
-
/* @__PURE__ */ (0,
|
|
5199
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
4938
5200
|
"input",
|
|
4939
5201
|
{
|
|
4940
5202
|
type: "range",
|
|
@@ -4954,7 +5216,7 @@ var RefineEdgePanel = ({ controller, selection, layers, className = "" }) => {
|
|
|
4954
5216
|
};
|
|
4955
5217
|
|
|
4956
5218
|
// src/image-editor/ImageEditor.tsx
|
|
4957
|
-
var
|
|
5219
|
+
var import_jsx_runtime26 = require("react/jsx-runtime");
|
|
4958
5220
|
var ImageEditor = ({
|
|
4959
5221
|
editor: externalEditor,
|
|
4960
5222
|
src,
|
|
@@ -4969,35 +5231,35 @@ var ImageEditor = ({
|
|
|
4969
5231
|
const internalEditor = useImageEditor({ image: src });
|
|
4970
5232
|
const editor = externalEditor || internalEditor;
|
|
4971
5233
|
const { state, controller } = editor;
|
|
4972
|
-
const legacyProcess = (0,
|
|
4973
|
-
const canvasRef = (0,
|
|
4974
|
-
const containerRef = (0,
|
|
4975
|
-
const [activeTab, setActiveTab] = (0,
|
|
4976
|
-
const [activeCropRatio, setActiveCropRatio] = (0,
|
|
4977
|
-
const [selectionOptions, setSelectionOptions] = (0,
|
|
4978
|
-
const selectionOptionsRef = (0,
|
|
5234
|
+
const legacyProcess = (0, import_image_editor11.normalizeProcessVersion)(state.adjustments.process) < import_image_editor11.LATEST_PROCESS_VERSION;
|
|
5235
|
+
const canvasRef = (0, import_react43.useRef)(null);
|
|
5236
|
+
const containerRef = (0, import_react43.useRef)(null);
|
|
5237
|
+
const [activeTab, setActiveTab] = (0, import_react43.useState)("crop");
|
|
5238
|
+
const [activeCropRatio, setActiveCropRatio] = (0, import_react43.useState)(null);
|
|
5239
|
+
const [selectionOptions, setSelectionOptions] = (0, import_react43.useState)(import_image_editor11.DEFAULT_SELECTION_TOOL_OPTIONS);
|
|
5240
|
+
const selectionOptionsRef = (0, import_react43.useRef)(selectionOptions);
|
|
4979
5241
|
selectionOptionsRef.current = selectionOptions;
|
|
4980
|
-
const selectionGestureRef = (0,
|
|
5242
|
+
const selectionGestureRef = (0, import_react43.useRef)(null);
|
|
4981
5243
|
if (!selectionGestureRef.current || selectionGestureRef.current.controller !== controller) {
|
|
4982
|
-
selectionGestureRef.current = new
|
|
5244
|
+
selectionGestureRef.current = new import_image_editor11.SelectionGesture(controller, () => selectionOptionsRef.current);
|
|
4983
5245
|
}
|
|
4984
|
-
const selectionDraftRef = (0,
|
|
4985
|
-
const [selectionError, setSelectionError] = (0,
|
|
4986
|
-
const paintGestureRef = (0,
|
|
4987
|
-
const paintControllerRef = (0,
|
|
5246
|
+
const selectionDraftRef = (0, import_react43.useRef)(null);
|
|
5247
|
+
const [selectionError, setSelectionError] = (0, import_react43.useState)(null);
|
|
5248
|
+
const paintGestureRef = (0, import_react43.useRef)(null);
|
|
5249
|
+
const paintControllerRef = (0, import_react43.useRef)(controller);
|
|
4988
5250
|
if (!paintGestureRef.current || paintControllerRef.current !== controller) {
|
|
4989
|
-
paintGestureRef.current = new
|
|
5251
|
+
paintGestureRef.current = new import_image_editor11.PaintGesture(controller);
|
|
4990
5252
|
paintControllerRef.current = controller;
|
|
4991
5253
|
}
|
|
4992
|
-
const brushCursorRef = (0,
|
|
4993
|
-
const [paintError, setPaintError] = (0,
|
|
4994
|
-
const [inpaintPrompt, setInpaintPrompt] = (0,
|
|
4995
|
-
const [inpaintMaskMode, setInpaintMaskMode] = (0,
|
|
4996
|
-
const [isRemovingBg, setIsRemovingBg] = (0,
|
|
4997
|
-
const [isInpainting, setIsInpainting] = (0,
|
|
4998
|
-
const [aiError, setAiError] = (0,
|
|
4999
|
-
const [aiSuccess, setAiSuccess] = (0,
|
|
5000
|
-
const [aiTarget, setAiTarget] = (0,
|
|
5254
|
+
const brushCursorRef = (0, import_react43.useRef)(null);
|
|
5255
|
+
const [paintError, setPaintError] = (0, import_react43.useState)(null);
|
|
5256
|
+
const [inpaintPrompt, setInpaintPrompt] = (0, import_react43.useState)("");
|
|
5257
|
+
const [inpaintMaskMode, setInpaintMaskMode] = (0, import_react43.useState)("annotations");
|
|
5258
|
+
const [isRemovingBg, setIsRemovingBg] = (0, import_react43.useState)(false);
|
|
5259
|
+
const [isInpainting, setIsInpainting] = (0, import_react43.useState)(false);
|
|
5260
|
+
const [aiError, setAiError] = (0, import_react43.useState)(null);
|
|
5261
|
+
const [aiSuccess, setAiSuccess] = (0, import_react43.useState)(null);
|
|
5262
|
+
const [aiTarget, setAiTarget] = (0, import_react43.useState)("auto");
|
|
5001
5263
|
const aiOptions = aiTarget === "auto" ? {} : { target: aiTarget };
|
|
5002
5264
|
const effectiveOnInpaint = onInpaint || aiHooks?.onInpaint;
|
|
5003
5265
|
const effectiveOnRemoveBg = onRemoveBackground || aiHooks?.onRemoveBackground;
|
|
@@ -5060,18 +5322,18 @@ var ImageEditor = ({
|
|
|
5060
5322
|
setIsInpainting(false);
|
|
5061
5323
|
}
|
|
5062
5324
|
};
|
|
5063
|
-
const [activeColor, setActiveColor] = (0,
|
|
5064
|
-
const [strokeWidth, setStrokeWidth] = (0,
|
|
5065
|
-
const [fontSize, setFontSize] = (0,
|
|
5066
|
-
const [textInput, setTextInput] = (0,
|
|
5067
|
-
const draftAnnotationRef = (0,
|
|
5068
|
-
const draftCropRef = (0,
|
|
5069
|
-
const cropDragInfoRef = (0,
|
|
5070
|
-
const annotationDragInfoRef = (0,
|
|
5071
|
-
const isDrawingRef = (0,
|
|
5072
|
-
const currentPathRef = (0,
|
|
5073
|
-
const dragStartPointRef = (0,
|
|
5074
|
-
const renderCanvas = (0,
|
|
5325
|
+
const [activeColor, setActiveColor] = (0, import_react43.useState)("#ef4444");
|
|
5326
|
+
const [strokeWidth, setStrokeWidth] = (0, import_react43.useState)(3);
|
|
5327
|
+
const [fontSize, setFontSize] = (0, import_react43.useState)(24);
|
|
5328
|
+
const [textInput, setTextInput] = (0, import_react43.useState)("");
|
|
5329
|
+
const draftAnnotationRef = (0, import_react43.useRef)(null);
|
|
5330
|
+
const draftCropRef = (0, import_react43.useRef)(null);
|
|
5331
|
+
const cropDragInfoRef = (0, import_react43.useRef)(null);
|
|
5332
|
+
const annotationDragInfoRef = (0, import_react43.useRef)(null);
|
|
5333
|
+
const isDrawingRef = (0, import_react43.useRef)(false);
|
|
5334
|
+
const currentPathRef = (0, import_react43.useRef)([]);
|
|
5335
|
+
const dragStartPointRef = (0, import_react43.useRef)(null);
|
|
5336
|
+
const renderCanvas = (0, import_react43.useCallback)(
|
|
5075
5337
|
async (draftAnnotation, draftCrop) => {
|
|
5076
5338
|
const canvas = canvasRef.current;
|
|
5077
5339
|
const container = containerRef.current;
|
|
@@ -5092,7 +5354,7 @@ var ImageEditor = ({
|
|
|
5092
5354
|
},
|
|
5093
5355
|
[controller, activeTab]
|
|
5094
5356
|
);
|
|
5095
|
-
(0,
|
|
5357
|
+
(0, import_react43.useEffect)(() => {
|
|
5096
5358
|
const raf = typeof requestAnimationFrame !== "undefined" ? requestAnimationFrame : (cb) => setTimeout(cb, 0);
|
|
5097
5359
|
const caf = typeof cancelAnimationFrame !== "undefined" ? cancelAnimationFrame : (id) => clearTimeout(id);
|
|
5098
5360
|
const animId = raf(() => {
|
|
@@ -5100,12 +5362,12 @@ var ImageEditor = ({
|
|
|
5100
5362
|
});
|
|
5101
5363
|
return () => caf(animId);
|
|
5102
5364
|
}, [renderCanvas, state]);
|
|
5103
|
-
(0,
|
|
5365
|
+
(0, import_react43.useEffect)(() => {
|
|
5104
5366
|
if (activeTab === "crop" && editor.state.activeTool !== "crop") {
|
|
5105
5367
|
editor.setTool("crop");
|
|
5106
5368
|
}
|
|
5107
5369
|
}, [activeTab, editor]);
|
|
5108
|
-
(0,
|
|
5370
|
+
(0, import_react43.useEffect)(() => {
|
|
5109
5371
|
const container = containerRef.current;
|
|
5110
5372
|
if (!container) return;
|
|
5111
5373
|
if (typeof ResizeObserver !== "undefined") {
|
|
@@ -5141,8 +5403,8 @@ var ImageEditor = ({
|
|
|
5141
5403
|
const sy = rect.height > 0 ? canvas.height / rect.height : 1;
|
|
5142
5404
|
const s = controller.getState();
|
|
5143
5405
|
return list.map((ev) => ({
|
|
5144
|
-
...(0,
|
|
5145
|
-
pressure: (0,
|
|
5406
|
+
...(0, import_image_editor11.canvasToImagePoint)({ x: (ev.clientX - rect.left) * sx, y: (ev.clientY - rect.top) * sy }, s, canvas.width, canvas.height, false),
|
|
5407
|
+
pressure: (0, import_image_editor11.pointerPressure)(ev)
|
|
5146
5408
|
}));
|
|
5147
5409
|
};
|
|
5148
5410
|
const handlePaintPointerDown = (e) => {
|
|
@@ -5170,10 +5432,10 @@ var ImageEditor = ({
|
|
|
5170
5432
|
if (g.error) setPaintError(g.error);
|
|
5171
5433
|
}
|
|
5172
5434
|
};
|
|
5173
|
-
(0,
|
|
5435
|
+
(0, import_react43.useEffect)(() => {
|
|
5174
5436
|
if (activeTab !== "paint" || typeof window === "undefined") return;
|
|
5175
5437
|
const onKey = (e) => {
|
|
5176
|
-
if ((0,
|
|
5438
|
+
if ((0, import_image_editor11.handlePaintShortcut)(controller, e)) e.preventDefault();
|
|
5177
5439
|
};
|
|
5178
5440
|
window.addEventListener("keydown", onKey);
|
|
5179
5441
|
return () => window.removeEventListener("keydown", onKey);
|
|
@@ -5184,7 +5446,7 @@ var ImageEditor = ({
|
|
|
5184
5446
|
const canvasPt = getCanvasEventPoint(e);
|
|
5185
5447
|
if (activeTab === "select") {
|
|
5186
5448
|
const gesture = selectionGestureRef.current;
|
|
5187
|
-
const imgPt = (0,
|
|
5449
|
+
const imgPt = (0, import_image_editor11.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false);
|
|
5188
5450
|
void gesture.begin(imgPt, e).then(() => setSelectionError(gesture.error));
|
|
5189
5451
|
return;
|
|
5190
5452
|
}
|
|
@@ -5195,8 +5457,8 @@ var ImageEditor = ({
|
|
|
5195
5457
|
width: state.imageDimensions.width,
|
|
5196
5458
|
height: state.imageDimensions.height
|
|
5197
5459
|
};
|
|
5198
|
-
const handle = (0,
|
|
5199
|
-
const startImgPt = (0,
|
|
5460
|
+
const handle = (0, import_image_editor11.hitTestCrop)(canvasPt, state, canvas.width, canvas.height, 14, activeCrop);
|
|
5461
|
+
const startImgPt = (0, import_image_editor11.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, true);
|
|
5200
5462
|
if (handle) {
|
|
5201
5463
|
cropDragInfoRef.current = {
|
|
5202
5464
|
handle,
|
|
@@ -5215,12 +5477,12 @@ var ImageEditor = ({
|
|
|
5215
5477
|
return;
|
|
5216
5478
|
}
|
|
5217
5479
|
if (activeTab === "annotate") {
|
|
5218
|
-
const imgPt = (0,
|
|
5480
|
+
const imgPt = (0, import_image_editor11.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false);
|
|
5219
5481
|
dragStartPointRef.current = imgPt;
|
|
5220
5482
|
if (state.activeTool === "select") {
|
|
5221
5483
|
for (let i = state.annotations.length - 1; i >= 0; i--) {
|
|
5222
5484
|
const ann = state.annotations[i];
|
|
5223
|
-
if ((0,
|
|
5485
|
+
if ((0, import_image_editor11.hitTestAnnotation)(imgPt, ann)) {
|
|
5224
5486
|
editor.selectAnnotation(ann.id);
|
|
5225
5487
|
annotationDragInfoRef.current = {
|
|
5226
5488
|
annId: ann.id,
|
|
@@ -5256,7 +5518,7 @@ var ImageEditor = ({
|
|
|
5256
5518
|
const canvasPt = getCanvasEventPoint(e);
|
|
5257
5519
|
if (activeTab === "select") {
|
|
5258
5520
|
const gesture = selectionGestureRef.current;
|
|
5259
|
-
if (gesture.active && gesture.move((0,
|
|
5521
|
+
if (gesture.active && gesture.move((0, import_image_editor11.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false))) {
|
|
5260
5522
|
selectionDraftRef.current = gesture.draftPath;
|
|
5261
5523
|
renderCanvas();
|
|
5262
5524
|
}
|
|
@@ -5265,7 +5527,7 @@ var ImageEditor = ({
|
|
|
5265
5527
|
if (activeTab === "crop") {
|
|
5266
5528
|
const drag = cropDragInfoRef.current;
|
|
5267
5529
|
if (drag) {
|
|
5268
|
-
const currentImgPt = (0,
|
|
5530
|
+
const currentImgPt = (0, import_image_editor11.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, true);
|
|
5269
5531
|
let newCrop;
|
|
5270
5532
|
if (drag.handle === "new") {
|
|
5271
5533
|
const minX = Math.max(0, Math.min(drag.startImgPt.x, currentImgPt.x));
|
|
@@ -5279,7 +5541,7 @@ var ImageEditor = ({
|
|
|
5279
5541
|
height: Math.round(Math.max(20, maxY - minY))
|
|
5280
5542
|
};
|
|
5281
5543
|
} else {
|
|
5282
|
-
newCrop = (0,
|
|
5544
|
+
newCrop = (0, import_image_editor11.calculateCropDrag)(
|
|
5283
5545
|
drag.startCrop,
|
|
5284
5546
|
drag.handle,
|
|
5285
5547
|
drag.startImgPt,
|
|
@@ -5299,15 +5561,15 @@ var ImageEditor = ({
|
|
|
5299
5561
|
width: state.imageDimensions.width,
|
|
5300
5562
|
height: state.imageDimensions.height
|
|
5301
5563
|
};
|
|
5302
|
-
const handle = (0,
|
|
5303
|
-
canvas.style.cursor = (0,
|
|
5564
|
+
const handle = (0, import_image_editor11.hitTestCrop)(canvasPt, state, canvas.width, canvas.height, 14, activeCrop);
|
|
5565
|
+
canvas.style.cursor = (0, import_image_editor11.getCropCursor)(handle, state.transform);
|
|
5304
5566
|
}
|
|
5305
5567
|
return;
|
|
5306
5568
|
}
|
|
5307
5569
|
if (activeTab === "annotate") {
|
|
5308
5570
|
if (annotationDragInfoRef.current) {
|
|
5309
5571
|
const drag = annotationDragInfoRef.current;
|
|
5310
|
-
const currentImgPt2 = (0,
|
|
5572
|
+
const currentImgPt2 = (0, import_image_editor11.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false);
|
|
5311
5573
|
const dx = currentImgPt2.x - drag.startImgPt.x;
|
|
5312
5574
|
const dy = currentImgPt2.y - drag.startImgPt.y;
|
|
5313
5575
|
editor.updateAnnotation(drag.annId, {
|
|
@@ -5319,10 +5581,10 @@ var ImageEditor = ({
|
|
|
5319
5581
|
const startPt = dragStartPointRef.current;
|
|
5320
5582
|
if (!startPt) {
|
|
5321
5583
|
if (state.activeTool === "select") {
|
|
5322
|
-
const imgPt = (0,
|
|
5584
|
+
const imgPt = (0, import_image_editor11.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false);
|
|
5323
5585
|
let hovered = false;
|
|
5324
5586
|
for (let i = state.annotations.length - 1; i >= 0; i--) {
|
|
5325
|
-
if ((0,
|
|
5587
|
+
if ((0, import_image_editor11.hitTestAnnotation)(imgPt, state.annotations[i])) {
|
|
5326
5588
|
hovered = true;
|
|
5327
5589
|
break;
|
|
5328
5590
|
}
|
|
@@ -5333,7 +5595,7 @@ var ImageEditor = ({
|
|
|
5333
5595
|
}
|
|
5334
5596
|
return;
|
|
5335
5597
|
}
|
|
5336
|
-
const currentImgPt = (0,
|
|
5598
|
+
const currentImgPt = (0, import_image_editor11.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false);
|
|
5337
5599
|
if (state.activeTool === "pen" && isDrawingRef.current) {
|
|
5338
5600
|
currentPathRef.current.push(currentImgPt);
|
|
5339
5601
|
const draft = {
|
|
@@ -5413,7 +5675,7 @@ var ImageEditor = ({
|
|
|
5413
5675
|
if (activeTab === "select") {
|
|
5414
5676
|
const gesture = selectionGestureRef.current;
|
|
5415
5677
|
if (gesture.active) {
|
|
5416
|
-
gesture.end((0,
|
|
5678
|
+
gesture.end((0, import_image_editor11.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false), e);
|
|
5417
5679
|
selectionDraftRef.current = null;
|
|
5418
5680
|
renderCanvas();
|
|
5419
5681
|
}
|
|
@@ -5437,7 +5699,7 @@ var ImageEditor = ({
|
|
|
5437
5699
|
}
|
|
5438
5700
|
const startPt = dragStartPointRef.current;
|
|
5439
5701
|
if (startPt) {
|
|
5440
|
-
const currentImgPt = (0,
|
|
5702
|
+
const currentImgPt = (0, import_image_editor11.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false);
|
|
5441
5703
|
if (state.activeTool === "pen" && isDrawingRef.current) {
|
|
5442
5704
|
if (currentPathRef.current.length > 1) {
|
|
5443
5705
|
editor.addAnnotation({
|
|
@@ -5533,15 +5795,15 @@ var ImageEditor = ({
|
|
|
5533
5795
|
link.click();
|
|
5534
5796
|
}
|
|
5535
5797
|
};
|
|
5536
|
-
return /* @__PURE__ */ (0,
|
|
5798
|
+
return /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(
|
|
5537
5799
|
"div",
|
|
5538
5800
|
{
|
|
5539
5801
|
className: `flex flex-col bg-slate-900 border border-slate-800 rounded-xl overflow-hidden shadow-2xl text-slate-100 ${className}`,
|
|
5540
5802
|
style,
|
|
5541
5803
|
children: [
|
|
5542
|
-
/* @__PURE__ */ (0,
|
|
5543
|
-
/* @__PURE__ */ (0,
|
|
5544
|
-
/* @__PURE__ */ (0,
|
|
5804
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.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: [
|
|
5805
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "flex items-center gap-1 bg-slate-900 p-1 rounded-lg border border-slate-800 text-xs", children: [
|
|
5806
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
5545
5807
|
"button",
|
|
5546
5808
|
{
|
|
5547
5809
|
type: "button",
|
|
@@ -5553,7 +5815,7 @@ var ImageEditor = ({
|
|
|
5553
5815
|
children: "Transform & Crop"
|
|
5554
5816
|
}
|
|
5555
5817
|
),
|
|
5556
|
-
/* @__PURE__ */ (0,
|
|
5818
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
5557
5819
|
"button",
|
|
5558
5820
|
{
|
|
5559
5821
|
type: "button",
|
|
@@ -5565,7 +5827,7 @@ var ImageEditor = ({
|
|
|
5565
5827
|
children: "Adjustments"
|
|
5566
5828
|
}
|
|
5567
5829
|
),
|
|
5568
|
-
/* @__PURE__ */ (0,
|
|
5830
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
5569
5831
|
"button",
|
|
5570
5832
|
{
|
|
5571
5833
|
type: "button",
|
|
@@ -5577,7 +5839,7 @@ var ImageEditor = ({
|
|
|
5577
5839
|
children: "Layers"
|
|
5578
5840
|
}
|
|
5579
5841
|
),
|
|
5580
|
-
/* @__PURE__ */ (0,
|
|
5842
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
5581
5843
|
"button",
|
|
5582
5844
|
{
|
|
5583
5845
|
type: "button",
|
|
@@ -5589,7 +5851,7 @@ var ImageEditor = ({
|
|
|
5589
5851
|
children: "Paint"
|
|
5590
5852
|
}
|
|
5591
5853
|
),
|
|
5592
|
-
/* @__PURE__ */ (0,
|
|
5854
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
5593
5855
|
"button",
|
|
5594
5856
|
{
|
|
5595
5857
|
type: "button",
|
|
@@ -5601,7 +5863,7 @@ var ImageEditor = ({
|
|
|
5601
5863
|
children: "Select & Mask"
|
|
5602
5864
|
}
|
|
5603
5865
|
),
|
|
5604
|
-
/* @__PURE__ */ (0,
|
|
5866
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
5605
5867
|
"button",
|
|
5606
5868
|
{
|
|
5607
5869
|
type: "button",
|
|
@@ -5613,7 +5875,7 @@ var ImageEditor = ({
|
|
|
5613
5875
|
children: "Annotations"
|
|
5614
5876
|
}
|
|
5615
5877
|
),
|
|
5616
|
-
/* @__PURE__ */ (0,
|
|
5878
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
5617
5879
|
"button",
|
|
5618
5880
|
{
|
|
5619
5881
|
type: "button",
|
|
@@ -5625,7 +5887,7 @@ var ImageEditor = ({
|
|
|
5625
5887
|
children: "Depth Mask"
|
|
5626
5888
|
}
|
|
5627
5889
|
),
|
|
5628
|
-
/* @__PURE__ */ (0,
|
|
5890
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(
|
|
5629
5891
|
"button",
|
|
5630
5892
|
{
|
|
5631
5893
|
type: "button",
|
|
@@ -5635,14 +5897,14 @@ var ImageEditor = ({
|
|
|
5635
5897
|
},
|
|
5636
5898
|
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"}`,
|
|
5637
5899
|
children: [
|
|
5638
|
-
/* @__PURE__ */ (0,
|
|
5900
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.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_runtime26.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" }) }),
|
|
5639
5901
|
"AI Tools"
|
|
5640
5902
|
]
|
|
5641
5903
|
}
|
|
5642
5904
|
)
|
|
5643
5905
|
] }),
|
|
5644
|
-
/* @__PURE__ */ (0,
|
|
5645
|
-
/* @__PURE__ */ (0,
|
|
5906
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "flex items-center gap-2 text-xs", children: [
|
|
5907
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
5646
5908
|
"button",
|
|
5647
5909
|
{
|
|
5648
5910
|
type: "button",
|
|
@@ -5653,7 +5915,7 @@ var ImageEditor = ({
|
|
|
5653
5915
|
children: "\u21A9"
|
|
5654
5916
|
}
|
|
5655
5917
|
),
|
|
5656
|
-
/* @__PURE__ */ (0,
|
|
5918
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
5657
5919
|
"button",
|
|
5658
5920
|
{
|
|
5659
5921
|
type: "button",
|
|
@@ -5664,7 +5926,7 @@ var ImageEditor = ({
|
|
|
5664
5926
|
children: "\u21AA"
|
|
5665
5927
|
}
|
|
5666
5928
|
),
|
|
5667
|
-
/* @__PURE__ */ (0,
|
|
5929
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
5668
5930
|
"button",
|
|
5669
5931
|
{
|
|
5670
5932
|
type: "button",
|
|
@@ -5673,8 +5935,8 @@ var ImageEditor = ({
|
|
|
5673
5935
|
children: "Reset"
|
|
5674
5936
|
}
|
|
5675
5937
|
),
|
|
5676
|
-
/* @__PURE__ */ (0,
|
|
5677
|
-
/* @__PURE__ */ (0,
|
|
5938
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "h-4 w-px bg-slate-800 mx-1" }),
|
|
5939
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
5678
5940
|
"button",
|
|
5679
5941
|
{
|
|
5680
5942
|
type: "button",
|
|
@@ -5684,11 +5946,11 @@ var ImageEditor = ({
|
|
|
5684
5946
|
children: "-"
|
|
5685
5947
|
}
|
|
5686
5948
|
),
|
|
5687
|
-
/* @__PURE__ */ (0,
|
|
5949
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("span", { className: "font-mono text-slate-400 w-10 text-center", children: [
|
|
5688
5950
|
Math.round(state.zoom * 100),
|
|
5689
5951
|
"%"
|
|
5690
5952
|
] }),
|
|
5691
|
-
/* @__PURE__ */ (0,
|
|
5953
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
5692
5954
|
"button",
|
|
5693
5955
|
{
|
|
5694
5956
|
type: "button",
|
|
@@ -5698,8 +5960,8 @@ var ImageEditor = ({
|
|
|
5698
5960
|
children: "+"
|
|
5699
5961
|
}
|
|
5700
5962
|
),
|
|
5701
|
-
/* @__PURE__ */ (0,
|
|
5702
|
-
/* @__PURE__ */ (0,
|
|
5963
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "h-4 w-px bg-slate-800 mx-1" }),
|
|
5964
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
5703
5965
|
"button",
|
|
5704
5966
|
{
|
|
5705
5967
|
type: "button",
|
|
@@ -5710,7 +5972,7 @@ var ImageEditor = ({
|
|
|
5710
5972
|
children: "Hold Compare"
|
|
5711
5973
|
}
|
|
5712
5974
|
),
|
|
5713
|
-
/* @__PURE__ */ (0,
|
|
5975
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
5714
5976
|
"button",
|
|
5715
5977
|
{
|
|
5716
5978
|
type: "button",
|
|
@@ -5721,13 +5983,13 @@ var ImageEditor = ({
|
|
|
5721
5983
|
)
|
|
5722
5984
|
] })
|
|
5723
5985
|
] }),
|
|
5724
|
-
/* @__PURE__ */ (0,
|
|
5725
|
-
/* @__PURE__ */ (0,
|
|
5986
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "flex flex-col md:flex-row flex-1 min-h-[520px] md:h-[560px]", children: [
|
|
5987
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
5726
5988
|
"div",
|
|
5727
5989
|
{
|
|
5728
5990
|
ref: containerRef,
|
|
5729
5991
|
className: "relative flex-1 h-[360px] md:h-full min-h-[320px] bg-slate-950 overflow-hidden select-none",
|
|
5730
|
-
children: /* @__PURE__ */ (0,
|
|
5992
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
5731
5993
|
"canvas",
|
|
5732
5994
|
{
|
|
5733
5995
|
ref: canvasRef,
|
|
@@ -5745,11 +6007,11 @@ var ImageEditor = ({
|
|
|
5745
6007
|
)
|
|
5746
6008
|
}
|
|
5747
6009
|
),
|
|
5748
|
-
/* @__PURE__ */ (0,
|
|
5749
|
-
activeTab === "crop" && /* @__PURE__ */ (0,
|
|
5750
|
-
/* @__PURE__ */ (0,
|
|
5751
|
-
/* @__PURE__ */ (0,
|
|
5752
|
-
/* @__PURE__ */ (0,
|
|
6010
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.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: [
|
|
6011
|
+
activeTab === "crop" && /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "flex flex-col gap-4 text-xs", children: [
|
|
6012
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Aspect Ratio Presets" }),
|
|
6013
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "grid grid-cols-3 gap-2", children: [
|
|
6014
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
5753
6015
|
"button",
|
|
5754
6016
|
{
|
|
5755
6017
|
type: "button",
|
|
@@ -5761,7 +6023,7 @@ var ImageEditor = ({
|
|
|
5761
6023
|
children: "Freeform"
|
|
5762
6024
|
}
|
|
5763
6025
|
),
|
|
5764
|
-
/* @__PURE__ */ (0,
|
|
6026
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
5765
6027
|
"button",
|
|
5766
6028
|
{
|
|
5767
6029
|
type: "button",
|
|
@@ -5773,7 +6035,7 @@ var ImageEditor = ({
|
|
|
5773
6035
|
children: "1:1 Square"
|
|
5774
6036
|
}
|
|
5775
6037
|
),
|
|
5776
|
-
/* @__PURE__ */ (0,
|
|
6038
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
5777
6039
|
"button",
|
|
5778
6040
|
{
|
|
5779
6041
|
type: "button",
|
|
@@ -5785,7 +6047,7 @@ var ImageEditor = ({
|
|
|
5785
6047
|
children: "4:3 Standard"
|
|
5786
6048
|
}
|
|
5787
6049
|
),
|
|
5788
|
-
/* @__PURE__ */ (0,
|
|
6050
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
5789
6051
|
"button",
|
|
5790
6052
|
{
|
|
5791
6053
|
type: "button",
|
|
@@ -5797,7 +6059,7 @@ var ImageEditor = ({
|
|
|
5797
6059
|
children: "16:9 Wide"
|
|
5798
6060
|
}
|
|
5799
6061
|
),
|
|
5800
|
-
/* @__PURE__ */ (0,
|
|
6062
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
5801
6063
|
"button",
|
|
5802
6064
|
{
|
|
5803
6065
|
type: "button",
|
|
@@ -5809,7 +6071,7 @@ var ImageEditor = ({
|
|
|
5809
6071
|
children: "3:2 Photo"
|
|
5810
6072
|
}
|
|
5811
6073
|
),
|
|
5812
|
-
/* @__PURE__ */ (0,
|
|
6074
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
5813
6075
|
"button",
|
|
5814
6076
|
{
|
|
5815
6077
|
type: "button",
|
|
@@ -5822,10 +6084,10 @@ var ImageEditor = ({
|
|
|
5822
6084
|
}
|
|
5823
6085
|
)
|
|
5824
6086
|
] }),
|
|
5825
|
-
/* @__PURE__ */ (0,
|
|
5826
|
-
/* @__PURE__ */ (0,
|
|
5827
|
-
/* @__PURE__ */ (0,
|
|
5828
|
-
/* @__PURE__ */ (0,
|
|
6087
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "h-px bg-slate-800 my-1" }),
|
|
6088
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Orientation & Flips" }),
|
|
6089
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "grid grid-cols-2 gap-2", children: [
|
|
6090
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
5829
6091
|
"button",
|
|
5830
6092
|
{
|
|
5831
6093
|
type: "button",
|
|
@@ -5834,7 +6096,7 @@ var ImageEditor = ({
|
|
|
5834
6096
|
children: "Rotate -90\xB0"
|
|
5835
6097
|
}
|
|
5836
6098
|
),
|
|
5837
|
-
/* @__PURE__ */ (0,
|
|
6099
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
5838
6100
|
"button",
|
|
5839
6101
|
{
|
|
5840
6102
|
type: "button",
|
|
@@ -5843,7 +6105,7 @@ var ImageEditor = ({
|
|
|
5843
6105
|
children: "Rotate +90\xB0"
|
|
5844
6106
|
}
|
|
5845
6107
|
),
|
|
5846
|
-
/* @__PURE__ */ (0,
|
|
6108
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
5847
6109
|
"button",
|
|
5848
6110
|
{
|
|
5849
6111
|
type: "button",
|
|
@@ -5852,7 +6114,7 @@ var ImageEditor = ({
|
|
|
5852
6114
|
children: "Flip Horizontal"
|
|
5853
6115
|
}
|
|
5854
6116
|
),
|
|
5855
|
-
/* @__PURE__ */ (0,
|
|
6117
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
5856
6118
|
"button",
|
|
5857
6119
|
{
|
|
5858
6120
|
type: "button",
|
|
@@ -5863,10 +6125,10 @@ var ImageEditor = ({
|
|
|
5863
6125
|
)
|
|
5864
6126
|
] })
|
|
5865
6127
|
] }),
|
|
5866
|
-
activeTab === "adjust" && /* @__PURE__ */ (0,
|
|
5867
|
-
/* @__PURE__ */ (0,
|
|
5868
|
-
/* @__PURE__ */ (0,
|
|
5869
|
-
/* @__PURE__ */ (0,
|
|
6128
|
+
activeTab === "adjust" && /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "flex flex-col gap-3 text-xs", children: [
|
|
6129
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "flex items-center justify-between", children: [
|
|
6130
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Color Adjustments" }),
|
|
6131
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
5870
6132
|
"button",
|
|
5871
6133
|
{
|
|
5872
6134
|
type: "button",
|
|
@@ -5876,25 +6138,25 @@ var ImageEditor = ({
|
|
|
5876
6138
|
}
|
|
5877
6139
|
)
|
|
5878
6140
|
] }),
|
|
5879
|
-
/* @__PURE__ */ (0,
|
|
5880
|
-
|
|
5881
|
-
/* @__PURE__ */ (0,
|
|
6141
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(Histogram, { histogram: editor.histogram }),
|
|
6142
|
+
import_image_editor11.IMAGE_ADJUSTMENT_CONTROLS.map((spec) => /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(import_react43.default.Fragment, { children: [
|
|
6143
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
5882
6144
|
ControlSlider,
|
|
5883
6145
|
{
|
|
5884
6146
|
spec,
|
|
5885
|
-
value: (0,
|
|
6147
|
+
value: (0, import_image_editor11.readAdjustmentControls)(state.adjustments)[spec.id],
|
|
5886
6148
|
disabled: spec.requiresProcess !== void 0 && legacyProcess,
|
|
5887
6149
|
onChange: (v) => editor.setAdjustments({ [spec.id]: v })
|
|
5888
6150
|
}
|
|
5889
6151
|
),
|
|
5890
|
-
spec.id === "tint" && legacyProcess && /* @__PURE__ */ (0,
|
|
6152
|
+
spec.id === "tint" && legacyProcess && /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(
|
|
5891
6153
|
"div",
|
|
5892
6154
|
{
|
|
5893
6155
|
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",
|
|
5894
6156
|
"data-testid": "image-editor-process-notice",
|
|
5895
6157
|
children: [
|
|
5896
|
-
/* @__PURE__ */ (0,
|
|
5897
|
-
/* @__PURE__ */ (0,
|
|
6158
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { children: "Legacy rendering (process 1). Tint needs the current process." }),
|
|
6159
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
5898
6160
|
"button",
|
|
5899
6161
|
{
|
|
5900
6162
|
type: "button",
|
|
@@ -5907,7 +6169,7 @@ var ImageEditor = ({
|
|
|
5907
6169
|
}
|
|
5908
6170
|
)
|
|
5909
6171
|
] }, spec.id)),
|
|
5910
|
-
/* @__PURE__ */ (0,
|
|
6172
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "border-t border-slate-700/60 pt-3", children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
5911
6173
|
AdjustmentLayersPanel,
|
|
5912
6174
|
{
|
|
5913
6175
|
controller,
|
|
@@ -5916,19 +6178,19 @@ var ImageEditor = ({
|
|
|
5916
6178
|
}
|
|
5917
6179
|
) })
|
|
5918
6180
|
] }),
|
|
5919
|
-
activeTab === "layers" && /* @__PURE__ */ (0,
|
|
5920
|
-
/* @__PURE__ */ (0,
|
|
5921
|
-
/* @__PURE__ */ (0,
|
|
6181
|
+
activeTab === "layers" && /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "flex flex-col gap-3 text-xs", children: [
|
|
6182
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Layers" }),
|
|
6183
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(LayersPanel, { controller })
|
|
5922
6184
|
] }),
|
|
5923
|
-
activeTab === "paint" && /* @__PURE__ */ (0,
|
|
5924
|
-
/* @__PURE__ */ (0,
|
|
5925
|
-
/* @__PURE__ */ (0,
|
|
5926
|
-
paintError && /* @__PURE__ */ (0,
|
|
5927
|
-
/* @__PURE__ */ (0,
|
|
6185
|
+
activeTab === "paint" && /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "flex flex-col gap-3 text-xs", children: [
|
|
6186
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Paint" }),
|
|
6187
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(BrushOptionsBar, { controller }),
|
|
6188
|
+
paintError && /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("p", { role: "alert", className: "text-rose-400", "data-testid": "paint-error", children: paintError }),
|
|
6189
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "border-t border-slate-700/60 pt-3", children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(LayersPanel, { controller }) })
|
|
5928
6190
|
] }),
|
|
5929
|
-
activeTab === "annotate" && /* @__PURE__ */ (0,
|
|
5930
|
-
/* @__PURE__ */ (0,
|
|
5931
|
-
/* @__PURE__ */ (0,
|
|
6191
|
+
activeTab === "annotate" && /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "flex flex-col gap-3 text-xs", children: [
|
|
6192
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Draw & Annotate" }),
|
|
6193
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "grid grid-cols-3 gap-1.5", children: ["pen", "rect", "circle", "arrow", "line"].map((t) => /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
5932
6194
|
"button",
|
|
5933
6195
|
{
|
|
5934
6196
|
type: "button",
|
|
@@ -5938,9 +6200,9 @@ var ImageEditor = ({
|
|
|
5938
6200
|
},
|
|
5939
6201
|
t
|
|
5940
6202
|
)) }),
|
|
5941
|
-
/* @__PURE__ */ (0,
|
|
5942
|
-
/* @__PURE__ */ (0,
|
|
5943
|
-
/* @__PURE__ */ (0,
|
|
6203
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "flex items-center gap-2 mt-2", children: [
|
|
6204
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("label", { className: "text-slate-400", children: "Color:" }),
|
|
6205
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
5944
6206
|
"input",
|
|
5945
6207
|
{
|
|
5946
6208
|
type: "color",
|
|
@@ -5949,15 +6211,15 @@ var ImageEditor = ({
|
|
|
5949
6211
|
className: "w-8 h-8 rounded border border-slate-700 cursor-pointer bg-transparent"
|
|
5950
6212
|
}
|
|
5951
6213
|
),
|
|
5952
|
-
/* @__PURE__ */ (0,
|
|
5953
|
-
/* @__PURE__ */ (0,
|
|
5954
|
-
/* @__PURE__ */ (0,
|
|
5955
|
-
/* @__PURE__ */ (0,
|
|
6214
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "flex-1 ml-2", children: [
|
|
6215
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "flex justify-between text-slate-400 mb-0.5", children: [
|
|
6216
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { children: "Width:" }),
|
|
6217
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("span", { className: "font-mono", children: [
|
|
5956
6218
|
strokeWidth,
|
|
5957
6219
|
"px"
|
|
5958
6220
|
] })
|
|
5959
6221
|
] }),
|
|
5960
|
-
/* @__PURE__ */ (0,
|
|
6222
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
5961
6223
|
"input",
|
|
5962
6224
|
{
|
|
5963
6225
|
type: "range",
|
|
@@ -5970,10 +6232,10 @@ var ImageEditor = ({
|
|
|
5970
6232
|
)
|
|
5971
6233
|
] })
|
|
5972
6234
|
] }),
|
|
5973
|
-
/* @__PURE__ */ (0,
|
|
5974
|
-
/* @__PURE__ */ (0,
|
|
5975
|
-
/* @__PURE__ */ (0,
|
|
5976
|
-
/* @__PURE__ */ (0,
|
|
6235
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "h-px bg-slate-800 my-1" }),
|
|
6236
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Add Text" }),
|
|
6237
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "flex gap-2", children: [
|
|
6238
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
5977
6239
|
"input",
|
|
5978
6240
|
{
|
|
5979
6241
|
type: "text",
|
|
@@ -5984,7 +6246,7 @@ var ImageEditor = ({
|
|
|
5984
6246
|
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"
|
|
5985
6247
|
}
|
|
5986
6248
|
),
|
|
5987
|
-
/* @__PURE__ */ (0,
|
|
6249
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
5988
6250
|
"button",
|
|
5989
6251
|
{
|
|
5990
6252
|
type: "button",
|
|
@@ -5994,14 +6256,14 @@ var ImageEditor = ({
|
|
|
5994
6256
|
}
|
|
5995
6257
|
)
|
|
5996
6258
|
] }),
|
|
5997
|
-
/* @__PURE__ */ (0,
|
|
5998
|
-
/* @__PURE__ */ (0,
|
|
5999
|
-
/* @__PURE__ */ (0,
|
|
6259
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "flex items-center justify-between text-slate-400", children: [
|
|
6260
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { children: "Font Size:" }),
|
|
6261
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("span", { className: "font-mono", children: [
|
|
6000
6262
|
fontSize,
|
|
6001
6263
|
"px"
|
|
6002
6264
|
] })
|
|
6003
6265
|
] }),
|
|
6004
|
-
/* @__PURE__ */ (0,
|
|
6266
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
6005
6267
|
"input",
|
|
6006
6268
|
{
|
|
6007
6269
|
type: "range",
|
|
@@ -6012,14 +6274,14 @@ var ImageEditor = ({
|
|
|
6012
6274
|
className: "w-full accent-indigo-500"
|
|
6013
6275
|
}
|
|
6014
6276
|
),
|
|
6015
|
-
/* @__PURE__ */ (0,
|
|
6016
|
-
/* @__PURE__ */ (0,
|
|
6017
|
-
/* @__PURE__ */ (0,
|
|
6277
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "h-px bg-slate-800 my-1" }),
|
|
6278
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "flex items-center justify-between", children: [
|
|
6279
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("span", { className: "text-slate-400", children: [
|
|
6018
6280
|
"Layers (",
|
|
6019
6281
|
state.annotations.length,
|
|
6020
6282
|
")"
|
|
6021
6283
|
] }),
|
|
6022
|
-
state.selectedAnnotationId && /* @__PURE__ */ (0,
|
|
6284
|
+
state.selectedAnnotationId && /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
6023
6285
|
"button",
|
|
6024
6286
|
{
|
|
6025
6287
|
type: "button",
|
|
@@ -6028,7 +6290,7 @@ var ImageEditor = ({
|
|
|
6028
6290
|
children: "Delete Selected"
|
|
6029
6291
|
}
|
|
6030
6292
|
),
|
|
6031
|
-
state.annotations.length > 0 && /* @__PURE__ */ (0,
|
|
6293
|
+
state.annotations.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
6032
6294
|
"button",
|
|
6033
6295
|
{
|
|
6034
6296
|
type: "button",
|
|
@@ -6039,10 +6301,10 @@ var ImageEditor = ({
|
|
|
6039
6301
|
)
|
|
6040
6302
|
] })
|
|
6041
6303
|
] }),
|
|
6042
|
-
activeTab === "depth" && /* @__PURE__ */ (0,
|
|
6043
|
-
/* @__PURE__ */ (0,
|
|
6044
|
-
/* @__PURE__ */ (0,
|
|
6045
|
-
/* @__PURE__ */ (0,
|
|
6304
|
+
activeTab === "depth" && /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "flex flex-col gap-3 text-xs", children: [
|
|
6305
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "flex items-center justify-between", children: [
|
|
6306
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Depth Masking" }),
|
|
6307
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
6046
6308
|
"button",
|
|
6047
6309
|
{
|
|
6048
6310
|
type: "button",
|
|
@@ -6052,8 +6314,8 @@ var ImageEditor = ({
|
|
|
6052
6314
|
}
|
|
6053
6315
|
)
|
|
6054
6316
|
] }),
|
|
6055
|
-
/* @__PURE__ */ (0,
|
|
6056
|
-
/* @__PURE__ */ (0,
|
|
6317
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("label", { className: "flex items-center gap-2 cursor-pointer text-slate-300", children: [
|
|
6318
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
6057
6319
|
"input",
|
|
6058
6320
|
{
|
|
6059
6321
|
type: "checkbox",
|
|
@@ -6062,12 +6324,12 @@ var ImageEditor = ({
|
|
|
6062
6324
|
className: "rounded accent-indigo-500"
|
|
6063
6325
|
}
|
|
6064
6326
|
),
|
|
6065
|
-
/* @__PURE__ */ (0,
|
|
6327
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { children: "Enable Depth / Alpha Mask" })
|
|
6066
6328
|
] }),
|
|
6067
|
-
state.depthMask.enabled && /* @__PURE__ */ (0,
|
|
6068
|
-
/* @__PURE__ */ (0,
|
|
6069
|
-
/* @__PURE__ */ (0,
|
|
6070
|
-
/* @__PURE__ */ (0,
|
|
6329
|
+
state.depthMask.enabled && /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(import_jsx_runtime26.Fragment, { children: [
|
|
6330
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { children: [
|
|
6331
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("label", { className: "text-slate-400 block mb-1", children: "Mask Image URL:" }),
|
|
6332
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
6071
6333
|
"input",
|
|
6072
6334
|
{
|
|
6073
6335
|
type: "text",
|
|
@@ -6078,8 +6340,8 @@ var ImageEditor = ({
|
|
|
6078
6340
|
}
|
|
6079
6341
|
)
|
|
6080
6342
|
] }),
|
|
6081
|
-
/* @__PURE__ */ (0,
|
|
6082
|
-
/* @__PURE__ */ (0,
|
|
6343
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "flex gap-2", children: [
|
|
6344
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
6083
6345
|
"button",
|
|
6084
6346
|
{
|
|
6085
6347
|
type: "button",
|
|
@@ -6088,7 +6350,7 @@ var ImageEditor = ({
|
|
|
6088
6350
|
children: "Threshold Mode"
|
|
6089
6351
|
}
|
|
6090
6352
|
),
|
|
6091
|
-
/* @__PURE__ */ (0,
|
|
6353
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
6092
6354
|
"button",
|
|
6093
6355
|
{
|
|
6094
6356
|
type: "button",
|
|
@@ -6098,12 +6360,12 @@ var ImageEditor = ({
|
|
|
6098
6360
|
}
|
|
6099
6361
|
)
|
|
6100
6362
|
] }),
|
|
6101
|
-
/* @__PURE__ */ (0,
|
|
6102
|
-
/* @__PURE__ */ (0,
|
|
6103
|
-
/* @__PURE__ */ (0,
|
|
6104
|
-
/* @__PURE__ */ (0,
|
|
6363
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { children: [
|
|
6364
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "flex justify-between text-slate-400 mb-1", children: [
|
|
6365
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { children: "Depth Start (Lower):" }),
|
|
6366
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { className: "font-mono", children: state.depthMask.depthRange[0] })
|
|
6105
6367
|
] }),
|
|
6106
|
-
/* @__PURE__ */ (0,
|
|
6368
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
6107
6369
|
"input",
|
|
6108
6370
|
{
|
|
6109
6371
|
type: "range",
|
|
@@ -6117,12 +6379,12 @@ var ImageEditor = ({
|
|
|
6117
6379
|
}
|
|
6118
6380
|
)
|
|
6119
6381
|
] }),
|
|
6120
|
-
/* @__PURE__ */ (0,
|
|
6121
|
-
/* @__PURE__ */ (0,
|
|
6122
|
-
/* @__PURE__ */ (0,
|
|
6123
|
-
/* @__PURE__ */ (0,
|
|
6382
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { children: [
|
|
6383
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "flex justify-between text-slate-400 mb-1", children: [
|
|
6384
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { children: "Depth Stop (Upper):" }),
|
|
6385
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { className: "font-mono", children: state.depthMask.depthRange[1] })
|
|
6124
6386
|
] }),
|
|
6125
|
-
/* @__PURE__ */ (0,
|
|
6387
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
6126
6388
|
"input",
|
|
6127
6389
|
{
|
|
6128
6390
|
type: "range",
|
|
@@ -6136,12 +6398,12 @@ var ImageEditor = ({
|
|
|
6136
6398
|
}
|
|
6137
6399
|
)
|
|
6138
6400
|
] }),
|
|
6139
|
-
/* @__PURE__ */ (0,
|
|
6140
|
-
/* @__PURE__ */ (0,
|
|
6141
|
-
/* @__PURE__ */ (0,
|
|
6142
|
-
/* @__PURE__ */ (0,
|
|
6401
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { children: [
|
|
6402
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "flex justify-between text-slate-400 mb-1", children: [
|
|
6403
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { children: "Softness:" }),
|
|
6404
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { className: "font-mono", children: state.depthMask.softness })
|
|
6143
6405
|
] }),
|
|
6144
|
-
/* @__PURE__ */ (0,
|
|
6406
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
6145
6407
|
"input",
|
|
6146
6408
|
{
|
|
6147
6409
|
type: "range",
|
|
@@ -6153,8 +6415,8 @@ var ImageEditor = ({
|
|
|
6153
6415
|
}
|
|
6154
6416
|
)
|
|
6155
6417
|
] }),
|
|
6156
|
-
/* @__PURE__ */ (0,
|
|
6157
|
-
/* @__PURE__ */ (0,
|
|
6418
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("label", { className: "flex items-center gap-2 cursor-pointer text-slate-300 mt-1", children: [
|
|
6419
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
6158
6420
|
"input",
|
|
6159
6421
|
{
|
|
6160
6422
|
type: "checkbox",
|
|
@@ -6163,12 +6425,12 @@ var ImageEditor = ({
|
|
|
6163
6425
|
className: "rounded accent-indigo-500"
|
|
6164
6426
|
}
|
|
6165
6427
|
),
|
|
6166
|
-
/* @__PURE__ */ (0,
|
|
6428
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { children: "Invert Mask" })
|
|
6167
6429
|
] })
|
|
6168
6430
|
] })
|
|
6169
6431
|
] }),
|
|
6170
|
-
activeTab === "select" && /* @__PURE__ */ (0,
|
|
6171
|
-
/* @__PURE__ */ (0,
|
|
6432
|
+
activeTab === "select" && /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "flex flex-col gap-4 text-xs", children: [
|
|
6433
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
6172
6434
|
SelectionOptionsBar,
|
|
6173
6435
|
{
|
|
6174
6436
|
controller,
|
|
@@ -6178,13 +6440,13 @@ var ImageEditor = ({
|
|
|
6178
6440
|
quickMask: Boolean(state.quickMask)
|
|
6179
6441
|
}
|
|
6180
6442
|
),
|
|
6181
|
-
selectionError && /* @__PURE__ */ (0,
|
|
6182
|
-
/* @__PURE__ */ (0,
|
|
6443
|
+
selectionError && /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("p", { role: "alert", className: "text-rose-400", children: selectionError }),
|
|
6444
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(RefineEdgePanel, { controller, selection: state.selection ?? null, layers: state.adjustments.layers })
|
|
6183
6445
|
] }),
|
|
6184
|
-
activeTab === "ai" && /* @__PURE__ */ (0,
|
|
6185
|
-
/* @__PURE__ */ (0,
|
|
6186
|
-
/* @__PURE__ */ (0,
|
|
6187
|
-
/* @__PURE__ */ (0,
|
|
6446
|
+
activeTab === "ai" && /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "flex flex-col gap-4 text-xs", children: [
|
|
6447
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("label", { className: "flex items-center justify-between gap-2 text-slate-300", children: [
|
|
6448
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { children: "Results go to" }),
|
|
6449
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(
|
|
6188
6450
|
"select",
|
|
6189
6451
|
{
|
|
6190
6452
|
"aria-label": "AI result target",
|
|
@@ -6192,54 +6454,54 @@ var ImageEditor = ({
|
|
|
6192
6454
|
onChange: (e) => setAiTarget(e.target.value),
|
|
6193
6455
|
className: "bg-slate-800 border border-slate-700 rounded px-1.5 py-1",
|
|
6194
6456
|
children: [
|
|
6195
|
-
/* @__PURE__ */ (0,
|
|
6196
|
-
/* @__PURE__ */ (0,
|
|
6197
|
-
/* @__PURE__ */ (0,
|
|
6457
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("option", { value: "auto", children: controller.isMultiLayer ? "Auto (new layer)" : "Auto (replace image)" }),
|
|
6458
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("option", { value: "new-layer", children: "New layer / mask" }),
|
|
6459
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("option", { value: "replace", children: "Replace image" })
|
|
6198
6460
|
]
|
|
6199
6461
|
}
|
|
6200
6462
|
)
|
|
6201
6463
|
] }),
|
|
6202
|
-
/* @__PURE__ */ (0,
|
|
6203
|
-
/* @__PURE__ */ (0,
|
|
6204
|
-
/* @__PURE__ */ (0,
|
|
6205
|
-
/* @__PURE__ */ (0,
|
|
6464
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "p-3 rounded-lg bg-slate-950/60 border border-slate-800 flex flex-col gap-2.5", children: [
|
|
6465
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "flex items-center justify-between", children: [
|
|
6466
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px] flex items-center gap-1.5", children: [
|
|
6467
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.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_runtime26.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" }) }),
|
|
6206
6468
|
"Background Removal"
|
|
6207
6469
|
] }),
|
|
6208
|
-
isRemovingBg && /* @__PURE__ */ (0,
|
|
6470
|
+
isRemovingBg && /* @__PURE__ */ (0, import_jsx_runtime26.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..." })
|
|
6209
6471
|
] }),
|
|
6210
|
-
/* @__PURE__ */ (0,
|
|
6211
|
-
/* @__PURE__ */ (0,
|
|
6472
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("p", { className: "text-slate-400 text-[11px] leading-relaxed", children: "Isolate foreground subject with AI alpha transparency segmentation." }),
|
|
6473
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
6212
6474
|
"button",
|
|
6213
6475
|
{
|
|
6214
6476
|
type: "button",
|
|
6215
6477
|
onClick: handleRemoveBackground,
|
|
6216
6478
|
disabled: isRemovingBg || isInpainting,
|
|
6217
6479
|
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",
|
|
6218
|
-
children: isRemovingBg ? /* @__PURE__ */ (0,
|
|
6219
|
-
/* @__PURE__ */ (0,
|
|
6480
|
+
children: isRemovingBg ? /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(import_jsx_runtime26.Fragment, { children: [
|
|
6481
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "w-3.5 h-3.5 border-2 border-white/30 border-t-white rounded-full animate-spin" }),
|
|
6220
6482
|
"Removing Background..."
|
|
6221
|
-
] }) : /* @__PURE__ */ (0,
|
|
6222
|
-
/* @__PURE__ */ (0,
|
|
6483
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(import_jsx_runtime26.Fragment, { children: [
|
|
6484
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.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_runtime26.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" }) }),
|
|
6223
6485
|
"Remove Background"
|
|
6224
6486
|
] })
|
|
6225
6487
|
}
|
|
6226
6488
|
)
|
|
6227
6489
|
] }),
|
|
6228
|
-
/* @__PURE__ */ (0,
|
|
6229
|
-
/* @__PURE__ */ (0,
|
|
6230
|
-
/* @__PURE__ */ (0,
|
|
6231
|
-
/* @__PURE__ */ (0,
|
|
6232
|
-
/* @__PURE__ */ (0,
|
|
6233
|
-
/* @__PURE__ */ (0,
|
|
6490
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "p-3 rounded-lg bg-slate-950/60 border border-slate-800 flex flex-col gap-2.5", children: [
|
|
6491
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "flex items-center justify-between", children: [
|
|
6492
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px] flex items-center gap-1.5", children: [
|
|
6493
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("svg", { className: "w-3.5 h-3.5 text-purple-400", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: [
|
|
6494
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.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" }),
|
|
6495
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("path", { d: "m14 7 3 3" })
|
|
6234
6496
|
] }),
|
|
6235
6497
|
"Generative Inpainting"
|
|
6236
6498
|
] }),
|
|
6237
|
-
isInpainting && /* @__PURE__ */ (0,
|
|
6499
|
+
isInpainting && /* @__PURE__ */ (0, import_jsx_runtime26.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..." })
|
|
6238
6500
|
] }),
|
|
6239
|
-
/* @__PURE__ */ (0,
|
|
6240
|
-
/* @__PURE__ */ (0,
|
|
6241
|
-
/* @__PURE__ */ (0,
|
|
6242
|
-
/* @__PURE__ */ (0,
|
|
6501
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("p", { className: "text-slate-400 text-[11px] leading-relaxed", children: "Replace, modify, or fill selected regions using prompt-guided generative inpainting." }),
|
|
6502
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "flex flex-col gap-1", children: [
|
|
6503
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("label", { htmlFor: "ai-inpaint-prompt-react", className: "text-slate-300 text-[11px] font-medium", children: "Prompt" }),
|
|
6504
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
6243
6505
|
"textarea",
|
|
6244
6506
|
{
|
|
6245
6507
|
id: "ai-inpaint-prompt-react",
|
|
@@ -6251,10 +6513,10 @@ var ImageEditor = ({
|
|
|
6251
6513
|
}
|
|
6252
6514
|
)
|
|
6253
6515
|
] }),
|
|
6254
|
-
/* @__PURE__ */ (0,
|
|
6255
|
-
/* @__PURE__ */ (0,
|
|
6256
|
-
/* @__PURE__ */ (0,
|
|
6257
|
-
/* @__PURE__ */ (0,
|
|
6516
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "flex flex-col gap-1", children: [
|
|
6517
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { className: "text-slate-300 text-[11px] font-medium", children: "Target Mask Region" }),
|
|
6518
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "grid grid-cols-2 gap-1.5", children: [
|
|
6519
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(
|
|
6258
6520
|
"button",
|
|
6259
6521
|
{
|
|
6260
6522
|
type: "button",
|
|
@@ -6267,7 +6529,7 @@ var ImageEditor = ({
|
|
|
6267
6529
|
]
|
|
6268
6530
|
}
|
|
6269
6531
|
),
|
|
6270
|
-
/* @__PURE__ */ (0,
|
|
6532
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(
|
|
6271
6533
|
"button",
|
|
6272
6534
|
{
|
|
6273
6535
|
type: "button",
|
|
@@ -6282,25 +6544,25 @@ var ImageEditor = ({
|
|
|
6282
6544
|
)
|
|
6283
6545
|
] })
|
|
6284
6546
|
] }),
|
|
6285
|
-
/* @__PURE__ */ (0,
|
|
6547
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
6286
6548
|
"button",
|
|
6287
6549
|
{
|
|
6288
6550
|
type: "button",
|
|
6289
6551
|
onClick: handleInpaint,
|
|
6290
6552
|
disabled: isInpainting || isRemovingBg || !inpaintPrompt.trim(),
|
|
6291
6553
|
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",
|
|
6292
|
-
children: isInpainting ? /* @__PURE__ */ (0,
|
|
6293
|
-
/* @__PURE__ */ (0,
|
|
6554
|
+
children: isInpainting ? /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(import_jsx_runtime26.Fragment, { children: [
|
|
6555
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "w-3.5 h-3.5 border-2 border-white/30 border-t-white rounded-full animate-spin" }),
|
|
6294
6556
|
"Generating Inpaint..."
|
|
6295
|
-
] }) : /* @__PURE__ */ (0,
|
|
6296
|
-
/* @__PURE__ */ (0,
|
|
6557
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(import_jsx_runtime26.Fragment, { children: [
|
|
6558
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.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_runtime26.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" }) }),
|
|
6297
6559
|
"Apply Inpainting"
|
|
6298
6560
|
] })
|
|
6299
6561
|
}
|
|
6300
6562
|
)
|
|
6301
6563
|
] }),
|
|
6302
|
-
aiError && /* @__PURE__ */ (0,
|
|
6303
|
-
aiSuccess && /* @__PURE__ */ (0,
|
|
6564
|
+
aiError && /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "p-2.5 rounded-lg bg-rose-950/60 border border-rose-800 text-rose-300 text-[11px]", children: aiError }),
|
|
6565
|
+
aiSuccess && /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "p-2.5 rounded-lg bg-emerald-950/60 border border-emerald-800 text-emerald-300 text-[11px]", children: aiSuccess })
|
|
6304
6566
|
] })
|
|
6305
6567
|
] })
|
|
6306
6568
|
] })
|
|
@@ -6310,7 +6572,7 @@ var ImageEditor = ({
|
|
|
6310
6572
|
};
|
|
6311
6573
|
|
|
6312
6574
|
// src/review/useReview.ts
|
|
6313
|
-
var
|
|
6575
|
+
var import_react44 = require("react");
|
|
6314
6576
|
var import_editor12 = require("@pixerate/editor");
|
|
6315
6577
|
var EMPTY_COMMENTS = Object.freeze({
|
|
6316
6578
|
threads: [],
|
|
@@ -6329,23 +6591,23 @@ function isCommentStore(value) {
|
|
|
6329
6591
|
}
|
|
6330
6592
|
function useComments(source) {
|
|
6331
6593
|
const store = isCommentStore(source) ? source : (0, import_editor12.getCommentStore)(source);
|
|
6332
|
-
const subscribe = (0,
|
|
6594
|
+
const subscribe = (0, import_react44.useCallback)(
|
|
6333
6595
|
(onChange) => store ? store.subscribe(() => onChange()) : noopUnsubscribe,
|
|
6334
6596
|
[store]
|
|
6335
6597
|
);
|
|
6336
6598
|
const getSnapshot = () => store?.getSnapshot() ?? EMPTY_COMMENTS;
|
|
6337
|
-
const snapshot = (0,
|
|
6338
|
-
return (0,
|
|
6599
|
+
const snapshot = (0, import_react44.useSyncExternalStore)(subscribe, getSnapshot, getSnapshot);
|
|
6600
|
+
return (0, import_react44.useMemo)(() => ({ ...snapshot, store }), [snapshot, store]);
|
|
6339
6601
|
}
|
|
6340
6602
|
function useTrackChanges(editor) {
|
|
6341
6603
|
const store = (0, import_editor12.getTrackChangesStore)(editor ?? null);
|
|
6342
|
-
const subscribe = (0,
|
|
6604
|
+
const subscribe = (0, import_react44.useCallback)(
|
|
6343
6605
|
(onChange) => store ? store.subscribe(() => onChange()) : noopUnsubscribe,
|
|
6344
6606
|
[store]
|
|
6345
6607
|
);
|
|
6346
6608
|
const getSnapshot = () => store?.getSnapshot() ?? EMPTY_TRACK_CHANGES;
|
|
6347
|
-
const snapshot = (0,
|
|
6348
|
-
return (0,
|
|
6609
|
+
const snapshot = (0, import_react44.useSyncExternalStore)(subscribe, getSnapshot, getSnapshot);
|
|
6610
|
+
return (0, import_react44.useMemo)(() => {
|
|
6349
6611
|
const run = (fn) => () => {
|
|
6350
6612
|
if (editor && !editor.isDestroyed) fn(editor);
|
|
6351
6613
|
};
|
|
@@ -6368,9 +6630,9 @@ function useTrackChanges(editor) {
|
|
|
6368
6630
|
}
|
|
6369
6631
|
|
|
6370
6632
|
// src/review/CommentsPanel.tsx
|
|
6371
|
-
var
|
|
6633
|
+
var import_react45 = require("react");
|
|
6372
6634
|
var import_editor13 = require("@pixerate/editor");
|
|
6373
|
-
var
|
|
6635
|
+
var import_jsx_runtime27 = require("react/jsx-runtime");
|
|
6374
6636
|
var buttonClass2 = "rounded px-2 py-1 text-xs text-muted-foreground hover:bg-muted hover:text-foreground disabled:opacity-50";
|
|
6375
6637
|
var primaryButtonClass = "rounded px-2 py-1 text-xs bg-primary/10 text-primary hover:bg-primary/20 disabled:opacity-50";
|
|
6376
6638
|
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";
|
|
@@ -6384,18 +6646,18 @@ var CommentsPanel = ({
|
|
|
6384
6646
|
emptyMessage = "No comments yet. Select text and add a comment."
|
|
6385
6647
|
}) => {
|
|
6386
6648
|
const { threads, activeThreadId, store } = useComments(storeProp ?? editor);
|
|
6387
|
-
const [showResolved, setShowResolved] = (0,
|
|
6649
|
+
const [showResolved, setShowResolved] = (0, import_react45.useState)(showResolvedInitial);
|
|
6388
6650
|
const author = authorProp ?? (0, import_editor13.getCommentAuthor)(editor) ?? { id: "anonymous", name: "Anonymous" };
|
|
6389
6651
|
const visible = threads.filter((t) => showResolved || !t.resolved);
|
|
6390
6652
|
const resolvedCount = threads.filter((t) => t.resolved).length;
|
|
6391
|
-
return /* @__PURE__ */ (0,
|
|
6392
|
-
/* @__PURE__ */ (0,
|
|
6393
|
-
/* @__PURE__ */ (0,
|
|
6653
|
+
return /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("aside", { className, "aria-label": "Comments", children: [
|
|
6654
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "flex items-center justify-between gap-2", children: [
|
|
6655
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("span", { className: "text-xs font-medium text-muted-foreground", children: [
|
|
6394
6656
|
threads.length - resolvedCount,
|
|
6395
6657
|
" open",
|
|
6396
6658
|
resolvedCount > 0 ? ` \xB7 ${resolvedCount} resolved` : ""
|
|
6397
6659
|
] }),
|
|
6398
|
-
resolvedCount > 0 && /* @__PURE__ */ (0,
|
|
6660
|
+
resolvedCount > 0 && /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
6399
6661
|
"button",
|
|
6400
6662
|
{
|
|
6401
6663
|
type: "button",
|
|
@@ -6406,7 +6668,7 @@ var CommentsPanel = ({
|
|
|
6406
6668
|
}
|
|
6407
6669
|
)
|
|
6408
6670
|
] }),
|
|
6409
|
-
visible.length === 0 ? /* @__PURE__ */ (0,
|
|
6671
|
+
visible.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("p", { className: "text-xs text-muted-foreground", children: emptyMessage }) : /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("ul", { className: "flex flex-col gap-2", role: "list", children: visible.map((thread) => /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
6410
6672
|
CommentThreadCard,
|
|
6411
6673
|
{
|
|
6412
6674
|
thread,
|
|
@@ -6428,7 +6690,7 @@ var CommentThreadCard = ({
|
|
|
6428
6690
|
author,
|
|
6429
6691
|
formatTime
|
|
6430
6692
|
}) => {
|
|
6431
|
-
const [draft, setDraft] = (0,
|
|
6693
|
+
const [draft, setDraft] = (0, import_react45.useState)("");
|
|
6432
6694
|
const isDraft = thread.body === "";
|
|
6433
6695
|
const quote = thread.anchor?.quote ?? thread.lastQuote ?? "";
|
|
6434
6696
|
const live = editor && !editor.isDestroyed ? editor : null;
|
|
@@ -6454,7 +6716,7 @@ var CommentThreadCard = ({
|
|
|
6454
6716
|
setDraft("");
|
|
6455
6717
|
};
|
|
6456
6718
|
const stop = (e) => e.stopPropagation();
|
|
6457
|
-
return /* @__PURE__ */ (0,
|
|
6719
|
+
return /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(
|
|
6458
6720
|
"li",
|
|
6459
6721
|
{
|
|
6460
6722
|
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" : ""}`,
|
|
@@ -6470,24 +6732,24 @@ var CommentThreadCard = ({
|
|
|
6470
6732
|
}
|
|
6471
6733
|
},
|
|
6472
6734
|
children: [
|
|
6473
|
-
/* @__PURE__ */ (0,
|
|
6474
|
-
/* @__PURE__ */ (0,
|
|
6475
|
-
/* @__PURE__ */ (0,
|
|
6735
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "flex items-baseline justify-between gap-2", children: [
|
|
6736
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: "font-medium", children: thread.author.name }),
|
|
6737
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: "text-xs text-muted-foreground", children: formatTime(thread.createdAt) })
|
|
6476
6738
|
] }),
|
|
6477
|
-
quote && /* @__PURE__ */ (0,
|
|
6478
|
-
thread.orphaned && /* @__PURE__ */ (0,
|
|
6479
|
-
thread.resolved && /* @__PURE__ */ (0,
|
|
6480
|
-
!isDraft && /* @__PURE__ */ (0,
|
|
6481
|
-
thread.replies.length > 0 && /* @__PURE__ */ (0,
|
|
6482
|
-
/* @__PURE__ */ (0,
|
|
6483
|
-
/* @__PURE__ */ (0,
|
|
6739
|
+
quote && /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("blockquote", { className: "border-l-2 border-border pl-2 text-xs text-muted-foreground line-clamp-2", children: quote }),
|
|
6740
|
+
thread.orphaned && /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: "text-xs text-destructive", children: "The commented text was deleted." }),
|
|
6741
|
+
thread.resolved && /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: "text-xs text-muted-foreground", children: "Resolved" }),
|
|
6742
|
+
!isDraft && /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("p", { className: "whitespace-pre-wrap break-words", children: thread.body }),
|
|
6743
|
+
thread.replies.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime27.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_runtime27.jsxs)("li", { className: "flex flex-col gap-0.5", "data-reply-id": reply.id, children: [
|
|
6744
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("span", { className: "text-xs", children: [
|
|
6745
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: "font-medium", children: reply.author.name }),
|
|
6484
6746
|
" ",
|
|
6485
|
-
/* @__PURE__ */ (0,
|
|
6747
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: "text-muted-foreground", children: formatTime(reply.createdAt) })
|
|
6486
6748
|
] }),
|
|
6487
|
-
/* @__PURE__ */ (0,
|
|
6749
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("p", { className: "whitespace-pre-wrap break-words", children: reply.body })
|
|
6488
6750
|
] }, reply.id)) }),
|
|
6489
|
-
(active || isDraft) && !thread.resolved && /* @__PURE__ */ (0,
|
|
6490
|
-
/* @__PURE__ */ (0,
|
|
6751
|
+
(active || isDraft) && !thread.resolved && /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "flex flex-col gap-1", onClick: stop, children: [
|
|
6752
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
6491
6753
|
"textarea",
|
|
6492
6754
|
{
|
|
6493
6755
|
className: textareaClass,
|
|
@@ -6505,9 +6767,9 @@ var CommentThreadCard = ({
|
|
|
6505
6767
|
}
|
|
6506
6768
|
}
|
|
6507
6769
|
),
|
|
6508
|
-
/* @__PURE__ */ (0,
|
|
6509
|
-
isDraft && /* @__PURE__ */ (0,
|
|
6510
|
-
/* @__PURE__ */ (0,
|
|
6770
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "flex justify-end gap-1", children: [
|
|
6771
|
+
isDraft && /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("button", { type: "button", className: buttonClass2, onClick: remove, children: "Cancel" }),
|
|
6772
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
6511
6773
|
"button",
|
|
6512
6774
|
{
|
|
6513
6775
|
type: "button",
|
|
@@ -6519,9 +6781,9 @@ var CommentThreadCard = ({
|
|
|
6519
6781
|
)
|
|
6520
6782
|
] })
|
|
6521
6783
|
] }),
|
|
6522
|
-
!isDraft && /* @__PURE__ */ (0,
|
|
6523
|
-
/* @__PURE__ */ (0,
|
|
6524
|
-
/* @__PURE__ */ (0,
|
|
6784
|
+
!isDraft && /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "flex justify-end gap-1", onClick: stop, children: [
|
|
6785
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("button", { type: "button", className: buttonClass2, onClick: () => setResolved(!thread.resolved), children: thread.resolved ? "Reopen" : "Resolve" }),
|
|
6786
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
6525
6787
|
"button",
|
|
6526
6788
|
{
|
|
6527
6789
|
type: "button",
|
|
@@ -6537,7 +6799,7 @@ var CommentThreadCard = ({
|
|
|
6537
6799
|
};
|
|
6538
6800
|
|
|
6539
6801
|
// src/review/ReviewToolbar.tsx
|
|
6540
|
-
var
|
|
6802
|
+
var import_jsx_runtime28 = require("react/jsx-runtime");
|
|
6541
6803
|
var defaultDescriptionClass = "max-w-[16rem] truncate px-1 text-xs text-muted-foreground";
|
|
6542
6804
|
var buttonClass3 = "rounded px-2 py-1 text-xs text-foreground hover:bg-muted disabled:opacity-40 disabled:hover:bg-transparent";
|
|
6543
6805
|
var ReviewToolbar = ({
|
|
@@ -6550,8 +6812,8 @@ var ReviewToolbar = ({
|
|
|
6550
6812
|
const count = review.changes.length;
|
|
6551
6813
|
const current = review.currentChange;
|
|
6552
6814
|
const index = current ? review.changes.findIndex((c) => c.id === current.id) + 1 : 0;
|
|
6553
|
-
return /* @__PURE__ */ (0,
|
|
6554
|
-
/* @__PURE__ */ (0,
|
|
6815
|
+
return /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className, role: "toolbar", "aria-label": "Review", children: [
|
|
6816
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
6555
6817
|
"button",
|
|
6556
6818
|
{
|
|
6557
6819
|
type: "button",
|
|
@@ -6562,8 +6824,8 @@ var ReviewToolbar = ({
|
|
|
6562
6824
|
children: review.enabled ? "Tracking on" : "Track changes"
|
|
6563
6825
|
}
|
|
6564
6826
|
),
|
|
6565
|
-
/* @__PURE__ */ (0,
|
|
6566
|
-
/* @__PURE__ */ (0,
|
|
6827
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", { className: "mx-1 h-4 w-px bg-border", "aria-hidden": "true" }),
|
|
6828
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
6567
6829
|
"button",
|
|
6568
6830
|
{
|
|
6569
6831
|
type: "button",
|
|
@@ -6574,8 +6836,8 @@ var ReviewToolbar = ({
|
|
|
6574
6836
|
children: "\u2039"
|
|
6575
6837
|
}
|
|
6576
6838
|
),
|
|
6577
|
-
/* @__PURE__ */ (0,
|
|
6578
|
-
/* @__PURE__ */ (0,
|
|
6839
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.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` }),
|
|
6840
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
6579
6841
|
"button",
|
|
6580
6842
|
{
|
|
6581
6843
|
type: "button",
|
|
@@ -6586,7 +6848,7 @@ var ReviewToolbar = ({
|
|
|
6586
6848
|
children: "\u203A"
|
|
6587
6849
|
}
|
|
6588
6850
|
),
|
|
6589
|
-
showDescription && current && /* @__PURE__ */ (0,
|
|
6851
|
+
showDescription && current && /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(
|
|
6590
6852
|
"span",
|
|
6591
6853
|
{
|
|
6592
6854
|
className: descriptionClassName,
|
|
@@ -6598,8 +6860,8 @@ var ReviewToolbar = ({
|
|
|
6598
6860
|
]
|
|
6599
6861
|
}
|
|
6600
6862
|
),
|
|
6601
|
-
/* @__PURE__ */ (0,
|
|
6602
|
-
/* @__PURE__ */ (0,
|
|
6863
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", { className: "mx-1 h-4 w-px bg-border", "aria-hidden": "true" }),
|
|
6864
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
6603
6865
|
"button",
|
|
6604
6866
|
{
|
|
6605
6867
|
type: "button",
|
|
@@ -6609,7 +6871,7 @@ var ReviewToolbar = ({
|
|
|
6609
6871
|
children: "Accept"
|
|
6610
6872
|
}
|
|
6611
6873
|
),
|
|
6612
|
-
/* @__PURE__ */ (0,
|
|
6874
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
6613
6875
|
"button",
|
|
6614
6876
|
{
|
|
6615
6877
|
type: "button",
|
|
@@ -6619,18 +6881,18 @@ var ReviewToolbar = ({
|
|
|
6619
6881
|
children: "Reject"
|
|
6620
6882
|
}
|
|
6621
6883
|
),
|
|
6622
|
-
/* @__PURE__ */ (0,
|
|
6623
|
-
/* @__PURE__ */ (0,
|
|
6884
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)("button", { type: "button", className: buttonClass3, disabled: count === 0, onClick: review.acceptAll, children: "Accept all" }),
|
|
6885
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)("button", { type: "button", className: buttonClass3, disabled: count === 0, onClick: review.rejectAll, children: "Reject all" })
|
|
6624
6886
|
] });
|
|
6625
6887
|
};
|
|
6626
6888
|
|
|
6627
6889
|
// src/review/CommentButton.tsx
|
|
6628
|
-
var
|
|
6890
|
+
var import_jsx_runtime29 = require("react/jsx-runtime");
|
|
6629
6891
|
var CommentButton = ({
|
|
6630
6892
|
editor,
|
|
6631
6893
|
className = "rounded px-2 py-1 text-xs text-popover-foreground hover:bg-muted",
|
|
6632
6894
|
children = "Comment"
|
|
6633
|
-
}) => /* @__PURE__ */ (0,
|
|
6895
|
+
}) => /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
6634
6896
|
"button",
|
|
6635
6897
|
{
|
|
6636
6898
|
type: "button",
|
|
@@ -6642,13 +6904,13 @@ var CommentButton = ({
|
|
|
6642
6904
|
);
|
|
6643
6905
|
|
|
6644
6906
|
// src/review/useDocumentCompare.ts
|
|
6645
|
-
var
|
|
6907
|
+
var import_react46 = require("react");
|
|
6646
6908
|
var import_editor14 = require("@pixerate/editor");
|
|
6647
6909
|
function useDocumentCompare(editor, options) {
|
|
6648
|
-
const [summary, setSummary] = (0,
|
|
6649
|
-
const defaults = (0,
|
|
6910
|
+
const [summary, setSummary] = (0, import_react46.useState)(null);
|
|
6911
|
+
const defaults = (0, import_react46.useRef)(options);
|
|
6650
6912
|
defaults.current = options;
|
|
6651
|
-
const compare = (0,
|
|
6913
|
+
const compare = (0, import_react46.useCallback)(
|
|
6652
6914
|
(original, revised, overrides) => {
|
|
6653
6915
|
if (!editor || editor.isDestroyed) return null;
|
|
6654
6916
|
const result = (0, import_editor14.applyDocumentComparison)(editor, original, revised, {
|
|
@@ -6660,13 +6922,13 @@ function useDocumentCompare(editor, options) {
|
|
|
6660
6922
|
},
|
|
6661
6923
|
[editor]
|
|
6662
6924
|
);
|
|
6663
|
-
const clear = (0,
|
|
6664
|
-
return (0,
|
|
6925
|
+
const clear = (0, import_react46.useCallback)(() => setSummary(null), []);
|
|
6926
|
+
return (0, import_react46.useMemo)(() => ({ summary, compare, clear }), [summary, compare, clear]);
|
|
6665
6927
|
}
|
|
6666
6928
|
|
|
6667
6929
|
// src/review/TrackedChangesList.tsx
|
|
6668
6930
|
var import_editor15 = require("@pixerate/editor");
|
|
6669
|
-
var
|
|
6931
|
+
var import_jsx_runtime30 = require("react/jsx-runtime");
|
|
6670
6932
|
var buttonClass4 = "rounded px-1.5 py-0.5 text-xs text-foreground hover:bg-muted disabled:opacity-40";
|
|
6671
6933
|
var TrackedChangesList = ({
|
|
6672
6934
|
editor,
|
|
@@ -6677,18 +6939,18 @@ var TrackedChangesList = ({
|
|
|
6677
6939
|
}) => {
|
|
6678
6940
|
const review = useTrackChanges(editor);
|
|
6679
6941
|
if (review.changes.length === 0) {
|
|
6680
|
-
return /* @__PURE__ */ (0,
|
|
6942
|
+
return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("div", { className, "data-tracked-changes-list": "", children: /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("div", { className: "pixerate-changes-empty text-xs text-muted-foreground", children: emptyState }) });
|
|
6681
6943
|
}
|
|
6682
|
-
return /* @__PURE__ */ (0,
|
|
6944
|
+
return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("ul", { className, role: "list", "aria-label": "Tracked changes", "data-tracked-changes-list": "", children: review.changes.map((change) => {
|
|
6683
6945
|
const active = change.id === review.currentChangeId;
|
|
6684
|
-
return /* @__PURE__ */ (0,
|
|
6946
|
+
return /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(
|
|
6685
6947
|
"li",
|
|
6686
6948
|
{
|
|
6687
6949
|
className: active ? `${itemClassName} ${activeItemClassName}` : itemClassName,
|
|
6688
6950
|
"data-change-type": change.type,
|
|
6689
6951
|
"data-change-id": change.id,
|
|
6690
6952
|
children: [
|
|
6691
|
-
/* @__PURE__ */ (0,
|
|
6953
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(
|
|
6692
6954
|
"button",
|
|
6693
6955
|
{
|
|
6694
6956
|
type: "button",
|
|
@@ -6696,14 +6958,14 @@ var TrackedChangesList = ({
|
|
|
6696
6958
|
title: `${change.author.name}: ${change.description}`,
|
|
6697
6959
|
onClick: () => review.select(change.id),
|
|
6698
6960
|
children: [
|
|
6699
|
-
/* @__PURE__ */ (0,
|
|
6961
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", { className: "font-medium", children: (0, import_editor15.trackedChangeLabel)(change) }),
|
|
6700
6962
|
change.author.name ? ` \xB7 ${change.author.name}` : "",
|
|
6701
|
-
/* @__PURE__ */ (0,
|
|
6963
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", { className: "block truncate text-muted-foreground", children: change.description })
|
|
6702
6964
|
]
|
|
6703
6965
|
}
|
|
6704
6966
|
),
|
|
6705
|
-
/* @__PURE__ */ (0,
|
|
6706
|
-
/* @__PURE__ */ (0,
|
|
6967
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("button", { type: "button", className: buttonClass4, onClick: () => review.accept(change.id), children: "Accept" }),
|
|
6968
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("button", { type: "button", className: buttonClass4, onClick: () => review.reject(change.id), children: "Reject" })
|
|
6707
6969
|
]
|
|
6708
6970
|
},
|
|
6709
6971
|
`${change.type}:${change.id}`
|
|
@@ -6712,12 +6974,12 @@ var TrackedChangesList = ({
|
|
|
6712
6974
|
};
|
|
6713
6975
|
|
|
6714
6976
|
// src/commands/useCommandPalette.ts
|
|
6715
|
-
var
|
|
6977
|
+
var import_react47 = require("react");
|
|
6716
6978
|
var import_commands2 = require("@pixerate/editor/commands");
|
|
6717
6979
|
function useCommandPalette(registry, options = {}) {
|
|
6718
|
-
const optionsRef = (0,
|
|
6980
|
+
const optionsRef = (0, import_react47.useRef)(options);
|
|
6719
6981
|
optionsRef.current = options;
|
|
6720
|
-
const controller = (0,
|
|
6982
|
+
const controller = (0, import_react47.useMemo)(
|
|
6721
6983
|
() => (0, import_commands2.createCommandPaletteController)(registry, {
|
|
6722
6984
|
context: () => {
|
|
6723
6985
|
const c = optionsRef.current.context;
|
|
@@ -6738,9 +7000,9 @@ function useCommandPalette(registry, options = {}) {
|
|
|
6738
7000
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
6739
7001
|
[registry]
|
|
6740
7002
|
);
|
|
6741
|
-
const state = (0,
|
|
7003
|
+
const state = (0, import_react47.useSyncExternalStore)(controller.subscribe, controller.getState, controller.getState);
|
|
6742
7004
|
const { hotkey, hotkeyTarget } = options;
|
|
6743
|
-
(0,
|
|
7005
|
+
(0, import_react47.useEffect)(() => {
|
|
6744
7006
|
if (!hotkey) return;
|
|
6745
7007
|
const target = hotkeyTarget ?? (typeof window !== "undefined" ? window : null);
|
|
6746
7008
|
if (!target) return;
|
|
@@ -6768,13 +7030,13 @@ function useCommandPalette(registry, options = {}) {
|
|
|
6768
7030
|
}
|
|
6769
7031
|
|
|
6770
7032
|
// src/commands/CommandPalette.tsx
|
|
6771
|
-
var
|
|
6772
|
-
var
|
|
7033
|
+
var import_react48 = __toESM(require("react"), 1);
|
|
7034
|
+
var import_jsx_runtime31 = require("react/jsx-runtime");
|
|
6773
7035
|
function HighlightedLabel({ item }) {
|
|
6774
|
-
if (item.labelIndices.length === 0) return /* @__PURE__ */ (0,
|
|
7036
|
+
if (item.labelIndices.length === 0) return /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_jsx_runtime31.Fragment, { children: item.label });
|
|
6775
7037
|
const marked = new Set(item.labelIndices);
|
|
6776
|
-
return /* @__PURE__ */ (0,
|
|
6777
|
-
(ch, i) => marked.has(i) ? /* @__PURE__ */ (0,
|
|
7038
|
+
return /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_jsx_runtime31.Fragment, { children: Array.from(item.label).map(
|
|
7039
|
+
(ch, i) => marked.has(i) ? /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("span", { className: "font-semibold text-foreground", "data-match": "", children: ch }, i) : /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_react48.default.Fragment, { children: ch }, i)
|
|
6778
7040
|
) });
|
|
6779
7041
|
}
|
|
6780
7042
|
var CommandPalette = ({
|
|
@@ -6783,22 +7045,22 @@ var CommandPalette = ({
|
|
|
6783
7045
|
emptyMessage = "No matching commands",
|
|
6784
7046
|
className = ""
|
|
6785
7047
|
}) => {
|
|
6786
|
-
const inputRef = (0,
|
|
6787
|
-
const listRef = (0,
|
|
6788
|
-
const baseId = (0,
|
|
7048
|
+
const inputRef = (0, import_react48.useRef)(null);
|
|
7049
|
+
const listRef = (0, import_react48.useRef)(null);
|
|
7050
|
+
const baseId = (0, import_react48.useId)();
|
|
6789
7051
|
const listId = `${baseId}-list`;
|
|
6790
7052
|
const optionId = (index) => `${baseId}-option-${index}`;
|
|
6791
7053
|
const { open, query, items, activeIndex } = palette;
|
|
6792
|
-
(0,
|
|
7054
|
+
(0, import_react48.useEffect)(() => {
|
|
6793
7055
|
if (open) inputRef.current?.focus();
|
|
6794
7056
|
}, [open]);
|
|
6795
|
-
(0,
|
|
7057
|
+
(0, import_react48.useEffect)(() => {
|
|
6796
7058
|
if (!open) return;
|
|
6797
7059
|
const active = listRef.current?.querySelector('[aria-selected="true"]');
|
|
6798
7060
|
active?.scrollIntoView?.({ block: "nearest" });
|
|
6799
7061
|
}, [open, activeIndex]);
|
|
6800
7062
|
if (!open) return null;
|
|
6801
|
-
return /* @__PURE__ */ (0,
|
|
7063
|
+
return /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
|
|
6802
7064
|
"div",
|
|
6803
7065
|
{
|
|
6804
7066
|
className: "fixed inset-0 z-50 flex items-start justify-center bg-black/30 px-4 pt-[15vh]",
|
|
@@ -6806,7 +7068,7 @@ var CommandPalette = ({
|
|
|
6806
7068
|
onMouseDown: (e) => {
|
|
6807
7069
|
if (e.target === e.currentTarget) palette.setOpen(false);
|
|
6808
7070
|
},
|
|
6809
|
-
children: /* @__PURE__ */ (0,
|
|
7071
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(
|
|
6810
7072
|
"div",
|
|
6811
7073
|
{
|
|
6812
7074
|
role: "dialog",
|
|
@@ -6815,7 +7077,7 @@ var CommandPalette = ({
|
|
|
6815
7077
|
className: `w-full max-w-lg overflow-hidden rounded-lg border border-border bg-popover text-popover-foreground shadow-xl ${className}`,
|
|
6816
7078
|
style: { background: "var(--popover, var(--background, #fff))" },
|
|
6817
7079
|
children: [
|
|
6818
|
-
/* @__PURE__ */ (0,
|
|
7080
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
|
|
6819
7081
|
"input",
|
|
6820
7082
|
{
|
|
6821
7083
|
ref: inputRef,
|
|
@@ -6835,7 +7097,7 @@ var CommandPalette = ({
|
|
|
6835
7097
|
className: "w-full border-b border-border bg-transparent px-3 py-2 text-sm outline-none placeholder:text-muted-foreground"
|
|
6836
7098
|
}
|
|
6837
7099
|
),
|
|
6838
|
-
items.length === 0 ? /* @__PURE__ */ (0,
|
|
7100
|
+
items.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("div", { className: "px-3 py-6 text-center text-sm text-muted-foreground", children: emptyMessage }) : /* @__PURE__ */ (0, import_jsx_runtime31.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_runtime31.jsxs)(
|
|
6839
7101
|
"li",
|
|
6840
7102
|
{
|
|
6841
7103
|
id: optionId(index),
|
|
@@ -6850,12 +7112,12 @@ var CommandPalette = ({
|
|
|
6850
7112
|
onClick: () => palette.run(item.id),
|
|
6851
7113
|
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"}`,
|
|
6852
7114
|
children: [
|
|
6853
|
-
/* @__PURE__ */ (0,
|
|
6854
|
-
/* @__PURE__ */ (0,
|
|
6855
|
-
item.disabledReason && /* @__PURE__ */ (0,
|
|
7115
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("span", { className: "min-w-0 flex-1 truncate", children: [
|
|
7116
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)(HighlightedLabel, { item }),
|
|
7117
|
+
item.disabledReason && /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("span", { className: "ml-2 text-xs text-muted-foreground", "data-disabled-reason": "", children: item.disabledReason })
|
|
6856
7118
|
] }),
|
|
6857
|
-
item.group && /* @__PURE__ */ (0,
|
|
6858
|
-
item.shortcut && /* @__PURE__ */ (0,
|
|
7119
|
+
item.group && /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("span", { className: "shrink-0 text-xs text-muted-foreground", children: item.group }),
|
|
7120
|
+
item.shortcut && /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("kbd", { className: "shrink-0 rounded border border-border px-1.5 font-mono text-[10px] text-muted-foreground", children: item.shortcut })
|
|
6859
7121
|
]
|
|
6860
7122
|
},
|
|
6861
7123
|
item.id
|
|
@@ -6868,12 +7130,12 @@ var CommandPalette = ({
|
|
|
6868
7130
|
};
|
|
6869
7131
|
|
|
6870
7132
|
// src/commands/useCommandShortcuts.ts
|
|
6871
|
-
var
|
|
7133
|
+
var import_react49 = require("react");
|
|
6872
7134
|
function useCommandShortcuts(registry, options = {}) {
|
|
6873
|
-
const optionsRef = (0,
|
|
7135
|
+
const optionsRef = (0, import_react49.useRef)(options);
|
|
6874
7136
|
optionsRef.current = options;
|
|
6875
7137
|
const { enabled = true, target } = options;
|
|
6876
|
-
(0,
|
|
7138
|
+
(0, import_react49.useEffect)(() => {
|
|
6877
7139
|
if (!registry || !enabled) return;
|
|
6878
7140
|
const eventTarget = target ?? (typeof window !== "undefined" ? window : null);
|
|
6879
7141
|
if (!eventTarget) return;
|
|
@@ -6891,14 +7153,14 @@ function useCommandShortcuts(registry, options = {}) {
|
|
|
6891
7153
|
}, [registry, enabled, target]);
|
|
6892
7154
|
}
|
|
6893
7155
|
function useRegisterCommands(registry, specs) {
|
|
6894
|
-
(0,
|
|
7156
|
+
(0, import_react49.useEffect)(() => {
|
|
6895
7157
|
if (!registry || !specs || specs.length === 0) return;
|
|
6896
7158
|
return registry.register(specs);
|
|
6897
7159
|
}, [registry, specs]);
|
|
6898
7160
|
}
|
|
6899
7161
|
|
|
6900
7162
|
// src/persistence/useAutosave.ts
|
|
6901
|
-
var
|
|
7163
|
+
var import_react50 = require("react");
|
|
6902
7164
|
var import_persistence = require("@pixerate/editor/persistence");
|
|
6903
7165
|
var IDLE = {
|
|
6904
7166
|
status: "idle",
|
|
@@ -6909,18 +7171,18 @@ var IDLE = {
|
|
|
6909
7171
|
ready: false
|
|
6910
7172
|
};
|
|
6911
7173
|
function useAutosave(options) {
|
|
6912
|
-
const optionsRef = (0,
|
|
7174
|
+
const optionsRef = (0, import_react50.useRef)(options);
|
|
6913
7175
|
optionsRef.current = options;
|
|
6914
7176
|
const { storage, key, history, dirty } = options;
|
|
6915
7177
|
const recover = options.recover !== false;
|
|
6916
7178
|
const flushOnHide = options.flushOnHide !== false;
|
|
6917
7179
|
const ready = options.ready !== false;
|
|
6918
|
-
const [controller, setController] = (0,
|
|
6919
|
-
const [status, setStatus] = (0,
|
|
6920
|
-
const [recovery, setRecovery] = (0,
|
|
6921
|
-
const [pendingRecovery, setPendingRecovery] = (0,
|
|
6922
|
-
const revisionsRef = (0,
|
|
6923
|
-
(0,
|
|
7180
|
+
const [controller, setController] = (0, import_react50.useState)(null);
|
|
7181
|
+
const [status, setStatus] = (0, import_react50.useState)(IDLE);
|
|
7182
|
+
const [recovery, setRecovery] = (0, import_react50.useState)(null);
|
|
7183
|
+
const [pendingRecovery, setPendingRecovery] = (0, import_react50.useState)(recover);
|
|
7184
|
+
const revisionsRef = (0, import_react50.useRef)(null);
|
|
7185
|
+
(0, import_react50.useEffect)(() => {
|
|
6924
7186
|
const revisions = (0, import_persistence.createRevisionTracker)({ history, dirty });
|
|
6925
7187
|
const o = optionsRef.current;
|
|
6926
7188
|
const instance = (0, import_persistence.createAutosaveController)({
|
|
@@ -6963,10 +7225,10 @@ function useAutosave(options) {
|
|
|
6963
7225
|
if (revisionsRef.current === revisions) revisionsRef.current = null;
|
|
6964
7226
|
};
|
|
6965
7227
|
}, [storage, key, history, dirty, recover]);
|
|
6966
|
-
(0,
|
|
7228
|
+
(0, import_react50.useEffect)(() => {
|
|
6967
7229
|
if (controller && ready && !pendingRecovery) controller.ready();
|
|
6968
7230
|
}, [controller, ready, pendingRecovery]);
|
|
6969
|
-
(0,
|
|
7231
|
+
(0, import_react50.useEffect)(() => {
|
|
6970
7232
|
if (!controller || !flushOnHide || typeof window === "undefined") return;
|
|
6971
7233
|
const flush = () => void controller.flushNow();
|
|
6972
7234
|
const onVisibility = () => {
|
|
@@ -6979,31 +7241,31 @@ function useAutosave(options) {
|
|
|
6979
7241
|
document.removeEventListener("visibilitychange", onVisibility);
|
|
6980
7242
|
};
|
|
6981
7243
|
}, [controller, flushOnHide]);
|
|
6982
|
-
const restore = (0,
|
|
7244
|
+
const restore = (0, import_react50.useCallback)(() => {
|
|
6983
7245
|
const snapshot = recovery?.snapshot;
|
|
6984
7246
|
setRecovery(null);
|
|
6985
7247
|
setPendingRecovery(false);
|
|
6986
7248
|
return snapshot;
|
|
6987
7249
|
}, [recovery]);
|
|
6988
|
-
const discard = (0,
|
|
7250
|
+
const discard = (0, import_react50.useCallback)(async () => {
|
|
6989
7251
|
if (controller) await controller.discardRecovery();
|
|
6990
7252
|
setRecovery(null);
|
|
6991
7253
|
setPendingRecovery(false);
|
|
6992
7254
|
}, [controller]);
|
|
6993
|
-
const flushNow = (0,
|
|
7255
|
+
const flushNow = (0, import_react50.useCallback)(async () => {
|
|
6994
7256
|
await controller?.flushNow();
|
|
6995
7257
|
}, [controller]);
|
|
6996
|
-
const markClean = (0,
|
|
7258
|
+
const markClean = (0, import_react50.useCallback)(async () => {
|
|
6997
7259
|
revisionsRef.current?.markSaved();
|
|
6998
7260
|
await controller?.markClean();
|
|
6999
7261
|
}, [controller]);
|
|
7000
|
-
const notifyChange = (0,
|
|
7262
|
+
const notifyChange = (0, import_react50.useCallback)(() => revisionsRef.current?.bump(), []);
|
|
7001
7263
|
return { status, recovery, pendingRecovery, restore, discard, flushNow, markClean, notifyChange, controller };
|
|
7002
7264
|
}
|
|
7003
7265
|
|
|
7004
7266
|
// src/persistence/RecoveryPrompt.tsx
|
|
7005
7267
|
var import_persistence2 = require("@pixerate/editor/persistence");
|
|
7006
|
-
var
|
|
7268
|
+
var import_jsx_runtime32 = require("react/jsx-runtime");
|
|
7007
7269
|
var RecoveryPrompt = ({
|
|
7008
7270
|
recovery,
|
|
7009
7271
|
onRestore,
|
|
@@ -7015,7 +7277,7 @@ var RecoveryPrompt = ({
|
|
|
7015
7277
|
}) => {
|
|
7016
7278
|
if (!recovery) return null;
|
|
7017
7279
|
const { name } = recovery.meta;
|
|
7018
|
-
return /* @__PURE__ */ (0,
|
|
7280
|
+
return /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(
|
|
7019
7281
|
"div",
|
|
7020
7282
|
{
|
|
7021
7283
|
role: "alertdialog",
|
|
@@ -7023,15 +7285,15 @@ var RecoveryPrompt = ({
|
|
|
7023
7285
|
"data-recovery-prompt": "",
|
|
7024
7286
|
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}`,
|
|
7025
7287
|
children: [
|
|
7026
|
-
/* @__PURE__ */ (0,
|
|
7288
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("span", { className: "min-w-0 flex-1", children: [
|
|
7027
7289
|
(0, import_persistence2.formatRecoveryMessage)(recovery.meta, formatTime),
|
|
7028
|
-
name ? /* @__PURE__ */ (0,
|
|
7290
|
+
name ? /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("span", { className: "ml-1 text-xs text-muted-foreground", children: [
|
|
7029
7291
|
"(",
|
|
7030
7292
|
name,
|
|
7031
7293
|
")"
|
|
7032
7294
|
] }) : null
|
|
7033
7295
|
] }),
|
|
7034
|
-
/* @__PURE__ */ (0,
|
|
7296
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
7035
7297
|
"button",
|
|
7036
7298
|
{
|
|
7037
7299
|
type: "button",
|
|
@@ -7041,7 +7303,7 @@ var RecoveryPrompt = ({
|
|
|
7041
7303
|
children: restoreLabel
|
|
7042
7304
|
}
|
|
7043
7305
|
),
|
|
7044
|
-
/* @__PURE__ */ (0,
|
|
7306
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
7045
7307
|
"button",
|
|
7046
7308
|
{
|
|
7047
7309
|
type: "button",
|
|
@@ -7057,17 +7319,17 @@ var RecoveryPrompt = ({
|
|
|
7057
7319
|
};
|
|
7058
7320
|
|
|
7059
7321
|
// src/generation/useGenerationPlan.ts
|
|
7060
|
-
var
|
|
7322
|
+
var import_react51 = require("react");
|
|
7061
7323
|
var import_generation = require("@pixerate/editor/generation");
|
|
7062
7324
|
function useGenerationPlan(request, capabilities, options = {}) {
|
|
7063
7325
|
const key = JSON.stringify([request, capabilities, options]);
|
|
7064
|
-
return (0,
|
|
7326
|
+
return (0, import_react51.useMemo)(() => (0, import_generation.planGenerationRequest)(request, capabilities, options), [key]);
|
|
7065
7327
|
}
|
|
7066
7328
|
function useJobProgress(options) {
|
|
7067
7329
|
const { startedAt, expectedMs, done, now, intervalMs = 1e3 } = options;
|
|
7068
|
-
const [tick, setTick] = (0,
|
|
7330
|
+
const [tick, setTick] = (0, import_react51.useState)(() => Date.now());
|
|
7069
7331
|
const ticking = !done && now === void 0;
|
|
7070
|
-
(0,
|
|
7332
|
+
(0, import_react51.useEffect)(() => {
|
|
7071
7333
|
if (!ticking) return;
|
|
7072
7334
|
setTick(Date.now());
|
|
7073
7335
|
const id = setInterval(() => setTick(Date.now()), Math.max(16, intervalMs));
|
|
@@ -7077,9 +7339,9 @@ function useJobProgress(options) {
|
|
|
7077
7339
|
}
|
|
7078
7340
|
|
|
7079
7341
|
// src/generation/GenerationSettings.tsx
|
|
7080
|
-
var
|
|
7342
|
+
var import_react52 = require("react");
|
|
7081
7343
|
var import_generation2 = require("@pixerate/editor/generation");
|
|
7082
|
-
var
|
|
7344
|
+
var import_jsx_runtime33 = require("react/jsx-runtime");
|
|
7083
7345
|
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";
|
|
7084
7346
|
function Control({
|
|
7085
7347
|
control,
|
|
@@ -7089,7 +7351,7 @@ function Control({
|
|
|
7089
7351
|
}) {
|
|
7090
7352
|
const shown = value ?? control.defaultValue;
|
|
7091
7353
|
if (control.kind === "checkbox") {
|
|
7092
|
-
return /* @__PURE__ */ (0,
|
|
7354
|
+
return /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
|
|
7093
7355
|
"input",
|
|
7094
7356
|
{
|
|
7095
7357
|
id,
|
|
@@ -7101,7 +7363,7 @@ function Control({
|
|
|
7101
7363
|
);
|
|
7102
7364
|
}
|
|
7103
7365
|
if (control.kind === "select") {
|
|
7104
|
-
return /* @__PURE__ */ (0,
|
|
7366
|
+
return /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(
|
|
7105
7367
|
"select",
|
|
7106
7368
|
{
|
|
7107
7369
|
id,
|
|
@@ -7110,14 +7372,14 @@ function Control({
|
|
|
7110
7372
|
value: shown === void 0 ? "" : String(shown),
|
|
7111
7373
|
onChange: (e) => onValue((0, import_generation2.parseControlValue)(control, e.target.value)),
|
|
7112
7374
|
children: [
|
|
7113
|
-
shown === void 0 && /* @__PURE__ */ (0,
|
|
7114
|
-
control.options.map((option) => /* @__PURE__ */ (0,
|
|
7375
|
+
shown === void 0 && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("option", { value: "", children: "Default" }),
|
|
7376
|
+
control.options.map((option) => /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("option", { value: String(option.value), children: option.label }, String(option.value)))
|
|
7115
7377
|
]
|
|
7116
7378
|
}
|
|
7117
7379
|
);
|
|
7118
7380
|
}
|
|
7119
7381
|
if (control.kind === "textarea") {
|
|
7120
|
-
return /* @__PURE__ */ (0,
|
|
7382
|
+
return /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
|
|
7121
7383
|
"textarea",
|
|
7122
7384
|
{
|
|
7123
7385
|
id,
|
|
@@ -7131,8 +7393,8 @@ function Control({
|
|
|
7131
7393
|
);
|
|
7132
7394
|
}
|
|
7133
7395
|
const numeric = typeof shown === "number" ? shown : void 0;
|
|
7134
|
-
return /* @__PURE__ */ (0,
|
|
7135
|
-
/* @__PURE__ */ (0,
|
|
7396
|
+
return /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
7397
|
+
/* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
|
|
7136
7398
|
"input",
|
|
7137
7399
|
{
|
|
7138
7400
|
id,
|
|
@@ -7146,7 +7408,7 @@ function Control({
|
|
|
7146
7408
|
onChange: (e) => onValue((0, import_generation2.parseControlValue)(control, e.target.value))
|
|
7147
7409
|
}
|
|
7148
7410
|
),
|
|
7149
|
-
control.kind === "range" && /* @__PURE__ */ (0,
|
|
7411
|
+
control.kind === "range" && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("span", { className: "w-10 text-right tabular-nums text-muted-foreground", "data-field-value": "", children: numeric ?? "\u2013" })
|
|
7150
7412
|
] });
|
|
7151
7413
|
}
|
|
7152
7414
|
var GenerationSettings = ({
|
|
@@ -7160,17 +7422,17 @@ var GenerationSettings = ({
|
|
|
7160
7422
|
renderReference,
|
|
7161
7423
|
className = ""
|
|
7162
7424
|
}) => {
|
|
7163
|
-
const baseId = (0,
|
|
7164
|
-
const controls = (0,
|
|
7425
|
+
const baseId = (0, import_react52.useId)();
|
|
7426
|
+
const controls = (0, import_react52.useMemo)(() => (0, import_generation2.getGenerationControls)(capabilities), [capabilities]);
|
|
7165
7427
|
const computed = useGenerationPlan(value, capabilities, { strategy });
|
|
7166
7428
|
const plan = planProp ?? computed;
|
|
7167
7429
|
const slots = (0, import_generation2.getReferenceSlots)(capabilities, value);
|
|
7168
|
-
return /* @__PURE__ */ (0,
|
|
7430
|
+
return /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("div", { className: `flex flex-col gap-3 text-sm ${className}`, "data-generation-settings": "", "data-model": capabilities.id, children: [
|
|
7169
7431
|
controls.map((control) => {
|
|
7170
7432
|
const id = `${baseId}-${control.key}`;
|
|
7171
|
-
return /* @__PURE__ */ (0,
|
|
7172
|
-
/* @__PURE__ */ (0,
|
|
7173
|
-
/* @__PURE__ */ (0,
|
|
7433
|
+
return /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("div", { className: "flex flex-col gap-1", "data-control": control.key, children: [
|
|
7434
|
+
/* @__PURE__ */ (0, import_jsx_runtime33.jsx)("label", { htmlFor: id, className: "text-xs font-medium text-muted-foreground", title: control.description, children: control.label }),
|
|
7435
|
+
/* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
|
|
7174
7436
|
Control,
|
|
7175
7437
|
{
|
|
7176
7438
|
control,
|
|
@@ -7181,23 +7443,23 @@ var GenerationSettings = ({
|
|
|
7181
7443
|
)
|
|
7182
7444
|
] }, control.key);
|
|
7183
7445
|
}),
|
|
7184
|
-
slots.map((slot) => /* @__PURE__ */ (0,
|
|
7185
|
-
/* @__PURE__ */ (0,
|
|
7446
|
+
slots.map((slot) => /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("fieldset", { className: "flex flex-col gap-1", "data-reference-role": slot.role, children: [
|
|
7447
|
+
/* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("legend", { className: "text-xs font-medium text-muted-foreground", title: slot.description, children: [
|
|
7186
7448
|
slot.label,
|
|
7187
7449
|
" ",
|
|
7188
|
-
/* @__PURE__ */ (0,
|
|
7450
|
+
/* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("span", { className: "tabular-nums", "data-reference-count": "", children: [
|
|
7189
7451
|
"(",
|
|
7190
7452
|
slot.references.length,
|
|
7191
7453
|
"/",
|
|
7192
7454
|
slot.max,
|
|
7193
7455
|
")"
|
|
7194
7456
|
] }),
|
|
7195
|
-
slot.min > 0 && /* @__PURE__ */ (0,
|
|
7457
|
+
slot.min > 0 && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("span", { className: "text-destructive", children: " *" })
|
|
7196
7458
|
] }),
|
|
7197
|
-
/* @__PURE__ */ (0,
|
|
7198
|
-
slot.references.map((ref) => /* @__PURE__ */ (0,
|
|
7199
|
-
renderReference ? renderReference(ref) : /* @__PURE__ */ (0,
|
|
7200
|
-
/* @__PURE__ */ (0,
|
|
7459
|
+
/* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("ul", { className: "flex flex-wrap gap-1", children: [
|
|
7460
|
+
slot.references.map((ref) => /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("li", { className: "flex items-center gap-1 rounded border border-border px-1.5 py-0.5", "data-reference-id": ref.id, children: [
|
|
7461
|
+
renderReference ? renderReference(ref) : /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("span", { className: "max-w-[10rem] truncate", children: ref.id }),
|
|
7462
|
+
/* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
|
|
7201
7463
|
"button",
|
|
7202
7464
|
{
|
|
7203
7465
|
type: "button",
|
|
@@ -7208,7 +7470,7 @@ var GenerationSettings = ({
|
|
|
7208
7470
|
}
|
|
7209
7471
|
)
|
|
7210
7472
|
] }, ref.id)),
|
|
7211
|
-
onAddReference && slot.canAdd && /* @__PURE__ */ (0,
|
|
7473
|
+
onAddReference && slot.canAdd && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("li", { children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
|
|
7212
7474
|
"button",
|
|
7213
7475
|
{
|
|
7214
7476
|
type: "button",
|
|
@@ -7219,21 +7481,21 @@ var GenerationSettings = ({
|
|
|
7219
7481
|
) })
|
|
7220
7482
|
] })
|
|
7221
7483
|
] }, slot.role)),
|
|
7222
|
-
showAdjustments && plan.adjustments.length > 0 && /* @__PURE__ */ (0,
|
|
7223
|
-
showAdjustments && plan.errors.length > 0 && /* @__PURE__ */ (0,
|
|
7484
|
+
showAdjustments && plan.adjustments.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime33.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_runtime33.jsx)("li", { "data-adjustment-field": adjustment.field, "data-adjustment-kind": adjustment.kind, children: adjustment.reason }, index)) }),
|
|
7485
|
+
showAdjustments && plan.errors.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime33.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_runtime33.jsx)("li", { "data-error-field": error.field, children: error.message }, index)) })
|
|
7224
7486
|
] });
|
|
7225
7487
|
};
|
|
7226
7488
|
|
|
7227
7489
|
// src/generation/JobProgress.tsx
|
|
7228
|
-
var
|
|
7490
|
+
var import_jsx_runtime34 = require("react/jsx-runtime");
|
|
7229
7491
|
var JobProgress = ({ title, className = "", ...options }) => {
|
|
7230
7492
|
const progress = useJobProgress(options);
|
|
7231
|
-
return /* @__PURE__ */ (0,
|
|
7232
|
-
/* @__PURE__ */ (0,
|
|
7233
|
-
title && /* @__PURE__ */ (0,
|
|
7234
|
-
/* @__PURE__ */ (0,
|
|
7493
|
+
return /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("div", { className: `flex flex-col gap-1 text-sm ${className}`, "data-job-progress": "", "data-done": options.done ? "" : void 0, children: [
|
|
7494
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("div", { className: "flex items-center justify-between gap-2 text-muted-foreground", children: [
|
|
7495
|
+
title && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("span", { className: "truncate text-foreground", children: title }),
|
|
7496
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)("span", { "data-job-progress-label": "", "aria-live": "polite", children: progress.label })
|
|
7235
7497
|
] }),
|
|
7236
|
-
/* @__PURE__ */ (0,
|
|
7498
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
7237
7499
|
"div",
|
|
7238
7500
|
{
|
|
7239
7501
|
role: "progressbar",
|
|
@@ -7243,7 +7505,7 @@ var JobProgress = ({ title, className = "", ...options }) => {
|
|
|
7243
7505
|
"aria-valuenow": progress.percent,
|
|
7244
7506
|
"aria-valuetext": `${progress.percent}%, ${progress.label}`,
|
|
7245
7507
|
className: "h-1.5 w-full overflow-hidden rounded-full bg-muted",
|
|
7246
|
-
children: /* @__PURE__ */ (0,
|
|
7508
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
7247
7509
|
"div",
|
|
7248
7510
|
{
|
|
7249
7511
|
className: "h-full rounded-full bg-primary transition-[width] duration-500",
|
|
@@ -7256,9 +7518,9 @@ var JobProgress = ({ title, className = "", ...options }) => {
|
|
|
7256
7518
|
};
|
|
7257
7519
|
|
|
7258
7520
|
// src/generation/AssetMentionChips.tsx
|
|
7259
|
-
var
|
|
7521
|
+
var import_react53 = require("react");
|
|
7260
7522
|
var import_generation3 = require("@pixerate/editor/generation");
|
|
7261
|
-
var
|
|
7523
|
+
var import_jsx_runtime35 = require("react/jsx-runtime");
|
|
7262
7524
|
var AssetMentionChips = ({
|
|
7263
7525
|
content,
|
|
7264
7526
|
onChange,
|
|
@@ -7268,14 +7530,14 @@ var AssetMentionChips = ({
|
|
|
7268
7530
|
renderAsset,
|
|
7269
7531
|
className = ""
|
|
7270
7532
|
}) => {
|
|
7271
|
-
const [open, setOpen] = (0,
|
|
7272
|
-
const rootRef = (0,
|
|
7273
|
-
const chips = (0,
|
|
7533
|
+
const [open, setOpen] = (0, import_react53.useState)(null);
|
|
7534
|
+
const rootRef = (0, import_react53.useRef)(null);
|
|
7535
|
+
const chips = (0, import_react53.useMemo)(
|
|
7274
7536
|
() => (0, import_generation3.describeAssetMentions)((0, import_generation3.findTextMentions)(content), assets, capabilities),
|
|
7275
7537
|
[content, assets, capabilities]
|
|
7276
7538
|
);
|
|
7277
7539
|
const options = roles ?? (capabilities ? (0, import_generation3.getAssetRoleOptions)(capabilities) : (0, import_generation3.defaultAssetRoleOptions)());
|
|
7278
|
-
(0,
|
|
7540
|
+
(0, import_react53.useEffect)(() => {
|
|
7279
7541
|
if (open === null) return;
|
|
7280
7542
|
const onPointer = (event) => {
|
|
7281
7543
|
if (!rootRef.current?.contains(event.target)) setOpen(null);
|
|
@@ -7289,13 +7551,13 @@ var AssetMentionChips = ({
|
|
|
7289
7551
|
onChange((0, import_generation3.setMentionRoleInText)(content, chip2.start, role));
|
|
7290
7552
|
};
|
|
7291
7553
|
if (chips.length === 0) return null;
|
|
7292
|
-
return /* @__PURE__ */ (0,
|
|
7554
|
+
return /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("div", { ref: rootRef, className: `flex flex-wrap gap-1.5 ${className}`, "data-asset-mention-chips": "", children: chips.map((chip2) => {
|
|
7293
7555
|
const error = chip2.issues.find((issue) => issue.severity === "error");
|
|
7294
7556
|
const warning = chip2.issues.find((issue) => issue.severity === "warning");
|
|
7295
7557
|
const problem = error ?? warning;
|
|
7296
7558
|
const isOpen = open === chip2.index;
|
|
7297
|
-
return /* @__PURE__ */ (0,
|
|
7298
|
-
/* @__PURE__ */ (0,
|
|
7559
|
+
return /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("span", { className: "relative inline-flex", "data-asset-chip": chip2.asset.id, children: [
|
|
7560
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsxs)(
|
|
7299
7561
|
"button",
|
|
7300
7562
|
{
|
|
7301
7563
|
type: "button",
|
|
@@ -7309,8 +7571,8 @@ var AssetMentionChips = ({
|
|
|
7309
7571
|
},
|
|
7310
7572
|
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`,
|
|
7311
7573
|
children: [
|
|
7312
|
-
/* @__PURE__ */ (0,
|
|
7313
|
-
/* @__PURE__ */ (0,
|
|
7574
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsx)("span", { children: renderAsset ? renderAsset(chip2) : `@${chip2.asset.label ?? chip2.handle}` }),
|
|
7575
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
|
|
7314
7576
|
"span",
|
|
7315
7577
|
{
|
|
7316
7578
|
className: `rounded px-1 text-[10px] uppercase tracking-wide ${chip2.role ? "bg-primary/15" : "opacity-60"}`,
|
|
@@ -7321,7 +7583,7 @@ var AssetMentionChips = ({
|
|
|
7321
7583
|
]
|
|
7322
7584
|
}
|
|
7323
7585
|
),
|
|
7324
|
-
isOpen && /* @__PURE__ */ (0,
|
|
7586
|
+
isOpen && /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)(
|
|
7325
7587
|
"div",
|
|
7326
7588
|
{
|
|
7327
7589
|
role: "listbox",
|
|
@@ -7332,7 +7594,7 @@ var AssetMentionChips = ({
|
|
|
7332
7594
|
if (e.key === "Escape") setOpen(null);
|
|
7333
7595
|
},
|
|
7334
7596
|
children: [
|
|
7335
|
-
options.map((option) => /* @__PURE__ */ (0,
|
|
7597
|
+
options.map((option) => /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)(
|
|
7336
7598
|
"button",
|
|
7337
7599
|
{
|
|
7338
7600
|
type: "button",
|
|
@@ -7343,13 +7605,13 @@ var AssetMentionChips = ({
|
|
|
7343
7605
|
onClick: () => pick(chip2, option.role),
|
|
7344
7606
|
className: "flex items-center justify-between gap-2 rounded px-2 py-1 text-left hover:bg-muted",
|
|
7345
7607
|
children: [
|
|
7346
|
-
/* @__PURE__ */ (0,
|
|
7347
|
-
option.accepts?.length ? /* @__PURE__ */ (0,
|
|
7608
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsx)("span", { children: option.label }),
|
|
7609
|
+
option.accepts?.length ? /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("span", { className: "text-[10px] opacity-60", children: option.accepts.join(", ") }) : null
|
|
7348
7610
|
]
|
|
7349
7611
|
},
|
|
7350
7612
|
option.role
|
|
7351
7613
|
)),
|
|
7352
|
-
/* @__PURE__ */ (0,
|
|
7614
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
|
|
7353
7615
|
"button",
|
|
7354
7616
|
{
|
|
7355
7617
|
type: "button",
|
|
@@ -7361,7 +7623,7 @@ var AssetMentionChips = ({
|
|
|
7361
7623
|
children: "No role"
|
|
7362
7624
|
}
|
|
7363
7625
|
),
|
|
7364
|
-
chip2.issues.length > 0 && /* @__PURE__ */ (0,
|
|
7626
|
+
chip2.issues.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("ul", { className: "mt-1 border-t border-border px-2 pt-1 text-[10px]", "data-chip-issues": "", children: chip2.issues.map((issue, i) => /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("li", { className: issue.severity === "error" ? "text-red-500" : "text-amber-500", children: issue.message }, i)) })
|
|
7365
7627
|
]
|
|
7366
7628
|
}
|
|
7367
7629
|
)
|
|
@@ -7370,15 +7632,15 @@ var AssetMentionChips = ({
|
|
|
7370
7632
|
};
|
|
7371
7633
|
|
|
7372
7634
|
// src/generation/GenerationHistory.tsx
|
|
7373
|
-
var
|
|
7635
|
+
var import_react54 = require("react");
|
|
7374
7636
|
var import_generation4 = require("@pixerate/editor/generation");
|
|
7375
|
-
var
|
|
7637
|
+
var import_jsx_runtime36 = require("react/jsx-runtime");
|
|
7376
7638
|
function useGenerationRecords(store, filter) {
|
|
7377
|
-
const [records, setRecords] = (0,
|
|
7378
|
-
const [loading, setLoading] = (0,
|
|
7379
|
-
const [error, setError] = (0,
|
|
7639
|
+
const [records, setRecords] = (0, import_react54.useState)([]);
|
|
7640
|
+
const [loading, setLoading] = (0, import_react54.useState)(!!store);
|
|
7641
|
+
const [error, setError] = (0, import_react54.useState)(null);
|
|
7380
7642
|
const filterKey = (0, import_generation4.stableStringify)(filter ?? {});
|
|
7381
|
-
const refresh = (0,
|
|
7643
|
+
const refresh = (0, import_react54.useCallback)(async () => {
|
|
7382
7644
|
if (!store) {
|
|
7383
7645
|
setRecords([]);
|
|
7384
7646
|
setLoading(false);
|
|
@@ -7395,7 +7657,7 @@ function useGenerationRecords(store, filter) {
|
|
|
7395
7657
|
setLoading(false);
|
|
7396
7658
|
}
|
|
7397
7659
|
}, [store, filterKey]);
|
|
7398
|
-
(0,
|
|
7660
|
+
(0, import_react54.useEffect)(() => {
|
|
7399
7661
|
void refresh();
|
|
7400
7662
|
if (!store) return;
|
|
7401
7663
|
return store.subscribe(() => void refresh());
|
|
@@ -7421,21 +7683,21 @@ var GenerationHistory = ({
|
|
|
7421
7683
|
emptyText = "No generations yet.",
|
|
7422
7684
|
className = ""
|
|
7423
7685
|
}) => {
|
|
7424
|
-
const [innerMode, setInnerMode] = (0,
|
|
7686
|
+
const [innerMode, setInnerMode] = (0, import_react54.useState)("exact");
|
|
7425
7687
|
const mode = modeProp ?? innerMode;
|
|
7426
7688
|
const setMode = (next) => {
|
|
7427
7689
|
if (modeProp === void 0) setInnerMode(next);
|
|
7428
7690
|
onModeChange?.(next);
|
|
7429
7691
|
};
|
|
7430
|
-
const options = (0,
|
|
7431
|
-
const results = (0,
|
|
7432
|
-
const models = (0,
|
|
7692
|
+
const options = (0, import_react54.useMemo)(() => ({ templates, capabilities, assets, mode }), [templates, capabilities, assets, mode]);
|
|
7693
|
+
const results = (0, import_react54.useMemo)(() => records.map((record) => (0, import_generation4.recreateRequest)(record, options)), [records, options]);
|
|
7694
|
+
const models = (0, import_react54.useMemo)(
|
|
7433
7695
|
() => capabilities ? Array.isArray(capabilities) ? capabilities : [capabilities] : [],
|
|
7434
7696
|
[capabilities]
|
|
7435
7697
|
);
|
|
7436
|
-
return /* @__PURE__ */ (0,
|
|
7437
|
-
/* @__PURE__ */ (0,
|
|
7438
|
-
/* @__PURE__ */ (0,
|
|
7698
|
+
return /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("div", { className: `flex flex-col gap-2 text-sm ${className}`, "data-generation-history": "", children: [
|
|
7699
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.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_runtime36.jsxs)("label", { className: "inline-flex items-center gap-1", children: [
|
|
7700
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
7439
7701
|
"input",
|
|
7440
7702
|
{
|
|
7441
7703
|
type: "radio",
|
|
@@ -7448,34 +7710,34 @@ var GenerationHistory = ({
|
|
|
7448
7710
|
),
|
|
7449
7711
|
value === "exact" ? "Exact (recorded versions)" : "Latest templates & settings"
|
|
7450
7712
|
] }, value)) }),
|
|
7451
|
-
records.length === 0 && /* @__PURE__ */ (0,
|
|
7452
|
-
/* @__PURE__ */ (0,
|
|
7713
|
+
records.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("p", { className: "text-xs text-muted-foreground", children: emptyText }),
|
|
7714
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)("ul", { className: "flex flex-col gap-2", children: records.map((record, i) => {
|
|
7453
7715
|
const result = results[i];
|
|
7454
7716
|
const model = models.find((m) => m.id === record.provenance.modelId);
|
|
7455
7717
|
const blocked = !result.ok;
|
|
7456
|
-
return /* @__PURE__ */ (0,
|
|
7718
|
+
return /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(
|
|
7457
7719
|
"li",
|
|
7458
7720
|
{
|
|
7459
7721
|
className: "rounded-md border border-border p-2",
|
|
7460
7722
|
"data-record": record.id,
|
|
7461
7723
|
"data-drift": result.drift.length,
|
|
7462
7724
|
children: [
|
|
7463
|
-
/* @__PURE__ */ (0,
|
|
7464
|
-
/* @__PURE__ */ (0,
|
|
7465
|
-
/* @__PURE__ */ (0,
|
|
7466
|
-
record.kind !== "generate" && /* @__PURE__ */ (0,
|
|
7725
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("div", { className: "flex flex-wrap items-center justify-between gap-2 text-xs", children: [
|
|
7726
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)("span", { className: "font-medium", children: model?.name ?? record.provenance.modelId }),
|
|
7727
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("span", { className: "text-muted-foreground", children: [
|
|
7728
|
+
record.kind !== "generate" && /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("span", { "data-kind": "", children: [
|
|
7467
7729
|
record.kind,
|
|
7468
7730
|
" \xB7 "
|
|
7469
7731
|
] }),
|
|
7470
|
-
/* @__PURE__ */ (0,
|
|
7471
|
-
record.seed !== void 0 && /* @__PURE__ */ (0,
|
|
7732
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)("time", { dateTime: record.createdAt, children: record.createdAt.replace("T", " ").slice(0, 16) }),
|
|
7733
|
+
record.seed !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(import_jsx_runtime36.Fragment, { children: [
|
|
7472
7734
|
" \xB7 seed ",
|
|
7473
7735
|
record.seed
|
|
7474
7736
|
] })
|
|
7475
7737
|
] })
|
|
7476
7738
|
] }),
|
|
7477
|
-
/* @__PURE__ */ (0,
|
|
7478
|
-
record.assets.length > 0 && /* @__PURE__ */ (0,
|
|
7739
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)("p", { className: "mt-1 line-clamp-3 break-words text-xs", "data-record-prompt": "", children: record.provenance.resolvedPrompt }),
|
|
7740
|
+
record.assets.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("div", { className: "mt-1 flex flex-wrap gap-1", children: record.assets.map((asset) => /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(
|
|
7479
7741
|
"span",
|
|
7480
7742
|
{
|
|
7481
7743
|
className: "rounded-full bg-muted px-2 py-0.5 text-[10px]",
|
|
@@ -7489,16 +7751,16 @@ var GenerationHistory = ({
|
|
|
7489
7751
|
`${asset.role}:${asset.id}`
|
|
7490
7752
|
)) }),
|
|
7491
7753
|
renderPreview?.(record),
|
|
7492
|
-
result.drift.length > 0 && /* @__PURE__ */ (0,
|
|
7493
|
-
/* @__PURE__ */ (0,
|
|
7754
|
+
result.drift.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime36.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_runtime36.jsxs)("li", { className: severityClass[item.severity], "data-drift-type": item.type, children: [
|
|
7755
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("strong", { children: [
|
|
7494
7756
|
import_generation4.DRIFT_TYPE_LABELS[item.type],
|
|
7495
7757
|
":"
|
|
7496
7758
|
] }),
|
|
7497
7759
|
" ",
|
|
7498
7760
|
item.message
|
|
7499
7761
|
] }, j)) }),
|
|
7500
|
-
/* @__PURE__ */ (0,
|
|
7501
|
-
onRecreate && /* @__PURE__ */ (0,
|
|
7762
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("div", { className: "mt-2 flex gap-2", children: [
|
|
7763
|
+
onRecreate && /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
7502
7764
|
"button",
|
|
7503
7765
|
{
|
|
7504
7766
|
type: "button",
|
|
@@ -7510,7 +7772,7 @@ var GenerationHistory = ({
|
|
|
7510
7772
|
children: "Recreate"
|
|
7511
7773
|
}
|
|
7512
7774
|
),
|
|
7513
|
-
onVariation && /* @__PURE__ */ (0,
|
|
7775
|
+
onVariation && /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
7514
7776
|
"button",
|
|
7515
7777
|
{
|
|
7516
7778
|
type: "button",
|
|
@@ -7520,7 +7782,7 @@ var GenerationHistory = ({
|
|
|
7520
7782
|
children: "Variation"
|
|
7521
7783
|
}
|
|
7522
7784
|
),
|
|
7523
|
-
onRemove && /* @__PURE__ */ (0,
|
|
7785
|
+
onRemove && /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
7524
7786
|
"button",
|
|
7525
7787
|
{
|
|
7526
7788
|
type: "button",
|
|
@@ -7540,19 +7802,19 @@ var GenerationHistory = ({
|
|
|
7540
7802
|
};
|
|
7541
7803
|
|
|
7542
7804
|
// src/find-replace/useFindReplace.ts
|
|
7543
|
-
var
|
|
7805
|
+
var import_react55 = require("react");
|
|
7544
7806
|
var import_editor16 = require("@pixerate/editor");
|
|
7545
7807
|
var noopUnsubscribe2 = () => {
|
|
7546
7808
|
};
|
|
7547
7809
|
function useFindReplace(editor) {
|
|
7548
7810
|
const store = (0, import_editor16.getFindReplaceStore)(editor ?? null);
|
|
7549
|
-
const subscribe = (0,
|
|
7811
|
+
const subscribe = (0, import_react55.useCallback)(
|
|
7550
7812
|
(onChange) => store ? store.subscribe(() => onChange()) : noopUnsubscribe2,
|
|
7551
7813
|
[store]
|
|
7552
7814
|
);
|
|
7553
7815
|
const getSnapshot = () => store?.getSnapshot() ?? import_editor16.EMPTY_FIND_REPLACE_SNAPSHOT;
|
|
7554
|
-
const snapshot = (0,
|
|
7555
|
-
return (0,
|
|
7816
|
+
const snapshot = (0, import_react55.useSyncExternalStore)(subscribe, getSnapshot, getSnapshot);
|
|
7817
|
+
return (0, import_react55.useMemo)(() => {
|
|
7556
7818
|
const run = (fn) => {
|
|
7557
7819
|
if (editor && !editor.isDestroyed && store) fn(editor);
|
|
7558
7820
|
};
|
|
@@ -7576,9 +7838,9 @@ function useFindReplace(editor) {
|
|
|
7576
7838
|
}
|
|
7577
7839
|
|
|
7578
7840
|
// src/find-replace/FindReplaceBar.tsx
|
|
7579
|
-
var
|
|
7841
|
+
var import_react56 = require("react");
|
|
7580
7842
|
var import_editor17 = require("@pixerate/editor");
|
|
7581
|
-
var
|
|
7843
|
+
var import_jsx_runtime37 = require("react/jsx-runtime");
|
|
7582
7844
|
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";
|
|
7583
7845
|
var buttonClass5 = "rounded px-2 py-1 text-xs text-foreground hover:bg-muted disabled:opacity-40 disabled:hover:bg-transparent";
|
|
7584
7846
|
var toggleClass = (on) => `${buttonClass5} font-mono ${on ? "bg-primary/10 text-primary" : "text-muted-foreground"}`;
|
|
@@ -7591,10 +7853,10 @@ var FindReplaceBar = ({
|
|
|
7591
7853
|
onClose
|
|
7592
7854
|
}) => {
|
|
7593
7855
|
const find = useFindReplace(editor);
|
|
7594
|
-
const findInput = (0,
|
|
7595
|
-
const [moreOpen, setMoreOpen] = (0,
|
|
7856
|
+
const findInput = (0, import_react56.useRef)(null);
|
|
7857
|
+
const [moreOpen, setMoreOpen] = (0, import_react56.useState)(false);
|
|
7596
7858
|
const visible = find.available && (alwaysOpen || find.open);
|
|
7597
|
-
(0,
|
|
7859
|
+
(0, import_react56.useEffect)(() => {
|
|
7598
7860
|
if (!visible || find.focusRequest === 0) return;
|
|
7599
7861
|
findInput.current?.focus();
|
|
7600
7862
|
findInput.current?.select();
|
|
@@ -7632,9 +7894,9 @@ var FindReplaceBar = ({
|
|
|
7632
7894
|
if (isMod(e)) find.replaceAll();
|
|
7633
7895
|
else find.replace();
|
|
7634
7896
|
};
|
|
7635
|
-
return /* @__PURE__ */ (0,
|
|
7636
|
-
/* @__PURE__ */ (0,
|
|
7637
|
-
/* @__PURE__ */ (0,
|
|
7897
|
+
return /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("div", { className, role: "search", "aria-label": "Find and replace", onKeyDown: onBarKeyDown, children: [
|
|
7898
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("div", { className: "flex items-center gap-1", children: [
|
|
7899
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
|
|
7638
7900
|
"button",
|
|
7639
7901
|
{
|
|
7640
7902
|
type: "button",
|
|
@@ -7645,7 +7907,7 @@ var FindReplaceBar = ({
|
|
|
7645
7907
|
children: showReplace ? "\u25BE" : "\u25B8"
|
|
7646
7908
|
}
|
|
7647
7909
|
),
|
|
7648
|
-
/* @__PURE__ */ (0,
|
|
7910
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
|
|
7649
7911
|
"input",
|
|
7650
7912
|
{
|
|
7651
7913
|
ref: findInput,
|
|
@@ -7659,7 +7921,7 @@ var FindReplaceBar = ({
|
|
|
7659
7921
|
onKeyDown: onFindKeyDown
|
|
7660
7922
|
}
|
|
7661
7923
|
),
|
|
7662
|
-
import_editor17.FIND_OPTION_TOGGLES.filter((t) => !t.advanced).map((t) => /* @__PURE__ */ (0,
|
|
7924
|
+
import_editor17.FIND_OPTION_TOGGLES.filter((t) => !t.advanced).map((t) => /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
|
|
7663
7925
|
"button",
|
|
7664
7926
|
{
|
|
7665
7927
|
type: "button",
|
|
@@ -7672,7 +7934,7 @@ var FindReplaceBar = ({
|
|
|
7672
7934
|
},
|
|
7673
7935
|
t.key
|
|
7674
7936
|
)),
|
|
7675
|
-
/* @__PURE__ */ (0,
|
|
7937
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
|
|
7676
7938
|
"span",
|
|
7677
7939
|
{
|
|
7678
7940
|
className: `min-w-[5rem] px-1 text-center text-xs ${find.error ? "text-destructive" : "text-muted-foreground"}`,
|
|
@@ -7682,9 +7944,9 @@ var FindReplaceBar = ({
|
|
|
7682
7944
|
children: status
|
|
7683
7945
|
}
|
|
7684
7946
|
),
|
|
7685
|
-
/* @__PURE__ */ (0,
|
|
7686
|
-
/* @__PURE__ */ (0,
|
|
7687
|
-
showMoreOptions && /* @__PURE__ */ (0,
|
|
7947
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsx)("button", { type: "button", className: buttonClass5, "aria-label": "Previous match", disabled: !hasMatches, onClick: find.previous, children: "\u2191" }),
|
|
7948
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsx)("button", { type: "button", className: buttonClass5, "aria-label": "Next match", disabled: !hasMatches, onClick: find.next, children: "\u2193" }),
|
|
7949
|
+
showMoreOptions && /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
|
|
7688
7950
|
"button",
|
|
7689
7951
|
{
|
|
7690
7952
|
type: "button",
|
|
@@ -7695,10 +7957,10 @@ var FindReplaceBar = ({
|
|
|
7695
7957
|
children: "\u2026"
|
|
7696
7958
|
}
|
|
7697
7959
|
),
|
|
7698
|
-
/* @__PURE__ */ (0,
|
|
7960
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsx)("button", { type: "button", className: buttonClass5, "aria-label": "Close find", onClick: close, children: "\xD7" })
|
|
7699
7961
|
] }),
|
|
7700
|
-
showReplace && /* @__PURE__ */ (0,
|
|
7701
|
-
/* @__PURE__ */ (0,
|
|
7962
|
+
showReplace && /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("div", { className: "flex items-center gap-1 pl-7", children: [
|
|
7963
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
|
|
7702
7964
|
"input",
|
|
7703
7965
|
{
|
|
7704
7966
|
type: "text",
|
|
@@ -7710,7 +7972,7 @@ var FindReplaceBar = ({
|
|
|
7710
7972
|
onKeyDown: onReplaceKeyDown
|
|
7711
7973
|
}
|
|
7712
7974
|
),
|
|
7713
|
-
/* @__PURE__ */ (0,
|
|
7975
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
|
|
7714
7976
|
"button",
|
|
7715
7977
|
{
|
|
7716
7978
|
type: "button",
|
|
@@ -7720,11 +7982,11 @@ var FindReplaceBar = ({
|
|
|
7720
7982
|
children: "Replace"
|
|
7721
7983
|
}
|
|
7722
7984
|
),
|
|
7723
|
-
/* @__PURE__ */ (0,
|
|
7724
|
-
find.lastReplaceCount !== null && /* @__PURE__ */ (0,
|
|
7985
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsx)("button", { type: "button", className: buttonClass5, disabled: !hasMatches, onClick: find.replaceAll, children: "Replace all" }),
|
|
7986
|
+
find.lastReplaceCount !== null && /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("span", { className: "px-1 text-xs text-muted-foreground", "aria-live": "polite", children: find.lastReplaceCount === 1 ? "1 replaced" : `${find.lastReplaceCount} replaced` })
|
|
7725
7987
|
] }),
|
|
7726
|
-
showMoreOptions && moreOpen && /* @__PURE__ */ (0,
|
|
7727
|
-
/* @__PURE__ */ (0,
|
|
7988
|
+
showMoreOptions && moreOpen && /* @__PURE__ */ (0, import_jsx_runtime37.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_runtime37.jsxs)("label", { className: "flex items-center gap-1", children: [
|
|
7989
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
|
|
7728
7990
|
"input",
|
|
7729
7991
|
{
|
|
7730
7992
|
type: "checkbox",
|
|
@@ -7738,12 +8000,12 @@ var FindReplaceBar = ({
|
|
|
7738
8000
|
};
|
|
7739
8001
|
|
|
7740
8002
|
// src/tables/useTableMenu.ts
|
|
7741
|
-
var
|
|
8003
|
+
var import_react57 = require("react");
|
|
7742
8004
|
var import_editor18 = require("@pixerate/editor");
|
|
7743
8005
|
function useTableMenu(editor) {
|
|
7744
|
-
const store = (0,
|
|
7745
|
-
const snapshot = (0,
|
|
7746
|
-
return (0,
|
|
8006
|
+
const store = (0, import_react57.useMemo)(() => (0, import_editor18.createTableStore)(editor), [editor]);
|
|
8007
|
+
const snapshot = (0, import_react57.useSyncExternalStore)(store.subscribe, store.getSnapshot, store.getSnapshot);
|
|
8008
|
+
return (0, import_react57.useMemo)(
|
|
7747
8009
|
() => ({
|
|
7748
8010
|
...snapshot,
|
|
7749
8011
|
run: (action, params) => (0, import_editor18.runTableAction)(editor, action, params, { focus: true }),
|
|
@@ -7754,9 +8016,9 @@ function useTableMenu(editor) {
|
|
|
7754
8016
|
}
|
|
7755
8017
|
|
|
7756
8018
|
// src/tables/TableToolbar.tsx
|
|
7757
|
-
var
|
|
8019
|
+
var import_react58 = __toESM(require("react"), 1);
|
|
7758
8020
|
var import_editor19 = require("@pixerate/editor");
|
|
7759
|
-
var
|
|
8021
|
+
var import_jsx_runtime38 = require("react/jsx-runtime");
|
|
7760
8022
|
var keepSelection2 = (event) => event.preventDefault();
|
|
7761
8023
|
var TableToolbar = ({
|
|
7762
8024
|
editor,
|
|
@@ -7770,14 +8032,14 @@ var TableToolbar = ({
|
|
|
7770
8032
|
}) => {
|
|
7771
8033
|
const table = useTableMenu(editor);
|
|
7772
8034
|
if (!editor || !table.inTable && !showWhenOutside) return null;
|
|
7773
|
-
return /* @__PURE__ */ (0,
|
|
8035
|
+
return /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("div", { className, role: "toolbar", "aria-label": "Table", "data-table-toolbar": "", children: items.map((item, index) => {
|
|
7774
8036
|
const status = table.check(item.action, item.params);
|
|
7775
8037
|
const enabled = status === true;
|
|
7776
8038
|
const active = item.active?.(table);
|
|
7777
8039
|
const separator = index > 0 && items[index - 1].group !== item.group;
|
|
7778
|
-
return /* @__PURE__ */ (0,
|
|
7779
|
-
separator && /* @__PURE__ */ (0,
|
|
7780
|
-
/* @__PURE__ */ (0,
|
|
8040
|
+
return /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(import_react58.default.Fragment, { children: [
|
|
8041
|
+
separator && /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("span", { className: separatorClassName, "aria-hidden": "true" }),
|
|
8042
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
|
|
7781
8043
|
"button",
|
|
7782
8044
|
{
|
|
7783
8045
|
type: "button",
|
|
@@ -7799,8 +8061,8 @@ var TableToolbar = ({
|
|
|
7799
8061
|
};
|
|
7800
8062
|
|
|
7801
8063
|
// src/tables/InsertTableGrid.tsx
|
|
7802
|
-
var
|
|
7803
|
-
var
|
|
8064
|
+
var import_react59 = require("react");
|
|
8065
|
+
var import_jsx_runtime39 = require("react/jsx-runtime");
|
|
7804
8066
|
var keepSelection3 = (event) => event.preventDefault();
|
|
7805
8067
|
var InsertTableGrid = ({
|
|
7806
8068
|
editor,
|
|
@@ -7813,14 +8075,14 @@ var InsertTableGrid = ({
|
|
|
7813
8075
|
onInsert
|
|
7814
8076
|
}) => {
|
|
7815
8077
|
const table = useTableMenu(editor);
|
|
7816
|
-
const [hover, setHover] = (0,
|
|
8078
|
+
const [hover, setHover] = (0, import_react59.useState)(null);
|
|
7817
8079
|
const status = table.actions.insertTable;
|
|
7818
8080
|
const disabled = !editor || !status.enabled;
|
|
7819
8081
|
const insert = (size) => {
|
|
7820
8082
|
if (table.run("insertTable", { ...size, withHeaderRow })) onInsert?.(size);
|
|
7821
8083
|
setHover(null);
|
|
7822
8084
|
};
|
|
7823
|
-
return /* @__PURE__ */ (0,
|
|
8085
|
+
return /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)(
|
|
7824
8086
|
"div",
|
|
7825
8087
|
{
|
|
7826
8088
|
className,
|
|
@@ -7830,7 +8092,7 @@ var InsertTableGrid = ({
|
|
|
7830
8092
|
"data-insert-table-grid": "",
|
|
7831
8093
|
onMouseLeave: () => setHover(null),
|
|
7832
8094
|
children: [
|
|
7833
|
-
/* @__PURE__ */ (0,
|
|
8095
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
|
|
7834
8096
|
"div",
|
|
7835
8097
|
{
|
|
7836
8098
|
role: "grid",
|
|
@@ -7839,7 +8101,7 @@ var InsertTableGrid = ({
|
|
|
7839
8101
|
children: Array.from({ length: rows * cols }, (_, i) => {
|
|
7840
8102
|
const size = { rows: Math.floor(i / cols) + 1, cols: i % cols + 1 };
|
|
7841
8103
|
const active = !!hover && size.rows <= hover.rows && size.cols <= hover.cols;
|
|
7842
|
-
return /* @__PURE__ */ (0,
|
|
8104
|
+
return /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
|
|
7843
8105
|
"button",
|
|
7844
8106
|
{
|
|
7845
8107
|
type: "button",
|
|
@@ -7859,7 +8121,7 @@ var InsertTableGrid = ({
|
|
|
7859
8121
|
})
|
|
7860
8122
|
}
|
|
7861
8123
|
),
|
|
7862
|
-
/* @__PURE__ */ (0,
|
|
8124
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsx)("div", { "aria-live": "polite", "data-testid": "insert-table-size", children: disabled ? status.reason : hover ? `${hover.rows} \xD7 ${hover.cols}` : "Insert table" })
|
|
7863
8125
|
]
|
|
7864
8126
|
}
|
|
7865
8127
|
);
|
|
@@ -7867,31 +8129,31 @@ var InsertTableGrid = ({
|
|
|
7867
8129
|
|
|
7868
8130
|
// src/tables/TableBubbleMenu.tsx
|
|
7869
8131
|
var import_editor20 = require("@pixerate/editor");
|
|
7870
|
-
var
|
|
8132
|
+
var import_jsx_runtime40 = require("react/jsx-runtime");
|
|
7871
8133
|
var TableBubbleMenu = ({
|
|
7872
8134
|
editor,
|
|
7873
8135
|
children,
|
|
7874
8136
|
toolbarProps,
|
|
7875
8137
|
pluginKey = "tableBubbleMenu",
|
|
7876
8138
|
...rest
|
|
7877
|
-
}) => /* @__PURE__ */ (0,
|
|
8139
|
+
}) => /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(BubbleMenu, { editor, pluginKey, shouldShow: import_editor20.shouldShowTableBubbleMenu, ...rest, children: children ?? /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(TableToolbar, { editor, ...toolbarProps }) });
|
|
7878
8140
|
|
|
7879
8141
|
// src/chart-node/ChartNodeView.tsx
|
|
7880
8142
|
var import_client = require("react-dom/client");
|
|
7881
8143
|
|
|
7882
8144
|
// src/chart/ChartCanvas.tsx
|
|
7883
|
-
var
|
|
8145
|
+
var import_react61 = require("react");
|
|
7884
8146
|
var import_chart2 = require("@pixerate/editor/chart");
|
|
7885
8147
|
|
|
7886
8148
|
// src/chart/useChartEditor.ts
|
|
7887
|
-
var
|
|
8149
|
+
var import_react60 = require("react");
|
|
7888
8150
|
var import_chart = require("@pixerate/editor/chart");
|
|
7889
8151
|
function useChartState(controller) {
|
|
7890
|
-
return (0,
|
|
8152
|
+
return (0, import_react60.useSyncExternalStore)(controller.subscribe, controller.getState, controller.getState);
|
|
7891
8153
|
}
|
|
7892
8154
|
|
|
7893
8155
|
// src/chart/ChartCanvas.tsx
|
|
7894
|
-
var
|
|
8156
|
+
var import_jsx_runtime41 = require("react/jsx-runtime");
|
|
7895
8157
|
function renderChartMark(mark, fontFamily, interactive) {
|
|
7896
8158
|
const common = {
|
|
7897
8159
|
"data-role": mark.role,
|
|
@@ -7903,9 +8165,9 @@ function renderChartMark(mark, fontFamily, interactive) {
|
|
|
7903
8165
|
};
|
|
7904
8166
|
switch (mark.kind) {
|
|
7905
8167
|
case "rect":
|
|
7906
|
-
return /* @__PURE__ */ (0,
|
|
8168
|
+
return /* @__PURE__ */ (0, import_jsx_runtime41.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);
|
|
7907
8169
|
case "path":
|
|
7908
|
-
return /* @__PURE__ */ (0,
|
|
8170
|
+
return /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
|
|
7909
8171
|
"path",
|
|
7910
8172
|
{
|
|
7911
8173
|
...common,
|
|
@@ -7918,11 +8180,11 @@ function renderChartMark(mark, fontFamily, interactive) {
|
|
|
7918
8180
|
mark.key
|
|
7919
8181
|
);
|
|
7920
8182
|
case "circle":
|
|
7921
|
-
return /* @__PURE__ */ (0,
|
|
8183
|
+
return /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("circle", { ...common, cx: mark.cx, cy: mark.cy, r: mark.r, style: { fill: mark.fill, stroke: mark.stroke, strokeWidth: mark.strokeWidth } }, mark.key);
|
|
7922
8184
|
case "line":
|
|
7923
|
-
return /* @__PURE__ */ (0,
|
|
8185
|
+
return /* @__PURE__ */ (0, import_jsx_runtime41.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);
|
|
7924
8186
|
case "text":
|
|
7925
|
-
return /* @__PURE__ */ (0,
|
|
8187
|
+
return /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
|
|
7926
8188
|
"text",
|
|
7927
8189
|
{
|
|
7928
8190
|
...common,
|
|
@@ -7939,23 +8201,23 @@ function renderChartMark(mark, fontFamily, interactive) {
|
|
|
7939
8201
|
}
|
|
7940
8202
|
}
|
|
7941
8203
|
function ChartPresenceLayer({ presence }) {
|
|
7942
|
-
const { actors } = (0,
|
|
7943
|
-
return /* @__PURE__ */ (0,
|
|
7944
|
-
/* @__PURE__ */ (0,
|
|
7945
|
-
/* @__PURE__ */ (0,
|
|
7946
|
-
/* @__PURE__ */ (0,
|
|
7947
|
-
/* @__PURE__ */ (0,
|
|
8204
|
+
const { actors } = (0, import_react61.useSyncExternalStore)(presence.subscribe, presence.getState, presence.getState);
|
|
8205
|
+
return /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("g", { "data-chart-presence": "", pointerEvents: "none", children: actors.map((a) => /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("g", { transform: `translate(${a.x} ${a.y})`, "data-actor": a.id, children: [
|
|
8206
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.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 }),
|
|
8207
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("g", { transform: "translate(13 16)", children: [
|
|
8208
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.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 } }),
|
|
8209
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)("text", { x: 6, y: 9, dominantBaseline: "central", style: { fill: "#ffffff", fontSize: 11, fontWeight: 600, fontFamily: "inherit" }, children: a.message ?? a.name })
|
|
7948
8210
|
] })
|
|
7949
8211
|
] }, a.id)) });
|
|
7950
8212
|
}
|
|
7951
8213
|
function ChartCanvas({ controller, width = 640, height = 400, responsive = true, theme, editable = true, measureText, emptyMessage, className, presence, sceneRef }) {
|
|
7952
8214
|
const state = useChartState(controller);
|
|
7953
|
-
const wrapper = (0,
|
|
7954
|
-
const svg = (0,
|
|
7955
|
-
const drag = (0,
|
|
7956
|
-
const [measured, setMeasured] = (0,
|
|
7957
|
-
const [frozen, setFrozen] = (0,
|
|
7958
|
-
(0,
|
|
8215
|
+
const wrapper = (0, import_react61.useRef)(null);
|
|
8216
|
+
const svg = (0, import_react61.useRef)(null);
|
|
8217
|
+
const drag = (0, import_react61.useRef)(null);
|
|
8218
|
+
const [measured, setMeasured] = (0, import_react61.useState)(null);
|
|
8219
|
+
const [frozen, setFrozen] = (0, import_react61.useState)(null);
|
|
8220
|
+
(0, import_react61.useEffect)(() => {
|
|
7959
8221
|
const el = wrapper.current;
|
|
7960
8222
|
if (!responsive || !el || typeof ResizeObserver === "undefined") return;
|
|
7961
8223
|
const observer = new ResizeObserver(([entry]) => {
|
|
@@ -7966,8 +8228,8 @@ function ChartCanvas({ controller, width = 640, height = 400, responsive = true,
|
|
|
7966
8228
|
return () => observer.disconnect();
|
|
7967
8229
|
}, [responsive]);
|
|
7968
8230
|
const sceneWidth = responsive && measured || width;
|
|
7969
|
-
const fullTheme = (0,
|
|
7970
|
-
const scene = (0,
|
|
8231
|
+
const fullTheme = (0, import_react61.useMemo)(() => ({ ...import_chart2.CSS_VARIABLE_CHART_THEME, ...theme }), [theme]);
|
|
8232
|
+
const scene = (0, import_react61.useMemo)(
|
|
7971
8233
|
() => (0, import_chart2.layoutChart)(state.spec, {
|
|
7972
8234
|
width: sceneWidth,
|
|
7973
8235
|
height,
|
|
@@ -7983,8 +8245,8 @@ function ChartCanvas({ controller, width = 640, height = 400, responsive = true,
|
|
|
7983
8245
|
[state.spec, state.selection, sceneWidth, height, fullTheme, editable, measureText, emptyMessage, frozen]
|
|
7984
8246
|
);
|
|
7985
8247
|
if (sceneRef) sceneRef.current = scene;
|
|
7986
|
-
const byKey = (0,
|
|
7987
|
-
(0,
|
|
8248
|
+
const byKey = (0, import_react61.useMemo)(() => new Map(scene.marks.map((m) => [m.key, m])), [scene]);
|
|
8249
|
+
(0, import_react61.useEffect)(() => () => drag.current?.end(), []);
|
|
7988
8250
|
const scenePoint = (e) => (0, import_chart2.chartClientToScene)(scene, svg.current.getBoundingClientRect(), e.clientX, e.clientY);
|
|
7989
8251
|
const onPointerDown = (e) => {
|
|
7990
8252
|
if (!editable || e.button !== 0) return;
|
|
@@ -8017,7 +8279,7 @@ function ChartCanvas({ controller, width = 640, height = 400, responsive = true,
|
|
|
8017
8279
|
if (editable && (0, import_chart2.handleChartKey)(controller, scene, e)) e.preventDefault();
|
|
8018
8280
|
};
|
|
8019
8281
|
const label = state.spec.title || "Chart";
|
|
8020
|
-
return /* @__PURE__ */ (0,
|
|
8282
|
+
return /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("div", { ref: wrapper, className: `w-full ${className ?? ""}`, "data-chart-canvas": "", children: /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)(
|
|
8021
8283
|
"svg",
|
|
8022
8284
|
{
|
|
8023
8285
|
ref: svg,
|
|
@@ -8035,14 +8297,14 @@ function ChartCanvas({ controller, width = 640, height = 400, responsive = true,
|
|
|
8035
8297
|
onKeyDown,
|
|
8036
8298
|
children: [
|
|
8037
8299
|
scene.marks.map((m) => renderChartMark(m, scene.theme.fontFamily, editable)),
|
|
8038
|
-
presence && /* @__PURE__ */ (0,
|
|
8300
|
+
presence && /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(ChartPresenceLayer, { presence })
|
|
8039
8301
|
]
|
|
8040
8302
|
}
|
|
8041
8303
|
) });
|
|
8042
8304
|
}
|
|
8043
8305
|
|
|
8044
8306
|
// src/chart/ChartDataGrid.tsx
|
|
8045
|
-
var
|
|
8307
|
+
var import_react62 = require("react");
|
|
8046
8308
|
var import_chart3 = require("@pixerate/editor/chart");
|
|
8047
8309
|
|
|
8048
8310
|
// src/chart/styles.ts
|
|
@@ -8055,11 +8317,11 @@ var chartSectionClass = "space-y-2 border-b border-border pb-3 last:border-b-0";
|
|
|
8055
8317
|
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";
|
|
8056
8318
|
|
|
8057
8319
|
// src/chart/ChartDataGrid.tsx
|
|
8058
|
-
var
|
|
8320
|
+
var import_jsx_runtime42 = require("react/jsx-runtime");
|
|
8059
8321
|
function ChartCommitInput({ value, onCommit, onKeyDown, onBlur, ...rest }) {
|
|
8060
|
-
const [draft, setDraft] = (0,
|
|
8061
|
-
const typing = (0,
|
|
8062
|
-
(0,
|
|
8322
|
+
const [draft, setDraft] = (0, import_react62.useState)(value);
|
|
8323
|
+
const typing = (0, import_react62.useRef)(false);
|
|
8324
|
+
(0, import_react62.useEffect)(() => {
|
|
8063
8325
|
if (!typing.current) setDraft(value);
|
|
8064
8326
|
}, [value]);
|
|
8065
8327
|
const commit = () => {
|
|
@@ -8068,7 +8330,7 @@ function ChartCommitInput({ value, onCommit, onKeyDown, onBlur, ...rest }) {
|
|
|
8068
8330
|
if (draft === value) return;
|
|
8069
8331
|
if (onCommit(draft) === false) setDraft(value);
|
|
8070
8332
|
};
|
|
8071
|
-
return /* @__PURE__ */ (0,
|
|
8333
|
+
return /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
|
|
8072
8334
|
"input",
|
|
8073
8335
|
{
|
|
8074
8336
|
...rest,
|
|
@@ -8103,15 +8365,15 @@ function ChartDataGrid({ controller, categoryHeader = "Category", readOnly = fal
|
|
|
8103
8365
|
e.preventDefault();
|
|
8104
8366
|
controller.pasteCells(row, column, text);
|
|
8105
8367
|
};
|
|
8106
|
-
return /* @__PURE__ */ (0,
|
|
8107
|
-
/* @__PURE__ */ (0,
|
|
8108
|
-
/* @__PURE__ */ (0,
|
|
8109
|
-
/* @__PURE__ */ (0,
|
|
8368
|
+
return /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("div", { className: `overflow-auto rounded-md border border-border ${className ?? ""}`, "data-chart-grid": "", children: [
|
|
8369
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("table", { className: "w-full border-collapse text-xs", children: [
|
|
8370
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)("thead", { className: "bg-muted/50", children: /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("tr", { children: [
|
|
8371
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)("th", { className: "border-b border-r border-border px-2 py-1 text-left font-medium text-muted-foreground", children: categoryHeader }),
|
|
8110
8372
|
spec.series.map((s, si) => {
|
|
8111
8373
|
const color = (0, import_chart3.chartSeriesColor)(spec, si);
|
|
8112
8374
|
const selected = selection?.kind === "series" && selection.seriesId === s.id;
|
|
8113
|
-
return /* @__PURE__ */ (0,
|
|
8114
|
-
/* @__PURE__ */ (0,
|
|
8375
|
+
return /* @__PURE__ */ (0, import_jsx_runtime42.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_runtime42.jsxs)("div", { className: "flex items-center gap-1", children: [
|
|
8376
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
|
|
8115
8377
|
"input",
|
|
8116
8378
|
{
|
|
8117
8379
|
type: "color",
|
|
@@ -8124,7 +8386,7 @@ function ChartDataGrid({ controller, categoryHeader = "Category", readOnly = fal
|
|
|
8124
8386
|
className: "h-5 w-5 shrink-0 cursor-pointer rounded border-0 bg-transparent p-0"
|
|
8125
8387
|
}
|
|
8126
8388
|
),
|
|
8127
|
-
/* @__PURE__ */ (0,
|
|
8389
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
|
|
8128
8390
|
ChartCommitInput,
|
|
8129
8391
|
{
|
|
8130
8392
|
value: s.name,
|
|
@@ -8134,8 +8396,8 @@ function ChartDataGrid({ controller, categoryHeader = "Category", readOnly = fal
|
|
|
8134
8396
|
className: `${chartInputClass} h-6 min-w-[5rem] border-transparent bg-transparent font-medium ${s.hidden ? "text-muted-foreground line-through" : ""}`
|
|
8135
8397
|
}
|
|
8136
8398
|
),
|
|
8137
|
-
!readOnly && /* @__PURE__ */ (0,
|
|
8138
|
-
/* @__PURE__ */ (0,
|
|
8399
|
+
!readOnly && /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)(import_jsx_runtime42.Fragment, { children: [
|
|
8400
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
|
|
8139
8401
|
"button",
|
|
8140
8402
|
{
|
|
8141
8403
|
type: "button",
|
|
@@ -8148,16 +8410,16 @@ function ChartDataGrid({ controller, categoryHeader = "Category", readOnly = fal
|
|
|
8148
8410
|
children: s.hidden ? "\u25CB" : "\u25CF"
|
|
8149
8411
|
}
|
|
8150
8412
|
),
|
|
8151
|
-
/* @__PURE__ */ (0,
|
|
8413
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.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" })
|
|
8152
8414
|
] })
|
|
8153
8415
|
] }) }, s.id);
|
|
8154
8416
|
}),
|
|
8155
|
-
!readOnly && /* @__PURE__ */ (0,
|
|
8417
|
+
!readOnly && /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("th", { className: "w-8 border-b border-border px-1", children: /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("button", { type: "button", className: chartIconButtonClass, title: "Add series", "aria-label": "Add series", "data-action": "add-series", onClick: () => controller.addSeries(), children: "+" }) })
|
|
8156
8418
|
] }) }),
|
|
8157
|
-
/* @__PURE__ */ (0,
|
|
8419
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)("tbody", { children: spec.categories.map((category, i) => {
|
|
8158
8420
|
const rowSelected = selection?.kind === "category" && selection.index === i;
|
|
8159
|
-
return /* @__PURE__ */ (0,
|
|
8160
|
-
/* @__PURE__ */ (0,
|
|
8421
|
+
return /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("tr", { "data-category-index": i, className: rowSelected ? "bg-primary/10" : void 0, children: [
|
|
8422
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)("th", { className: "border-b border-r border-border p-0 text-left font-normal", children: /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
|
|
8161
8423
|
ChartCommitInput,
|
|
8162
8424
|
{
|
|
8163
8425
|
value: category,
|
|
@@ -8171,7 +8433,7 @@ function ChartDataGrid({ controller, categoryHeader = "Category", readOnly = fal
|
|
|
8171
8433
|
spec.series.map((s) => {
|
|
8172
8434
|
const value = s.values[i];
|
|
8173
8435
|
const selected = selection?.kind === "point" && selection.seriesId === s.id && selection.index === i;
|
|
8174
|
-
return /* @__PURE__ */ (0,
|
|
8436
|
+
return /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("td", { className: `border-b border-r border-border p-0 ${selected ? "bg-primary/10" : ""}`, children: /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
|
|
8175
8437
|
ChartCommitInput,
|
|
8176
8438
|
{
|
|
8177
8439
|
value: value === null || value === void 0 ? "" : String(value),
|
|
@@ -8186,38 +8448,38 @@ function ChartDataGrid({ controller, categoryHeader = "Category", readOnly = fal
|
|
|
8186
8448
|
}
|
|
8187
8449
|
) }, s.id);
|
|
8188
8450
|
}),
|
|
8189
|
-
!readOnly && /* @__PURE__ */ (0,
|
|
8451
|
+
!readOnly && /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("td", { className: "border-b border-border px-1", children: /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("button", { type: "button", className: chartIconButtonClass, title: "Delete category", "aria-label": `Delete ${category}`, "data-action": "remove-category", onClick: () => controller.removeCategory(i), children: "\xD7" }) })
|
|
8190
8452
|
] }, i);
|
|
8191
8453
|
}) })
|
|
8192
8454
|
] }),
|
|
8193
|
-
!readOnly && /* @__PURE__ */ (0,
|
|
8455
|
+
!readOnly && /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("div", { className: "p-1", children: /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("button", { type: "button", className: `${chartButtonClass} h-6 border-dashed`, "data-action": "add-category", onClick: () => controller.addCategory(), children: "+ Add category" }) })
|
|
8194
8456
|
] });
|
|
8195
8457
|
}
|
|
8196
8458
|
|
|
8197
8459
|
// src/chart/ChartInspector.tsx
|
|
8198
|
-
var
|
|
8460
|
+
var import_react63 = require("react");
|
|
8199
8461
|
var import_chart4 = require("@pixerate/editor/chart");
|
|
8200
|
-
var
|
|
8462
|
+
var import_jsx_runtime43 = require("react/jsx-runtime");
|
|
8201
8463
|
var cap = (s) => s.charAt(0).toUpperCase() + s.slice(1);
|
|
8202
8464
|
function Field({ label, htmlFor, children }) {
|
|
8203
|
-
return /* @__PURE__ */ (0,
|
|
8204
|
-
/* @__PURE__ */ (0,
|
|
8205
|
-
/* @__PURE__ */ (0,
|
|
8465
|
+
return /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
8466
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)("label", { htmlFor, className: `${chartLabelClass} w-20 shrink-0`, children: label }),
|
|
8467
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)("div", { className: "min-w-0 flex-1", children })
|
|
8206
8468
|
] });
|
|
8207
8469
|
}
|
|
8208
8470
|
function Toggle({ label, checked, onChange, name }) {
|
|
8209
|
-
return /* @__PURE__ */ (0,
|
|
8210
|
-
/* @__PURE__ */ (0,
|
|
8471
|
+
return /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("label", { className: "flex cursor-pointer items-center gap-2 text-xs text-foreground", children: [
|
|
8472
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)("input", { type: "checkbox", className: "h-3.5 w-3.5 accent-primary", checked, "data-option": name, onChange: (e) => onChange(e.currentTarget.checked) }),
|
|
8211
8473
|
label
|
|
8212
8474
|
] });
|
|
8213
8475
|
}
|
|
8214
8476
|
function Select({ id, value, options, onChange, name, labels }) {
|
|
8215
|
-
return /* @__PURE__ */ (0,
|
|
8477
|
+
return /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("select", { id, className: chartInputClass, value, "data-option": name, onChange: (e) => onChange(e.currentTarget.value), children: options.map((o) => /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("option", { value: o, children: labels?.[o] ?? cap(o) }, o)) });
|
|
8216
8478
|
}
|
|
8217
8479
|
function AxisSection({ controller, axis, value, idBase, horizontal, numeric = false, scales = false }) {
|
|
8218
8480
|
const set = (patch) => controller.setAxis(axis, patch);
|
|
8219
8481
|
const setFormat = (patch) => set({ format: { ...value.format, ...patch } });
|
|
8220
|
-
const bound = (key2) => /* @__PURE__ */ (0,
|
|
8482
|
+
const bound = (key2) => /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
|
|
8221
8483
|
ChartCommitInput,
|
|
8222
8484
|
{
|
|
8223
8485
|
id: `${idBase}-${axis}-${key2}`,
|
|
@@ -8232,26 +8494,26 @@ function AxisSection({ controller, axis, value, idBase, horizontal, numeric = fa
|
|
|
8232
8494
|
const name = axis === "x" ? numeric ? "X axis" : "Category axis" : axis === "y" ? "Value axis" : "Secondary axis";
|
|
8233
8495
|
const valueAxis = axis !== "x" || numeric;
|
|
8234
8496
|
const key = axis === "y2" ? "yAxis2" : `${axis}Axis`;
|
|
8235
|
-
return /* @__PURE__ */ (0,
|
|
8236
|
-
/* @__PURE__ */ (0,
|
|
8237
|
-
/* @__PURE__ */ (0,
|
|
8497
|
+
return /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("div", { className: chartSectionClass, "data-section": `axis-${axis}`, children: [
|
|
8498
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("div", { className: "flex items-center justify-between", children: [
|
|
8499
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("h4", { className: "text-xs font-semibold text-foreground", children: [
|
|
8238
8500
|
name,
|
|
8239
|
-
/* @__PURE__ */ (0,
|
|
8501
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("span", { className: "ml-1 font-normal text-muted-foreground", children: [
|
|
8240
8502
|
"(",
|
|
8241
8503
|
axis === "x" ? horizontal ? "left" : "bottom" : axis === "y2" ? horizontal ? "top" : "right" : horizontal ? "bottom" : "left",
|
|
8242
8504
|
")"
|
|
8243
8505
|
] })
|
|
8244
8506
|
] }),
|
|
8245
|
-
/* @__PURE__ */ (0,
|
|
8507
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)(Toggle, { label: "Show", name: `${axis}Axis.show`, checked: value.show, onChange: (show) => set({ show }) })
|
|
8246
8508
|
] }),
|
|
8247
|
-
/* @__PURE__ */ (0,
|
|
8248
|
-
/* @__PURE__ */ (0,
|
|
8249
|
-
/* @__PURE__ */ (0,
|
|
8250
|
-
axis === "x" && !numeric && /* @__PURE__ */ (0,
|
|
8251
|
-
scales && /* @__PURE__ */ (0,
|
|
8252
|
-
scales && valueAxis && /* @__PURE__ */ (0,
|
|
8509
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)(Field, { label: "Title", htmlFor: `${idBase}-${axis}-title`, children: /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(ChartCommitInput, { id: `${idBase}-${axis}-title`, value: value.title, "data-option": `${axis}Axis.title`, className: chartInputClass, onCommit: (title) => void set({ title }) }) }),
|
|
8510
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("div", { className: "flex flex-wrap gap-x-4 gap-y-1", children: [
|
|
8511
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)(Toggle, { label: "Grid lines", name: `${key}.gridlines`, checked: value.gridlines, onChange: (gridlines) => set({ gridlines }) }),
|
|
8512
|
+
axis === "x" && !numeric && /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(Toggle, { label: "Dates", name: "xAxis.kind", checked: value.kind === "date", onChange: (dates) => set({ kind: dates ? "date" : void 0 }) }),
|
|
8513
|
+
scales && /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(Toggle, { label: "Reverse", name: `${key}.reverse`, checked: !!value.reverse, onChange: (reverse) => set({ reverse }) }),
|
|
8514
|
+
scales && valueAxis && /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(Toggle, { label: "Log scale", name: `${key}.scale`, checked: value.scale === "log", onChange: (log) => set({ scale: log ? "log" : "linear" }) })
|
|
8253
8515
|
] }),
|
|
8254
|
-
scales && valueAxis && value.scale === "log" && /* @__PURE__ */ (0,
|
|
8516
|
+
scales && valueAxis && value.scale === "log" && /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(Field, { label: "Log base", htmlFor: `${idBase}-${axis}-log-base`, children: /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
|
|
8255
8517
|
ChartCommitInput,
|
|
8256
8518
|
{
|
|
8257
8519
|
id: `${idBase}-${axis}-log-base`,
|
|
@@ -8262,7 +8524,7 @@ function AxisSection({ controller, axis, value, idBase, horizontal, numeric = fa
|
|
|
8262
8524
|
onCommit: (text) => set({ logBase: text.trim() === "" ? void 0 : Number(text) }).ok
|
|
8263
8525
|
}
|
|
8264
8526
|
) }),
|
|
8265
|
-
valueAxis && value.scale !== "log" && /* @__PURE__ */ (0,
|
|
8527
|
+
valueAxis && value.scale !== "log" && /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(Field, { label: "Step", htmlFor: `${idBase}-${axis}-step`, children: /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
|
|
8266
8528
|
ChartCommitInput,
|
|
8267
8529
|
{
|
|
8268
8530
|
id: `${idBase}-${axis}-step`,
|
|
@@ -8274,14 +8536,14 @@ function AxisSection({ controller, axis, value, idBase, horizontal, numeric = fa
|
|
|
8274
8536
|
onCommit: (text) => set({ step: text.trim() === "" ? null : Number(text) }).ok
|
|
8275
8537
|
}
|
|
8276
8538
|
) }),
|
|
8277
|
-
valueAxis && /* @__PURE__ */ (0,
|
|
8278
|
-
/* @__PURE__ */ (0,
|
|
8539
|
+
valueAxis && /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)(import_jsx_runtime43.Fragment, { children: [
|
|
8540
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)(Field, { label: "Min / max", children: /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("div", { className: "flex gap-1", children: [
|
|
8279
8541
|
bound("min"),
|
|
8280
8542
|
bound("max")
|
|
8281
8543
|
] }) }),
|
|
8282
|
-
/* @__PURE__ */ (0,
|
|
8283
|
-
/* @__PURE__ */ (0,
|
|
8284
|
-
/* @__PURE__ */ (0,
|
|
8544
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)(Field, { label: "Format", htmlFor: `${idBase}-${axis}-format`, children: /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("div", { className: "flex gap-1", children: [
|
|
8545
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.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 }) }),
|
|
8546
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
|
|
8285
8547
|
ChartCommitInput,
|
|
8286
8548
|
{
|
|
8287
8549
|
value: value.format.decimals === void 0 ? "" : String(value.format.decimals),
|
|
@@ -8300,8 +8562,8 @@ function AxisSection({ controller, axis, value, idBase, horizontal, numeric = fa
|
|
|
8300
8562
|
}
|
|
8301
8563
|
)
|
|
8302
8564
|
] }) }),
|
|
8303
|
-
value.format.style === "currency" && /* @__PURE__ */ (0,
|
|
8304
|
-
/* @__PURE__ */ (0,
|
|
8565
|
+
value.format.style === "currency" && /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(Field, { label: "Currency", htmlFor: `${idBase}-${axis}-currency`, children: /* @__PURE__ */ (0, import_jsx_runtime43.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() }) }) }),
|
|
8566
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)(Field, { label: "Code", htmlFor: `${idBase}-${axis}-code`, children: /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
|
|
8305
8567
|
ChartCommitInput,
|
|
8306
8568
|
{
|
|
8307
8569
|
id: `${idBase}-${axis}-code`,
|
|
@@ -8327,15 +8589,15 @@ function ErrorBarFields({ controller, series, which, idBase }) {
|
|
|
8327
8589
|
const values = which === "xErrorBars" ? series.x ?? [] : series.values;
|
|
8328
8590
|
const set = (next) => controller.updateSeries(series.id, { [which]: next });
|
|
8329
8591
|
const patch = (p) => bars && set({ ...bars, ...p });
|
|
8330
|
-
return /* @__PURE__ */ (0,
|
|
8331
|
-
/* @__PURE__ */ (0,
|
|
8332
|
-
/* @__PURE__ */ (0,
|
|
8333
|
-
import_chart4.CHART_ERROR_BAR_TYPES.map((t) => /* @__PURE__ */ (0,
|
|
8592
|
+
return /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("div", { className: "space-y-1.5", "data-section": which === "errorBars" ? "error-bars" : "x-error-bars", children: [
|
|
8593
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)(Field, { label: which === "errorBars" ? "Error bars" : "X error bars", htmlFor: `${id}-type`, children: /* @__PURE__ */ (0, import_jsx_runtime43.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: [
|
|
8594
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)("option", { value: "", children: "None" }),
|
|
8595
|
+
import_chart4.CHART_ERROR_BAR_TYPES.map((t) => /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("option", { value: t, children: import_chart4.CHART_ERROR_BAR_LABELS[t] }, t))
|
|
8334
8596
|
] }) }),
|
|
8335
|
-
bars && (bars.type === "fixed" || bars.type === "percent" || bars.type === "stddev") && /* @__PURE__ */ (0,
|
|
8336
|
-
bars?.type === "custom" && /* @__PURE__ */ (0,
|
|
8337
|
-
/* @__PURE__ */ (0,
|
|
8338
|
-
/* @__PURE__ */ (0,
|
|
8597
|
+
bars && (bars.type === "fixed" || bars.type === "percent" || bars.type === "stddev") && /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(Field, { label: bars.type === "percent" ? "Percent" : bars.type === "stddev" ? "Deviations" : "Amount", htmlFor: `${id}-value`, children: /* @__PURE__ */ (0, import_jsx_runtime43.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 }) }),
|
|
8598
|
+
bars?.type === "custom" && /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)(import_jsx_runtime43.Fragment, { children: [
|
|
8599
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)(Field, { label: "Plus", htmlFor: `${id}-plus`, children: /* @__PURE__ */ (0, import_jsx_runtime43.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 }) }),
|
|
8600
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)(Field, { label: "Minus", htmlFor: `${id}-minus`, children: /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
|
|
8339
8601
|
ChartCommitInput,
|
|
8340
8602
|
{
|
|
8341
8603
|
id: `${id}-minus`,
|
|
@@ -8352,15 +8614,15 @@ function ErrorBarFields({ controller, series, which, idBase }) {
|
|
|
8352
8614
|
}
|
|
8353
8615
|
) })
|
|
8354
8616
|
] }),
|
|
8355
|
-
bars && /* @__PURE__ */ (0,
|
|
8356
|
-
/* @__PURE__ */ (0,
|
|
8357
|
-
/* @__PURE__ */ (0,
|
|
8617
|
+
bars && /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
8618
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.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_runtime43.jsx)("option", { value: d, children: d === "both" ? "Both ways" : d === "plus" ? "Plus only" : "Minus only" }, d)) }),
|
|
8619
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)(Toggle, { label: "Caps", name: `${key}.cap`, checked: bars.cap !== false, onChange: (cap2) => patch({ cap: cap2 }) })
|
|
8358
8620
|
] })
|
|
8359
8621
|
] });
|
|
8360
8622
|
}
|
|
8361
8623
|
function ChartInspector({ controller, sections, className }) {
|
|
8362
8624
|
const { spec, selectedSeries } = useChartState(controller);
|
|
8363
|
-
const idBase = (0,
|
|
8625
|
+
const idBase = (0, import_react63.useId)();
|
|
8364
8626
|
const show = (section) => !sections || sections.includes(section);
|
|
8365
8627
|
const cartesian = (0, import_chart4.isCartesianChart)(spec.type);
|
|
8366
8628
|
const family = (0, import_chart4.chartFamily)(spec);
|
|
@@ -8372,29 +8634,29 @@ function ChartInspector({ controller, sections, className }) {
|
|
|
8372
8634
|
const hasLines = cartesian && types.some((t) => t === "line" || t === "area");
|
|
8373
8635
|
const seriesIndex = selectedSeries ? spec.series.findIndex((s) => s.id === selectedSeries.id) : -1;
|
|
8374
8636
|
const scales = family === "cartesian" || family === "xy";
|
|
8375
|
-
return /* @__PURE__ */ (0,
|
|
8376
|
-
show("type") && /* @__PURE__ */ (0,
|
|
8377
|
-
show("style") && /* @__PURE__ */ (0,
|
|
8378
|
-
/* @__PURE__ */ (0,
|
|
8379
|
-
/* @__PURE__ */ (0,
|
|
8380
|
-
import_chart4.CHART_LAYOUT_PRESETS.map((p) => /* @__PURE__ */ (0,
|
|
8637
|
+
return /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("div", { className: `space-y-3 text-xs ${className ?? ""}`, "data-chart-inspector": "", children: [
|
|
8638
|
+
show("type") && /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("div", { className: chartSectionClass, "data-section": "type", children: /* @__PURE__ */ (0, import_jsx_runtime43.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_runtime43.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)) }) }),
|
|
8639
|
+
show("style") && /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("div", { className: chartSectionClass, "data-section": "style", children: [
|
|
8640
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)(Field, { label: "Layout", htmlFor: `${idBase}-layout`, children: /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("select", { id: `${idBase}-layout`, className: chartInputClass, value: "", "data-option": "preset.layout", onChange: (e) => e.currentTarget.value && controller.applyPreset({ layout: e.currentTarget.value }), children: [
|
|
8641
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)("option", { value: "", children: "Quick layout\u2026" }),
|
|
8642
|
+
import_chart4.CHART_LAYOUT_PRESETS.map((p) => /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("option", { value: p.id, title: p.description, children: p.label }, p.id))
|
|
8381
8643
|
] }) }),
|
|
8382
|
-
/* @__PURE__ */ (0,
|
|
8383
|
-
/* @__PURE__ */ (0,
|
|
8384
|
-
import_chart4.CHART_COLOR_SCHEMES.map((c) => /* @__PURE__ */ (0,
|
|
8644
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)(Field, { label: "Colours", htmlFor: `${idBase}-colors`, children: /* @__PURE__ */ (0, import_jsx_runtime43.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: [
|
|
8645
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)("option", { value: "", children: "Custom" }),
|
|
8646
|
+
import_chart4.CHART_COLOR_SCHEMES.map((c) => /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("option", { value: c.id, title: c.description, children: c.label }, c.id))
|
|
8385
8647
|
] }) }),
|
|
8386
|
-
!colorCheck.ok && /* @__PURE__ */ (0,
|
|
8387
|
-
/* @__PURE__ */ (0,
|
|
8648
|
+
!colorCheck.ok && /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("p", { className: "text-[11px] leading-snug text-amber-600 dark:text-amber-400", "data-chart-color-warning": "", children: colorCheck.issues[0] }),
|
|
8649
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)("button", { type: "button", className: chartButtonClass, "data-action": "transpose", onClick: () => controller.transpose(), children: "Switch rows and columns" })
|
|
8388
8650
|
] }),
|
|
8389
|
-
show("titles") && /* @__PURE__ */ (0,
|
|
8390
|
-
/* @__PURE__ */ (0,
|
|
8391
|
-
/* @__PURE__ */ (0,
|
|
8651
|
+
show("titles") && /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("div", { className: chartSectionClass, "data-section": "titles", children: [
|
|
8652
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)(Field, { label: "Title", htmlFor: `${idBase}-title`, children: /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(ChartCommitInput, { id: `${idBase}-title`, value: spec.title, "data-option": "title", className: chartInputClass, onCommit: (title) => void controller.setTitle(title) }) }),
|
|
8653
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)(Field, { label: "Subtitle", htmlFor: `${idBase}-subtitle`, children: /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(ChartCommitInput, { id: `${idBase}-subtitle`, value: spec.subtitle, "data-option": "subtitle", className: chartInputClass, onCommit: (subtitle) => void controller.setSubtitle(subtitle) }) })
|
|
8392
8654
|
] }),
|
|
8393
|
-
show("options") && /* @__PURE__ */ (0,
|
|
8394
|
-
cartesian && /* @__PURE__ */ (0,
|
|
8395
|
-
hasBars && /* @__PURE__ */ (0,
|
|
8396
|
-
hasLines && /* @__PURE__ */ (0,
|
|
8397
|
-
spec.type === "donut" && /* @__PURE__ */ (0,
|
|
8655
|
+
show("options") && /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("div", { className: chartSectionClass, "data-section": "options", children: [
|
|
8656
|
+
cartesian && /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(Field, { label: "Stacking", htmlFor: `${idBase}-stacking`, children: /* @__PURE__ */ (0, import_jsx_runtime43.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 }) }) }),
|
|
8657
|
+
hasBars && /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(Field, { label: "Bars", children: /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("div", { className: "flex gap-0.5 rounded-md bg-muted p-0.5", children: ["vertical", "horizontal"].map((o) => /* @__PURE__ */ (0, import_jsx_runtime43.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)) }) }),
|
|
8658
|
+
hasLines && /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(Field, { label: "Lines", htmlFor: `${idBase}-curve`, children: /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(Select, { id: `${idBase}-curve`, name: "curve", value: spec.curve, options: import_chart4.CHART_CURVES, onChange: (curve) => controller.update({ curve }) }) }),
|
|
8659
|
+
spec.type === "donut" && /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(Field, { label: "Hole", htmlFor: `${idBase}-hole`, children: /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
|
|
8398
8660
|
"input",
|
|
8399
8661
|
{
|
|
8400
8662
|
id: `${idBase}-hole`,
|
|
@@ -8410,7 +8672,7 @@ function ChartInspector({ controller, sections, className }) {
|
|
|
8410
8672
|
onChange: (e) => controller.update({ innerRadius: Number(e.currentTarget.value) })
|
|
8411
8673
|
}
|
|
8412
8674
|
) }),
|
|
8413
|
-
hasBars && /* @__PURE__ */ (0,
|
|
8675
|
+
hasBars && /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(Field, { label: "Spacing", htmlFor: `${idBase}-gap`, children: /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
|
|
8414
8676
|
"input",
|
|
8415
8677
|
{
|
|
8416
8678
|
id: `${idBase}-gap`,
|
|
@@ -8426,31 +8688,31 @@ function ChartInspector({ controller, sections, className }) {
|
|
|
8426
8688
|
onChange: (e) => controller.update({ gapWidth: Number(e.currentTarget.value) })
|
|
8427
8689
|
}
|
|
8428
8690
|
) }),
|
|
8429
|
-
spec.dataLabels && hasBars && /* @__PURE__ */ (0,
|
|
8430
|
-
spec.type === "histogram" && /* @__PURE__ */ (0,
|
|
8431
|
-
/* @__PURE__ */ (0,
|
|
8432
|
-
spec.type === "waterfall" && /* @__PURE__ */ (0,
|
|
8433
|
-
hasLines && /* @__PURE__ */ (0,
|
|
8434
|
-
/* @__PURE__ */ (0,
|
|
8691
|
+
spec.dataLabels && hasBars && /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(Field, { label: "Labels", htmlFor: `${idBase}-label-position`, children: /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(Select, { id: `${idBase}-label-position`, name: "labelPosition", value: spec.labelPosition, options: import_chart4.CHART_LABEL_POSITIONS, onChange: (labelPosition) => controller.update({ labelPosition }) }) }),
|
|
8692
|
+
spec.type === "histogram" && /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(Field, { label: "Bins", htmlFor: `${idBase}-bins`, children: /* @__PURE__ */ (0, import_jsx_runtime43.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 }) }),
|
|
8693
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("div", { className: "flex flex-wrap gap-x-4 gap-y-1", children: [
|
|
8694
|
+
spec.type === "waterfall" && /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(Toggle, { label: "Total bar", name: "showTotal", checked: spec.showTotal, onChange: (showTotal) => controller.update({ showTotal }) }),
|
|
8695
|
+
hasLines && /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(Toggle, { label: "Points", name: "points", checked: spec.points, onChange: (points) => controller.update({ points }) }),
|
|
8696
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)(Toggle, { label: "Data labels", name: "dataLabels", checked: spec.dataLabels, onChange: (dataLabels) => controller.update({ dataLabels }) })
|
|
8435
8697
|
] })
|
|
8436
8698
|
] }),
|
|
8437
|
-
show("legend") && /* @__PURE__ */ (0,
|
|
8438
|
-
/* @__PURE__ */ (0,
|
|
8439
|
-
/* @__PURE__ */ (0,
|
|
8440
|
-
/* @__PURE__ */ (0,
|
|
8699
|
+
show("legend") && /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("div", { className: chartSectionClass, "data-section": "legend", children: [
|
|
8700
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("div", { className: "flex items-center justify-between", children: [
|
|
8701
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)("h4", { className: "text-xs font-semibold text-foreground", children: "Legend" }),
|
|
8702
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)(Toggle, { label: "Show", name: "legend.show", checked: spec.legend.show, onChange: (v) => controller.setLegend({ show: v }) })
|
|
8441
8703
|
] }),
|
|
8442
|
-
spec.legend.show && /* @__PURE__ */ (0,
|
|
8704
|
+
spec.legend.show && /* @__PURE__ */ (0, import_jsx_runtime43.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_runtime43.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)) })
|
|
8443
8705
|
] }),
|
|
8444
|
-
show("axes") && hasAxes && /* @__PURE__ */ (0,
|
|
8445
|
-
family !== "box" && family !== "histogram" && /* @__PURE__ */ (0,
|
|
8446
|
-
/* @__PURE__ */ (0,
|
|
8447
|
-
usesSecondary && /* @__PURE__ */ (0,
|
|
8706
|
+
show("axes") && hasAxes && /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)(import_jsx_runtime43.Fragment, { children: [
|
|
8707
|
+
family !== "box" && family !== "histogram" && /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(AxisSection, { controller, axis: "x", value: spec.xAxis, idBase, horizontal: spec.orientation === "horizontal", numeric: family === "xy", scales }),
|
|
8708
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)(AxisSection, { controller, axis: "y", value: spec.yAxis, idBase, horizontal: spec.orientation === "horizontal", scales }),
|
|
8709
|
+
usesSecondary && /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(AxisSection, { controller, axis: "y2", value: spec.yAxis2, idBase, horizontal: spec.orientation === "horizontal", scales })
|
|
8448
8710
|
] }),
|
|
8449
|
-
show("series") && selectedSeries && /* @__PURE__ */ (0,
|
|
8450
|
-
/* @__PURE__ */ (0,
|
|
8451
|
-
/* @__PURE__ */ (0,
|
|
8452
|
-
/* @__PURE__ */ (0,
|
|
8453
|
-
/* @__PURE__ */ (0,
|
|
8711
|
+
show("series") && selectedSeries && /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("div", { className: chartSectionClass, "data-section": "series", "data-series-id": selectedSeries.id, children: [
|
|
8712
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)("h4", { className: "text-xs font-semibold text-foreground", children: "Series" }),
|
|
8713
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)(Field, { label: "Name", htmlFor: `${idBase}-series-name`, children: /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(ChartCommitInput, { id: `${idBase}-series-name`, value: selectedSeries.name, "data-option": "series.name", className: chartInputClass, onCommit: (name) => void controller.updateSeries(selectedSeries.id, { name }) }) }),
|
|
8714
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)(Field, { label: "Colour", htmlFor: `${idBase}-series-color`, children: /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("div", { className: "flex items-center gap-1", children: [
|
|
8715
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
|
|
8454
8716
|
"input",
|
|
8455
8717
|
{
|
|
8456
8718
|
id: `${idBase}-series-color`,
|
|
@@ -8463,9 +8725,9 @@ function ChartInspector({ controller, sections, className }) {
|
|
|
8463
8725
|
onChange: (e) => controller.updateSeries(selectedSeries.id, { color: e.currentTarget.value })
|
|
8464
8726
|
}
|
|
8465
8727
|
),
|
|
8466
|
-
selectedSeries.color && /* @__PURE__ */ (0,
|
|
8728
|
+
selectedSeries.color && /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("button", { type: "button", className: chartButtonClass, "data-action": "reset-color", onClick: () => controller.updateSeries(selectedSeries.id, { color: null }), children: "Palette" })
|
|
8467
8729
|
] }) }),
|
|
8468
|
-
cartesian && /* @__PURE__ */ (0,
|
|
8730
|
+
cartesian && /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(Field, { label: "Draw as", htmlFor: `${idBase}-series-type`, children: /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)(
|
|
8469
8731
|
"select",
|
|
8470
8732
|
{
|
|
8471
8733
|
id: `${idBase}-series-type`,
|
|
@@ -8474,12 +8736,12 @@ function ChartInspector({ controller, sections, className }) {
|
|
|
8474
8736
|
"data-option": "series.type",
|
|
8475
8737
|
onChange: (e) => controller.updateSeries(selectedSeries.id, { type: e.currentTarget.value || null }),
|
|
8476
8738
|
children: [
|
|
8477
|
-
/* @__PURE__ */ (0,
|
|
8478
|
-
import_chart4.CHART_SERIES_TYPES.map((t) => /* @__PURE__ */ (0,
|
|
8739
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)("option", { value: "", children: "Chart type" }),
|
|
8740
|
+
import_chart4.CHART_SERIES_TYPES.map((t) => /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("option", { value: t, children: import_chart4.CHART_TYPE_LABELS[t] }, t))
|
|
8479
8741
|
]
|
|
8480
8742
|
}
|
|
8481
8743
|
) }),
|
|
8482
|
-
(cartesian || family === "xy") && ["line", "area", "scatter"].includes((0, import_chart4.chartSeriesType)(spec, selectedSeries)) && /* @__PURE__ */ (0,
|
|
8744
|
+
(cartesian || family === "xy") && ["line", "area", "scatter"].includes((0, import_chart4.chartSeriesType)(spec, selectedSeries)) && /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(Field, { label: "Marker", htmlFor: `${idBase}-series-marker`, children: /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)(
|
|
8483
8745
|
"select",
|
|
8484
8746
|
{
|
|
8485
8747
|
id: `${idBase}-series-marker`,
|
|
@@ -8488,20 +8750,20 @@ function ChartInspector({ controller, sections, className }) {
|
|
|
8488
8750
|
"data-option": "series.marker",
|
|
8489
8751
|
onChange: (e) => controller.updateSeries(selectedSeries.id, { marker: e.currentTarget.value || null }),
|
|
8490
8752
|
children: [
|
|
8491
|
-
/* @__PURE__ */ (0,
|
|
8492
|
-
import_chart4.CHART_MARKERS.map((m) => /* @__PURE__ */ (0,
|
|
8753
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)("option", { value: "", children: "Default" }),
|
|
8754
|
+
import_chart4.CHART_MARKERS.map((m) => /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("option", { value: m, children: cap(m) }, m))
|
|
8493
8755
|
]
|
|
8494
8756
|
}
|
|
8495
8757
|
) }),
|
|
8496
|
-
scales && /* @__PURE__ */ (0,
|
|
8497
|
-
family === "xy" && /* @__PURE__ */ (0,
|
|
8498
|
-
(0, import_chart4.chartSupportsTrendlines)(spec.type, spec.stacking) && /* @__PURE__ */ (0,
|
|
8499
|
-
(selectedSeries.trendlines ?? []).map((t, i) => /* @__PURE__ */ (0,
|
|
8500
|
-
/* @__PURE__ */ (0,
|
|
8501
|
-
/* @__PURE__ */ (0,
|
|
8502
|
-
/* @__PURE__ */ (0,
|
|
8758
|
+
scales && /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(ErrorBarFields, { controller, series: selectedSeries, which: "errorBars", idBase }),
|
|
8759
|
+
family === "xy" && /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(ErrorBarFields, { controller, series: selectedSeries, which: "xErrorBars", idBase }),
|
|
8760
|
+
(0, import_chart4.chartSupportsTrendlines)(spec.type, spec.stacking) && /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("div", { className: "space-y-1", "data-section": "trendlines", children: [
|
|
8761
|
+
(selectedSeries.trendlines ?? []).map((t, i) => /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("div", { className: "flex items-center gap-1", "data-trendline": i, children: [
|
|
8762
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)("span", { className: "flex-1 truncate text-muted-foreground", children: (0, import_chart4.chartTrendlineName)(t, selectedSeries.name) }),
|
|
8763
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)(Toggle, { label: "R\xB2", name: `trendline.${i}.showR2`, checked: !!t.showR2, onChange: (showR2) => controller.updateTrendline(selectedSeries.id, i, { showR2 }) }),
|
|
8764
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)("button", { type: "button", className: chartButtonClass, "aria-label": "Delete trendline", "data-action": "trendline-delete", onClick: () => controller.removeTrendline(selectedSeries.id, i), children: "\xD7" })
|
|
8503
8765
|
] }, i)),
|
|
8504
|
-
/* @__PURE__ */ (0,
|
|
8766
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsxs)(
|
|
8505
8767
|
"select",
|
|
8506
8768
|
{
|
|
8507
8769
|
className: chartInputClass,
|
|
@@ -8510,32 +8772,32 @@ function ChartInspector({ controller, sections, className }) {
|
|
|
8510
8772
|
"data-option": "trendline.add",
|
|
8511
8773
|
onChange: (e) => e.currentTarget.value && controller.addTrendline(selectedSeries.id, { type: e.currentTarget.value }),
|
|
8512
8774
|
children: [
|
|
8513
|
-
/* @__PURE__ */ (0,
|
|
8514
|
-
import_chart4.CHART_TRENDLINE_TYPES.map((t) => /* @__PURE__ */ (0,
|
|
8775
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)("option", { value: "", children: "Add trendline\u2026" }),
|
|
8776
|
+
import_chart4.CHART_TRENDLINE_TYPES.map((t) => /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("option", { value: t, children: cap(t.replace("-", " ")) }, t))
|
|
8515
8777
|
]
|
|
8516
8778
|
}
|
|
8517
8779
|
)
|
|
8518
8780
|
] }),
|
|
8519
|
-
/* @__PURE__ */ (0,
|
|
8520
|
-
/* @__PURE__ */ (0,
|
|
8521
|
-
family === "cartesian" && /* @__PURE__ */ (0,
|
|
8522
|
-
/* @__PURE__ */ (0,
|
|
8523
|
-
/* @__PURE__ */ (0,
|
|
8524
|
-
/* @__PURE__ */ (0,
|
|
8525
|
-
/* @__PURE__ */ (0,
|
|
8781
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("div", { className: "flex flex-wrap items-center gap-1", children: [
|
|
8782
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)(Toggle, { label: "Hidden", name: "series.hidden", checked: !!selectedSeries.hidden, onChange: (hidden) => controller.updateSeries(selectedSeries.id, { hidden }) }),
|
|
8783
|
+
family === "cartesian" && /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(Toggle, { label: "Secondary axis", name: "series.axis", checked: selectedSeries.axis === "secondary", onChange: (secondary) => controller.updateSeries(selectedSeries.id, { axis: secondary ? "secondary" : null }) }),
|
|
8784
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)("span", { className: "flex-1" }),
|
|
8785
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.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" }),
|
|
8786
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.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" }),
|
|
8787
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)("button", { type: "button", className: `${chartButtonClass} text-destructive`, "data-action": "series-delete", onClick: () => controller.removeSeries(selectedSeries.id), children: "Delete" })
|
|
8526
8788
|
] })
|
|
8527
8789
|
] })
|
|
8528
8790
|
] });
|
|
8529
8791
|
}
|
|
8530
8792
|
|
|
8531
8793
|
// src/chart-node/ChartNodeView.tsx
|
|
8532
|
-
var
|
|
8794
|
+
var import_jsx_runtime44 = require("react/jsx-runtime");
|
|
8533
8795
|
function ChartNodeView({ state, theme, showDataGrid = true }) {
|
|
8534
8796
|
const { controller, editing, editable, selected, width, height, setEditing } = state;
|
|
8535
8797
|
const open = () => {
|
|
8536
8798
|
if (editable && !editing) setEditing(true);
|
|
8537
8799
|
};
|
|
8538
|
-
return /* @__PURE__ */ (0,
|
|
8800
|
+
return /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)(
|
|
8539
8801
|
"div",
|
|
8540
8802
|
{
|
|
8541
8803
|
className: `not-prose my-2 rounded-md border bg-background p-1 ${selected ? "border-primary ring-1 ring-primary" : "border-border"}`,
|
|
@@ -8548,24 +8810,24 @@ function ChartNodeView({ state, theme, showDataGrid = true }) {
|
|
|
8548
8810
|
}
|
|
8549
8811
|
},
|
|
8550
8812
|
children: [
|
|
8551
|
-
editing && /* @__PURE__ */ (0,
|
|
8552
|
-
/* @__PURE__ */ (0,
|
|
8553
|
-
/* @__PURE__ */ (0,
|
|
8813
|
+
editing && /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("div", { className: "mb-1 flex items-center justify-between gap-2 px-1", "data-chart-node-toolbar": "", children: [
|
|
8814
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsx)("span", { className: "text-xs text-muted-foreground", children: "Editing chart" }),
|
|
8815
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsx)("button", { type: "button", className: chartButtonClass, "data-action": "done", onClick: () => setEditing(false), children: "Done" })
|
|
8554
8816
|
] }),
|
|
8555
|
-
/* @__PURE__ */ (0,
|
|
8817
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
|
|
8556
8818
|
"div",
|
|
8557
8819
|
{
|
|
8558
8820
|
className: editable && !editing ? "cursor-pointer" : void 0,
|
|
8559
8821
|
onClick: open,
|
|
8560
8822
|
title: editable && !editing ? "Click to edit the chart" : void 0,
|
|
8561
8823
|
"data-chart-node-canvas": "",
|
|
8562
|
-
children: /* @__PURE__ */ (0,
|
|
8824
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(ChartCanvas, { controller, width: width ?? 640, height, responsive: width === null, editable: editing, theme })
|
|
8563
8825
|
}
|
|
8564
8826
|
),
|
|
8565
8827
|
editing && // Wraps by the document's width, not the viewport's: side by side when there is room.
|
|
8566
|
-
/* @__PURE__ */ (0,
|
|
8567
|
-
showDataGrid && /* @__PURE__ */ (0,
|
|
8568
|
-
/* @__PURE__ */ (0,
|
|
8828
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("div", { className: "mt-2 flex flex-wrap items-start gap-2", "data-chart-node-panel": "", children: [
|
|
8829
|
+
showDataGrid && /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("div", { className: "min-w-0 flex-[1_1_20rem] overflow-x-auto", children: /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(ChartDataGrid, { controller }) }),
|
|
8830
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsx)(ChartInspector, { controller, className: "max-h-96 min-w-0 flex-[1_1_16rem] overflow-y-auto rounded-md border border-border p-3" })
|
|
8569
8831
|
] })
|
|
8570
8832
|
]
|
|
8571
8833
|
}
|
|
@@ -8583,7 +8845,7 @@ function createReactChartNodeView(options = {}) {
|
|
|
8583
8845
|
scheduled = true;
|
|
8584
8846
|
queueMicrotask(() => {
|
|
8585
8847
|
scheduled = false;
|
|
8586
|
-
if (!destroyed) root.render(/* @__PURE__ */ (0,
|
|
8848
|
+
if (!destroyed) root.render(/* @__PURE__ */ (0, import_jsx_runtime44.jsx)(Component, { ...props, state: latest }));
|
|
8587
8849
|
});
|
|
8588
8850
|
};
|
|
8589
8851
|
schedule();
|
|
@@ -8624,6 +8886,7 @@ function createReactChartNodeView(options = {}) {
|
|
|
8624
8886
|
ImageEditor,
|
|
8625
8887
|
InsertTableGrid,
|
|
8626
8888
|
JobProgress,
|
|
8889
|
+
LayerEffectsPanel,
|
|
8627
8890
|
LayersPanel,
|
|
8628
8891
|
MergePreview,
|
|
8629
8892
|
NameManager,
|