@pixerate/editor-react 0.63.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-QJSMW4CM.js → chunk-M4WLX3IR.js} +582 -375
- package/dist/chunk-M4WLX3IR.js.map +1 -0
- package/dist/image-editor/index.cjs +618 -411
- package/dist/image-editor/index.cjs.map +1 -1
- package/dist/image-editor/index.d.cts +18 -2
- package/dist/image-editor/index.d.ts +18 -2
- package/dist/image-editor/index.js +3 -1
- package/dist/index.cjs +1036 -829
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
- package/dist/chunk-QJSMW4CM.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,14 +4797,14 @@ 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
4809
|
const { brush, foreground, background, mixer, mixerLoad } = state.paint;
|
|
4604
4810
|
const attempt = (fn) => {
|
|
@@ -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,21 +4867,21 @@ var BrushOptionsBar = ({ controller, className }) => {
|
|
|
4661
4867
|
},
|
|
4662
4868
|
spec.id
|
|
4663
4869
|
)),
|
|
4664
|
-
state.activeTool === "mixer" && /* @__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)(
|
|
4667
4873
|
"span",
|
|
4668
4874
|
{
|
|
4669
4875
|
"aria-label": "Brush load",
|
|
4670
|
-
title: mixerLoad.reservoir ? `Loaded ${(0,
|
|
4876
|
+
title: mixerLoad.reservoir ? `Loaded ${(0, import_image_editor8.rgbUnitToHex)(mixerLoad.reservoir)}, ${Math.round(mixerLoad.amount * 100)}% left` : "Unloaded",
|
|
4671
4877
|
className: "h-6 w-6 rounded border border-slate-700",
|
|
4672
|
-
style: { background: mixerLoad.reservoir ? (0,
|
|
4878
|
+
style: { background: mixerLoad.reservoir ? (0, import_image_editor8.rgbUnitToHex)(mixerLoad.reservoir) : "transparent" }
|
|
4673
4879
|
}
|
|
4674
4880
|
),
|
|
4675
|
-
/* @__PURE__ */ (0,
|
|
4676
|
-
/* @__PURE__ */ (0,
|
|
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" })
|
|
4677
4883
|
] }),
|
|
4678
|
-
/* @__PURE__ */ (0,
|
|
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)(
|
|
4679
4885
|
"button",
|
|
4680
4886
|
{
|
|
4681
4887
|
type: "button",
|
|
@@ -4687,10 +4893,10 @@ var BrushOptionsBar = ({ controller, className }) => {
|
|
|
4687
4893
|
},
|
|
4688
4894
|
m.id
|
|
4689
4895
|
)) }),
|
|
4690
|
-
|
|
4691
|
-
/* @__PURE__ */ (0,
|
|
4692
|
-
/* @__PURE__ */ (0,
|
|
4693
|
-
/* @__PURE__ */ (0,
|
|
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)(
|
|
4694
4900
|
"input",
|
|
4695
4901
|
{
|
|
4696
4902
|
type: "checkbox",
|
|
@@ -4702,8 +4908,8 @@ var BrushOptionsBar = ({ controller, className }) => {
|
|
|
4702
4908
|
),
|
|
4703
4909
|
"Load each stroke"
|
|
4704
4910
|
] }),
|
|
4705
|
-
/* @__PURE__ */ (0,
|
|
4706
|
-
/* @__PURE__ */ (0,
|
|
4911
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("label", { className: "flex items-center gap-1.5", children: [
|
|
4912
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
4707
4913
|
"input",
|
|
4708
4914
|
{
|
|
4709
4915
|
type: "checkbox",
|
|
@@ -4717,9 +4923,9 @@ var BrushOptionsBar = ({ controller, className }) => {
|
|
|
4717
4923
|
] })
|
|
4718
4924
|
] })
|
|
4719
4925
|
] }),
|
|
4720
|
-
/* @__PURE__ */ (0,
|
|
4721
|
-
/* @__PURE__ */ (0,
|
|
4722
|
-
/* @__PURE__ */ (0,
|
|
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)(
|
|
4723
4929
|
"input",
|
|
4724
4930
|
{
|
|
4725
4931
|
type: "checkbox",
|
|
@@ -4731,8 +4937,8 @@ var BrushOptionsBar = ({ controller, className }) => {
|
|
|
4731
4937
|
),
|
|
4732
4938
|
"Pressure size"
|
|
4733
4939
|
] }),
|
|
4734
|
-
/* @__PURE__ */ (0,
|
|
4735
|
-
/* @__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)(
|
|
4736
4942
|
"input",
|
|
4737
4943
|
{
|
|
4738
4944
|
type: "checkbox",
|
|
@@ -4745,18 +4951,18 @@ var BrushOptionsBar = ({ controller, className }) => {
|
|
|
4745
4951
|
"Pressure opacity"
|
|
4746
4952
|
] })
|
|
4747
4953
|
] }),
|
|
4748
|
-
/* @__PURE__ */ (0,
|
|
4749
|
-
/* @__PURE__ */ (0,
|
|
4750
|
-
/* @__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" })
|
|
4751
4957
|
] }),
|
|
4752
|
-
error && /* @__PURE__ */ (0,
|
|
4958
|
+
error && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("p", { role: "alert", className: "text-rose-400", children: error })
|
|
4753
4959
|
] });
|
|
4754
4960
|
};
|
|
4755
4961
|
|
|
4756
4962
|
// src/image-editor/SelectionOptionsBar.tsx
|
|
4757
|
-
var
|
|
4758
|
-
var
|
|
4759
|
-
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");
|
|
4760
4966
|
var MODIFY_OPS = [
|
|
4761
4967
|
{ op: "grow", label: "Grow" },
|
|
4762
4968
|
{ op: "shrink", label: "Shrink" },
|
|
@@ -4773,20 +4979,20 @@ var SelectionOptionsBar = ({
|
|
|
4773
4979
|
quickMask,
|
|
4774
4980
|
className = ""
|
|
4775
4981
|
}) => {
|
|
4776
|
-
const [radius, setRadius] = (0,
|
|
4982
|
+
const [radius, setRadius] = (0, import_react41.useState)(2);
|
|
4777
4983
|
const set = (patch) => onOptionsChange({ ...options, ...patch });
|
|
4778
4984
|
const sel = selection === void 0 ? controller.getSelection() : selection;
|
|
4779
4985
|
const qm = quickMask ?? Boolean(controller.getState().quickMask);
|
|
4780
|
-
return /* @__PURE__ */ (0,
|
|
4781
|
-
/* @__PURE__ */ (0,
|
|
4782
|
-
/* @__PURE__ */ (0,
|
|
4783
|
-
options.tool === "wand" && /* @__PURE__ */ (0,
|
|
4784
|
-
/* @__PURE__ */ (0,
|
|
4785
|
-
/* @__PURE__ */ (0,
|
|
4786
|
-
/* @__PURE__ */ (0,
|
|
4787
|
-
/* @__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 })
|
|
4788
4994
|
] }),
|
|
4789
|
-
/* @__PURE__ */ (0,
|
|
4995
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
4790
4996
|
"input",
|
|
4791
4997
|
{
|
|
4792
4998
|
type: "range",
|
|
@@ -4800,17 +5006,17 @@ var SelectionOptionsBar = ({
|
|
|
4800
5006
|
}
|
|
4801
5007
|
)
|
|
4802
5008
|
] }),
|
|
4803
|
-
/* @__PURE__ */ (0,
|
|
4804
|
-
/* @__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 }) }),
|
|
4805
5011
|
"Contiguous"
|
|
4806
5012
|
] }),
|
|
4807
|
-
/* @__PURE__ */ (0,
|
|
4808
|
-
/* @__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 }) }),
|
|
4809
5015
|
"Sample adjusted image"
|
|
4810
5016
|
] }),
|
|
4811
|
-
/* @__PURE__ */ (0,
|
|
5017
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("label", { className: "flex items-center gap-2 text-slate-300", children: [
|
|
4812
5018
|
"Sample",
|
|
4813
|
-
/* @__PURE__ */ (0,
|
|
5019
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(
|
|
4814
5020
|
"select",
|
|
4815
5021
|
{
|
|
4816
5022
|
"aria-label": "Sample from",
|
|
@@ -4818,27 +5024,27 @@ var SelectionOptionsBar = ({
|
|
|
4818
5024
|
onChange: (e) => set({ sample: e.target.value }),
|
|
4819
5025
|
className: "bg-slate-800 border border-slate-700 rounded px-1 py-0.5",
|
|
4820
5026
|
children: [
|
|
4821
|
-
/* @__PURE__ */ (0,
|
|
4822
|
-
/* @__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" })
|
|
4823
5029
|
]
|
|
4824
5030
|
}
|
|
4825
5031
|
)
|
|
4826
5032
|
] })
|
|
4827
5033
|
] }),
|
|
4828
|
-
/* @__PURE__ */ (0,
|
|
4829
|
-
/* @__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 }) }),
|
|
4830
5036
|
"Anti-alias"
|
|
4831
5037
|
] }),
|
|
4832
|
-
/* @__PURE__ */ (0,
|
|
4833
|
-
/* @__PURE__ */ (0,
|
|
4834
|
-
/* @__PURE__ */ (0,
|
|
4835
|
-
/* @__PURE__ */ (0,
|
|
4836
|
-
/* @__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" })
|
|
4837
5043
|
] }),
|
|
4838
|
-
/* @__PURE__ */ (0,
|
|
4839
|
-
/* @__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: [
|
|
4840
5046
|
"Radius",
|
|
4841
|
-
/* @__PURE__ */ (0,
|
|
5047
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
4842
5048
|
"input",
|
|
4843
5049
|
{
|
|
4844
5050
|
type: "number",
|
|
@@ -4852,24 +5058,24 @@ var SelectionOptionsBar = ({
|
|
|
4852
5058
|
}
|
|
4853
5059
|
)
|
|
4854
5060
|
] }),
|
|
4855
|
-
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))
|
|
4856
5062
|
] }),
|
|
4857
|
-
/* @__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) })
|
|
4858
5064
|
] });
|
|
4859
5065
|
};
|
|
4860
5066
|
|
|
4861
5067
|
// src/image-editor/RefineEdgePanel.tsx
|
|
4862
|
-
var
|
|
4863
|
-
var
|
|
4864
|
-
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");
|
|
4865
5071
|
var DEFAULT_PARAMS = { radius: 8, smartRadius: false, smooth: 0, feather: 0, contrast: 0, shiftEdge: 0 };
|
|
4866
|
-
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";
|
|
4867
5073
|
var RefineEdgePanel = ({ controller, selection, layers, className = "" }) => {
|
|
4868
|
-
const [params, setParams] = (0,
|
|
4869
|
-
const [busy, setBusy] = (0,
|
|
4870
|
-
const [error, setError] = (0,
|
|
4871
|
-
const [layerId, setLayerId] = (0,
|
|
4872
|
-
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");
|
|
4873
5079
|
const sel = selection === void 0 ? controller.getSelection() : selection;
|
|
4874
5080
|
const list = layers ?? controller.getAdjustmentLayers();
|
|
4875
5081
|
const target = list.find((l) => l.id === layerId) ?? list[list.length - 1];
|
|
@@ -4884,17 +5090,17 @@ var RefineEdgePanel = ({ controller, selection, layers, className = "" }) => {
|
|
|
4884
5090
|
setBusy(false);
|
|
4885
5091
|
}
|
|
4886
5092
|
};
|
|
4887
|
-
return /* @__PURE__ */ (0,
|
|
4888
|
-
/* @__PURE__ */ (0,
|
|
4889
|
-
|
|
4890
|
-
/* @__PURE__ */ (0,
|
|
4891
|
-
/* @__PURE__ */ (0,
|
|
4892
|
-
/* @__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: [
|
|
4893
5099
|
params[c.id],
|
|
4894
5100
|
c.unit
|
|
4895
5101
|
] })
|
|
4896
5102
|
] }),
|
|
4897
|
-
/* @__PURE__ */ (0,
|
|
5103
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
4898
5104
|
"input",
|
|
4899
5105
|
{
|
|
4900
5106
|
type: "range",
|
|
@@ -4908,67 +5114,67 @@ var RefineEdgePanel = ({ controller, selection, layers, className = "" }) => {
|
|
|
4908
5114
|
}
|
|
4909
5115
|
)
|
|
4910
5116
|
] }, c.id)),
|
|
4911
|
-
/* @__PURE__ */ (0,
|
|
4912
|
-
/* @__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 }) }),
|
|
4913
5119
|
"Smart Radius"
|
|
4914
5120
|
] }),
|
|
4915
|
-
/* @__PURE__ */ (0,
|
|
4916
|
-
/* @__PURE__ */ (0,
|
|
4917
|
-
/* @__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" })
|
|
4918
5124
|
] }),
|
|
4919
|
-
error && /* @__PURE__ */ (0,
|
|
4920
|
-
/* @__PURE__ */ (0,
|
|
4921
|
-
/* @__PURE__ */ (0,
|
|
4922
|
-
/* @__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)(
|
|
4923
5129
|
"select",
|
|
4924
5130
|
{
|
|
4925
5131
|
"aria-label": "New masked layer kind",
|
|
4926
5132
|
value: newKind,
|
|
4927
5133
|
onChange: (e) => setNewKind(e.target.value),
|
|
4928
5134
|
className: "flex-1 bg-slate-950 border border-slate-800 rounded px-1 py-1 text-slate-200",
|
|
4929
|
-
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))
|
|
4930
5136
|
}
|
|
4931
5137
|
),
|
|
4932
|
-
/* @__PURE__ */ (0,
|
|
5138
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
4933
5139
|
"button",
|
|
4934
5140
|
{
|
|
4935
5141
|
type: "button",
|
|
4936
|
-
className:
|
|
5142
|
+
className: button2,
|
|
4937
5143
|
disabled: !sel,
|
|
4938
|
-
onClick: () => sel && setLayerId(controller.addAdjustmentLayer({ kind: newKind, mask: (0,
|
|
5144
|
+
onClick: () => sel && setLayerId(controller.addAdjustmentLayer({ kind: newKind, mask: (0, import_image_editor10.layerMaskFromSelection)(sel) })),
|
|
4939
5145
|
children: "New Masked Layer"
|
|
4940
5146
|
}
|
|
4941
5147
|
)
|
|
4942
5148
|
] }),
|
|
4943
|
-
list.length > 0 && target && /* @__PURE__ */ (0,
|
|
4944
|
-
/* @__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)(
|
|
4945
5151
|
"select",
|
|
4946
5152
|
{
|
|
4947
5153
|
"aria-label": "Mask layer",
|
|
4948
5154
|
value: target.id,
|
|
4949
5155
|
onChange: (e) => setLayerId(e.target.value),
|
|
4950
5156
|
className: "bg-slate-950 border border-slate-800 rounded px-1 py-1 text-slate-200",
|
|
4951
|
-
children: list.map((l) => /* @__PURE__ */ (0,
|
|
4952
|
-
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),
|
|
4953
5159
|
l.mask ? " (masked)" : ""
|
|
4954
5160
|
] }, l.id))
|
|
4955
5161
|
}
|
|
4956
5162
|
),
|
|
4957
|
-
/* @__PURE__ */ (0,
|
|
4958
|
-
/* @__PURE__ */ (0,
|
|
4959
|
-
/* @__PURE__ */ (0,
|
|
4960
|
-
/* @__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" })
|
|
4961
5167
|
] }),
|
|
4962
|
-
target.mask && /* @__PURE__ */ (0,
|
|
4963
|
-
/* @__PURE__ */ (0,
|
|
4964
|
-
/* @__PURE__ */ (0,
|
|
4965
|
-
/* @__PURE__ */ (0,
|
|
4966
|
-
/* @__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: [
|
|
4967
5173
|
Math.round((target.mask.density ?? 1) * 100),
|
|
4968
5174
|
"%"
|
|
4969
5175
|
] })
|
|
4970
5176
|
] }),
|
|
4971
|
-
/* @__PURE__ */ (0,
|
|
5177
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
4972
5178
|
"input",
|
|
4973
5179
|
{
|
|
4974
5180
|
type: "range",
|
|
@@ -4982,15 +5188,15 @@ var RefineEdgePanel = ({ controller, selection, layers, className = "" }) => {
|
|
|
4982
5188
|
}
|
|
4983
5189
|
)
|
|
4984
5190
|
] }),
|
|
4985
|
-
/* @__PURE__ */ (0,
|
|
4986
|
-
/* @__PURE__ */ (0,
|
|
4987
|
-
/* @__PURE__ */ (0,
|
|
4988
|
-
/* @__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: [
|
|
4989
5195
|
target.mask.feather ?? 0,
|
|
4990
5196
|
"px"
|
|
4991
5197
|
] })
|
|
4992
5198
|
] }),
|
|
4993
|
-
/* @__PURE__ */ (0,
|
|
5199
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
4994
5200
|
"input",
|
|
4995
5201
|
{
|
|
4996
5202
|
type: "range",
|
|
@@ -5010,7 +5216,7 @@ var RefineEdgePanel = ({ controller, selection, layers, className = "" }) => {
|
|
|
5010
5216
|
};
|
|
5011
5217
|
|
|
5012
5218
|
// src/image-editor/ImageEditor.tsx
|
|
5013
|
-
var
|
|
5219
|
+
var import_jsx_runtime26 = require("react/jsx-runtime");
|
|
5014
5220
|
var ImageEditor = ({
|
|
5015
5221
|
editor: externalEditor,
|
|
5016
5222
|
src,
|
|
@@ -5025,35 +5231,35 @@ var ImageEditor = ({
|
|
|
5025
5231
|
const internalEditor = useImageEditor({ image: src });
|
|
5026
5232
|
const editor = externalEditor || internalEditor;
|
|
5027
5233
|
const { state, controller } = editor;
|
|
5028
|
-
const legacyProcess = (0,
|
|
5029
|
-
const canvasRef = (0,
|
|
5030
|
-
const containerRef = (0,
|
|
5031
|
-
const [activeTab, setActiveTab] = (0,
|
|
5032
|
-
const [activeCropRatio, setActiveCropRatio] = (0,
|
|
5033
|
-
const [selectionOptions, setSelectionOptions] = (0,
|
|
5034
|
-
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);
|
|
5035
5241
|
selectionOptionsRef.current = selectionOptions;
|
|
5036
|
-
const selectionGestureRef = (0,
|
|
5242
|
+
const selectionGestureRef = (0, import_react43.useRef)(null);
|
|
5037
5243
|
if (!selectionGestureRef.current || selectionGestureRef.current.controller !== controller) {
|
|
5038
|
-
selectionGestureRef.current = new
|
|
5244
|
+
selectionGestureRef.current = new import_image_editor11.SelectionGesture(controller, () => selectionOptionsRef.current);
|
|
5039
5245
|
}
|
|
5040
|
-
const selectionDraftRef = (0,
|
|
5041
|
-
const [selectionError, setSelectionError] = (0,
|
|
5042
|
-
const paintGestureRef = (0,
|
|
5043
|
-
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);
|
|
5044
5250
|
if (!paintGestureRef.current || paintControllerRef.current !== controller) {
|
|
5045
|
-
paintGestureRef.current = new
|
|
5251
|
+
paintGestureRef.current = new import_image_editor11.PaintGesture(controller);
|
|
5046
5252
|
paintControllerRef.current = controller;
|
|
5047
5253
|
}
|
|
5048
|
-
const brushCursorRef = (0,
|
|
5049
|
-
const [paintError, setPaintError] = (0,
|
|
5050
|
-
const [inpaintPrompt, setInpaintPrompt] = (0,
|
|
5051
|
-
const [inpaintMaskMode, setInpaintMaskMode] = (0,
|
|
5052
|
-
const [isRemovingBg, setIsRemovingBg] = (0,
|
|
5053
|
-
const [isInpainting, setIsInpainting] = (0,
|
|
5054
|
-
const [aiError, setAiError] = (0,
|
|
5055
|
-
const [aiSuccess, setAiSuccess] = (0,
|
|
5056
|
-
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");
|
|
5057
5263
|
const aiOptions = aiTarget === "auto" ? {} : { target: aiTarget };
|
|
5058
5264
|
const effectiveOnInpaint = onInpaint || aiHooks?.onInpaint;
|
|
5059
5265
|
const effectiveOnRemoveBg = onRemoveBackground || aiHooks?.onRemoveBackground;
|
|
@@ -5116,18 +5322,18 @@ var ImageEditor = ({
|
|
|
5116
5322
|
setIsInpainting(false);
|
|
5117
5323
|
}
|
|
5118
5324
|
};
|
|
5119
|
-
const [activeColor, setActiveColor] = (0,
|
|
5120
|
-
const [strokeWidth, setStrokeWidth] = (0,
|
|
5121
|
-
const [fontSize, setFontSize] = (0,
|
|
5122
|
-
const [textInput, setTextInput] = (0,
|
|
5123
|
-
const draftAnnotationRef = (0,
|
|
5124
|
-
const draftCropRef = (0,
|
|
5125
|
-
const cropDragInfoRef = (0,
|
|
5126
|
-
const annotationDragInfoRef = (0,
|
|
5127
|
-
const isDrawingRef = (0,
|
|
5128
|
-
const currentPathRef = (0,
|
|
5129
|
-
const dragStartPointRef = (0,
|
|
5130
|
-
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)(
|
|
5131
5337
|
async (draftAnnotation, draftCrop) => {
|
|
5132
5338
|
const canvas = canvasRef.current;
|
|
5133
5339
|
const container = containerRef.current;
|
|
@@ -5148,7 +5354,7 @@ var ImageEditor = ({
|
|
|
5148
5354
|
},
|
|
5149
5355
|
[controller, activeTab]
|
|
5150
5356
|
);
|
|
5151
|
-
(0,
|
|
5357
|
+
(0, import_react43.useEffect)(() => {
|
|
5152
5358
|
const raf = typeof requestAnimationFrame !== "undefined" ? requestAnimationFrame : (cb) => setTimeout(cb, 0);
|
|
5153
5359
|
const caf = typeof cancelAnimationFrame !== "undefined" ? cancelAnimationFrame : (id) => clearTimeout(id);
|
|
5154
5360
|
const animId = raf(() => {
|
|
@@ -5156,12 +5362,12 @@ var ImageEditor = ({
|
|
|
5156
5362
|
});
|
|
5157
5363
|
return () => caf(animId);
|
|
5158
5364
|
}, [renderCanvas, state]);
|
|
5159
|
-
(0,
|
|
5365
|
+
(0, import_react43.useEffect)(() => {
|
|
5160
5366
|
if (activeTab === "crop" && editor.state.activeTool !== "crop") {
|
|
5161
5367
|
editor.setTool("crop");
|
|
5162
5368
|
}
|
|
5163
5369
|
}, [activeTab, editor]);
|
|
5164
|
-
(0,
|
|
5370
|
+
(0, import_react43.useEffect)(() => {
|
|
5165
5371
|
const container = containerRef.current;
|
|
5166
5372
|
if (!container) return;
|
|
5167
5373
|
if (typeof ResizeObserver !== "undefined") {
|
|
@@ -5197,8 +5403,8 @@ var ImageEditor = ({
|
|
|
5197
5403
|
const sy = rect.height > 0 ? canvas.height / rect.height : 1;
|
|
5198
5404
|
const s = controller.getState();
|
|
5199
5405
|
return list.map((ev) => ({
|
|
5200
|
-
...(0,
|
|
5201
|
-
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)
|
|
5202
5408
|
}));
|
|
5203
5409
|
};
|
|
5204
5410
|
const handlePaintPointerDown = (e) => {
|
|
@@ -5226,10 +5432,10 @@ var ImageEditor = ({
|
|
|
5226
5432
|
if (g.error) setPaintError(g.error);
|
|
5227
5433
|
}
|
|
5228
5434
|
};
|
|
5229
|
-
(0,
|
|
5435
|
+
(0, import_react43.useEffect)(() => {
|
|
5230
5436
|
if (activeTab !== "paint" || typeof window === "undefined") return;
|
|
5231
5437
|
const onKey = (e) => {
|
|
5232
|
-
if ((0,
|
|
5438
|
+
if ((0, import_image_editor11.handlePaintShortcut)(controller, e)) e.preventDefault();
|
|
5233
5439
|
};
|
|
5234
5440
|
window.addEventListener("keydown", onKey);
|
|
5235
5441
|
return () => window.removeEventListener("keydown", onKey);
|
|
@@ -5240,7 +5446,7 @@ var ImageEditor = ({
|
|
|
5240
5446
|
const canvasPt = getCanvasEventPoint(e);
|
|
5241
5447
|
if (activeTab === "select") {
|
|
5242
5448
|
const gesture = selectionGestureRef.current;
|
|
5243
|
-
const imgPt = (0,
|
|
5449
|
+
const imgPt = (0, import_image_editor11.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false);
|
|
5244
5450
|
void gesture.begin(imgPt, e).then(() => setSelectionError(gesture.error));
|
|
5245
5451
|
return;
|
|
5246
5452
|
}
|
|
@@ -5251,8 +5457,8 @@ var ImageEditor = ({
|
|
|
5251
5457
|
width: state.imageDimensions.width,
|
|
5252
5458
|
height: state.imageDimensions.height
|
|
5253
5459
|
};
|
|
5254
|
-
const handle = (0,
|
|
5255
|
-
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);
|
|
5256
5462
|
if (handle) {
|
|
5257
5463
|
cropDragInfoRef.current = {
|
|
5258
5464
|
handle,
|
|
@@ -5271,12 +5477,12 @@ var ImageEditor = ({
|
|
|
5271
5477
|
return;
|
|
5272
5478
|
}
|
|
5273
5479
|
if (activeTab === "annotate") {
|
|
5274
|
-
const imgPt = (0,
|
|
5480
|
+
const imgPt = (0, import_image_editor11.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false);
|
|
5275
5481
|
dragStartPointRef.current = imgPt;
|
|
5276
5482
|
if (state.activeTool === "select") {
|
|
5277
5483
|
for (let i = state.annotations.length - 1; i >= 0; i--) {
|
|
5278
5484
|
const ann = state.annotations[i];
|
|
5279
|
-
if ((0,
|
|
5485
|
+
if ((0, import_image_editor11.hitTestAnnotation)(imgPt, ann)) {
|
|
5280
5486
|
editor.selectAnnotation(ann.id);
|
|
5281
5487
|
annotationDragInfoRef.current = {
|
|
5282
5488
|
annId: ann.id,
|
|
@@ -5312,7 +5518,7 @@ var ImageEditor = ({
|
|
|
5312
5518
|
const canvasPt = getCanvasEventPoint(e);
|
|
5313
5519
|
if (activeTab === "select") {
|
|
5314
5520
|
const gesture = selectionGestureRef.current;
|
|
5315
|
-
if (gesture.active && gesture.move((0,
|
|
5521
|
+
if (gesture.active && gesture.move((0, import_image_editor11.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false))) {
|
|
5316
5522
|
selectionDraftRef.current = gesture.draftPath;
|
|
5317
5523
|
renderCanvas();
|
|
5318
5524
|
}
|
|
@@ -5321,7 +5527,7 @@ var ImageEditor = ({
|
|
|
5321
5527
|
if (activeTab === "crop") {
|
|
5322
5528
|
const drag = cropDragInfoRef.current;
|
|
5323
5529
|
if (drag) {
|
|
5324
|
-
const currentImgPt = (0,
|
|
5530
|
+
const currentImgPt = (0, import_image_editor11.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, true);
|
|
5325
5531
|
let newCrop;
|
|
5326
5532
|
if (drag.handle === "new") {
|
|
5327
5533
|
const minX = Math.max(0, Math.min(drag.startImgPt.x, currentImgPt.x));
|
|
@@ -5335,7 +5541,7 @@ var ImageEditor = ({
|
|
|
5335
5541
|
height: Math.round(Math.max(20, maxY - minY))
|
|
5336
5542
|
};
|
|
5337
5543
|
} else {
|
|
5338
|
-
newCrop = (0,
|
|
5544
|
+
newCrop = (0, import_image_editor11.calculateCropDrag)(
|
|
5339
5545
|
drag.startCrop,
|
|
5340
5546
|
drag.handle,
|
|
5341
5547
|
drag.startImgPt,
|
|
@@ -5355,15 +5561,15 @@ var ImageEditor = ({
|
|
|
5355
5561
|
width: state.imageDimensions.width,
|
|
5356
5562
|
height: state.imageDimensions.height
|
|
5357
5563
|
};
|
|
5358
|
-
const handle = (0,
|
|
5359
|
-
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);
|
|
5360
5566
|
}
|
|
5361
5567
|
return;
|
|
5362
5568
|
}
|
|
5363
5569
|
if (activeTab === "annotate") {
|
|
5364
5570
|
if (annotationDragInfoRef.current) {
|
|
5365
5571
|
const drag = annotationDragInfoRef.current;
|
|
5366
|
-
const currentImgPt2 = (0,
|
|
5572
|
+
const currentImgPt2 = (0, import_image_editor11.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false);
|
|
5367
5573
|
const dx = currentImgPt2.x - drag.startImgPt.x;
|
|
5368
5574
|
const dy = currentImgPt2.y - drag.startImgPt.y;
|
|
5369
5575
|
editor.updateAnnotation(drag.annId, {
|
|
@@ -5375,10 +5581,10 @@ var ImageEditor = ({
|
|
|
5375
5581
|
const startPt = dragStartPointRef.current;
|
|
5376
5582
|
if (!startPt) {
|
|
5377
5583
|
if (state.activeTool === "select") {
|
|
5378
|
-
const imgPt = (0,
|
|
5584
|
+
const imgPt = (0, import_image_editor11.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false);
|
|
5379
5585
|
let hovered = false;
|
|
5380
5586
|
for (let i = state.annotations.length - 1; i >= 0; i--) {
|
|
5381
|
-
if ((0,
|
|
5587
|
+
if ((0, import_image_editor11.hitTestAnnotation)(imgPt, state.annotations[i])) {
|
|
5382
5588
|
hovered = true;
|
|
5383
5589
|
break;
|
|
5384
5590
|
}
|
|
@@ -5389,7 +5595,7 @@ var ImageEditor = ({
|
|
|
5389
5595
|
}
|
|
5390
5596
|
return;
|
|
5391
5597
|
}
|
|
5392
|
-
const currentImgPt = (0,
|
|
5598
|
+
const currentImgPt = (0, import_image_editor11.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false);
|
|
5393
5599
|
if (state.activeTool === "pen" && isDrawingRef.current) {
|
|
5394
5600
|
currentPathRef.current.push(currentImgPt);
|
|
5395
5601
|
const draft = {
|
|
@@ -5469,7 +5675,7 @@ var ImageEditor = ({
|
|
|
5469
5675
|
if (activeTab === "select") {
|
|
5470
5676
|
const gesture = selectionGestureRef.current;
|
|
5471
5677
|
if (gesture.active) {
|
|
5472
|
-
gesture.end((0,
|
|
5678
|
+
gesture.end((0, import_image_editor11.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false), e);
|
|
5473
5679
|
selectionDraftRef.current = null;
|
|
5474
5680
|
renderCanvas();
|
|
5475
5681
|
}
|
|
@@ -5493,7 +5699,7 @@ var ImageEditor = ({
|
|
|
5493
5699
|
}
|
|
5494
5700
|
const startPt = dragStartPointRef.current;
|
|
5495
5701
|
if (startPt) {
|
|
5496
|
-
const currentImgPt = (0,
|
|
5702
|
+
const currentImgPt = (0, import_image_editor11.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false);
|
|
5497
5703
|
if (state.activeTool === "pen" && isDrawingRef.current) {
|
|
5498
5704
|
if (currentPathRef.current.length > 1) {
|
|
5499
5705
|
editor.addAnnotation({
|
|
@@ -5589,15 +5795,15 @@ var ImageEditor = ({
|
|
|
5589
5795
|
link.click();
|
|
5590
5796
|
}
|
|
5591
5797
|
};
|
|
5592
|
-
return /* @__PURE__ */ (0,
|
|
5798
|
+
return /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(
|
|
5593
5799
|
"div",
|
|
5594
5800
|
{
|
|
5595
5801
|
className: `flex flex-col bg-slate-900 border border-slate-800 rounded-xl overflow-hidden shadow-2xl text-slate-100 ${className}`,
|
|
5596
5802
|
style,
|
|
5597
5803
|
children: [
|
|
5598
|
-
/* @__PURE__ */ (0,
|
|
5599
|
-
/* @__PURE__ */ (0,
|
|
5600
|
-
/* @__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)(
|
|
5601
5807
|
"button",
|
|
5602
5808
|
{
|
|
5603
5809
|
type: "button",
|
|
@@ -5609,7 +5815,7 @@ var ImageEditor = ({
|
|
|
5609
5815
|
children: "Transform & Crop"
|
|
5610
5816
|
}
|
|
5611
5817
|
),
|
|
5612
|
-
/* @__PURE__ */ (0,
|
|
5818
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
5613
5819
|
"button",
|
|
5614
5820
|
{
|
|
5615
5821
|
type: "button",
|
|
@@ -5621,7 +5827,7 @@ var ImageEditor = ({
|
|
|
5621
5827
|
children: "Adjustments"
|
|
5622
5828
|
}
|
|
5623
5829
|
),
|
|
5624
|
-
/* @__PURE__ */ (0,
|
|
5830
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
5625
5831
|
"button",
|
|
5626
5832
|
{
|
|
5627
5833
|
type: "button",
|
|
@@ -5633,7 +5839,7 @@ var ImageEditor = ({
|
|
|
5633
5839
|
children: "Layers"
|
|
5634
5840
|
}
|
|
5635
5841
|
),
|
|
5636
|
-
/* @__PURE__ */ (0,
|
|
5842
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
5637
5843
|
"button",
|
|
5638
5844
|
{
|
|
5639
5845
|
type: "button",
|
|
@@ -5645,7 +5851,7 @@ var ImageEditor = ({
|
|
|
5645
5851
|
children: "Paint"
|
|
5646
5852
|
}
|
|
5647
5853
|
),
|
|
5648
|
-
/* @__PURE__ */ (0,
|
|
5854
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
5649
5855
|
"button",
|
|
5650
5856
|
{
|
|
5651
5857
|
type: "button",
|
|
@@ -5657,7 +5863,7 @@ var ImageEditor = ({
|
|
|
5657
5863
|
children: "Select & Mask"
|
|
5658
5864
|
}
|
|
5659
5865
|
),
|
|
5660
|
-
/* @__PURE__ */ (0,
|
|
5866
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
5661
5867
|
"button",
|
|
5662
5868
|
{
|
|
5663
5869
|
type: "button",
|
|
@@ -5669,7 +5875,7 @@ var ImageEditor = ({
|
|
|
5669
5875
|
children: "Annotations"
|
|
5670
5876
|
}
|
|
5671
5877
|
),
|
|
5672
|
-
/* @__PURE__ */ (0,
|
|
5878
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
5673
5879
|
"button",
|
|
5674
5880
|
{
|
|
5675
5881
|
type: "button",
|
|
@@ -5681,7 +5887,7 @@ var ImageEditor = ({
|
|
|
5681
5887
|
children: "Depth Mask"
|
|
5682
5888
|
}
|
|
5683
5889
|
),
|
|
5684
|
-
/* @__PURE__ */ (0,
|
|
5890
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(
|
|
5685
5891
|
"button",
|
|
5686
5892
|
{
|
|
5687
5893
|
type: "button",
|
|
@@ -5691,14 +5897,14 @@ var ImageEditor = ({
|
|
|
5691
5897
|
},
|
|
5692
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"}`,
|
|
5693
5899
|
children: [
|
|
5694
|
-
/* @__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" }) }),
|
|
5695
5901
|
"AI Tools"
|
|
5696
5902
|
]
|
|
5697
5903
|
}
|
|
5698
5904
|
)
|
|
5699
5905
|
] }),
|
|
5700
|
-
/* @__PURE__ */ (0,
|
|
5701
|
-
/* @__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)(
|
|
5702
5908
|
"button",
|
|
5703
5909
|
{
|
|
5704
5910
|
type: "button",
|
|
@@ -5709,7 +5915,7 @@ var ImageEditor = ({
|
|
|
5709
5915
|
children: "\u21A9"
|
|
5710
5916
|
}
|
|
5711
5917
|
),
|
|
5712
|
-
/* @__PURE__ */ (0,
|
|
5918
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
5713
5919
|
"button",
|
|
5714
5920
|
{
|
|
5715
5921
|
type: "button",
|
|
@@ -5720,7 +5926,7 @@ var ImageEditor = ({
|
|
|
5720
5926
|
children: "\u21AA"
|
|
5721
5927
|
}
|
|
5722
5928
|
),
|
|
5723
|
-
/* @__PURE__ */ (0,
|
|
5929
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
5724
5930
|
"button",
|
|
5725
5931
|
{
|
|
5726
5932
|
type: "button",
|
|
@@ -5729,8 +5935,8 @@ var ImageEditor = ({
|
|
|
5729
5935
|
children: "Reset"
|
|
5730
5936
|
}
|
|
5731
5937
|
),
|
|
5732
|
-
/* @__PURE__ */ (0,
|
|
5733
|
-
/* @__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)(
|
|
5734
5940
|
"button",
|
|
5735
5941
|
{
|
|
5736
5942
|
type: "button",
|
|
@@ -5740,11 +5946,11 @@ var ImageEditor = ({
|
|
|
5740
5946
|
children: "-"
|
|
5741
5947
|
}
|
|
5742
5948
|
),
|
|
5743
|
-
/* @__PURE__ */ (0,
|
|
5949
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("span", { className: "font-mono text-slate-400 w-10 text-center", children: [
|
|
5744
5950
|
Math.round(state.zoom * 100),
|
|
5745
5951
|
"%"
|
|
5746
5952
|
] }),
|
|
5747
|
-
/* @__PURE__ */ (0,
|
|
5953
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
5748
5954
|
"button",
|
|
5749
5955
|
{
|
|
5750
5956
|
type: "button",
|
|
@@ -5754,8 +5960,8 @@ var ImageEditor = ({
|
|
|
5754
5960
|
children: "+"
|
|
5755
5961
|
}
|
|
5756
5962
|
),
|
|
5757
|
-
/* @__PURE__ */ (0,
|
|
5758
|
-
/* @__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)(
|
|
5759
5965
|
"button",
|
|
5760
5966
|
{
|
|
5761
5967
|
type: "button",
|
|
@@ -5766,7 +5972,7 @@ var ImageEditor = ({
|
|
|
5766
5972
|
children: "Hold Compare"
|
|
5767
5973
|
}
|
|
5768
5974
|
),
|
|
5769
|
-
/* @__PURE__ */ (0,
|
|
5975
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
5770
5976
|
"button",
|
|
5771
5977
|
{
|
|
5772
5978
|
type: "button",
|
|
@@ -5777,13 +5983,13 @@ var ImageEditor = ({
|
|
|
5777
5983
|
)
|
|
5778
5984
|
] })
|
|
5779
5985
|
] }),
|
|
5780
|
-
/* @__PURE__ */ (0,
|
|
5781
|
-
/* @__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)(
|
|
5782
5988
|
"div",
|
|
5783
5989
|
{
|
|
5784
5990
|
ref: containerRef,
|
|
5785
5991
|
className: "relative flex-1 h-[360px] md:h-full min-h-[320px] bg-slate-950 overflow-hidden select-none",
|
|
5786
|
-
children: /* @__PURE__ */ (0,
|
|
5992
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
5787
5993
|
"canvas",
|
|
5788
5994
|
{
|
|
5789
5995
|
ref: canvasRef,
|
|
@@ -5801,11 +6007,11 @@ var ImageEditor = ({
|
|
|
5801
6007
|
)
|
|
5802
6008
|
}
|
|
5803
6009
|
),
|
|
5804
|
-
/* @__PURE__ */ (0,
|
|
5805
|
-
activeTab === "crop" && /* @__PURE__ */ (0,
|
|
5806
|
-
/* @__PURE__ */ (0,
|
|
5807
|
-
/* @__PURE__ */ (0,
|
|
5808
|
-
/* @__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)(
|
|
5809
6015
|
"button",
|
|
5810
6016
|
{
|
|
5811
6017
|
type: "button",
|
|
@@ -5817,7 +6023,7 @@ var ImageEditor = ({
|
|
|
5817
6023
|
children: "Freeform"
|
|
5818
6024
|
}
|
|
5819
6025
|
),
|
|
5820
|
-
/* @__PURE__ */ (0,
|
|
6026
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
5821
6027
|
"button",
|
|
5822
6028
|
{
|
|
5823
6029
|
type: "button",
|
|
@@ -5829,7 +6035,7 @@ var ImageEditor = ({
|
|
|
5829
6035
|
children: "1:1 Square"
|
|
5830
6036
|
}
|
|
5831
6037
|
),
|
|
5832
|
-
/* @__PURE__ */ (0,
|
|
6038
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
5833
6039
|
"button",
|
|
5834
6040
|
{
|
|
5835
6041
|
type: "button",
|
|
@@ -5841,7 +6047,7 @@ var ImageEditor = ({
|
|
|
5841
6047
|
children: "4:3 Standard"
|
|
5842
6048
|
}
|
|
5843
6049
|
),
|
|
5844
|
-
/* @__PURE__ */ (0,
|
|
6050
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
5845
6051
|
"button",
|
|
5846
6052
|
{
|
|
5847
6053
|
type: "button",
|
|
@@ -5853,7 +6059,7 @@ var ImageEditor = ({
|
|
|
5853
6059
|
children: "16:9 Wide"
|
|
5854
6060
|
}
|
|
5855
6061
|
),
|
|
5856
|
-
/* @__PURE__ */ (0,
|
|
6062
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
5857
6063
|
"button",
|
|
5858
6064
|
{
|
|
5859
6065
|
type: "button",
|
|
@@ -5865,7 +6071,7 @@ var ImageEditor = ({
|
|
|
5865
6071
|
children: "3:2 Photo"
|
|
5866
6072
|
}
|
|
5867
6073
|
),
|
|
5868
|
-
/* @__PURE__ */ (0,
|
|
6074
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
5869
6075
|
"button",
|
|
5870
6076
|
{
|
|
5871
6077
|
type: "button",
|
|
@@ -5878,10 +6084,10 @@ var ImageEditor = ({
|
|
|
5878
6084
|
}
|
|
5879
6085
|
)
|
|
5880
6086
|
] }),
|
|
5881
|
-
/* @__PURE__ */ (0,
|
|
5882
|
-
/* @__PURE__ */ (0,
|
|
5883
|
-
/* @__PURE__ */ (0,
|
|
5884
|
-
/* @__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)(
|
|
5885
6091
|
"button",
|
|
5886
6092
|
{
|
|
5887
6093
|
type: "button",
|
|
@@ -5890,7 +6096,7 @@ var ImageEditor = ({
|
|
|
5890
6096
|
children: "Rotate -90\xB0"
|
|
5891
6097
|
}
|
|
5892
6098
|
),
|
|
5893
|
-
/* @__PURE__ */ (0,
|
|
6099
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
5894
6100
|
"button",
|
|
5895
6101
|
{
|
|
5896
6102
|
type: "button",
|
|
@@ -5899,7 +6105,7 @@ var ImageEditor = ({
|
|
|
5899
6105
|
children: "Rotate +90\xB0"
|
|
5900
6106
|
}
|
|
5901
6107
|
),
|
|
5902
|
-
/* @__PURE__ */ (0,
|
|
6108
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
5903
6109
|
"button",
|
|
5904
6110
|
{
|
|
5905
6111
|
type: "button",
|
|
@@ -5908,7 +6114,7 @@ var ImageEditor = ({
|
|
|
5908
6114
|
children: "Flip Horizontal"
|
|
5909
6115
|
}
|
|
5910
6116
|
),
|
|
5911
|
-
/* @__PURE__ */ (0,
|
|
6117
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
5912
6118
|
"button",
|
|
5913
6119
|
{
|
|
5914
6120
|
type: "button",
|
|
@@ -5919,10 +6125,10 @@ var ImageEditor = ({
|
|
|
5919
6125
|
)
|
|
5920
6126
|
] })
|
|
5921
6127
|
] }),
|
|
5922
|
-
activeTab === "adjust" && /* @__PURE__ */ (0,
|
|
5923
|
-
/* @__PURE__ */ (0,
|
|
5924
|
-
/* @__PURE__ */ (0,
|
|
5925
|
-
/* @__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)(
|
|
5926
6132
|
"button",
|
|
5927
6133
|
{
|
|
5928
6134
|
type: "button",
|
|
@@ -5932,25 +6138,25 @@ var ImageEditor = ({
|
|
|
5932
6138
|
}
|
|
5933
6139
|
)
|
|
5934
6140
|
] }),
|
|
5935
|
-
/* @__PURE__ */ (0,
|
|
5936
|
-
|
|
5937
|
-
/* @__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)(
|
|
5938
6144
|
ControlSlider,
|
|
5939
6145
|
{
|
|
5940
6146
|
spec,
|
|
5941
|
-
value: (0,
|
|
6147
|
+
value: (0, import_image_editor11.readAdjustmentControls)(state.adjustments)[spec.id],
|
|
5942
6148
|
disabled: spec.requiresProcess !== void 0 && legacyProcess,
|
|
5943
6149
|
onChange: (v) => editor.setAdjustments({ [spec.id]: v })
|
|
5944
6150
|
}
|
|
5945
6151
|
),
|
|
5946
|
-
spec.id === "tint" && legacyProcess && /* @__PURE__ */ (0,
|
|
6152
|
+
spec.id === "tint" && legacyProcess && /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(
|
|
5947
6153
|
"div",
|
|
5948
6154
|
{
|
|
5949
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",
|
|
5950
6156
|
"data-testid": "image-editor-process-notice",
|
|
5951
6157
|
children: [
|
|
5952
|
-
/* @__PURE__ */ (0,
|
|
5953
|
-
/* @__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)(
|
|
5954
6160
|
"button",
|
|
5955
6161
|
{
|
|
5956
6162
|
type: "button",
|
|
@@ -5963,7 +6169,7 @@ var ImageEditor = ({
|
|
|
5963
6169
|
}
|
|
5964
6170
|
)
|
|
5965
6171
|
] }, spec.id)),
|
|
5966
|
-
/* @__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)(
|
|
5967
6173
|
AdjustmentLayersPanel,
|
|
5968
6174
|
{
|
|
5969
6175
|
controller,
|
|
@@ -5972,19 +6178,19 @@ var ImageEditor = ({
|
|
|
5972
6178
|
}
|
|
5973
6179
|
) })
|
|
5974
6180
|
] }),
|
|
5975
|
-
activeTab === "layers" && /* @__PURE__ */ (0,
|
|
5976
|
-
/* @__PURE__ */ (0,
|
|
5977
|
-
/* @__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 })
|
|
5978
6184
|
] }),
|
|
5979
|
-
activeTab === "paint" && /* @__PURE__ */ (0,
|
|
5980
|
-
/* @__PURE__ */ (0,
|
|
5981
|
-
/* @__PURE__ */ (0,
|
|
5982
|
-
paintError && /* @__PURE__ */ (0,
|
|
5983
|
-
/* @__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 }) })
|
|
5984
6190
|
] }),
|
|
5985
|
-
activeTab === "annotate" && /* @__PURE__ */ (0,
|
|
5986
|
-
/* @__PURE__ */ (0,
|
|
5987
|
-
/* @__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)(
|
|
5988
6194
|
"button",
|
|
5989
6195
|
{
|
|
5990
6196
|
type: "button",
|
|
@@ -5994,9 +6200,9 @@ var ImageEditor = ({
|
|
|
5994
6200
|
},
|
|
5995
6201
|
t
|
|
5996
6202
|
)) }),
|
|
5997
|
-
/* @__PURE__ */ (0,
|
|
5998
|
-
/* @__PURE__ */ (0,
|
|
5999
|
-
/* @__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)(
|
|
6000
6206
|
"input",
|
|
6001
6207
|
{
|
|
6002
6208
|
type: "color",
|
|
@@ -6005,15 +6211,15 @@ var ImageEditor = ({
|
|
|
6005
6211
|
className: "w-8 h-8 rounded border border-slate-700 cursor-pointer bg-transparent"
|
|
6006
6212
|
}
|
|
6007
6213
|
),
|
|
6008
|
-
/* @__PURE__ */ (0,
|
|
6009
|
-
/* @__PURE__ */ (0,
|
|
6010
|
-
/* @__PURE__ */ (0,
|
|
6011
|
-
/* @__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: [
|
|
6012
6218
|
strokeWidth,
|
|
6013
6219
|
"px"
|
|
6014
6220
|
] })
|
|
6015
6221
|
] }),
|
|
6016
|
-
/* @__PURE__ */ (0,
|
|
6222
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
6017
6223
|
"input",
|
|
6018
6224
|
{
|
|
6019
6225
|
type: "range",
|
|
@@ -6026,10 +6232,10 @@ var ImageEditor = ({
|
|
|
6026
6232
|
)
|
|
6027
6233
|
] })
|
|
6028
6234
|
] }),
|
|
6029
|
-
/* @__PURE__ */ (0,
|
|
6030
|
-
/* @__PURE__ */ (0,
|
|
6031
|
-
/* @__PURE__ */ (0,
|
|
6032
|
-
/* @__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)(
|
|
6033
6239
|
"input",
|
|
6034
6240
|
{
|
|
6035
6241
|
type: "text",
|
|
@@ -6040,7 +6246,7 @@ var ImageEditor = ({
|
|
|
6040
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"
|
|
6041
6247
|
}
|
|
6042
6248
|
),
|
|
6043
|
-
/* @__PURE__ */ (0,
|
|
6249
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
6044
6250
|
"button",
|
|
6045
6251
|
{
|
|
6046
6252
|
type: "button",
|
|
@@ -6050,14 +6256,14 @@ var ImageEditor = ({
|
|
|
6050
6256
|
}
|
|
6051
6257
|
)
|
|
6052
6258
|
] }),
|
|
6053
|
-
/* @__PURE__ */ (0,
|
|
6054
|
-
/* @__PURE__ */ (0,
|
|
6055
|
-
/* @__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: [
|
|
6056
6262
|
fontSize,
|
|
6057
6263
|
"px"
|
|
6058
6264
|
] })
|
|
6059
6265
|
] }),
|
|
6060
|
-
/* @__PURE__ */ (0,
|
|
6266
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
6061
6267
|
"input",
|
|
6062
6268
|
{
|
|
6063
6269
|
type: "range",
|
|
@@ -6068,14 +6274,14 @@ var ImageEditor = ({
|
|
|
6068
6274
|
className: "w-full accent-indigo-500"
|
|
6069
6275
|
}
|
|
6070
6276
|
),
|
|
6071
|
-
/* @__PURE__ */ (0,
|
|
6072
|
-
/* @__PURE__ */ (0,
|
|
6073
|
-
/* @__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: [
|
|
6074
6280
|
"Layers (",
|
|
6075
6281
|
state.annotations.length,
|
|
6076
6282
|
")"
|
|
6077
6283
|
] }),
|
|
6078
|
-
state.selectedAnnotationId && /* @__PURE__ */ (0,
|
|
6284
|
+
state.selectedAnnotationId && /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
6079
6285
|
"button",
|
|
6080
6286
|
{
|
|
6081
6287
|
type: "button",
|
|
@@ -6084,7 +6290,7 @@ var ImageEditor = ({
|
|
|
6084
6290
|
children: "Delete Selected"
|
|
6085
6291
|
}
|
|
6086
6292
|
),
|
|
6087
|
-
state.annotations.length > 0 && /* @__PURE__ */ (0,
|
|
6293
|
+
state.annotations.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
6088
6294
|
"button",
|
|
6089
6295
|
{
|
|
6090
6296
|
type: "button",
|
|
@@ -6095,10 +6301,10 @@ var ImageEditor = ({
|
|
|
6095
6301
|
)
|
|
6096
6302
|
] })
|
|
6097
6303
|
] }),
|
|
6098
|
-
activeTab === "depth" && /* @__PURE__ */ (0,
|
|
6099
|
-
/* @__PURE__ */ (0,
|
|
6100
|
-
/* @__PURE__ */ (0,
|
|
6101
|
-
/* @__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)(
|
|
6102
6308
|
"button",
|
|
6103
6309
|
{
|
|
6104
6310
|
type: "button",
|
|
@@ -6108,8 +6314,8 @@ var ImageEditor = ({
|
|
|
6108
6314
|
}
|
|
6109
6315
|
)
|
|
6110
6316
|
] }),
|
|
6111
|
-
/* @__PURE__ */ (0,
|
|
6112
|
-
/* @__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)(
|
|
6113
6319
|
"input",
|
|
6114
6320
|
{
|
|
6115
6321
|
type: "checkbox",
|
|
@@ -6118,12 +6324,12 @@ var ImageEditor = ({
|
|
|
6118
6324
|
className: "rounded accent-indigo-500"
|
|
6119
6325
|
}
|
|
6120
6326
|
),
|
|
6121
|
-
/* @__PURE__ */ (0,
|
|
6327
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { children: "Enable Depth / Alpha Mask" })
|
|
6122
6328
|
] }),
|
|
6123
|
-
state.depthMask.enabled && /* @__PURE__ */ (0,
|
|
6124
|
-
/* @__PURE__ */ (0,
|
|
6125
|
-
/* @__PURE__ */ (0,
|
|
6126
|
-
/* @__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)(
|
|
6127
6333
|
"input",
|
|
6128
6334
|
{
|
|
6129
6335
|
type: "text",
|
|
@@ -6134,8 +6340,8 @@ var ImageEditor = ({
|
|
|
6134
6340
|
}
|
|
6135
6341
|
)
|
|
6136
6342
|
] }),
|
|
6137
|
-
/* @__PURE__ */ (0,
|
|
6138
|
-
/* @__PURE__ */ (0,
|
|
6343
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "flex gap-2", children: [
|
|
6344
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
6139
6345
|
"button",
|
|
6140
6346
|
{
|
|
6141
6347
|
type: "button",
|
|
@@ -6144,7 +6350,7 @@ var ImageEditor = ({
|
|
|
6144
6350
|
children: "Threshold Mode"
|
|
6145
6351
|
}
|
|
6146
6352
|
),
|
|
6147
|
-
/* @__PURE__ */ (0,
|
|
6353
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
6148
6354
|
"button",
|
|
6149
6355
|
{
|
|
6150
6356
|
type: "button",
|
|
@@ -6154,12 +6360,12 @@ var ImageEditor = ({
|
|
|
6154
6360
|
}
|
|
6155
6361
|
)
|
|
6156
6362
|
] }),
|
|
6157
|
-
/* @__PURE__ */ (0,
|
|
6158
|
-
/* @__PURE__ */ (0,
|
|
6159
|
-
/* @__PURE__ */ (0,
|
|
6160
|
-
/* @__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] })
|
|
6161
6367
|
] }),
|
|
6162
|
-
/* @__PURE__ */ (0,
|
|
6368
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
6163
6369
|
"input",
|
|
6164
6370
|
{
|
|
6165
6371
|
type: "range",
|
|
@@ -6173,12 +6379,12 @@ var ImageEditor = ({
|
|
|
6173
6379
|
}
|
|
6174
6380
|
)
|
|
6175
6381
|
] }),
|
|
6176
|
-
/* @__PURE__ */ (0,
|
|
6177
|
-
/* @__PURE__ */ (0,
|
|
6178
|
-
/* @__PURE__ */ (0,
|
|
6179
|
-
/* @__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] })
|
|
6180
6386
|
] }),
|
|
6181
|
-
/* @__PURE__ */ (0,
|
|
6387
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
6182
6388
|
"input",
|
|
6183
6389
|
{
|
|
6184
6390
|
type: "range",
|
|
@@ -6192,12 +6398,12 @@ var ImageEditor = ({
|
|
|
6192
6398
|
}
|
|
6193
6399
|
)
|
|
6194
6400
|
] }),
|
|
6195
|
-
/* @__PURE__ */ (0,
|
|
6196
|
-
/* @__PURE__ */ (0,
|
|
6197
|
-
/* @__PURE__ */ (0,
|
|
6198
|
-
/* @__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 })
|
|
6199
6405
|
] }),
|
|
6200
|
-
/* @__PURE__ */ (0,
|
|
6406
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
6201
6407
|
"input",
|
|
6202
6408
|
{
|
|
6203
6409
|
type: "range",
|
|
@@ -6209,8 +6415,8 @@ var ImageEditor = ({
|
|
|
6209
6415
|
}
|
|
6210
6416
|
)
|
|
6211
6417
|
] }),
|
|
6212
|
-
/* @__PURE__ */ (0,
|
|
6213
|
-
/* @__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)(
|
|
6214
6420
|
"input",
|
|
6215
6421
|
{
|
|
6216
6422
|
type: "checkbox",
|
|
@@ -6219,12 +6425,12 @@ var ImageEditor = ({
|
|
|
6219
6425
|
className: "rounded accent-indigo-500"
|
|
6220
6426
|
}
|
|
6221
6427
|
),
|
|
6222
|
-
/* @__PURE__ */ (0,
|
|
6428
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { children: "Invert Mask" })
|
|
6223
6429
|
] })
|
|
6224
6430
|
] })
|
|
6225
6431
|
] }),
|
|
6226
|
-
activeTab === "select" && /* @__PURE__ */ (0,
|
|
6227
|
-
/* @__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)(
|
|
6228
6434
|
SelectionOptionsBar,
|
|
6229
6435
|
{
|
|
6230
6436
|
controller,
|
|
@@ -6234,13 +6440,13 @@ var ImageEditor = ({
|
|
|
6234
6440
|
quickMask: Boolean(state.quickMask)
|
|
6235
6441
|
}
|
|
6236
6442
|
),
|
|
6237
|
-
selectionError && /* @__PURE__ */ (0,
|
|
6238
|
-
/* @__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 })
|
|
6239
6445
|
] }),
|
|
6240
|
-
activeTab === "ai" && /* @__PURE__ */ (0,
|
|
6241
|
-
/* @__PURE__ */ (0,
|
|
6242
|
-
/* @__PURE__ */ (0,
|
|
6243
|
-
/* @__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)(
|
|
6244
6450
|
"select",
|
|
6245
6451
|
{
|
|
6246
6452
|
"aria-label": "AI result target",
|
|
@@ -6248,54 +6454,54 @@ var ImageEditor = ({
|
|
|
6248
6454
|
onChange: (e) => setAiTarget(e.target.value),
|
|
6249
6455
|
className: "bg-slate-800 border border-slate-700 rounded px-1.5 py-1",
|
|
6250
6456
|
children: [
|
|
6251
|
-
/* @__PURE__ */ (0,
|
|
6252
|
-
/* @__PURE__ */ (0,
|
|
6253
|
-
/* @__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" })
|
|
6254
6460
|
]
|
|
6255
6461
|
}
|
|
6256
6462
|
)
|
|
6257
6463
|
] }),
|
|
6258
|
-
/* @__PURE__ */ (0,
|
|
6259
|
-
/* @__PURE__ */ (0,
|
|
6260
|
-
/* @__PURE__ */ (0,
|
|
6261
|
-
/* @__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" }) }),
|
|
6262
6468
|
"Background Removal"
|
|
6263
6469
|
] }),
|
|
6264
|
-
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..." })
|
|
6265
6471
|
] }),
|
|
6266
|
-
/* @__PURE__ */ (0,
|
|
6267
|
-
/* @__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)(
|
|
6268
6474
|
"button",
|
|
6269
6475
|
{
|
|
6270
6476
|
type: "button",
|
|
6271
6477
|
onClick: handleRemoveBackground,
|
|
6272
6478
|
disabled: isRemovingBg || isInpainting,
|
|
6273
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",
|
|
6274
|
-
children: isRemovingBg ? /* @__PURE__ */ (0,
|
|
6275
|
-
/* @__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" }),
|
|
6276
6482
|
"Removing Background..."
|
|
6277
|
-
] }) : /* @__PURE__ */ (0,
|
|
6278
|
-
/* @__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" }) }),
|
|
6279
6485
|
"Remove Background"
|
|
6280
6486
|
] })
|
|
6281
6487
|
}
|
|
6282
6488
|
)
|
|
6283
6489
|
] }),
|
|
6284
|
-
/* @__PURE__ */ (0,
|
|
6285
|
-
/* @__PURE__ */ (0,
|
|
6286
|
-
/* @__PURE__ */ (0,
|
|
6287
|
-
/* @__PURE__ */ (0,
|
|
6288
|
-
/* @__PURE__ */ (0,
|
|
6289
|
-
/* @__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" })
|
|
6290
6496
|
] }),
|
|
6291
6497
|
"Generative Inpainting"
|
|
6292
6498
|
] }),
|
|
6293
|
-
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..." })
|
|
6294
6500
|
] }),
|
|
6295
|
-
/* @__PURE__ */ (0,
|
|
6296
|
-
/* @__PURE__ */ (0,
|
|
6297
|
-
/* @__PURE__ */ (0,
|
|
6298
|
-
/* @__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)(
|
|
6299
6505
|
"textarea",
|
|
6300
6506
|
{
|
|
6301
6507
|
id: "ai-inpaint-prompt-react",
|
|
@@ -6307,10 +6513,10 @@ var ImageEditor = ({
|
|
|
6307
6513
|
}
|
|
6308
6514
|
)
|
|
6309
6515
|
] }),
|
|
6310
|
-
/* @__PURE__ */ (0,
|
|
6311
|
-
/* @__PURE__ */ (0,
|
|
6312
|
-
/* @__PURE__ */ (0,
|
|
6313
|
-
/* @__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)(
|
|
6314
6520
|
"button",
|
|
6315
6521
|
{
|
|
6316
6522
|
type: "button",
|
|
@@ -6323,7 +6529,7 @@ var ImageEditor = ({
|
|
|
6323
6529
|
]
|
|
6324
6530
|
}
|
|
6325
6531
|
),
|
|
6326
|
-
/* @__PURE__ */ (0,
|
|
6532
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(
|
|
6327
6533
|
"button",
|
|
6328
6534
|
{
|
|
6329
6535
|
type: "button",
|
|
@@ -6338,25 +6544,25 @@ var ImageEditor = ({
|
|
|
6338
6544
|
)
|
|
6339
6545
|
] })
|
|
6340
6546
|
] }),
|
|
6341
|
-
/* @__PURE__ */ (0,
|
|
6547
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
6342
6548
|
"button",
|
|
6343
6549
|
{
|
|
6344
6550
|
type: "button",
|
|
6345
6551
|
onClick: handleInpaint,
|
|
6346
6552
|
disabled: isInpainting || isRemovingBg || !inpaintPrompt.trim(),
|
|
6347
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",
|
|
6348
|
-
children: isInpainting ? /* @__PURE__ */ (0,
|
|
6349
|
-
/* @__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" }),
|
|
6350
6556
|
"Generating Inpaint..."
|
|
6351
|
-
] }) : /* @__PURE__ */ (0,
|
|
6352
|
-
/* @__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" }) }),
|
|
6353
6559
|
"Apply Inpainting"
|
|
6354
6560
|
] })
|
|
6355
6561
|
}
|
|
6356
6562
|
)
|
|
6357
6563
|
] }),
|
|
6358
|
-
aiError && /* @__PURE__ */ (0,
|
|
6359
|
-
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 })
|
|
6360
6566
|
] })
|
|
6361
6567
|
] })
|
|
6362
6568
|
] })
|
|
@@ -6366,7 +6572,7 @@ var ImageEditor = ({
|
|
|
6366
6572
|
};
|
|
6367
6573
|
|
|
6368
6574
|
// src/review/useReview.ts
|
|
6369
|
-
var
|
|
6575
|
+
var import_react44 = require("react");
|
|
6370
6576
|
var import_editor12 = require("@pixerate/editor");
|
|
6371
6577
|
var EMPTY_COMMENTS = Object.freeze({
|
|
6372
6578
|
threads: [],
|
|
@@ -6385,23 +6591,23 @@ function isCommentStore(value) {
|
|
|
6385
6591
|
}
|
|
6386
6592
|
function useComments(source) {
|
|
6387
6593
|
const store = isCommentStore(source) ? source : (0, import_editor12.getCommentStore)(source);
|
|
6388
|
-
const subscribe = (0,
|
|
6594
|
+
const subscribe = (0, import_react44.useCallback)(
|
|
6389
6595
|
(onChange) => store ? store.subscribe(() => onChange()) : noopUnsubscribe,
|
|
6390
6596
|
[store]
|
|
6391
6597
|
);
|
|
6392
6598
|
const getSnapshot = () => store?.getSnapshot() ?? EMPTY_COMMENTS;
|
|
6393
|
-
const snapshot = (0,
|
|
6394
|
-
return (0,
|
|
6599
|
+
const snapshot = (0, import_react44.useSyncExternalStore)(subscribe, getSnapshot, getSnapshot);
|
|
6600
|
+
return (0, import_react44.useMemo)(() => ({ ...snapshot, store }), [snapshot, store]);
|
|
6395
6601
|
}
|
|
6396
6602
|
function useTrackChanges(editor) {
|
|
6397
6603
|
const store = (0, import_editor12.getTrackChangesStore)(editor ?? null);
|
|
6398
|
-
const subscribe = (0,
|
|
6604
|
+
const subscribe = (0, import_react44.useCallback)(
|
|
6399
6605
|
(onChange) => store ? store.subscribe(() => onChange()) : noopUnsubscribe,
|
|
6400
6606
|
[store]
|
|
6401
6607
|
);
|
|
6402
6608
|
const getSnapshot = () => store?.getSnapshot() ?? EMPTY_TRACK_CHANGES;
|
|
6403
|
-
const snapshot = (0,
|
|
6404
|
-
return (0,
|
|
6609
|
+
const snapshot = (0, import_react44.useSyncExternalStore)(subscribe, getSnapshot, getSnapshot);
|
|
6610
|
+
return (0, import_react44.useMemo)(() => {
|
|
6405
6611
|
const run = (fn) => () => {
|
|
6406
6612
|
if (editor && !editor.isDestroyed) fn(editor);
|
|
6407
6613
|
};
|
|
@@ -6424,9 +6630,9 @@ function useTrackChanges(editor) {
|
|
|
6424
6630
|
}
|
|
6425
6631
|
|
|
6426
6632
|
// src/review/CommentsPanel.tsx
|
|
6427
|
-
var
|
|
6633
|
+
var import_react45 = require("react");
|
|
6428
6634
|
var import_editor13 = require("@pixerate/editor");
|
|
6429
|
-
var
|
|
6635
|
+
var import_jsx_runtime27 = require("react/jsx-runtime");
|
|
6430
6636
|
var buttonClass2 = "rounded px-2 py-1 text-xs text-muted-foreground hover:bg-muted hover:text-foreground disabled:opacity-50";
|
|
6431
6637
|
var primaryButtonClass = "rounded px-2 py-1 text-xs bg-primary/10 text-primary hover:bg-primary/20 disabled:opacity-50";
|
|
6432
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";
|
|
@@ -6440,18 +6646,18 @@ var CommentsPanel = ({
|
|
|
6440
6646
|
emptyMessage = "No comments yet. Select text and add a comment."
|
|
6441
6647
|
}) => {
|
|
6442
6648
|
const { threads, activeThreadId, store } = useComments(storeProp ?? editor);
|
|
6443
|
-
const [showResolved, setShowResolved] = (0,
|
|
6649
|
+
const [showResolved, setShowResolved] = (0, import_react45.useState)(showResolvedInitial);
|
|
6444
6650
|
const author = authorProp ?? (0, import_editor13.getCommentAuthor)(editor) ?? { id: "anonymous", name: "Anonymous" };
|
|
6445
6651
|
const visible = threads.filter((t) => showResolved || !t.resolved);
|
|
6446
6652
|
const resolvedCount = threads.filter((t) => t.resolved).length;
|
|
6447
|
-
return /* @__PURE__ */ (0,
|
|
6448
|
-
/* @__PURE__ */ (0,
|
|
6449
|
-
/* @__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: [
|
|
6450
6656
|
threads.length - resolvedCount,
|
|
6451
6657
|
" open",
|
|
6452
6658
|
resolvedCount > 0 ? ` \xB7 ${resolvedCount} resolved` : ""
|
|
6453
6659
|
] }),
|
|
6454
|
-
resolvedCount > 0 && /* @__PURE__ */ (0,
|
|
6660
|
+
resolvedCount > 0 && /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
6455
6661
|
"button",
|
|
6456
6662
|
{
|
|
6457
6663
|
type: "button",
|
|
@@ -6462,7 +6668,7 @@ var CommentsPanel = ({
|
|
|
6462
6668
|
}
|
|
6463
6669
|
)
|
|
6464
6670
|
] }),
|
|
6465
|
-
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)(
|
|
6466
6672
|
CommentThreadCard,
|
|
6467
6673
|
{
|
|
6468
6674
|
thread,
|
|
@@ -6484,7 +6690,7 @@ var CommentThreadCard = ({
|
|
|
6484
6690
|
author,
|
|
6485
6691
|
formatTime
|
|
6486
6692
|
}) => {
|
|
6487
|
-
const [draft, setDraft] = (0,
|
|
6693
|
+
const [draft, setDraft] = (0, import_react45.useState)("");
|
|
6488
6694
|
const isDraft = thread.body === "";
|
|
6489
6695
|
const quote = thread.anchor?.quote ?? thread.lastQuote ?? "";
|
|
6490
6696
|
const live = editor && !editor.isDestroyed ? editor : null;
|
|
@@ -6510,7 +6716,7 @@ var CommentThreadCard = ({
|
|
|
6510
6716
|
setDraft("");
|
|
6511
6717
|
};
|
|
6512
6718
|
const stop = (e) => e.stopPropagation();
|
|
6513
|
-
return /* @__PURE__ */ (0,
|
|
6719
|
+
return /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(
|
|
6514
6720
|
"li",
|
|
6515
6721
|
{
|
|
6516
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" : ""}`,
|
|
@@ -6526,24 +6732,24 @@ var CommentThreadCard = ({
|
|
|
6526
6732
|
}
|
|
6527
6733
|
},
|
|
6528
6734
|
children: [
|
|
6529
|
-
/* @__PURE__ */ (0,
|
|
6530
|
-
/* @__PURE__ */ (0,
|
|
6531
|
-
/* @__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) })
|
|
6532
6738
|
] }),
|
|
6533
|
-
quote && /* @__PURE__ */ (0,
|
|
6534
|
-
thread.orphaned && /* @__PURE__ */ (0,
|
|
6535
|
-
thread.resolved && /* @__PURE__ */ (0,
|
|
6536
|
-
!isDraft && /* @__PURE__ */ (0,
|
|
6537
|
-
thread.replies.length > 0 && /* @__PURE__ */ (0,
|
|
6538
|
-
/* @__PURE__ */ (0,
|
|
6539
|
-
/* @__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 }),
|
|
6540
6746
|
" ",
|
|
6541
|
-
/* @__PURE__ */ (0,
|
|
6747
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: "text-muted-foreground", children: formatTime(reply.createdAt) })
|
|
6542
6748
|
] }),
|
|
6543
|
-
/* @__PURE__ */ (0,
|
|
6749
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("p", { className: "whitespace-pre-wrap break-words", children: reply.body })
|
|
6544
6750
|
] }, reply.id)) }),
|
|
6545
|
-
(active || isDraft) && !thread.resolved && /* @__PURE__ */ (0,
|
|
6546
|
-
/* @__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)(
|
|
6547
6753
|
"textarea",
|
|
6548
6754
|
{
|
|
6549
6755
|
className: textareaClass,
|
|
@@ -6561,9 +6767,9 @@ var CommentThreadCard = ({
|
|
|
6561
6767
|
}
|
|
6562
6768
|
}
|
|
6563
6769
|
),
|
|
6564
|
-
/* @__PURE__ */ (0,
|
|
6565
|
-
isDraft && /* @__PURE__ */ (0,
|
|
6566
|
-
/* @__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)(
|
|
6567
6773
|
"button",
|
|
6568
6774
|
{
|
|
6569
6775
|
type: "button",
|
|
@@ -6575,9 +6781,9 @@ var CommentThreadCard = ({
|
|
|
6575
6781
|
)
|
|
6576
6782
|
] })
|
|
6577
6783
|
] }),
|
|
6578
|
-
!isDraft && /* @__PURE__ */ (0,
|
|
6579
|
-
/* @__PURE__ */ (0,
|
|
6580
|
-
/* @__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)(
|
|
6581
6787
|
"button",
|
|
6582
6788
|
{
|
|
6583
6789
|
type: "button",
|
|
@@ -6593,7 +6799,7 @@ var CommentThreadCard = ({
|
|
|
6593
6799
|
};
|
|
6594
6800
|
|
|
6595
6801
|
// src/review/ReviewToolbar.tsx
|
|
6596
|
-
var
|
|
6802
|
+
var import_jsx_runtime28 = require("react/jsx-runtime");
|
|
6597
6803
|
var defaultDescriptionClass = "max-w-[16rem] truncate px-1 text-xs text-muted-foreground";
|
|
6598
6804
|
var buttonClass3 = "rounded px-2 py-1 text-xs text-foreground hover:bg-muted disabled:opacity-40 disabled:hover:bg-transparent";
|
|
6599
6805
|
var ReviewToolbar = ({
|
|
@@ -6606,8 +6812,8 @@ var ReviewToolbar = ({
|
|
|
6606
6812
|
const count = review.changes.length;
|
|
6607
6813
|
const current = review.currentChange;
|
|
6608
6814
|
const index = current ? review.changes.findIndex((c) => c.id === current.id) + 1 : 0;
|
|
6609
|
-
return /* @__PURE__ */ (0,
|
|
6610
|
-
/* @__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)(
|
|
6611
6817
|
"button",
|
|
6612
6818
|
{
|
|
6613
6819
|
type: "button",
|
|
@@ -6618,8 +6824,8 @@ var ReviewToolbar = ({
|
|
|
6618
6824
|
children: review.enabled ? "Tracking on" : "Track changes"
|
|
6619
6825
|
}
|
|
6620
6826
|
),
|
|
6621
|
-
/* @__PURE__ */ (0,
|
|
6622
|
-
/* @__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)(
|
|
6623
6829
|
"button",
|
|
6624
6830
|
{
|
|
6625
6831
|
type: "button",
|
|
@@ -6630,8 +6836,8 @@ var ReviewToolbar = ({
|
|
|
6630
6836
|
children: "\u2039"
|
|
6631
6837
|
}
|
|
6632
6838
|
),
|
|
6633
|
-
/* @__PURE__ */ (0,
|
|
6634
|
-
/* @__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)(
|
|
6635
6841
|
"button",
|
|
6636
6842
|
{
|
|
6637
6843
|
type: "button",
|
|
@@ -6642,7 +6848,7 @@ var ReviewToolbar = ({
|
|
|
6642
6848
|
children: "\u203A"
|
|
6643
6849
|
}
|
|
6644
6850
|
),
|
|
6645
|
-
showDescription && current && /* @__PURE__ */ (0,
|
|
6851
|
+
showDescription && current && /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(
|
|
6646
6852
|
"span",
|
|
6647
6853
|
{
|
|
6648
6854
|
className: descriptionClassName,
|
|
@@ -6654,8 +6860,8 @@ var ReviewToolbar = ({
|
|
|
6654
6860
|
]
|
|
6655
6861
|
}
|
|
6656
6862
|
),
|
|
6657
|
-
/* @__PURE__ */ (0,
|
|
6658
|
-
/* @__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)(
|
|
6659
6865
|
"button",
|
|
6660
6866
|
{
|
|
6661
6867
|
type: "button",
|
|
@@ -6665,7 +6871,7 @@ var ReviewToolbar = ({
|
|
|
6665
6871
|
children: "Accept"
|
|
6666
6872
|
}
|
|
6667
6873
|
),
|
|
6668
|
-
/* @__PURE__ */ (0,
|
|
6874
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
6669
6875
|
"button",
|
|
6670
6876
|
{
|
|
6671
6877
|
type: "button",
|
|
@@ -6675,18 +6881,18 @@ var ReviewToolbar = ({
|
|
|
6675
6881
|
children: "Reject"
|
|
6676
6882
|
}
|
|
6677
6883
|
),
|
|
6678
|
-
/* @__PURE__ */ (0,
|
|
6679
|
-
/* @__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" })
|
|
6680
6886
|
] });
|
|
6681
6887
|
};
|
|
6682
6888
|
|
|
6683
6889
|
// src/review/CommentButton.tsx
|
|
6684
|
-
var
|
|
6890
|
+
var import_jsx_runtime29 = require("react/jsx-runtime");
|
|
6685
6891
|
var CommentButton = ({
|
|
6686
6892
|
editor,
|
|
6687
6893
|
className = "rounded px-2 py-1 text-xs text-popover-foreground hover:bg-muted",
|
|
6688
6894
|
children = "Comment"
|
|
6689
|
-
}) => /* @__PURE__ */ (0,
|
|
6895
|
+
}) => /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
6690
6896
|
"button",
|
|
6691
6897
|
{
|
|
6692
6898
|
type: "button",
|
|
@@ -6698,13 +6904,13 @@ var CommentButton = ({
|
|
|
6698
6904
|
);
|
|
6699
6905
|
|
|
6700
6906
|
// src/review/useDocumentCompare.ts
|
|
6701
|
-
var
|
|
6907
|
+
var import_react46 = require("react");
|
|
6702
6908
|
var import_editor14 = require("@pixerate/editor");
|
|
6703
6909
|
function useDocumentCompare(editor, options) {
|
|
6704
|
-
const [summary, setSummary] = (0,
|
|
6705
|
-
const defaults = (0,
|
|
6910
|
+
const [summary, setSummary] = (0, import_react46.useState)(null);
|
|
6911
|
+
const defaults = (0, import_react46.useRef)(options);
|
|
6706
6912
|
defaults.current = options;
|
|
6707
|
-
const compare = (0,
|
|
6913
|
+
const compare = (0, import_react46.useCallback)(
|
|
6708
6914
|
(original, revised, overrides) => {
|
|
6709
6915
|
if (!editor || editor.isDestroyed) return null;
|
|
6710
6916
|
const result = (0, import_editor14.applyDocumentComparison)(editor, original, revised, {
|
|
@@ -6716,13 +6922,13 @@ function useDocumentCompare(editor, options) {
|
|
|
6716
6922
|
},
|
|
6717
6923
|
[editor]
|
|
6718
6924
|
);
|
|
6719
|
-
const clear = (0,
|
|
6720
|
-
return (0,
|
|
6925
|
+
const clear = (0, import_react46.useCallback)(() => setSummary(null), []);
|
|
6926
|
+
return (0, import_react46.useMemo)(() => ({ summary, compare, clear }), [summary, compare, clear]);
|
|
6721
6927
|
}
|
|
6722
6928
|
|
|
6723
6929
|
// src/review/TrackedChangesList.tsx
|
|
6724
6930
|
var import_editor15 = require("@pixerate/editor");
|
|
6725
|
-
var
|
|
6931
|
+
var import_jsx_runtime30 = require("react/jsx-runtime");
|
|
6726
6932
|
var buttonClass4 = "rounded px-1.5 py-0.5 text-xs text-foreground hover:bg-muted disabled:opacity-40";
|
|
6727
6933
|
var TrackedChangesList = ({
|
|
6728
6934
|
editor,
|
|
@@ -6733,18 +6939,18 @@ var TrackedChangesList = ({
|
|
|
6733
6939
|
}) => {
|
|
6734
6940
|
const review = useTrackChanges(editor);
|
|
6735
6941
|
if (review.changes.length === 0) {
|
|
6736
|
-
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 }) });
|
|
6737
6943
|
}
|
|
6738
|
-
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) => {
|
|
6739
6945
|
const active = change.id === review.currentChangeId;
|
|
6740
|
-
return /* @__PURE__ */ (0,
|
|
6946
|
+
return /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(
|
|
6741
6947
|
"li",
|
|
6742
6948
|
{
|
|
6743
6949
|
className: active ? `${itemClassName} ${activeItemClassName}` : itemClassName,
|
|
6744
6950
|
"data-change-type": change.type,
|
|
6745
6951
|
"data-change-id": change.id,
|
|
6746
6952
|
children: [
|
|
6747
|
-
/* @__PURE__ */ (0,
|
|
6953
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(
|
|
6748
6954
|
"button",
|
|
6749
6955
|
{
|
|
6750
6956
|
type: "button",
|
|
@@ -6752,14 +6958,14 @@ var TrackedChangesList = ({
|
|
|
6752
6958
|
title: `${change.author.name}: ${change.description}`,
|
|
6753
6959
|
onClick: () => review.select(change.id),
|
|
6754
6960
|
children: [
|
|
6755
|
-
/* @__PURE__ */ (0,
|
|
6961
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", { className: "font-medium", children: (0, import_editor15.trackedChangeLabel)(change) }),
|
|
6756
6962
|
change.author.name ? ` \xB7 ${change.author.name}` : "",
|
|
6757
|
-
/* @__PURE__ */ (0,
|
|
6963
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", { className: "block truncate text-muted-foreground", children: change.description })
|
|
6758
6964
|
]
|
|
6759
6965
|
}
|
|
6760
6966
|
),
|
|
6761
|
-
/* @__PURE__ */ (0,
|
|
6762
|
-
/* @__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" })
|
|
6763
6969
|
]
|
|
6764
6970
|
},
|
|
6765
6971
|
`${change.type}:${change.id}`
|
|
@@ -6768,12 +6974,12 @@ var TrackedChangesList = ({
|
|
|
6768
6974
|
};
|
|
6769
6975
|
|
|
6770
6976
|
// src/commands/useCommandPalette.ts
|
|
6771
|
-
var
|
|
6977
|
+
var import_react47 = require("react");
|
|
6772
6978
|
var import_commands2 = require("@pixerate/editor/commands");
|
|
6773
6979
|
function useCommandPalette(registry, options = {}) {
|
|
6774
|
-
const optionsRef = (0,
|
|
6980
|
+
const optionsRef = (0, import_react47.useRef)(options);
|
|
6775
6981
|
optionsRef.current = options;
|
|
6776
|
-
const controller = (0,
|
|
6982
|
+
const controller = (0, import_react47.useMemo)(
|
|
6777
6983
|
() => (0, import_commands2.createCommandPaletteController)(registry, {
|
|
6778
6984
|
context: () => {
|
|
6779
6985
|
const c = optionsRef.current.context;
|
|
@@ -6794,9 +7000,9 @@ function useCommandPalette(registry, options = {}) {
|
|
|
6794
7000
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
6795
7001
|
[registry]
|
|
6796
7002
|
);
|
|
6797
|
-
const state = (0,
|
|
7003
|
+
const state = (0, import_react47.useSyncExternalStore)(controller.subscribe, controller.getState, controller.getState);
|
|
6798
7004
|
const { hotkey, hotkeyTarget } = options;
|
|
6799
|
-
(0,
|
|
7005
|
+
(0, import_react47.useEffect)(() => {
|
|
6800
7006
|
if (!hotkey) return;
|
|
6801
7007
|
const target = hotkeyTarget ?? (typeof window !== "undefined" ? window : null);
|
|
6802
7008
|
if (!target) return;
|
|
@@ -6824,13 +7030,13 @@ function useCommandPalette(registry, options = {}) {
|
|
|
6824
7030
|
}
|
|
6825
7031
|
|
|
6826
7032
|
// src/commands/CommandPalette.tsx
|
|
6827
|
-
var
|
|
6828
|
-
var
|
|
7033
|
+
var import_react48 = __toESM(require("react"), 1);
|
|
7034
|
+
var import_jsx_runtime31 = require("react/jsx-runtime");
|
|
6829
7035
|
function HighlightedLabel({ item }) {
|
|
6830
|
-
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 });
|
|
6831
7037
|
const marked = new Set(item.labelIndices);
|
|
6832
|
-
return /* @__PURE__ */ (0,
|
|
6833
|
-
(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)
|
|
6834
7040
|
) });
|
|
6835
7041
|
}
|
|
6836
7042
|
var CommandPalette = ({
|
|
@@ -6839,22 +7045,22 @@ var CommandPalette = ({
|
|
|
6839
7045
|
emptyMessage = "No matching commands",
|
|
6840
7046
|
className = ""
|
|
6841
7047
|
}) => {
|
|
6842
|
-
const inputRef = (0,
|
|
6843
|
-
const listRef = (0,
|
|
6844
|
-
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)();
|
|
6845
7051
|
const listId = `${baseId}-list`;
|
|
6846
7052
|
const optionId = (index) => `${baseId}-option-${index}`;
|
|
6847
7053
|
const { open, query, items, activeIndex } = palette;
|
|
6848
|
-
(0,
|
|
7054
|
+
(0, import_react48.useEffect)(() => {
|
|
6849
7055
|
if (open) inputRef.current?.focus();
|
|
6850
7056
|
}, [open]);
|
|
6851
|
-
(0,
|
|
7057
|
+
(0, import_react48.useEffect)(() => {
|
|
6852
7058
|
if (!open) return;
|
|
6853
7059
|
const active = listRef.current?.querySelector('[aria-selected="true"]');
|
|
6854
7060
|
active?.scrollIntoView?.({ block: "nearest" });
|
|
6855
7061
|
}, [open, activeIndex]);
|
|
6856
7062
|
if (!open) return null;
|
|
6857
|
-
return /* @__PURE__ */ (0,
|
|
7063
|
+
return /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
|
|
6858
7064
|
"div",
|
|
6859
7065
|
{
|
|
6860
7066
|
className: "fixed inset-0 z-50 flex items-start justify-center bg-black/30 px-4 pt-[15vh]",
|
|
@@ -6862,7 +7068,7 @@ var CommandPalette = ({
|
|
|
6862
7068
|
onMouseDown: (e) => {
|
|
6863
7069
|
if (e.target === e.currentTarget) palette.setOpen(false);
|
|
6864
7070
|
},
|
|
6865
|
-
children: /* @__PURE__ */ (0,
|
|
7071
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(
|
|
6866
7072
|
"div",
|
|
6867
7073
|
{
|
|
6868
7074
|
role: "dialog",
|
|
@@ -6871,7 +7077,7 @@ var CommandPalette = ({
|
|
|
6871
7077
|
className: `w-full max-w-lg overflow-hidden rounded-lg border border-border bg-popover text-popover-foreground shadow-xl ${className}`,
|
|
6872
7078
|
style: { background: "var(--popover, var(--background, #fff))" },
|
|
6873
7079
|
children: [
|
|
6874
|
-
/* @__PURE__ */ (0,
|
|
7080
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
|
|
6875
7081
|
"input",
|
|
6876
7082
|
{
|
|
6877
7083
|
ref: inputRef,
|
|
@@ -6891,7 +7097,7 @@ var CommandPalette = ({
|
|
|
6891
7097
|
className: "w-full border-b border-border bg-transparent px-3 py-2 text-sm outline-none placeholder:text-muted-foreground"
|
|
6892
7098
|
}
|
|
6893
7099
|
),
|
|
6894
|
-
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)(
|
|
6895
7101
|
"li",
|
|
6896
7102
|
{
|
|
6897
7103
|
id: optionId(index),
|
|
@@ -6906,12 +7112,12 @@ var CommandPalette = ({
|
|
|
6906
7112
|
onClick: () => palette.run(item.id),
|
|
6907
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"}`,
|
|
6908
7114
|
children: [
|
|
6909
|
-
/* @__PURE__ */ (0,
|
|
6910
|
-
/* @__PURE__ */ (0,
|
|
6911
|
-
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 })
|
|
6912
7118
|
] }),
|
|
6913
|
-
item.group && /* @__PURE__ */ (0,
|
|
6914
|
-
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 })
|
|
6915
7121
|
]
|
|
6916
7122
|
},
|
|
6917
7123
|
item.id
|
|
@@ -6924,12 +7130,12 @@ var CommandPalette = ({
|
|
|
6924
7130
|
};
|
|
6925
7131
|
|
|
6926
7132
|
// src/commands/useCommandShortcuts.ts
|
|
6927
|
-
var
|
|
7133
|
+
var import_react49 = require("react");
|
|
6928
7134
|
function useCommandShortcuts(registry, options = {}) {
|
|
6929
|
-
const optionsRef = (0,
|
|
7135
|
+
const optionsRef = (0, import_react49.useRef)(options);
|
|
6930
7136
|
optionsRef.current = options;
|
|
6931
7137
|
const { enabled = true, target } = options;
|
|
6932
|
-
(0,
|
|
7138
|
+
(0, import_react49.useEffect)(() => {
|
|
6933
7139
|
if (!registry || !enabled) return;
|
|
6934
7140
|
const eventTarget = target ?? (typeof window !== "undefined" ? window : null);
|
|
6935
7141
|
if (!eventTarget) return;
|
|
@@ -6947,14 +7153,14 @@ function useCommandShortcuts(registry, options = {}) {
|
|
|
6947
7153
|
}, [registry, enabled, target]);
|
|
6948
7154
|
}
|
|
6949
7155
|
function useRegisterCommands(registry, specs) {
|
|
6950
|
-
(0,
|
|
7156
|
+
(0, import_react49.useEffect)(() => {
|
|
6951
7157
|
if (!registry || !specs || specs.length === 0) return;
|
|
6952
7158
|
return registry.register(specs);
|
|
6953
7159
|
}, [registry, specs]);
|
|
6954
7160
|
}
|
|
6955
7161
|
|
|
6956
7162
|
// src/persistence/useAutosave.ts
|
|
6957
|
-
var
|
|
7163
|
+
var import_react50 = require("react");
|
|
6958
7164
|
var import_persistence = require("@pixerate/editor/persistence");
|
|
6959
7165
|
var IDLE = {
|
|
6960
7166
|
status: "idle",
|
|
@@ -6965,18 +7171,18 @@ var IDLE = {
|
|
|
6965
7171
|
ready: false
|
|
6966
7172
|
};
|
|
6967
7173
|
function useAutosave(options) {
|
|
6968
|
-
const optionsRef = (0,
|
|
7174
|
+
const optionsRef = (0, import_react50.useRef)(options);
|
|
6969
7175
|
optionsRef.current = options;
|
|
6970
7176
|
const { storage, key, history, dirty } = options;
|
|
6971
7177
|
const recover = options.recover !== false;
|
|
6972
7178
|
const flushOnHide = options.flushOnHide !== false;
|
|
6973
7179
|
const ready = options.ready !== false;
|
|
6974
|
-
const [controller, setController] = (0,
|
|
6975
|
-
const [status, setStatus] = (0,
|
|
6976
|
-
const [recovery, setRecovery] = (0,
|
|
6977
|
-
const [pendingRecovery, setPendingRecovery] = (0,
|
|
6978
|
-
const revisionsRef = (0,
|
|
6979
|
-
(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)(() => {
|
|
6980
7186
|
const revisions = (0, import_persistence.createRevisionTracker)({ history, dirty });
|
|
6981
7187
|
const o = optionsRef.current;
|
|
6982
7188
|
const instance = (0, import_persistence.createAutosaveController)({
|
|
@@ -7019,10 +7225,10 @@ function useAutosave(options) {
|
|
|
7019
7225
|
if (revisionsRef.current === revisions) revisionsRef.current = null;
|
|
7020
7226
|
};
|
|
7021
7227
|
}, [storage, key, history, dirty, recover]);
|
|
7022
|
-
(0,
|
|
7228
|
+
(0, import_react50.useEffect)(() => {
|
|
7023
7229
|
if (controller && ready && !pendingRecovery) controller.ready();
|
|
7024
7230
|
}, [controller, ready, pendingRecovery]);
|
|
7025
|
-
(0,
|
|
7231
|
+
(0, import_react50.useEffect)(() => {
|
|
7026
7232
|
if (!controller || !flushOnHide || typeof window === "undefined") return;
|
|
7027
7233
|
const flush = () => void controller.flushNow();
|
|
7028
7234
|
const onVisibility = () => {
|
|
@@ -7035,31 +7241,31 @@ function useAutosave(options) {
|
|
|
7035
7241
|
document.removeEventListener("visibilitychange", onVisibility);
|
|
7036
7242
|
};
|
|
7037
7243
|
}, [controller, flushOnHide]);
|
|
7038
|
-
const restore = (0,
|
|
7244
|
+
const restore = (0, import_react50.useCallback)(() => {
|
|
7039
7245
|
const snapshot = recovery?.snapshot;
|
|
7040
7246
|
setRecovery(null);
|
|
7041
7247
|
setPendingRecovery(false);
|
|
7042
7248
|
return snapshot;
|
|
7043
7249
|
}, [recovery]);
|
|
7044
|
-
const discard = (0,
|
|
7250
|
+
const discard = (0, import_react50.useCallback)(async () => {
|
|
7045
7251
|
if (controller) await controller.discardRecovery();
|
|
7046
7252
|
setRecovery(null);
|
|
7047
7253
|
setPendingRecovery(false);
|
|
7048
7254
|
}, [controller]);
|
|
7049
|
-
const flushNow = (0,
|
|
7255
|
+
const flushNow = (0, import_react50.useCallback)(async () => {
|
|
7050
7256
|
await controller?.flushNow();
|
|
7051
7257
|
}, [controller]);
|
|
7052
|
-
const markClean = (0,
|
|
7258
|
+
const markClean = (0, import_react50.useCallback)(async () => {
|
|
7053
7259
|
revisionsRef.current?.markSaved();
|
|
7054
7260
|
await controller?.markClean();
|
|
7055
7261
|
}, [controller]);
|
|
7056
|
-
const notifyChange = (0,
|
|
7262
|
+
const notifyChange = (0, import_react50.useCallback)(() => revisionsRef.current?.bump(), []);
|
|
7057
7263
|
return { status, recovery, pendingRecovery, restore, discard, flushNow, markClean, notifyChange, controller };
|
|
7058
7264
|
}
|
|
7059
7265
|
|
|
7060
7266
|
// src/persistence/RecoveryPrompt.tsx
|
|
7061
7267
|
var import_persistence2 = require("@pixerate/editor/persistence");
|
|
7062
|
-
var
|
|
7268
|
+
var import_jsx_runtime32 = require("react/jsx-runtime");
|
|
7063
7269
|
var RecoveryPrompt = ({
|
|
7064
7270
|
recovery,
|
|
7065
7271
|
onRestore,
|
|
@@ -7071,7 +7277,7 @@ var RecoveryPrompt = ({
|
|
|
7071
7277
|
}) => {
|
|
7072
7278
|
if (!recovery) return null;
|
|
7073
7279
|
const { name } = recovery.meta;
|
|
7074
|
-
return /* @__PURE__ */ (0,
|
|
7280
|
+
return /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(
|
|
7075
7281
|
"div",
|
|
7076
7282
|
{
|
|
7077
7283
|
role: "alertdialog",
|
|
@@ -7079,15 +7285,15 @@ var RecoveryPrompt = ({
|
|
|
7079
7285
|
"data-recovery-prompt": "",
|
|
7080
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}`,
|
|
7081
7287
|
children: [
|
|
7082
|
-
/* @__PURE__ */ (0,
|
|
7288
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("span", { className: "min-w-0 flex-1", children: [
|
|
7083
7289
|
(0, import_persistence2.formatRecoveryMessage)(recovery.meta, formatTime),
|
|
7084
|
-
name ? /* @__PURE__ */ (0,
|
|
7290
|
+
name ? /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("span", { className: "ml-1 text-xs text-muted-foreground", children: [
|
|
7085
7291
|
"(",
|
|
7086
7292
|
name,
|
|
7087
7293
|
")"
|
|
7088
7294
|
] }) : null
|
|
7089
7295
|
] }),
|
|
7090
|
-
/* @__PURE__ */ (0,
|
|
7296
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
7091
7297
|
"button",
|
|
7092
7298
|
{
|
|
7093
7299
|
type: "button",
|
|
@@ -7097,7 +7303,7 @@ var RecoveryPrompt = ({
|
|
|
7097
7303
|
children: restoreLabel
|
|
7098
7304
|
}
|
|
7099
7305
|
),
|
|
7100
|
-
/* @__PURE__ */ (0,
|
|
7306
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
7101
7307
|
"button",
|
|
7102
7308
|
{
|
|
7103
7309
|
type: "button",
|
|
@@ -7113,17 +7319,17 @@ var RecoveryPrompt = ({
|
|
|
7113
7319
|
};
|
|
7114
7320
|
|
|
7115
7321
|
// src/generation/useGenerationPlan.ts
|
|
7116
|
-
var
|
|
7322
|
+
var import_react51 = require("react");
|
|
7117
7323
|
var import_generation = require("@pixerate/editor/generation");
|
|
7118
7324
|
function useGenerationPlan(request, capabilities, options = {}) {
|
|
7119
7325
|
const key = JSON.stringify([request, capabilities, options]);
|
|
7120
|
-
return (0,
|
|
7326
|
+
return (0, import_react51.useMemo)(() => (0, import_generation.planGenerationRequest)(request, capabilities, options), [key]);
|
|
7121
7327
|
}
|
|
7122
7328
|
function useJobProgress(options) {
|
|
7123
7329
|
const { startedAt, expectedMs, done, now, intervalMs = 1e3 } = options;
|
|
7124
|
-
const [tick, setTick] = (0,
|
|
7330
|
+
const [tick, setTick] = (0, import_react51.useState)(() => Date.now());
|
|
7125
7331
|
const ticking = !done && now === void 0;
|
|
7126
|
-
(0,
|
|
7332
|
+
(0, import_react51.useEffect)(() => {
|
|
7127
7333
|
if (!ticking) return;
|
|
7128
7334
|
setTick(Date.now());
|
|
7129
7335
|
const id = setInterval(() => setTick(Date.now()), Math.max(16, intervalMs));
|
|
@@ -7133,9 +7339,9 @@ function useJobProgress(options) {
|
|
|
7133
7339
|
}
|
|
7134
7340
|
|
|
7135
7341
|
// src/generation/GenerationSettings.tsx
|
|
7136
|
-
var
|
|
7342
|
+
var import_react52 = require("react");
|
|
7137
7343
|
var import_generation2 = require("@pixerate/editor/generation");
|
|
7138
|
-
var
|
|
7344
|
+
var import_jsx_runtime33 = require("react/jsx-runtime");
|
|
7139
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";
|
|
7140
7346
|
function Control({
|
|
7141
7347
|
control,
|
|
@@ -7145,7 +7351,7 @@ function Control({
|
|
|
7145
7351
|
}) {
|
|
7146
7352
|
const shown = value ?? control.defaultValue;
|
|
7147
7353
|
if (control.kind === "checkbox") {
|
|
7148
|
-
return /* @__PURE__ */ (0,
|
|
7354
|
+
return /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
|
|
7149
7355
|
"input",
|
|
7150
7356
|
{
|
|
7151
7357
|
id,
|
|
@@ -7157,7 +7363,7 @@ function Control({
|
|
|
7157
7363
|
);
|
|
7158
7364
|
}
|
|
7159
7365
|
if (control.kind === "select") {
|
|
7160
|
-
return /* @__PURE__ */ (0,
|
|
7366
|
+
return /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(
|
|
7161
7367
|
"select",
|
|
7162
7368
|
{
|
|
7163
7369
|
id,
|
|
@@ -7166,14 +7372,14 @@ function Control({
|
|
|
7166
7372
|
value: shown === void 0 ? "" : String(shown),
|
|
7167
7373
|
onChange: (e) => onValue((0, import_generation2.parseControlValue)(control, e.target.value)),
|
|
7168
7374
|
children: [
|
|
7169
|
-
shown === void 0 && /* @__PURE__ */ (0,
|
|
7170
|
-
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)))
|
|
7171
7377
|
]
|
|
7172
7378
|
}
|
|
7173
7379
|
);
|
|
7174
7380
|
}
|
|
7175
7381
|
if (control.kind === "textarea") {
|
|
7176
|
-
return /* @__PURE__ */ (0,
|
|
7382
|
+
return /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
|
|
7177
7383
|
"textarea",
|
|
7178
7384
|
{
|
|
7179
7385
|
id,
|
|
@@ -7187,8 +7393,8 @@ function Control({
|
|
|
7187
7393
|
);
|
|
7188
7394
|
}
|
|
7189
7395
|
const numeric = typeof shown === "number" ? shown : void 0;
|
|
7190
|
-
return /* @__PURE__ */ (0,
|
|
7191
|
-
/* @__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)(
|
|
7192
7398
|
"input",
|
|
7193
7399
|
{
|
|
7194
7400
|
id,
|
|
@@ -7202,7 +7408,7 @@ function Control({
|
|
|
7202
7408
|
onChange: (e) => onValue((0, import_generation2.parseControlValue)(control, e.target.value))
|
|
7203
7409
|
}
|
|
7204
7410
|
),
|
|
7205
|
-
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" })
|
|
7206
7412
|
] });
|
|
7207
7413
|
}
|
|
7208
7414
|
var GenerationSettings = ({
|
|
@@ -7216,17 +7422,17 @@ var GenerationSettings = ({
|
|
|
7216
7422
|
renderReference,
|
|
7217
7423
|
className = ""
|
|
7218
7424
|
}) => {
|
|
7219
|
-
const baseId = (0,
|
|
7220
|
-
const controls = (0,
|
|
7425
|
+
const baseId = (0, import_react52.useId)();
|
|
7426
|
+
const controls = (0, import_react52.useMemo)(() => (0, import_generation2.getGenerationControls)(capabilities), [capabilities]);
|
|
7221
7427
|
const computed = useGenerationPlan(value, capabilities, { strategy });
|
|
7222
7428
|
const plan = planProp ?? computed;
|
|
7223
7429
|
const slots = (0, import_generation2.getReferenceSlots)(capabilities, value);
|
|
7224
|
-
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: [
|
|
7225
7431
|
controls.map((control) => {
|
|
7226
7432
|
const id = `${baseId}-${control.key}`;
|
|
7227
|
-
return /* @__PURE__ */ (0,
|
|
7228
|
-
/* @__PURE__ */ (0,
|
|
7229
|
-
/* @__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)(
|
|
7230
7436
|
Control,
|
|
7231
7437
|
{
|
|
7232
7438
|
control,
|
|
@@ -7237,23 +7443,23 @@ var GenerationSettings = ({
|
|
|
7237
7443
|
)
|
|
7238
7444
|
] }, control.key);
|
|
7239
7445
|
}),
|
|
7240
|
-
slots.map((slot) => /* @__PURE__ */ (0,
|
|
7241
|
-
/* @__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: [
|
|
7242
7448
|
slot.label,
|
|
7243
7449
|
" ",
|
|
7244
|
-
/* @__PURE__ */ (0,
|
|
7450
|
+
/* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("span", { className: "tabular-nums", "data-reference-count": "", children: [
|
|
7245
7451
|
"(",
|
|
7246
7452
|
slot.references.length,
|
|
7247
7453
|
"/",
|
|
7248
7454
|
slot.max,
|
|
7249
7455
|
")"
|
|
7250
7456
|
] }),
|
|
7251
|
-
slot.min > 0 && /* @__PURE__ */ (0,
|
|
7457
|
+
slot.min > 0 && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("span", { className: "text-destructive", children: " *" })
|
|
7252
7458
|
] }),
|
|
7253
|
-
/* @__PURE__ */ (0,
|
|
7254
|
-
slot.references.map((ref) => /* @__PURE__ */ (0,
|
|
7255
|
-
renderReference ? renderReference(ref) : /* @__PURE__ */ (0,
|
|
7256
|
-
/* @__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)(
|
|
7257
7463
|
"button",
|
|
7258
7464
|
{
|
|
7259
7465
|
type: "button",
|
|
@@ -7264,7 +7470,7 @@ var GenerationSettings = ({
|
|
|
7264
7470
|
}
|
|
7265
7471
|
)
|
|
7266
7472
|
] }, ref.id)),
|
|
7267
|
-
onAddReference && slot.canAdd && /* @__PURE__ */ (0,
|
|
7473
|
+
onAddReference && slot.canAdd && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("li", { children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
|
|
7268
7474
|
"button",
|
|
7269
7475
|
{
|
|
7270
7476
|
type: "button",
|
|
@@ -7275,21 +7481,21 @@ var GenerationSettings = ({
|
|
|
7275
7481
|
) })
|
|
7276
7482
|
] })
|
|
7277
7483
|
] }, slot.role)),
|
|
7278
|
-
showAdjustments && plan.adjustments.length > 0 && /* @__PURE__ */ (0,
|
|
7279
|
-
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)) })
|
|
7280
7486
|
] });
|
|
7281
7487
|
};
|
|
7282
7488
|
|
|
7283
7489
|
// src/generation/JobProgress.tsx
|
|
7284
|
-
var
|
|
7490
|
+
var import_jsx_runtime34 = require("react/jsx-runtime");
|
|
7285
7491
|
var JobProgress = ({ title, className = "", ...options }) => {
|
|
7286
7492
|
const progress = useJobProgress(options);
|
|
7287
|
-
return /* @__PURE__ */ (0,
|
|
7288
|
-
/* @__PURE__ */ (0,
|
|
7289
|
-
title && /* @__PURE__ */ (0,
|
|
7290
|
-
/* @__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 })
|
|
7291
7497
|
] }),
|
|
7292
|
-
/* @__PURE__ */ (0,
|
|
7498
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
7293
7499
|
"div",
|
|
7294
7500
|
{
|
|
7295
7501
|
role: "progressbar",
|
|
@@ -7299,7 +7505,7 @@ var JobProgress = ({ title, className = "", ...options }) => {
|
|
|
7299
7505
|
"aria-valuenow": progress.percent,
|
|
7300
7506
|
"aria-valuetext": `${progress.percent}%, ${progress.label}`,
|
|
7301
7507
|
className: "h-1.5 w-full overflow-hidden rounded-full bg-muted",
|
|
7302
|
-
children: /* @__PURE__ */ (0,
|
|
7508
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
7303
7509
|
"div",
|
|
7304
7510
|
{
|
|
7305
7511
|
className: "h-full rounded-full bg-primary transition-[width] duration-500",
|
|
@@ -7312,9 +7518,9 @@ var JobProgress = ({ title, className = "", ...options }) => {
|
|
|
7312
7518
|
};
|
|
7313
7519
|
|
|
7314
7520
|
// src/generation/AssetMentionChips.tsx
|
|
7315
|
-
var
|
|
7521
|
+
var import_react53 = require("react");
|
|
7316
7522
|
var import_generation3 = require("@pixerate/editor/generation");
|
|
7317
|
-
var
|
|
7523
|
+
var import_jsx_runtime35 = require("react/jsx-runtime");
|
|
7318
7524
|
var AssetMentionChips = ({
|
|
7319
7525
|
content,
|
|
7320
7526
|
onChange,
|
|
@@ -7324,14 +7530,14 @@ var AssetMentionChips = ({
|
|
|
7324
7530
|
renderAsset,
|
|
7325
7531
|
className = ""
|
|
7326
7532
|
}) => {
|
|
7327
|
-
const [open, setOpen] = (0,
|
|
7328
|
-
const rootRef = (0,
|
|
7329
|
-
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)(
|
|
7330
7536
|
() => (0, import_generation3.describeAssetMentions)((0, import_generation3.findTextMentions)(content), assets, capabilities),
|
|
7331
7537
|
[content, assets, capabilities]
|
|
7332
7538
|
);
|
|
7333
7539
|
const options = roles ?? (capabilities ? (0, import_generation3.getAssetRoleOptions)(capabilities) : (0, import_generation3.defaultAssetRoleOptions)());
|
|
7334
|
-
(0,
|
|
7540
|
+
(0, import_react53.useEffect)(() => {
|
|
7335
7541
|
if (open === null) return;
|
|
7336
7542
|
const onPointer = (event) => {
|
|
7337
7543
|
if (!rootRef.current?.contains(event.target)) setOpen(null);
|
|
@@ -7345,13 +7551,13 @@ var AssetMentionChips = ({
|
|
|
7345
7551
|
onChange((0, import_generation3.setMentionRoleInText)(content, chip2.start, role));
|
|
7346
7552
|
};
|
|
7347
7553
|
if (chips.length === 0) return null;
|
|
7348
|
-
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) => {
|
|
7349
7555
|
const error = chip2.issues.find((issue) => issue.severity === "error");
|
|
7350
7556
|
const warning = chip2.issues.find((issue) => issue.severity === "warning");
|
|
7351
7557
|
const problem = error ?? warning;
|
|
7352
7558
|
const isOpen = open === chip2.index;
|
|
7353
|
-
return /* @__PURE__ */ (0,
|
|
7354
|
-
/* @__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)(
|
|
7355
7561
|
"button",
|
|
7356
7562
|
{
|
|
7357
7563
|
type: "button",
|
|
@@ -7365,8 +7571,8 @@ var AssetMentionChips = ({
|
|
|
7365
7571
|
},
|
|
7366
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`,
|
|
7367
7573
|
children: [
|
|
7368
|
-
/* @__PURE__ */ (0,
|
|
7369
|
-
/* @__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)(
|
|
7370
7576
|
"span",
|
|
7371
7577
|
{
|
|
7372
7578
|
className: `rounded px-1 text-[10px] uppercase tracking-wide ${chip2.role ? "bg-primary/15" : "opacity-60"}`,
|
|
@@ -7377,7 +7583,7 @@ var AssetMentionChips = ({
|
|
|
7377
7583
|
]
|
|
7378
7584
|
}
|
|
7379
7585
|
),
|
|
7380
|
-
isOpen && /* @__PURE__ */ (0,
|
|
7586
|
+
isOpen && /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)(
|
|
7381
7587
|
"div",
|
|
7382
7588
|
{
|
|
7383
7589
|
role: "listbox",
|
|
@@ -7388,7 +7594,7 @@ var AssetMentionChips = ({
|
|
|
7388
7594
|
if (e.key === "Escape") setOpen(null);
|
|
7389
7595
|
},
|
|
7390
7596
|
children: [
|
|
7391
|
-
options.map((option) => /* @__PURE__ */ (0,
|
|
7597
|
+
options.map((option) => /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)(
|
|
7392
7598
|
"button",
|
|
7393
7599
|
{
|
|
7394
7600
|
type: "button",
|
|
@@ -7399,13 +7605,13 @@ var AssetMentionChips = ({
|
|
|
7399
7605
|
onClick: () => pick(chip2, option.role),
|
|
7400
7606
|
className: "flex items-center justify-between gap-2 rounded px-2 py-1 text-left hover:bg-muted",
|
|
7401
7607
|
children: [
|
|
7402
|
-
/* @__PURE__ */ (0,
|
|
7403
|
-
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
|
|
7404
7610
|
]
|
|
7405
7611
|
},
|
|
7406
7612
|
option.role
|
|
7407
7613
|
)),
|
|
7408
|
-
/* @__PURE__ */ (0,
|
|
7614
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
|
|
7409
7615
|
"button",
|
|
7410
7616
|
{
|
|
7411
7617
|
type: "button",
|
|
@@ -7417,7 +7623,7 @@ var AssetMentionChips = ({
|
|
|
7417
7623
|
children: "No role"
|
|
7418
7624
|
}
|
|
7419
7625
|
),
|
|
7420
|
-
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)) })
|
|
7421
7627
|
]
|
|
7422
7628
|
}
|
|
7423
7629
|
)
|
|
@@ -7426,15 +7632,15 @@ var AssetMentionChips = ({
|
|
|
7426
7632
|
};
|
|
7427
7633
|
|
|
7428
7634
|
// src/generation/GenerationHistory.tsx
|
|
7429
|
-
var
|
|
7635
|
+
var import_react54 = require("react");
|
|
7430
7636
|
var import_generation4 = require("@pixerate/editor/generation");
|
|
7431
|
-
var
|
|
7637
|
+
var import_jsx_runtime36 = require("react/jsx-runtime");
|
|
7432
7638
|
function useGenerationRecords(store, filter) {
|
|
7433
|
-
const [records, setRecords] = (0,
|
|
7434
|
-
const [loading, setLoading] = (0,
|
|
7435
|
-
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);
|
|
7436
7642
|
const filterKey = (0, import_generation4.stableStringify)(filter ?? {});
|
|
7437
|
-
const refresh = (0,
|
|
7643
|
+
const refresh = (0, import_react54.useCallback)(async () => {
|
|
7438
7644
|
if (!store) {
|
|
7439
7645
|
setRecords([]);
|
|
7440
7646
|
setLoading(false);
|
|
@@ -7451,7 +7657,7 @@ function useGenerationRecords(store, filter) {
|
|
|
7451
7657
|
setLoading(false);
|
|
7452
7658
|
}
|
|
7453
7659
|
}, [store, filterKey]);
|
|
7454
|
-
(0,
|
|
7660
|
+
(0, import_react54.useEffect)(() => {
|
|
7455
7661
|
void refresh();
|
|
7456
7662
|
if (!store) return;
|
|
7457
7663
|
return store.subscribe(() => void refresh());
|
|
@@ -7477,21 +7683,21 @@ var GenerationHistory = ({
|
|
|
7477
7683
|
emptyText = "No generations yet.",
|
|
7478
7684
|
className = ""
|
|
7479
7685
|
}) => {
|
|
7480
|
-
const [innerMode, setInnerMode] = (0,
|
|
7686
|
+
const [innerMode, setInnerMode] = (0, import_react54.useState)("exact");
|
|
7481
7687
|
const mode = modeProp ?? innerMode;
|
|
7482
7688
|
const setMode = (next) => {
|
|
7483
7689
|
if (modeProp === void 0) setInnerMode(next);
|
|
7484
7690
|
onModeChange?.(next);
|
|
7485
7691
|
};
|
|
7486
|
-
const options = (0,
|
|
7487
|
-
const results = (0,
|
|
7488
|
-
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)(
|
|
7489
7695
|
() => capabilities ? Array.isArray(capabilities) ? capabilities : [capabilities] : [],
|
|
7490
7696
|
[capabilities]
|
|
7491
7697
|
);
|
|
7492
|
-
return /* @__PURE__ */ (0,
|
|
7493
|
-
/* @__PURE__ */ (0,
|
|
7494
|
-
/* @__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)(
|
|
7495
7701
|
"input",
|
|
7496
7702
|
{
|
|
7497
7703
|
type: "radio",
|
|
@@ -7504,34 +7710,34 @@ var GenerationHistory = ({
|
|
|
7504
7710
|
),
|
|
7505
7711
|
value === "exact" ? "Exact (recorded versions)" : "Latest templates & settings"
|
|
7506
7712
|
] }, value)) }),
|
|
7507
|
-
records.length === 0 && /* @__PURE__ */ (0,
|
|
7508
|
-
/* @__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) => {
|
|
7509
7715
|
const result = results[i];
|
|
7510
7716
|
const model = models.find((m) => m.id === record.provenance.modelId);
|
|
7511
7717
|
const blocked = !result.ok;
|
|
7512
|
-
return /* @__PURE__ */ (0,
|
|
7718
|
+
return /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(
|
|
7513
7719
|
"li",
|
|
7514
7720
|
{
|
|
7515
7721
|
className: "rounded-md border border-border p-2",
|
|
7516
7722
|
"data-record": record.id,
|
|
7517
7723
|
"data-drift": result.drift.length,
|
|
7518
7724
|
children: [
|
|
7519
|
-
/* @__PURE__ */ (0,
|
|
7520
|
-
/* @__PURE__ */ (0,
|
|
7521
|
-
/* @__PURE__ */ (0,
|
|
7522
|
-
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: [
|
|
7523
7729
|
record.kind,
|
|
7524
7730
|
" \xB7 "
|
|
7525
7731
|
] }),
|
|
7526
|
-
/* @__PURE__ */ (0,
|
|
7527
|
-
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: [
|
|
7528
7734
|
" \xB7 seed ",
|
|
7529
7735
|
record.seed
|
|
7530
7736
|
] })
|
|
7531
7737
|
] })
|
|
7532
7738
|
] }),
|
|
7533
|
-
/* @__PURE__ */ (0,
|
|
7534
|
-
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)(
|
|
7535
7741
|
"span",
|
|
7536
7742
|
{
|
|
7537
7743
|
className: "rounded-full bg-muted px-2 py-0.5 text-[10px]",
|
|
@@ -7545,16 +7751,16 @@ var GenerationHistory = ({
|
|
|
7545
7751
|
`${asset.role}:${asset.id}`
|
|
7546
7752
|
)) }),
|
|
7547
7753
|
renderPreview?.(record),
|
|
7548
|
-
result.drift.length > 0 && /* @__PURE__ */ (0,
|
|
7549
|
-
/* @__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: [
|
|
7550
7756
|
import_generation4.DRIFT_TYPE_LABELS[item.type],
|
|
7551
7757
|
":"
|
|
7552
7758
|
] }),
|
|
7553
7759
|
" ",
|
|
7554
7760
|
item.message
|
|
7555
7761
|
] }, j)) }),
|
|
7556
|
-
/* @__PURE__ */ (0,
|
|
7557
|
-
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)(
|
|
7558
7764
|
"button",
|
|
7559
7765
|
{
|
|
7560
7766
|
type: "button",
|
|
@@ -7566,7 +7772,7 @@ var GenerationHistory = ({
|
|
|
7566
7772
|
children: "Recreate"
|
|
7567
7773
|
}
|
|
7568
7774
|
),
|
|
7569
|
-
onVariation && /* @__PURE__ */ (0,
|
|
7775
|
+
onVariation && /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
7570
7776
|
"button",
|
|
7571
7777
|
{
|
|
7572
7778
|
type: "button",
|
|
@@ -7576,7 +7782,7 @@ var GenerationHistory = ({
|
|
|
7576
7782
|
children: "Variation"
|
|
7577
7783
|
}
|
|
7578
7784
|
),
|
|
7579
|
-
onRemove && /* @__PURE__ */ (0,
|
|
7785
|
+
onRemove && /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
7580
7786
|
"button",
|
|
7581
7787
|
{
|
|
7582
7788
|
type: "button",
|
|
@@ -7596,19 +7802,19 @@ var GenerationHistory = ({
|
|
|
7596
7802
|
};
|
|
7597
7803
|
|
|
7598
7804
|
// src/find-replace/useFindReplace.ts
|
|
7599
|
-
var
|
|
7805
|
+
var import_react55 = require("react");
|
|
7600
7806
|
var import_editor16 = require("@pixerate/editor");
|
|
7601
7807
|
var noopUnsubscribe2 = () => {
|
|
7602
7808
|
};
|
|
7603
7809
|
function useFindReplace(editor) {
|
|
7604
7810
|
const store = (0, import_editor16.getFindReplaceStore)(editor ?? null);
|
|
7605
|
-
const subscribe = (0,
|
|
7811
|
+
const subscribe = (0, import_react55.useCallback)(
|
|
7606
7812
|
(onChange) => store ? store.subscribe(() => onChange()) : noopUnsubscribe2,
|
|
7607
7813
|
[store]
|
|
7608
7814
|
);
|
|
7609
7815
|
const getSnapshot = () => store?.getSnapshot() ?? import_editor16.EMPTY_FIND_REPLACE_SNAPSHOT;
|
|
7610
|
-
const snapshot = (0,
|
|
7611
|
-
return (0,
|
|
7816
|
+
const snapshot = (0, import_react55.useSyncExternalStore)(subscribe, getSnapshot, getSnapshot);
|
|
7817
|
+
return (0, import_react55.useMemo)(() => {
|
|
7612
7818
|
const run = (fn) => {
|
|
7613
7819
|
if (editor && !editor.isDestroyed && store) fn(editor);
|
|
7614
7820
|
};
|
|
@@ -7632,9 +7838,9 @@ function useFindReplace(editor) {
|
|
|
7632
7838
|
}
|
|
7633
7839
|
|
|
7634
7840
|
// src/find-replace/FindReplaceBar.tsx
|
|
7635
|
-
var
|
|
7841
|
+
var import_react56 = require("react");
|
|
7636
7842
|
var import_editor17 = require("@pixerate/editor");
|
|
7637
|
-
var
|
|
7843
|
+
var import_jsx_runtime37 = require("react/jsx-runtime");
|
|
7638
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";
|
|
7639
7845
|
var buttonClass5 = "rounded px-2 py-1 text-xs text-foreground hover:bg-muted disabled:opacity-40 disabled:hover:bg-transparent";
|
|
7640
7846
|
var toggleClass = (on) => `${buttonClass5} font-mono ${on ? "bg-primary/10 text-primary" : "text-muted-foreground"}`;
|
|
@@ -7647,10 +7853,10 @@ var FindReplaceBar = ({
|
|
|
7647
7853
|
onClose
|
|
7648
7854
|
}) => {
|
|
7649
7855
|
const find = useFindReplace(editor);
|
|
7650
|
-
const findInput = (0,
|
|
7651
|
-
const [moreOpen, setMoreOpen] = (0,
|
|
7856
|
+
const findInput = (0, import_react56.useRef)(null);
|
|
7857
|
+
const [moreOpen, setMoreOpen] = (0, import_react56.useState)(false);
|
|
7652
7858
|
const visible = find.available && (alwaysOpen || find.open);
|
|
7653
|
-
(0,
|
|
7859
|
+
(0, import_react56.useEffect)(() => {
|
|
7654
7860
|
if (!visible || find.focusRequest === 0) return;
|
|
7655
7861
|
findInput.current?.focus();
|
|
7656
7862
|
findInput.current?.select();
|
|
@@ -7688,9 +7894,9 @@ var FindReplaceBar = ({
|
|
|
7688
7894
|
if (isMod(e)) find.replaceAll();
|
|
7689
7895
|
else find.replace();
|
|
7690
7896
|
};
|
|
7691
|
-
return /* @__PURE__ */ (0,
|
|
7692
|
-
/* @__PURE__ */ (0,
|
|
7693
|
-
/* @__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)(
|
|
7694
7900
|
"button",
|
|
7695
7901
|
{
|
|
7696
7902
|
type: "button",
|
|
@@ -7701,7 +7907,7 @@ var FindReplaceBar = ({
|
|
|
7701
7907
|
children: showReplace ? "\u25BE" : "\u25B8"
|
|
7702
7908
|
}
|
|
7703
7909
|
),
|
|
7704
|
-
/* @__PURE__ */ (0,
|
|
7910
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
|
|
7705
7911
|
"input",
|
|
7706
7912
|
{
|
|
7707
7913
|
ref: findInput,
|
|
@@ -7715,7 +7921,7 @@ var FindReplaceBar = ({
|
|
|
7715
7921
|
onKeyDown: onFindKeyDown
|
|
7716
7922
|
}
|
|
7717
7923
|
),
|
|
7718
|
-
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)(
|
|
7719
7925
|
"button",
|
|
7720
7926
|
{
|
|
7721
7927
|
type: "button",
|
|
@@ -7728,7 +7934,7 @@ var FindReplaceBar = ({
|
|
|
7728
7934
|
},
|
|
7729
7935
|
t.key
|
|
7730
7936
|
)),
|
|
7731
|
-
/* @__PURE__ */ (0,
|
|
7937
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
|
|
7732
7938
|
"span",
|
|
7733
7939
|
{
|
|
7734
7940
|
className: `min-w-[5rem] px-1 text-center text-xs ${find.error ? "text-destructive" : "text-muted-foreground"}`,
|
|
@@ -7738,9 +7944,9 @@ var FindReplaceBar = ({
|
|
|
7738
7944
|
children: status
|
|
7739
7945
|
}
|
|
7740
7946
|
),
|
|
7741
|
-
/* @__PURE__ */ (0,
|
|
7742
|
-
/* @__PURE__ */ (0,
|
|
7743
|
-
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)(
|
|
7744
7950
|
"button",
|
|
7745
7951
|
{
|
|
7746
7952
|
type: "button",
|
|
@@ -7751,10 +7957,10 @@ var FindReplaceBar = ({
|
|
|
7751
7957
|
children: "\u2026"
|
|
7752
7958
|
}
|
|
7753
7959
|
),
|
|
7754
|
-
/* @__PURE__ */ (0,
|
|
7960
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsx)("button", { type: "button", className: buttonClass5, "aria-label": "Close find", onClick: close, children: "\xD7" })
|
|
7755
7961
|
] }),
|
|
7756
|
-
showReplace && /* @__PURE__ */ (0,
|
|
7757
|
-
/* @__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)(
|
|
7758
7964
|
"input",
|
|
7759
7965
|
{
|
|
7760
7966
|
type: "text",
|
|
@@ -7766,7 +7972,7 @@ var FindReplaceBar = ({
|
|
|
7766
7972
|
onKeyDown: onReplaceKeyDown
|
|
7767
7973
|
}
|
|
7768
7974
|
),
|
|
7769
|
-
/* @__PURE__ */ (0,
|
|
7975
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
|
|
7770
7976
|
"button",
|
|
7771
7977
|
{
|
|
7772
7978
|
type: "button",
|
|
@@ -7776,11 +7982,11 @@ var FindReplaceBar = ({
|
|
|
7776
7982
|
children: "Replace"
|
|
7777
7983
|
}
|
|
7778
7984
|
),
|
|
7779
|
-
/* @__PURE__ */ (0,
|
|
7780
|
-
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` })
|
|
7781
7987
|
] }),
|
|
7782
|
-
showMoreOptions && moreOpen && /* @__PURE__ */ (0,
|
|
7783
|
-
/* @__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)(
|
|
7784
7990
|
"input",
|
|
7785
7991
|
{
|
|
7786
7992
|
type: "checkbox",
|
|
@@ -7794,12 +8000,12 @@ var FindReplaceBar = ({
|
|
|
7794
8000
|
};
|
|
7795
8001
|
|
|
7796
8002
|
// src/tables/useTableMenu.ts
|
|
7797
|
-
var
|
|
8003
|
+
var import_react57 = require("react");
|
|
7798
8004
|
var import_editor18 = require("@pixerate/editor");
|
|
7799
8005
|
function useTableMenu(editor) {
|
|
7800
|
-
const store = (0,
|
|
7801
|
-
const snapshot = (0,
|
|
7802
|
-
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)(
|
|
7803
8009
|
() => ({
|
|
7804
8010
|
...snapshot,
|
|
7805
8011
|
run: (action, params) => (0, import_editor18.runTableAction)(editor, action, params, { focus: true }),
|
|
@@ -7810,9 +8016,9 @@ function useTableMenu(editor) {
|
|
|
7810
8016
|
}
|
|
7811
8017
|
|
|
7812
8018
|
// src/tables/TableToolbar.tsx
|
|
7813
|
-
var
|
|
8019
|
+
var import_react58 = __toESM(require("react"), 1);
|
|
7814
8020
|
var import_editor19 = require("@pixerate/editor");
|
|
7815
|
-
var
|
|
8021
|
+
var import_jsx_runtime38 = require("react/jsx-runtime");
|
|
7816
8022
|
var keepSelection2 = (event) => event.preventDefault();
|
|
7817
8023
|
var TableToolbar = ({
|
|
7818
8024
|
editor,
|
|
@@ -7826,14 +8032,14 @@ var TableToolbar = ({
|
|
|
7826
8032
|
}) => {
|
|
7827
8033
|
const table = useTableMenu(editor);
|
|
7828
8034
|
if (!editor || !table.inTable && !showWhenOutside) return null;
|
|
7829
|
-
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) => {
|
|
7830
8036
|
const status = table.check(item.action, item.params);
|
|
7831
8037
|
const enabled = status === true;
|
|
7832
8038
|
const active = item.active?.(table);
|
|
7833
8039
|
const separator = index > 0 && items[index - 1].group !== item.group;
|
|
7834
|
-
return /* @__PURE__ */ (0,
|
|
7835
|
-
separator && /* @__PURE__ */ (0,
|
|
7836
|
-
/* @__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)(
|
|
7837
8043
|
"button",
|
|
7838
8044
|
{
|
|
7839
8045
|
type: "button",
|
|
@@ -7855,8 +8061,8 @@ var TableToolbar = ({
|
|
|
7855
8061
|
};
|
|
7856
8062
|
|
|
7857
8063
|
// src/tables/InsertTableGrid.tsx
|
|
7858
|
-
var
|
|
7859
|
-
var
|
|
8064
|
+
var import_react59 = require("react");
|
|
8065
|
+
var import_jsx_runtime39 = require("react/jsx-runtime");
|
|
7860
8066
|
var keepSelection3 = (event) => event.preventDefault();
|
|
7861
8067
|
var InsertTableGrid = ({
|
|
7862
8068
|
editor,
|
|
@@ -7869,14 +8075,14 @@ var InsertTableGrid = ({
|
|
|
7869
8075
|
onInsert
|
|
7870
8076
|
}) => {
|
|
7871
8077
|
const table = useTableMenu(editor);
|
|
7872
|
-
const [hover, setHover] = (0,
|
|
8078
|
+
const [hover, setHover] = (0, import_react59.useState)(null);
|
|
7873
8079
|
const status = table.actions.insertTable;
|
|
7874
8080
|
const disabled = !editor || !status.enabled;
|
|
7875
8081
|
const insert = (size) => {
|
|
7876
8082
|
if (table.run("insertTable", { ...size, withHeaderRow })) onInsert?.(size);
|
|
7877
8083
|
setHover(null);
|
|
7878
8084
|
};
|
|
7879
|
-
return /* @__PURE__ */ (0,
|
|
8085
|
+
return /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)(
|
|
7880
8086
|
"div",
|
|
7881
8087
|
{
|
|
7882
8088
|
className,
|
|
@@ -7886,7 +8092,7 @@ var InsertTableGrid = ({
|
|
|
7886
8092
|
"data-insert-table-grid": "",
|
|
7887
8093
|
onMouseLeave: () => setHover(null),
|
|
7888
8094
|
children: [
|
|
7889
|
-
/* @__PURE__ */ (0,
|
|
8095
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
|
|
7890
8096
|
"div",
|
|
7891
8097
|
{
|
|
7892
8098
|
role: "grid",
|
|
@@ -7895,7 +8101,7 @@ var InsertTableGrid = ({
|
|
|
7895
8101
|
children: Array.from({ length: rows * cols }, (_, i) => {
|
|
7896
8102
|
const size = { rows: Math.floor(i / cols) + 1, cols: i % cols + 1 };
|
|
7897
8103
|
const active = !!hover && size.rows <= hover.rows && size.cols <= hover.cols;
|
|
7898
|
-
return /* @__PURE__ */ (0,
|
|
8104
|
+
return /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
|
|
7899
8105
|
"button",
|
|
7900
8106
|
{
|
|
7901
8107
|
type: "button",
|
|
@@ -7915,7 +8121,7 @@ var InsertTableGrid = ({
|
|
|
7915
8121
|
})
|
|
7916
8122
|
}
|
|
7917
8123
|
),
|
|
7918
|
-
/* @__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" })
|
|
7919
8125
|
]
|
|
7920
8126
|
}
|
|
7921
8127
|
);
|
|
@@ -7923,31 +8129,31 @@ var InsertTableGrid = ({
|
|
|
7923
8129
|
|
|
7924
8130
|
// src/tables/TableBubbleMenu.tsx
|
|
7925
8131
|
var import_editor20 = require("@pixerate/editor");
|
|
7926
|
-
var
|
|
8132
|
+
var import_jsx_runtime40 = require("react/jsx-runtime");
|
|
7927
8133
|
var TableBubbleMenu = ({
|
|
7928
8134
|
editor,
|
|
7929
8135
|
children,
|
|
7930
8136
|
toolbarProps,
|
|
7931
8137
|
pluginKey = "tableBubbleMenu",
|
|
7932
8138
|
...rest
|
|
7933
|
-
}) => /* @__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 }) });
|
|
7934
8140
|
|
|
7935
8141
|
// src/chart-node/ChartNodeView.tsx
|
|
7936
8142
|
var import_client = require("react-dom/client");
|
|
7937
8143
|
|
|
7938
8144
|
// src/chart/ChartCanvas.tsx
|
|
7939
|
-
var
|
|
8145
|
+
var import_react61 = require("react");
|
|
7940
8146
|
var import_chart2 = require("@pixerate/editor/chart");
|
|
7941
8147
|
|
|
7942
8148
|
// src/chart/useChartEditor.ts
|
|
7943
|
-
var
|
|
8149
|
+
var import_react60 = require("react");
|
|
7944
8150
|
var import_chart = require("@pixerate/editor/chart");
|
|
7945
8151
|
function useChartState(controller) {
|
|
7946
|
-
return (0,
|
|
8152
|
+
return (0, import_react60.useSyncExternalStore)(controller.subscribe, controller.getState, controller.getState);
|
|
7947
8153
|
}
|
|
7948
8154
|
|
|
7949
8155
|
// src/chart/ChartCanvas.tsx
|
|
7950
|
-
var
|
|
8156
|
+
var import_jsx_runtime41 = require("react/jsx-runtime");
|
|
7951
8157
|
function renderChartMark(mark, fontFamily, interactive) {
|
|
7952
8158
|
const common = {
|
|
7953
8159
|
"data-role": mark.role,
|
|
@@ -7959,9 +8165,9 @@ function renderChartMark(mark, fontFamily, interactive) {
|
|
|
7959
8165
|
};
|
|
7960
8166
|
switch (mark.kind) {
|
|
7961
8167
|
case "rect":
|
|
7962
|
-
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);
|
|
7963
8169
|
case "path":
|
|
7964
|
-
return /* @__PURE__ */ (0,
|
|
8170
|
+
return /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
|
|
7965
8171
|
"path",
|
|
7966
8172
|
{
|
|
7967
8173
|
...common,
|
|
@@ -7974,11 +8180,11 @@ function renderChartMark(mark, fontFamily, interactive) {
|
|
|
7974
8180
|
mark.key
|
|
7975
8181
|
);
|
|
7976
8182
|
case "circle":
|
|
7977
|
-
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);
|
|
7978
8184
|
case "line":
|
|
7979
|
-
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);
|
|
7980
8186
|
case "text":
|
|
7981
|
-
return /* @__PURE__ */ (0,
|
|
8187
|
+
return /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
|
|
7982
8188
|
"text",
|
|
7983
8189
|
{
|
|
7984
8190
|
...common,
|
|
@@ -7995,23 +8201,23 @@ function renderChartMark(mark, fontFamily, interactive) {
|
|
|
7995
8201
|
}
|
|
7996
8202
|
}
|
|
7997
8203
|
function ChartPresenceLayer({ presence }) {
|
|
7998
|
-
const { actors } = (0,
|
|
7999
|
-
return /* @__PURE__ */ (0,
|
|
8000
|
-
/* @__PURE__ */ (0,
|
|
8001
|
-
/* @__PURE__ */ (0,
|
|
8002
|
-
/* @__PURE__ */ (0,
|
|
8003
|
-
/* @__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 })
|
|
8004
8210
|
] })
|
|
8005
8211
|
] }, a.id)) });
|
|
8006
8212
|
}
|
|
8007
8213
|
function ChartCanvas({ controller, width = 640, height = 400, responsive = true, theme, editable = true, measureText, emptyMessage, className, presence, sceneRef }) {
|
|
8008
8214
|
const state = useChartState(controller);
|
|
8009
|
-
const wrapper = (0,
|
|
8010
|
-
const svg = (0,
|
|
8011
|
-
const drag = (0,
|
|
8012
|
-
const [measured, setMeasured] = (0,
|
|
8013
|
-
const [frozen, setFrozen] = (0,
|
|
8014
|
-
(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)(() => {
|
|
8015
8221
|
const el = wrapper.current;
|
|
8016
8222
|
if (!responsive || !el || typeof ResizeObserver === "undefined") return;
|
|
8017
8223
|
const observer = new ResizeObserver(([entry]) => {
|
|
@@ -8022,8 +8228,8 @@ function ChartCanvas({ controller, width = 640, height = 400, responsive = true,
|
|
|
8022
8228
|
return () => observer.disconnect();
|
|
8023
8229
|
}, [responsive]);
|
|
8024
8230
|
const sceneWidth = responsive && measured || width;
|
|
8025
|
-
const fullTheme = (0,
|
|
8026
|
-
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)(
|
|
8027
8233
|
() => (0, import_chart2.layoutChart)(state.spec, {
|
|
8028
8234
|
width: sceneWidth,
|
|
8029
8235
|
height,
|
|
@@ -8039,8 +8245,8 @@ function ChartCanvas({ controller, width = 640, height = 400, responsive = true,
|
|
|
8039
8245
|
[state.spec, state.selection, sceneWidth, height, fullTheme, editable, measureText, emptyMessage, frozen]
|
|
8040
8246
|
);
|
|
8041
8247
|
if (sceneRef) sceneRef.current = scene;
|
|
8042
|
-
const byKey = (0,
|
|
8043
|
-
(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(), []);
|
|
8044
8250
|
const scenePoint = (e) => (0, import_chart2.chartClientToScene)(scene, svg.current.getBoundingClientRect(), e.clientX, e.clientY);
|
|
8045
8251
|
const onPointerDown = (e) => {
|
|
8046
8252
|
if (!editable || e.button !== 0) return;
|
|
@@ -8073,7 +8279,7 @@ function ChartCanvas({ controller, width = 640, height = 400, responsive = true,
|
|
|
8073
8279
|
if (editable && (0, import_chart2.handleChartKey)(controller, scene, e)) e.preventDefault();
|
|
8074
8280
|
};
|
|
8075
8281
|
const label = state.spec.title || "Chart";
|
|
8076
|
-
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)(
|
|
8077
8283
|
"svg",
|
|
8078
8284
|
{
|
|
8079
8285
|
ref: svg,
|
|
@@ -8091,14 +8297,14 @@ function ChartCanvas({ controller, width = 640, height = 400, responsive = true,
|
|
|
8091
8297
|
onKeyDown,
|
|
8092
8298
|
children: [
|
|
8093
8299
|
scene.marks.map((m) => renderChartMark(m, scene.theme.fontFamily, editable)),
|
|
8094
|
-
presence && /* @__PURE__ */ (0,
|
|
8300
|
+
presence && /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(ChartPresenceLayer, { presence })
|
|
8095
8301
|
]
|
|
8096
8302
|
}
|
|
8097
8303
|
) });
|
|
8098
8304
|
}
|
|
8099
8305
|
|
|
8100
8306
|
// src/chart/ChartDataGrid.tsx
|
|
8101
|
-
var
|
|
8307
|
+
var import_react62 = require("react");
|
|
8102
8308
|
var import_chart3 = require("@pixerate/editor/chart");
|
|
8103
8309
|
|
|
8104
8310
|
// src/chart/styles.ts
|
|
@@ -8111,11 +8317,11 @@ var chartSectionClass = "space-y-2 border-b border-border pb-3 last:border-b-0";
|
|
|
8111
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";
|
|
8112
8318
|
|
|
8113
8319
|
// src/chart/ChartDataGrid.tsx
|
|
8114
|
-
var
|
|
8320
|
+
var import_jsx_runtime42 = require("react/jsx-runtime");
|
|
8115
8321
|
function ChartCommitInput({ value, onCommit, onKeyDown, onBlur, ...rest }) {
|
|
8116
|
-
const [draft, setDraft] = (0,
|
|
8117
|
-
const typing = (0,
|
|
8118
|
-
(0,
|
|
8322
|
+
const [draft, setDraft] = (0, import_react62.useState)(value);
|
|
8323
|
+
const typing = (0, import_react62.useRef)(false);
|
|
8324
|
+
(0, import_react62.useEffect)(() => {
|
|
8119
8325
|
if (!typing.current) setDraft(value);
|
|
8120
8326
|
}, [value]);
|
|
8121
8327
|
const commit = () => {
|
|
@@ -8124,7 +8330,7 @@ function ChartCommitInput({ value, onCommit, onKeyDown, onBlur, ...rest }) {
|
|
|
8124
8330
|
if (draft === value) return;
|
|
8125
8331
|
if (onCommit(draft) === false) setDraft(value);
|
|
8126
8332
|
};
|
|
8127
|
-
return /* @__PURE__ */ (0,
|
|
8333
|
+
return /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
|
|
8128
8334
|
"input",
|
|
8129
8335
|
{
|
|
8130
8336
|
...rest,
|
|
@@ -8159,15 +8365,15 @@ function ChartDataGrid({ controller, categoryHeader = "Category", readOnly = fal
|
|
|
8159
8365
|
e.preventDefault();
|
|
8160
8366
|
controller.pasteCells(row, column, text);
|
|
8161
8367
|
};
|
|
8162
|
-
return /* @__PURE__ */ (0,
|
|
8163
|
-
/* @__PURE__ */ (0,
|
|
8164
|
-
/* @__PURE__ */ (0,
|
|
8165
|
-
/* @__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 }),
|
|
8166
8372
|
spec.series.map((s, si) => {
|
|
8167
8373
|
const color = (0, import_chart3.chartSeriesColor)(spec, si);
|
|
8168
8374
|
const selected = selection?.kind === "series" && selection.seriesId === s.id;
|
|
8169
|
-
return /* @__PURE__ */ (0,
|
|
8170
|
-
/* @__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)(
|
|
8171
8377
|
"input",
|
|
8172
8378
|
{
|
|
8173
8379
|
type: "color",
|
|
@@ -8180,7 +8386,7 @@ function ChartDataGrid({ controller, categoryHeader = "Category", readOnly = fal
|
|
|
8180
8386
|
className: "h-5 w-5 shrink-0 cursor-pointer rounded border-0 bg-transparent p-0"
|
|
8181
8387
|
}
|
|
8182
8388
|
),
|
|
8183
|
-
/* @__PURE__ */ (0,
|
|
8389
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
|
|
8184
8390
|
ChartCommitInput,
|
|
8185
8391
|
{
|
|
8186
8392
|
value: s.name,
|
|
@@ -8190,8 +8396,8 @@ function ChartDataGrid({ controller, categoryHeader = "Category", readOnly = fal
|
|
|
8190
8396
|
className: `${chartInputClass} h-6 min-w-[5rem] border-transparent bg-transparent font-medium ${s.hidden ? "text-muted-foreground line-through" : ""}`
|
|
8191
8397
|
}
|
|
8192
8398
|
),
|
|
8193
|
-
!readOnly && /* @__PURE__ */ (0,
|
|
8194
|
-
/* @__PURE__ */ (0,
|
|
8399
|
+
!readOnly && /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)(import_jsx_runtime42.Fragment, { children: [
|
|
8400
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
|
|
8195
8401
|
"button",
|
|
8196
8402
|
{
|
|
8197
8403
|
type: "button",
|
|
@@ -8204,16 +8410,16 @@ function ChartDataGrid({ controller, categoryHeader = "Category", readOnly = fal
|
|
|
8204
8410
|
children: s.hidden ? "\u25CB" : "\u25CF"
|
|
8205
8411
|
}
|
|
8206
8412
|
),
|
|
8207
|
-
/* @__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" })
|
|
8208
8414
|
] })
|
|
8209
8415
|
] }) }, s.id);
|
|
8210
8416
|
}),
|
|
8211
|
-
!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: "+" }) })
|
|
8212
8418
|
] }) }),
|
|
8213
|
-
/* @__PURE__ */ (0,
|
|
8419
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)("tbody", { children: spec.categories.map((category, i) => {
|
|
8214
8420
|
const rowSelected = selection?.kind === "category" && selection.index === i;
|
|
8215
|
-
return /* @__PURE__ */ (0,
|
|
8216
|
-
/* @__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)(
|
|
8217
8423
|
ChartCommitInput,
|
|
8218
8424
|
{
|
|
8219
8425
|
value: category,
|
|
@@ -8227,7 +8433,7 @@ function ChartDataGrid({ controller, categoryHeader = "Category", readOnly = fal
|
|
|
8227
8433
|
spec.series.map((s) => {
|
|
8228
8434
|
const value = s.values[i];
|
|
8229
8435
|
const selected = selection?.kind === "point" && selection.seriesId === s.id && selection.index === i;
|
|
8230
|
-
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)(
|
|
8231
8437
|
ChartCommitInput,
|
|
8232
8438
|
{
|
|
8233
8439
|
value: value === null || value === void 0 ? "" : String(value),
|
|
@@ -8242,38 +8448,38 @@ function ChartDataGrid({ controller, categoryHeader = "Category", readOnly = fal
|
|
|
8242
8448
|
}
|
|
8243
8449
|
) }, s.id);
|
|
8244
8450
|
}),
|
|
8245
|
-
!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" }) })
|
|
8246
8452
|
] }, i);
|
|
8247
8453
|
}) })
|
|
8248
8454
|
] }),
|
|
8249
|
-
!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" }) })
|
|
8250
8456
|
] });
|
|
8251
8457
|
}
|
|
8252
8458
|
|
|
8253
8459
|
// src/chart/ChartInspector.tsx
|
|
8254
|
-
var
|
|
8460
|
+
var import_react63 = require("react");
|
|
8255
8461
|
var import_chart4 = require("@pixerate/editor/chart");
|
|
8256
|
-
var
|
|
8462
|
+
var import_jsx_runtime43 = require("react/jsx-runtime");
|
|
8257
8463
|
var cap = (s) => s.charAt(0).toUpperCase() + s.slice(1);
|
|
8258
8464
|
function Field({ label, htmlFor, children }) {
|
|
8259
|
-
return /* @__PURE__ */ (0,
|
|
8260
|
-
/* @__PURE__ */ (0,
|
|
8261
|
-
/* @__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 })
|
|
8262
8468
|
] });
|
|
8263
8469
|
}
|
|
8264
8470
|
function Toggle({ label, checked, onChange, name }) {
|
|
8265
|
-
return /* @__PURE__ */ (0,
|
|
8266
|
-
/* @__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) }),
|
|
8267
8473
|
label
|
|
8268
8474
|
] });
|
|
8269
8475
|
}
|
|
8270
8476
|
function Select({ id, value, options, onChange, name, labels }) {
|
|
8271
|
-
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)) });
|
|
8272
8478
|
}
|
|
8273
8479
|
function AxisSection({ controller, axis, value, idBase, horizontal, numeric = false, scales = false }) {
|
|
8274
8480
|
const set = (patch) => controller.setAxis(axis, patch);
|
|
8275
8481
|
const setFormat = (patch) => set({ format: { ...value.format, ...patch } });
|
|
8276
|
-
const bound = (key2) => /* @__PURE__ */ (0,
|
|
8482
|
+
const bound = (key2) => /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
|
|
8277
8483
|
ChartCommitInput,
|
|
8278
8484
|
{
|
|
8279
8485
|
id: `${idBase}-${axis}-${key2}`,
|
|
@@ -8288,26 +8494,26 @@ function AxisSection({ controller, axis, value, idBase, horizontal, numeric = fa
|
|
|
8288
8494
|
const name = axis === "x" ? numeric ? "X axis" : "Category axis" : axis === "y" ? "Value axis" : "Secondary axis";
|
|
8289
8495
|
const valueAxis = axis !== "x" || numeric;
|
|
8290
8496
|
const key = axis === "y2" ? "yAxis2" : `${axis}Axis`;
|
|
8291
|
-
return /* @__PURE__ */ (0,
|
|
8292
|
-
/* @__PURE__ */ (0,
|
|
8293
|
-
/* @__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: [
|
|
8294
8500
|
name,
|
|
8295
|
-
/* @__PURE__ */ (0,
|
|
8501
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("span", { className: "ml-1 font-normal text-muted-foreground", children: [
|
|
8296
8502
|
"(",
|
|
8297
8503
|
axis === "x" ? horizontal ? "left" : "bottom" : axis === "y2" ? horizontal ? "top" : "right" : horizontal ? "bottom" : "left",
|
|
8298
8504
|
")"
|
|
8299
8505
|
] })
|
|
8300
8506
|
] }),
|
|
8301
|
-
/* @__PURE__ */ (0,
|
|
8507
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)(Toggle, { label: "Show", name: `${axis}Axis.show`, checked: value.show, onChange: (show) => set({ show }) })
|
|
8302
8508
|
] }),
|
|
8303
|
-
/* @__PURE__ */ (0,
|
|
8304
|
-
/* @__PURE__ */ (0,
|
|
8305
|
-
/* @__PURE__ */ (0,
|
|
8306
|
-
axis === "x" && !numeric && /* @__PURE__ */ (0,
|
|
8307
|
-
scales && /* @__PURE__ */ (0,
|
|
8308
|
-
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" }) })
|
|
8309
8515
|
] }),
|
|
8310
|
-
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)(
|
|
8311
8517
|
ChartCommitInput,
|
|
8312
8518
|
{
|
|
8313
8519
|
id: `${idBase}-${axis}-log-base`,
|
|
@@ -8318,7 +8524,7 @@ function AxisSection({ controller, axis, value, idBase, horizontal, numeric = fa
|
|
|
8318
8524
|
onCommit: (text) => set({ logBase: text.trim() === "" ? void 0 : Number(text) }).ok
|
|
8319
8525
|
}
|
|
8320
8526
|
) }),
|
|
8321
|
-
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)(
|
|
8322
8528
|
ChartCommitInput,
|
|
8323
8529
|
{
|
|
8324
8530
|
id: `${idBase}-${axis}-step`,
|
|
@@ -8330,14 +8536,14 @@ function AxisSection({ controller, axis, value, idBase, horizontal, numeric = fa
|
|
|
8330
8536
|
onCommit: (text) => set({ step: text.trim() === "" ? null : Number(text) }).ok
|
|
8331
8537
|
}
|
|
8332
8538
|
) }),
|
|
8333
|
-
valueAxis && /* @__PURE__ */ (0,
|
|
8334
|
-
/* @__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: [
|
|
8335
8541
|
bound("min"),
|
|
8336
8542
|
bound("max")
|
|
8337
8543
|
] }) }),
|
|
8338
|
-
/* @__PURE__ */ (0,
|
|
8339
|
-
/* @__PURE__ */ (0,
|
|
8340
|
-
/* @__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)(
|
|
8341
8547
|
ChartCommitInput,
|
|
8342
8548
|
{
|
|
8343
8549
|
value: value.format.decimals === void 0 ? "" : String(value.format.decimals),
|
|
@@ -8356,8 +8562,8 @@ function AxisSection({ controller, axis, value, idBase, horizontal, numeric = fa
|
|
|
8356
8562
|
}
|
|
8357
8563
|
)
|
|
8358
8564
|
] }) }),
|
|
8359
|
-
value.format.style === "currency" && /* @__PURE__ */ (0,
|
|
8360
|
-
/* @__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)(
|
|
8361
8567
|
ChartCommitInput,
|
|
8362
8568
|
{
|
|
8363
8569
|
id: `${idBase}-${axis}-code`,
|
|
@@ -8383,15 +8589,15 @@ function ErrorBarFields({ controller, series, which, idBase }) {
|
|
|
8383
8589
|
const values = which === "xErrorBars" ? series.x ?? [] : series.values;
|
|
8384
8590
|
const set = (next) => controller.updateSeries(series.id, { [which]: next });
|
|
8385
8591
|
const patch = (p) => bars && set({ ...bars, ...p });
|
|
8386
|
-
return /* @__PURE__ */ (0,
|
|
8387
|
-
/* @__PURE__ */ (0,
|
|
8388
|
-
/* @__PURE__ */ (0,
|
|
8389
|
-
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))
|
|
8390
8596
|
] }) }),
|
|
8391
|
-
bars && (bars.type === "fixed" || bars.type === "percent" || bars.type === "stddev") && /* @__PURE__ */ (0,
|
|
8392
|
-
bars?.type === "custom" && /* @__PURE__ */ (0,
|
|
8393
|
-
/* @__PURE__ */ (0,
|
|
8394
|
-
/* @__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)(
|
|
8395
8601
|
ChartCommitInput,
|
|
8396
8602
|
{
|
|
8397
8603
|
id: `${id}-minus`,
|
|
@@ -8408,15 +8614,15 @@ function ErrorBarFields({ controller, series, which, idBase }) {
|
|
|
8408
8614
|
}
|
|
8409
8615
|
) })
|
|
8410
8616
|
] }),
|
|
8411
|
-
bars && /* @__PURE__ */ (0,
|
|
8412
|
-
/* @__PURE__ */ (0,
|
|
8413
|
-
/* @__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 }) })
|
|
8414
8620
|
] })
|
|
8415
8621
|
] });
|
|
8416
8622
|
}
|
|
8417
8623
|
function ChartInspector({ controller, sections, className }) {
|
|
8418
8624
|
const { spec, selectedSeries } = useChartState(controller);
|
|
8419
|
-
const idBase = (0,
|
|
8625
|
+
const idBase = (0, import_react63.useId)();
|
|
8420
8626
|
const show = (section) => !sections || sections.includes(section);
|
|
8421
8627
|
const cartesian = (0, import_chart4.isCartesianChart)(spec.type);
|
|
8422
8628
|
const family = (0, import_chart4.chartFamily)(spec);
|
|
@@ -8428,29 +8634,29 @@ function ChartInspector({ controller, sections, className }) {
|
|
|
8428
8634
|
const hasLines = cartesian && types.some((t) => t === "line" || t === "area");
|
|
8429
8635
|
const seriesIndex = selectedSeries ? spec.series.findIndex((s) => s.id === selectedSeries.id) : -1;
|
|
8430
8636
|
const scales = family === "cartesian" || family === "xy";
|
|
8431
|
-
return /* @__PURE__ */ (0,
|
|
8432
|
-
show("type") && /* @__PURE__ */ (0,
|
|
8433
|
-
show("style") && /* @__PURE__ */ (0,
|
|
8434
|
-
/* @__PURE__ */ (0,
|
|
8435
|
-
/* @__PURE__ */ (0,
|
|
8436
|
-
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))
|
|
8437
8643
|
] }) }),
|
|
8438
|
-
/* @__PURE__ */ (0,
|
|
8439
|
-
/* @__PURE__ */ (0,
|
|
8440
|
-
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))
|
|
8441
8647
|
] }) }),
|
|
8442
|
-
!colorCheck.ok && /* @__PURE__ */ (0,
|
|
8443
|
-
/* @__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" })
|
|
8444
8650
|
] }),
|
|
8445
|
-
show("titles") && /* @__PURE__ */ (0,
|
|
8446
|
-
/* @__PURE__ */ (0,
|
|
8447
|
-
/* @__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) }) })
|
|
8448
8654
|
] }),
|
|
8449
|
-
show("options") && /* @__PURE__ */ (0,
|
|
8450
|
-
cartesian && /* @__PURE__ */ (0,
|
|
8451
|
-
hasBars && /* @__PURE__ */ (0,
|
|
8452
|
-
hasLines && /* @__PURE__ */ (0,
|
|
8453
|
-
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)(
|
|
8454
8660
|
"input",
|
|
8455
8661
|
{
|
|
8456
8662
|
id: `${idBase}-hole`,
|
|
@@ -8466,7 +8672,7 @@ function ChartInspector({ controller, sections, className }) {
|
|
|
8466
8672
|
onChange: (e) => controller.update({ innerRadius: Number(e.currentTarget.value) })
|
|
8467
8673
|
}
|
|
8468
8674
|
) }),
|
|
8469
|
-
hasBars && /* @__PURE__ */ (0,
|
|
8675
|
+
hasBars && /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(Field, { label: "Spacing", htmlFor: `${idBase}-gap`, children: /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
|
|
8470
8676
|
"input",
|
|
8471
8677
|
{
|
|
8472
8678
|
id: `${idBase}-gap`,
|
|
@@ -8482,31 +8688,31 @@ function ChartInspector({ controller, sections, className }) {
|
|
|
8482
8688
|
onChange: (e) => controller.update({ gapWidth: Number(e.currentTarget.value) })
|
|
8483
8689
|
}
|
|
8484
8690
|
) }),
|
|
8485
|
-
spec.dataLabels && hasBars && /* @__PURE__ */ (0,
|
|
8486
|
-
spec.type === "histogram" && /* @__PURE__ */ (0,
|
|
8487
|
-
/* @__PURE__ */ (0,
|
|
8488
|
-
spec.type === "waterfall" && /* @__PURE__ */ (0,
|
|
8489
|
-
hasLines && /* @__PURE__ */ (0,
|
|
8490
|
-
/* @__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 }) })
|
|
8491
8697
|
] })
|
|
8492
8698
|
] }),
|
|
8493
|
-
show("legend") && /* @__PURE__ */ (0,
|
|
8494
|
-
/* @__PURE__ */ (0,
|
|
8495
|
-
/* @__PURE__ */ (0,
|
|
8496
|
-
/* @__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 }) })
|
|
8497
8703
|
] }),
|
|
8498
|
-
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)) })
|
|
8499
8705
|
] }),
|
|
8500
|
-
show("axes") && hasAxes && /* @__PURE__ */ (0,
|
|
8501
|
-
family !== "box" && family !== "histogram" && /* @__PURE__ */ (0,
|
|
8502
|
-
/* @__PURE__ */ (0,
|
|
8503
|
-
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 })
|
|
8504
8710
|
] }),
|
|
8505
|
-
show("series") && selectedSeries && /* @__PURE__ */ (0,
|
|
8506
|
-
/* @__PURE__ */ (0,
|
|
8507
|
-
/* @__PURE__ */ (0,
|
|
8508
|
-
/* @__PURE__ */ (0,
|
|
8509
|
-
/* @__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)(
|
|
8510
8716
|
"input",
|
|
8511
8717
|
{
|
|
8512
8718
|
id: `${idBase}-series-color`,
|
|
@@ -8519,9 +8725,9 @@ function ChartInspector({ controller, sections, className }) {
|
|
|
8519
8725
|
onChange: (e) => controller.updateSeries(selectedSeries.id, { color: e.currentTarget.value })
|
|
8520
8726
|
}
|
|
8521
8727
|
),
|
|
8522
|
-
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" })
|
|
8523
8729
|
] }) }),
|
|
8524
|
-
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)(
|
|
8525
8731
|
"select",
|
|
8526
8732
|
{
|
|
8527
8733
|
id: `${idBase}-series-type`,
|
|
@@ -8530,12 +8736,12 @@ function ChartInspector({ controller, sections, className }) {
|
|
|
8530
8736
|
"data-option": "series.type",
|
|
8531
8737
|
onChange: (e) => controller.updateSeries(selectedSeries.id, { type: e.currentTarget.value || null }),
|
|
8532
8738
|
children: [
|
|
8533
|
-
/* @__PURE__ */ (0,
|
|
8534
|
-
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))
|
|
8535
8741
|
]
|
|
8536
8742
|
}
|
|
8537
8743
|
) }),
|
|
8538
|
-
(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)(
|
|
8539
8745
|
"select",
|
|
8540
8746
|
{
|
|
8541
8747
|
id: `${idBase}-series-marker`,
|
|
@@ -8544,20 +8750,20 @@ function ChartInspector({ controller, sections, className }) {
|
|
|
8544
8750
|
"data-option": "series.marker",
|
|
8545
8751
|
onChange: (e) => controller.updateSeries(selectedSeries.id, { marker: e.currentTarget.value || null }),
|
|
8546
8752
|
children: [
|
|
8547
|
-
/* @__PURE__ */ (0,
|
|
8548
|
-
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))
|
|
8549
8755
|
]
|
|
8550
8756
|
}
|
|
8551
8757
|
) }),
|
|
8552
|
-
scales && /* @__PURE__ */ (0,
|
|
8553
|
-
family === "xy" && /* @__PURE__ */ (0,
|
|
8554
|
-
(0, import_chart4.chartSupportsTrendlines)(spec.type, spec.stacking) && /* @__PURE__ */ (0,
|
|
8555
|
-
(selectedSeries.trendlines ?? []).map((t, i) => /* @__PURE__ */ (0,
|
|
8556
|
-
/* @__PURE__ */ (0,
|
|
8557
|
-
/* @__PURE__ */ (0,
|
|
8558
|
-
/* @__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" })
|
|
8559
8765
|
] }, i)),
|
|
8560
|
-
/* @__PURE__ */ (0,
|
|
8766
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsxs)(
|
|
8561
8767
|
"select",
|
|
8562
8768
|
{
|
|
8563
8769
|
className: chartInputClass,
|
|
@@ -8566,32 +8772,32 @@ function ChartInspector({ controller, sections, className }) {
|
|
|
8566
8772
|
"data-option": "trendline.add",
|
|
8567
8773
|
onChange: (e) => e.currentTarget.value && controller.addTrendline(selectedSeries.id, { type: e.currentTarget.value }),
|
|
8568
8774
|
children: [
|
|
8569
|
-
/* @__PURE__ */ (0,
|
|
8570
|
-
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))
|
|
8571
8777
|
]
|
|
8572
8778
|
}
|
|
8573
8779
|
)
|
|
8574
8780
|
] }),
|
|
8575
|
-
/* @__PURE__ */ (0,
|
|
8576
|
-
/* @__PURE__ */ (0,
|
|
8577
|
-
family === "cartesian" && /* @__PURE__ */ (0,
|
|
8578
|
-
/* @__PURE__ */ (0,
|
|
8579
|
-
/* @__PURE__ */ (0,
|
|
8580
|
-
/* @__PURE__ */ (0,
|
|
8581
|
-
/* @__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" })
|
|
8582
8788
|
] })
|
|
8583
8789
|
] })
|
|
8584
8790
|
] });
|
|
8585
8791
|
}
|
|
8586
8792
|
|
|
8587
8793
|
// src/chart-node/ChartNodeView.tsx
|
|
8588
|
-
var
|
|
8794
|
+
var import_jsx_runtime44 = require("react/jsx-runtime");
|
|
8589
8795
|
function ChartNodeView({ state, theme, showDataGrid = true }) {
|
|
8590
8796
|
const { controller, editing, editable, selected, width, height, setEditing } = state;
|
|
8591
8797
|
const open = () => {
|
|
8592
8798
|
if (editable && !editing) setEditing(true);
|
|
8593
8799
|
};
|
|
8594
|
-
return /* @__PURE__ */ (0,
|
|
8800
|
+
return /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)(
|
|
8595
8801
|
"div",
|
|
8596
8802
|
{
|
|
8597
8803
|
className: `not-prose my-2 rounded-md border bg-background p-1 ${selected ? "border-primary ring-1 ring-primary" : "border-border"}`,
|
|
@@ -8604,24 +8810,24 @@ function ChartNodeView({ state, theme, showDataGrid = true }) {
|
|
|
8604
8810
|
}
|
|
8605
8811
|
},
|
|
8606
8812
|
children: [
|
|
8607
|
-
editing && /* @__PURE__ */ (0,
|
|
8608
|
-
/* @__PURE__ */ (0,
|
|
8609
|
-
/* @__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" })
|
|
8610
8816
|
] }),
|
|
8611
|
-
/* @__PURE__ */ (0,
|
|
8817
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
|
|
8612
8818
|
"div",
|
|
8613
8819
|
{
|
|
8614
8820
|
className: editable && !editing ? "cursor-pointer" : void 0,
|
|
8615
8821
|
onClick: open,
|
|
8616
8822
|
title: editable && !editing ? "Click to edit the chart" : void 0,
|
|
8617
8823
|
"data-chart-node-canvas": "",
|
|
8618
|
-
children: /* @__PURE__ */ (0,
|
|
8824
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(ChartCanvas, { controller, width: width ?? 640, height, responsive: width === null, editable: editing, theme })
|
|
8619
8825
|
}
|
|
8620
8826
|
),
|
|
8621
8827
|
editing && // Wraps by the document's width, not the viewport's: side by side when there is room.
|
|
8622
|
-
/* @__PURE__ */ (0,
|
|
8623
|
-
showDataGrid && /* @__PURE__ */ (0,
|
|
8624
|
-
/* @__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" })
|
|
8625
8831
|
] })
|
|
8626
8832
|
]
|
|
8627
8833
|
}
|
|
@@ -8639,7 +8845,7 @@ function createReactChartNodeView(options = {}) {
|
|
|
8639
8845
|
scheduled = true;
|
|
8640
8846
|
queueMicrotask(() => {
|
|
8641
8847
|
scheduled = false;
|
|
8642
|
-
if (!destroyed) root.render(/* @__PURE__ */ (0,
|
|
8848
|
+
if (!destroyed) root.render(/* @__PURE__ */ (0, import_jsx_runtime44.jsx)(Component, { ...props, state: latest }));
|
|
8643
8849
|
});
|
|
8644
8850
|
};
|
|
8645
8851
|
schedule();
|
|
@@ -8680,6 +8886,7 @@ function createReactChartNodeView(options = {}) {
|
|
|
8680
8886
|
ImageEditor,
|
|
8681
8887
|
InsertTableGrid,
|
|
8682
8888
|
JobProgress,
|
|
8889
|
+
LayerEffectsPanel,
|
|
8683
8890
|
LayersPanel,
|
|
8684
8891
|
MergePreview,
|
|
8685
8892
|
NameManager,
|