@xenosystem/blocks 0.13.17 → 0.13.18
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/data/index.js +1 -1
- package/dist/edit/index.d.ts +195 -23
- package/dist/edit/index.js +560 -394
- package/dist/icons/index.js +1 -1
- package/dist/ops/index.js +1 -1
- package/dist/time/index.js +1 -1
- package/package.json +3 -3
- /package/dist/{chunk-PI5WOATA.js → chunk-7S2RKUAM.js} +0 -0
package/dist/edit/index.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import {
|
|
2
|
-
ChevronGlyph,
|
|
3
2
|
CollapseGlyph,
|
|
4
3
|
DiamondIcon,
|
|
5
4
|
EntryIcon,
|
|
@@ -22,7 +21,7 @@ import {
|
|
|
22
21
|
VisibilityIcon,
|
|
23
22
|
XIcon,
|
|
24
23
|
XIcon2
|
|
25
|
-
} from "../chunk-
|
|
24
|
+
} from "../chunk-7S2RKUAM.js";
|
|
26
25
|
import "../chunk-2KG3PWR4.js";
|
|
27
26
|
|
|
28
27
|
// src/edit/layers/panel.ts
|
|
@@ -1488,9 +1487,9 @@ function LayersPanelView({ controller }) {
|
|
|
1488
1487
|
const getSnapshot = useCallback(() => controller.getRevision(), [controller]);
|
|
1489
1488
|
useSyncExternalStore(subscribe, getSnapshot, getSnapshot);
|
|
1490
1489
|
const view = layersViewState(controller);
|
|
1491
|
-
const
|
|
1490
|
+
const ui8 = (intent) => applyLayersUi(controller, intent);
|
|
1492
1491
|
return /* @__PURE__ */ jsxs(Column, { className: "xeno-layers-panel", children: [
|
|
1493
|
-
view.searchShown ? /* @__PURE__ */ jsx2(Toolbar, { children: /* @__PURE__ */ jsx2(SearchField, { value: view.filter, onChange: (v) =>
|
|
1492
|
+
view.searchShown ? /* @__PURE__ */ jsx2(Toolbar, { children: /* @__PURE__ */ jsx2(SearchField, { value: view.filter, onChange: (v) => ui8({ kind: "filter", value: v }), placeholder: "Search layers", label: "Search layers" }) }) : null,
|
|
1494
1493
|
/* @__PURE__ */ jsxs(LayersScroller, { controller, children: [
|
|
1495
1494
|
/* @__PURE__ */ jsx2(RowList, { role: "tree", "aria-label": "Layers", children: /* @__PURE__ */ jsx2(VirtualWindow, { totalHeight: view.totalHeight, offsetTop: view.offsetTop, children: view.rows.map((row2) => /* @__PURE__ */ jsx2(LayerRow, { row: row2, thumbnailSize: view.thumbnailSize, controller }, row2.id)) }) }),
|
|
1496
1495
|
view.empty ? /* @__PURE__ */ jsx2(EmptyState, { title: "No layers" }) : null
|
|
@@ -1603,7 +1602,7 @@ function LayersThumbnail({ thumbnailKey, size, controller }) {
|
|
|
1603
1602
|
return /* @__PURE__ */ jsx2(Thumbnail, { size, data: controller.getThumbnail(thumbnailKey) });
|
|
1604
1603
|
}
|
|
1605
1604
|
function LayerRow({ row: row2, thumbnailSize, controller }) {
|
|
1606
|
-
const
|
|
1605
|
+
const ui8 = (intent) => applyLayersUi(controller, intent);
|
|
1607
1606
|
return /* @__PURE__ */ jsx2(
|
|
1608
1607
|
Row,
|
|
1609
1608
|
{
|
|
@@ -1618,11 +1617,11 @@ function LayerRow({ row: row2, thumbnailSize, controller }) {
|
|
|
1618
1617
|
title: row2.title,
|
|
1619
1618
|
icon: row2.hasThumbnail ? /* @__PURE__ */ jsx2(LayersThumbnail, { thumbnailKey: row2.thumbnailKey, size: thumbnailSize, controller }) : /* @__PURE__ */ jsx2(KindGlyph, {}),
|
|
1620
1619
|
leading: /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1621
|
-
row2.showVisibility ? /* @__PURE__ */ jsx2(IconButton, { size: "sm", icon: /* @__PURE__ */ jsx2(VisibilityIcon, { open: row2.visible }), label: row2.visibilityLabel, active: row2.visible, onClick: () =>
|
|
1622
|
-
row2.showLock ? /* @__PURE__ */ jsx2(IconButton, { size: "sm", icon: /* @__PURE__ */ jsx2(LockStateIcon, { locked: row2.locked }), label: row2.lockLabel, active: row2.locked, onClick: () =>
|
|
1623
|
-
row2.showSolo ? /* @__PURE__ */ jsx2(ChipToggle, { glyph: "S", label: "Solo", on: row2.solo, onChange: () =>
|
|
1624
|
-
row2.showMute ? /* @__PURE__ */ jsx2(ChipToggle, { glyph: "M", label: "Mute", on: row2.muted, onChange: () =>
|
|
1625
|
-
row2.showArm ? /* @__PURE__ */ jsx2(ChipToggle, { glyph: "R", label: "Arm", on: row2.armed, onChange: () =>
|
|
1620
|
+
row2.showVisibility ? /* @__PURE__ */ jsx2(IconButton, { size: "sm", icon: /* @__PURE__ */ jsx2(VisibilityIcon, { open: row2.visible }), label: row2.visibilityLabel, active: row2.visible, onClick: () => ui8({ kind: "toggleProp", id: row2.id, prop: "visible" }) }) : null,
|
|
1621
|
+
row2.showLock ? /* @__PURE__ */ jsx2(IconButton, { size: "sm", icon: /* @__PURE__ */ jsx2(LockStateIcon, { locked: row2.locked }), label: row2.lockLabel, active: row2.locked, onClick: () => ui8({ kind: "toggleProp", id: row2.id, prop: "locked" }) }) : null,
|
|
1622
|
+
row2.showSolo ? /* @__PURE__ */ jsx2(ChipToggle, { glyph: "S", label: "Solo", on: row2.solo, onChange: () => ui8({ kind: "toggleProp", id: row2.id, prop: "solo" }) }) : null,
|
|
1623
|
+
row2.showMute ? /* @__PURE__ */ jsx2(ChipToggle, { glyph: "M", label: "Mute", on: row2.muted, onChange: () => ui8({ kind: "toggleProp", id: row2.id, prop: "muted" }) }) : null,
|
|
1624
|
+
row2.showArm ? /* @__PURE__ */ jsx2(ChipToggle, { glyph: "R", label: "Arm", on: row2.armed, onChange: () => ui8({ kind: "toggleProp", id: row2.id, prop: "armed" }) }) : null,
|
|
1626
1625
|
row2.showColor ? /* @__PURE__ */ jsx2(ColorTag, { color: row2.colorLabel }) : null
|
|
1627
1626
|
] }),
|
|
1628
1627
|
label: row2.renaming ? /* @__PURE__ */ jsx2(LayersRenameField, { id: row2.id, controller }) : row2.name,
|
|
@@ -1630,9 +1629,9 @@ function LayerRow({ row: row2, thumbnailSize, controller }) {
|
|
|
1630
1629
|
row2.adornments.map((a) => /* @__PURE__ */ jsx2(Badge, { size: "sm", title: a.title, children: a.text }, a.key)),
|
|
1631
1630
|
row2.showOpacity ? /* @__PURE__ */ jsx2(Text, { role: "number", children: row2.opacity }) : null
|
|
1632
1631
|
] }),
|
|
1633
|
-
onExpandedChange: () =>
|
|
1634
|
-
onDoubleClick: () =>
|
|
1635
|
-
onContextMenuAt: (x, y) =>
|
|
1632
|
+
onExpandedChange: () => ui8({ kind: "toggleExpanded", id: row2.id }),
|
|
1633
|
+
onDoubleClick: () => ui8({ kind: "beginRename", id: row2.id }),
|
|
1634
|
+
onContextMenuAt: (x, y) => ui8({ kind: "contextMenu", id: row2.id, x, y })
|
|
1636
1635
|
}
|
|
1637
1636
|
);
|
|
1638
1637
|
}
|
|
@@ -2024,8 +2023,8 @@ function constraintsOf(field) {
|
|
|
2024
2023
|
scale: field.scale
|
|
2025
2024
|
};
|
|
2026
2025
|
}
|
|
2027
|
-
function parseNumeric(
|
|
2028
|
-
const trimmed = String(
|
|
2026
|
+
function parseNumeric(text8) {
|
|
2027
|
+
const trimmed = String(text8).trim();
|
|
2029
2028
|
if (trimmed.length === 0) return { ok: false, reason: "empty" };
|
|
2030
2029
|
const match = /^[+-]?(\d+\.?\d*|\.\d+)(?:[eE][+-]?\d+)?/.exec(trimmed);
|
|
2031
2030
|
if (!match) return { ok: false, reason: "nan" };
|
|
@@ -2050,8 +2049,8 @@ function normalizeNumeric(value, c) {
|
|
|
2050
2049
|
function formatNumeric(value, field) {
|
|
2051
2050
|
if (!Number.isFinite(value)) return "";
|
|
2052
2051
|
const precision = field.precision;
|
|
2053
|
-
const
|
|
2054
|
-
return field.unit ? `${
|
|
2052
|
+
const text8 = typeof precision === "number" && Number.isFinite(precision) ? value.toFixed(Math.max(0, Math.floor(precision))) : String(value);
|
|
2053
|
+
return field.unit ? `${text8}${field.unit}` : text8;
|
|
2055
2054
|
}
|
|
2056
2055
|
function usesLogScale(c) {
|
|
2057
2056
|
return c.scale === "log" && typeof c.min === "number" && typeof c.max === "number" && c.min > 0 && c.max > c.min;
|
|
@@ -2385,44 +2384,44 @@ var InspectorPanelController = class {
|
|
|
2385
2384
|
if (!field || !isFieldEditable(field)) return;
|
|
2386
2385
|
const mixed = isFieldMixed(field);
|
|
2387
2386
|
const value = this.getFieldValue(fieldId);
|
|
2388
|
-
const
|
|
2389
|
-
this.drafts.set(fieldId, { text:
|
|
2387
|
+
const text8 = mixed ? "" : field.type === "number" && typeof value === "number" ? formatNumeric(value, field) : value === void 0 || value === null ? "" : String(value);
|
|
2388
|
+
this.drafts.set(fieldId, { text: text8, original: value });
|
|
2390
2389
|
this.focusedFieldId = fieldId;
|
|
2391
2390
|
this.emitFieldFocus(fieldId);
|
|
2392
2391
|
this.notify();
|
|
2393
2392
|
}
|
|
2394
2393
|
/** Update the draft text (typing). Emits nothing under the `blur` policy. */
|
|
2395
|
-
setDraft(fieldId,
|
|
2394
|
+
setDraft(fieldId, text8) {
|
|
2396
2395
|
const draft = this.drafts.get(fieldId);
|
|
2397
2396
|
if (!draft) {
|
|
2398
|
-
this.drafts.set(fieldId, { text:
|
|
2397
|
+
this.drafts.set(fieldId, { text: text8, original: this.getFieldValue(fieldId) });
|
|
2399
2398
|
} else {
|
|
2400
|
-
draft.text =
|
|
2399
|
+
draft.text = text8;
|
|
2401
2400
|
}
|
|
2402
2401
|
const field = this.getField(fieldId);
|
|
2403
2402
|
if (field && commitPolicyOf(field) === "live") {
|
|
2404
|
-
const parsed = this.parseDraft(fieldId,
|
|
2403
|
+
const parsed = this.parseDraft(fieldId, text8);
|
|
2405
2404
|
if (parsed.ok) this.emitSet(fieldId, parsed.value);
|
|
2406
2405
|
}
|
|
2407
2406
|
this.notify();
|
|
2408
2407
|
}
|
|
2409
2408
|
/** Parse a draft string into a field-appropriate value. */
|
|
2410
|
-
parseDraft(fieldId,
|
|
2409
|
+
parseDraft(fieldId, text8) {
|
|
2411
2410
|
const field = this.getField(fieldId);
|
|
2412
2411
|
if (!field) return { ok: false };
|
|
2413
2412
|
if (field.type === "number") {
|
|
2414
|
-
const parsed = parseNumeric(
|
|
2413
|
+
const parsed = parseNumeric(text8);
|
|
2415
2414
|
if (!parsed.ok) return { ok: false };
|
|
2416
2415
|
return { ok: true, value: normalizeNumeric(parsed.value, constraintsOf(field)) };
|
|
2417
2416
|
}
|
|
2418
2417
|
if (field.type === "json") {
|
|
2419
2418
|
try {
|
|
2420
|
-
return { ok: true, value: JSON.parse(
|
|
2419
|
+
return { ok: true, value: JSON.parse(text8) };
|
|
2421
2420
|
} catch {
|
|
2422
2421
|
return { ok: false };
|
|
2423
2422
|
}
|
|
2424
2423
|
}
|
|
2425
|
-
return { ok: true, value:
|
|
2424
|
+
return { ok: true, value: text8 };
|
|
2426
2425
|
}
|
|
2427
2426
|
/**
|
|
2428
2427
|
* Commit the draft (Enter / blur). Invalid input reverts instead of committing garbage.
|
|
@@ -3348,7 +3347,7 @@ function NumberWidget({ field, controller, component }) {
|
|
|
3348
3347
|
},
|
|
3349
3348
|
[controller, editable, field.id, component]
|
|
3350
3349
|
);
|
|
3351
|
-
const
|
|
3350
|
+
const text8 = component !== void 0 ? (() => {
|
|
3352
3351
|
const raw = controller.getFieldValue(field.id);
|
|
3353
3352
|
const v = Array.isArray(raw) ? raw[component] : void 0;
|
|
3354
3353
|
return typeof v === "number" ? formatNumeric(v, field) : "";
|
|
@@ -3360,7 +3359,7 @@ function NumberWidget({ field, controller, component }) {
|
|
|
3360
3359
|
Input2,
|
|
3361
3360
|
{
|
|
3362
3361
|
inputMode: "decimal",
|
|
3363
|
-
value:
|
|
3362
|
+
value: text8,
|
|
3364
3363
|
placeholder: mixed ? controller.getMixedPlaceholder() : field.placeholder,
|
|
3365
3364
|
mixed,
|
|
3366
3365
|
readOnly: !editable,
|
|
@@ -3578,7 +3577,7 @@ function ActionGlyph({ glyph }) {
|
|
|
3578
3577
|
return /* @__PURE__ */ jsx4("span", { "aria-hidden": true, children: glyph });
|
|
3579
3578
|
}
|
|
3580
3579
|
function SectionView({ section, controller }) {
|
|
3581
|
-
const
|
|
3580
|
+
const ui8 = (intent) => applyInspectorUi(controller, intent);
|
|
3582
3581
|
const hasActions = section.actions.length > 0 || section.hasAddMenu;
|
|
3583
3582
|
return /* @__PURE__ */ jsxs3(
|
|
3584
3583
|
Section,
|
|
@@ -3587,13 +3586,13 @@ function SectionView({ section, controller }) {
|
|
|
3587
3586
|
flush: true,
|
|
3588
3587
|
collapsible: section.collapsible,
|
|
3589
3588
|
collapsed: section.collapsed,
|
|
3590
|
-
onCollapsedChange: () =>
|
|
3589
|
+
onCollapsedChange: () => ui8({ kind: "toggleSectionCollapsed", sectionId: section.id }),
|
|
3591
3590
|
enabled: section.enabled,
|
|
3592
|
-
onEnabledChange: () =>
|
|
3591
|
+
onEnabledChange: () => ui8({ kind: "toggleSectionEnabled", sectionId: section.id }),
|
|
3593
3592
|
badge: section.badge ? /* @__PURE__ */ jsx4(Badge2, { children: section.badge }) : null,
|
|
3594
3593
|
actions: hasActions ? /* @__PURE__ */ jsxs3(Fragment3, { children: [
|
|
3595
|
-
section.actions.map((action) => /* @__PURE__ */ jsx4(IconButton3, { size: "sm", icon: /* @__PURE__ */ jsx4(ActionGlyph, { glyph: action.glyph }), label: action.label, disabled: action.disabled, onClick: () =>
|
|
3596
|
-
section.hasAddMenu ? /* @__PURE__ */ jsx4(Menu, { size: "sm", trigger: "\uFF0B", items: section.addItems, label: section.addLabel, align: "end", onSelect: (id) =>
|
|
3594
|
+
section.actions.map((action) => /* @__PURE__ */ jsx4(IconButton3, { size: "sm", icon: /* @__PURE__ */ jsx4(ActionGlyph, { glyph: action.glyph }), label: action.label, disabled: action.disabled, onClick: () => ui8({ kind: "runAction", sectionId: section.id, actionId: action.id }) }, action.id)),
|
|
3595
|
+
section.hasAddMenu ? /* @__PURE__ */ jsx4(Menu, { size: "sm", trigger: "\uFF0B", items: section.addItems, label: section.addLabel, align: "end", onSelect: (id) => ui8({ kind: "addItem", sectionId: section.id, itemId: id }) }) : null
|
|
3597
3596
|
] }) : null,
|
|
3598
3597
|
children: [
|
|
3599
3598
|
section.showEmptyHint ? /* @__PURE__ */ jsx4(Stack2, { pad: "inset", children: /* @__PURE__ */ jsx4(Text3, { role: "caption", children: section.emptyHint }) }) : null,
|
|
@@ -3603,7 +3602,7 @@ function SectionView({ section, controller }) {
|
|
|
3603
3602
|
);
|
|
3604
3603
|
}
|
|
3605
3604
|
function FieldRow({ row: row2, controller }) {
|
|
3606
|
-
const
|
|
3605
|
+
const ui8 = (intent) => applyInspectorUi(controller, intent);
|
|
3607
3606
|
return /* @__PURE__ */ jsxs3(Fragment3, { children: [
|
|
3608
3607
|
/* @__PURE__ */ jsxs3(
|
|
3609
3608
|
Field,
|
|
@@ -3611,19 +3610,19 @@ function FieldRow({ row: row2, controller }) {
|
|
|
3611
3610
|
label: row2.label,
|
|
3612
3611
|
title: row2.title,
|
|
3613
3612
|
focused: row2.focused,
|
|
3614
|
-
onLabelClick: () =>
|
|
3615
|
-
onContextMenu: (x, y) =>
|
|
3613
|
+
onLabelClick: () => ui8({ kind: "focusField", fieldId: row2.id }),
|
|
3614
|
+
onContextMenu: (x, y) => ui8({ kind: "contextMenu", fieldId: row2.id, x, y }),
|
|
3616
3615
|
leading: row2.showKeyframes ? /* @__PURE__ */ jsxs3(Fragment3, { children: [
|
|
3617
|
-
/* @__PURE__ */ jsx4(IconButton3, { size: "sm", icon: /* @__PURE__ */ jsx4(StopwatchIcon, {}), label: "Toggle animation", active: row2.animated, onClick: () =>
|
|
3618
|
-
row2.animated ? /* @__PURE__ */ jsx4(IconButton3, { size: "sm", icon: /* @__PURE__ */ jsx4(PrevIcon, {}), label: "Previous keyframe", disabled: row2.prevDisabled, onClick: () =>
|
|
3619
|
-
row2.animated ? /* @__PURE__ */ jsx4(IconButton3, { size: "sm", icon: /* @__PURE__ */ jsx4(DiamondIcon, { filled: row2.onKeyframe }), label: row2.keyframeLabel, onClick: () =>
|
|
3620
|
-
row2.animated ? /* @__PURE__ */ jsx4(IconButton3, { size: "sm", icon: /* @__PURE__ */ jsx4(NextIcon, {}), label: "Next keyframe", disabled: row2.nextDisabled, onClick: () =>
|
|
3616
|
+
/* @__PURE__ */ jsx4(IconButton3, { size: "sm", icon: /* @__PURE__ */ jsx4(StopwatchIcon, {}), label: "Toggle animation", active: row2.animated, onClick: () => ui8({ kind: "keyframe", fieldId: row2.id, op: "toggleAnim" }) }),
|
|
3617
|
+
row2.animated ? /* @__PURE__ */ jsx4(IconButton3, { size: "sm", icon: /* @__PURE__ */ jsx4(PrevIcon, {}), label: "Previous keyframe", disabled: row2.prevDisabled, onClick: () => ui8({ kind: "keyframe", fieldId: row2.id, op: "prev" }) }) : null,
|
|
3618
|
+
row2.animated ? /* @__PURE__ */ jsx4(IconButton3, { size: "sm", icon: /* @__PURE__ */ jsx4(DiamondIcon, { filled: row2.onKeyframe }), label: row2.keyframeLabel, onClick: () => ui8({ kind: "keyframe", fieldId: row2.id, op: row2.keyframeOp }) }) : null,
|
|
3619
|
+
row2.animated ? /* @__PURE__ */ jsx4(IconButton3, { size: "sm", icon: /* @__PURE__ */ jsx4(NextIcon, {}), label: "Next keyframe", disabled: row2.nextDisabled, onClick: () => ui8({ kind: "keyframe", fieldId: row2.id, op: "next" }) }) : null
|
|
3621
3620
|
] }) : null,
|
|
3622
3621
|
trailing: /* @__PURE__ */ jsxs3(Fragment3, { children: [
|
|
3623
|
-
row2.showEasing ? /* @__PURE__ */ jsx4(Select2, { size: "sm", options: row2.easingOptions, value: row2.easing, label: "Easing", onChange: (v) =>
|
|
3622
|
+
row2.showEasing ? /* @__PURE__ */ jsx4(Select2, { size: "sm", options: row2.easingOptions, value: row2.easing, label: "Easing", onChange: (v) => ui8({ kind: "setEasing", fieldId: row2.id, easing: v }) }) : null,
|
|
3624
3623
|
row2.showKeyframes ? /* @__PURE__ */ jsx4(Badge2, { size: "sm", children: row2.keyframeChip }) : null,
|
|
3625
|
-
row2.showToken ? /* @__PURE__ */ jsx4(IconButton3, { size: "sm", icon: /* @__PURE__ */ jsx4(LinkIcon, {}), label: row2.tokenActionLabel, active: row2.bound, onClick: () =>
|
|
3626
|
-
row2.showReset ? /* @__PURE__ */ jsx4(IconButton3, { size: "sm", icon: /* @__PURE__ */ jsx4(ResetIcon, {}), label: "Reset to default", onClick: () =>
|
|
3624
|
+
row2.showToken ? /* @__PURE__ */ jsx4(IconButton3, { size: "sm", icon: /* @__PURE__ */ jsx4(LinkIcon, {}), label: row2.tokenActionLabel, active: row2.bound, onClick: () => ui8({ kind: "bindToken", fieldId: row2.id }) }) : null,
|
|
3625
|
+
row2.showReset ? /* @__PURE__ */ jsx4(IconButton3, { size: "sm", icon: /* @__PURE__ */ jsx4(ResetIcon, {}), label: "Reset to default", onClick: () => ui8({ kind: "resetField", fieldId: row2.id }) }) : null
|
|
3627
3626
|
] }),
|
|
3628
3627
|
children: [
|
|
3629
3628
|
row2.bound ? /* @__PURE__ */ jsx4(Badge2, { title: row2.tokenTitle, children: row2.tokenLabel }) : null,
|
|
@@ -4876,23 +4875,23 @@ function HistoryPanelView({ controller }) {
|
|
|
4876
4875
|
const getSnapshot = useCallback4(() => controller.getRevision(), [controller]);
|
|
4877
4876
|
useSyncExternalStore3(subscribe, getSnapshot, getSnapshot);
|
|
4878
4877
|
const view = historyViewState(controller);
|
|
4879
|
-
const
|
|
4878
|
+
const ui8 = (intent) => applyHistoryUi(controller, intent);
|
|
4880
4879
|
return /* @__PURE__ */ jsxs4(Column3, { className: "xeno-history-panel", children: [
|
|
4881
4880
|
/* @__PURE__ */ jsx5(
|
|
4882
4881
|
Toolbar2,
|
|
4883
4882
|
{
|
|
4884
4883
|
left: /* @__PURE__ */ jsxs4(Fragment4, { children: [
|
|
4885
|
-
/* @__PURE__ */ jsx5(IconButton4, { size: "sm", icon: /* @__PURE__ */ jsx5(UndoIcon, {}), label: "Undo", disabled: !view.canUndo, onClick: () =>
|
|
4886
|
-
/* @__PURE__ */ jsx5(IconButton4, { size: "sm", icon: /* @__PURE__ */ jsx5(RedoIcon, {}), label: "Redo", disabled: !view.canRedo, onClick: () =>
|
|
4884
|
+
/* @__PURE__ */ jsx5(IconButton4, { size: "sm", icon: /* @__PURE__ */ jsx5(UndoIcon, {}), label: "Undo", disabled: !view.canUndo, onClick: () => ui8({ kind: "undo" }) }),
|
|
4885
|
+
/* @__PURE__ */ jsx5(IconButton4, { size: "sm", icon: /* @__PURE__ */ jsx5(RedoIcon, {}), label: "Redo", disabled: !view.canRedo, onClick: () => ui8({ kind: "redo" }) })
|
|
4887
4886
|
] }),
|
|
4888
4887
|
right: /* @__PURE__ */ jsxs4(Fragment4, { children: [
|
|
4889
4888
|
/* @__PURE__ */ jsx5(Text4, { role: "number", children: view.counter }),
|
|
4890
|
-
view.clearAllowed ? /* @__PURE__ */ jsx5(IconButton4, { size: "sm", icon: /* @__PURE__ */ jsx5(TrashIcon, {}), label: "Clear history", onClick: () =>
|
|
4889
|
+
view.clearAllowed ? /* @__PURE__ */ jsx5(IconButton4, { size: "sm", icon: /* @__PURE__ */ jsx5(TrashIcon, {}), label: "Clear history", onClick: () => ui8({ kind: "requestClear" }) }) : null
|
|
4891
4890
|
] }),
|
|
4892
|
-
children: view.searchShown ? /* @__PURE__ */ jsx5(SearchField3, { value: view.filter, onChange: (v) =>
|
|
4891
|
+
children: view.searchShown ? /* @__PURE__ */ jsx5(SearchField3, { value: view.filter, onChange: (v) => ui8({ kind: "filter", value: v }), placeholder: "Search history", label: "Search history" }) : null
|
|
4893
4892
|
}
|
|
4894
4893
|
),
|
|
4895
|
-
view.confirmingClear ? /* @__PURE__ */ jsx5(InlineConfirm, { message: "Clear all history?", label: "Confirm clear history", confirmLabel: "Clear", onConfirm: () =>
|
|
4894
|
+
view.confirmingClear ? /* @__PURE__ */ jsx5(InlineConfirm, { message: "Clear all history?", label: "Confirm clear history", confirmLabel: "Clear", onConfirm: () => ui8({ kind: "confirmClear" }), onCancel: () => ui8({ kind: "cancelClear" }) }) : null,
|
|
4896
4895
|
view.pruned ? /* @__PURE__ */ jsx5(Text4, { role: "caption", children: "Earlier history discarded (limit reached)" }) : null,
|
|
4897
4896
|
/* @__PURE__ */ jsxs4(HistoryScroller, { controller, children: [
|
|
4898
4897
|
/* @__PURE__ */ jsx5(RowList2, { role: "listbox", "aria-label": "History", children: /* @__PURE__ */ jsx5(VirtualWindow2, { totalHeight: view.totalHeight, offsetTop: view.offsetTop, children: view.rows.map((row2) => /* @__PURE__ */ jsx5(HistoryRowView, { row: row2, controller }, row2.key)) }) }),
|
|
@@ -4951,7 +4950,7 @@ function HistoryCancelButton({ entryId, controller }) {
|
|
|
4951
4950
|
);
|
|
4952
4951
|
}
|
|
4953
4952
|
function HistoryRowView({ row: row2, controller }) {
|
|
4954
|
-
const
|
|
4953
|
+
const ui8 = (intent) => applyHistoryUi(controller, intent);
|
|
4955
4954
|
return /* @__PURE__ */ jsx5(
|
|
4956
4955
|
Row2,
|
|
4957
4956
|
{
|
|
@@ -4974,9 +4973,9 @@ function HistoryRowView({ row: row2, controller }) {
|
|
|
4974
4973
|
row2.showTime ? /* @__PURE__ */ jsx5(Text4, { role: "meta", children: row2.time }) : null,
|
|
4975
4974
|
row2.pending ? /* @__PURE__ */ jsx5(HistoryCancelButton, { entryId: row2.cancelId, controller }) : null
|
|
4976
4975
|
] }),
|
|
4977
|
-
onClick: () =>
|
|
4978
|
-
onMouseEnter: () =>
|
|
4979
|
-
onContextMenuAt: (x, y) =>
|
|
4976
|
+
onClick: () => ui8({ kind: "jump", entryId: row2.entryId }),
|
|
4977
|
+
onMouseEnter: () => ui8({ kind: "hover", entryId: row2.entryId }),
|
|
4978
|
+
onContextMenuAt: (x, y) => ui8({ kind: "contextMenu", entryId: row2.entryId, x, y })
|
|
4980
4979
|
}
|
|
4981
4980
|
);
|
|
4982
4981
|
}
|
|
@@ -6262,27 +6261,27 @@ function ColorPanelView({ controller }) {
|
|
|
6262
6261
|
const getSnapshot = useCallback5(() => controller.getRevision(), [controller]);
|
|
6263
6262
|
useSyncExternalStore4(subscribe, getSnapshot, getSnapshot);
|
|
6264
6263
|
const view = colorViewState(controller);
|
|
6265
|
-
const
|
|
6264
|
+
const ui8 = (intent) => applyColorUi(controller, intent);
|
|
6266
6265
|
return /* @__PURE__ */ jsx6(Column4, { className: "xeno-color-panel", children: /* @__PURE__ */ jsxs5(Stack3, { gap: 8, children: [
|
|
6267
6266
|
view.fgBg ? /* @__PURE__ */ jsxs5(Stack3, { direction: "row", pad: "none", children: [
|
|
6268
|
-
/* @__PURE__ */ jsx6(ColorChip, { color: view.hex, label: "Foreground", pressed: view.fgActive, onClick: () =>
|
|
6269
|
-
/* @__PURE__ */ jsx6(IconButton5, { size: "sm", icon: /* @__PURE__ */ jsx6(SwapIcon, {}), label: "Swap FG/BG (X)", onClick: () =>
|
|
6270
|
-
/* @__PURE__ */ jsx6(ColorChip, { color: null, label: "Background", pressed: view.bgActive, onClick: () =>
|
|
6267
|
+
/* @__PURE__ */ jsx6(ColorChip, { color: view.hex, label: "Foreground", pressed: view.fgActive, onClick: () => ui8({ kind: "setChannel", channel: "fg" }) }),
|
|
6268
|
+
/* @__PURE__ */ jsx6(IconButton5, { size: "sm", icon: /* @__PURE__ */ jsx6(SwapIcon, {}), label: "Swap FG/BG (X)", onClick: () => ui8({ kind: "swapChannels" }) }),
|
|
6269
|
+
/* @__PURE__ */ jsx6(ColorChip, { color: null, label: "Background", pressed: view.bgActive, onClick: () => ui8({ kind: "setChannel", channel: "bg" }) })
|
|
6271
6270
|
] }) : null,
|
|
6272
6271
|
/* @__PURE__ */ jsx6(ColorPicker, { controller }),
|
|
6273
6272
|
/* @__PURE__ */ jsxs5(Stack3, { direction: "row", pad: "none", gap: 4, children: [
|
|
6274
|
-
/* @__PURE__ */ jsx6(Select3, { size: "sm", label: "Color model", value: view.space, options: view.spaceOptions, onChange: (v) =>
|
|
6275
|
-
view.isHex ? /* @__PURE__ */ jsx6(Input3, { variant: "mono", label: "Hex", value: view.hex, onChange: (v) =>
|
|
6276
|
-
view.components.map((comp) => /* @__PURE__ */ jsx6(NumberInput, { caption: comp.label, value: comp.value, onChange: (n) =>
|
|
6277
|
-
view.alphaShown ? /* @__PURE__ */ jsx6(NumberInput, { caption: "A", label: "Alpha", min: 0, max: 100, value: view.alphaPercent, onChange: (n) =>
|
|
6278
|
-
/* @__PURE__ */ jsx6(IconButton5, { size: "sm", icon: /* @__PURE__ */ jsx6(EyedropperIcon, {}), label: "Pick from screen", onClick: () =>
|
|
6273
|
+
/* @__PURE__ */ jsx6(Select3, { size: "sm", label: "Color model", value: view.space, options: view.spaceOptions, onChange: (v) => ui8({ kind: "setSpace", space: v }) }),
|
|
6274
|
+
view.isHex ? /* @__PURE__ */ jsx6(Input3, { variant: "mono", label: "Hex", value: view.hex, onChange: (v) => ui8({ kind: "setHex", value: v }), disabled: view.bound }) : null,
|
|
6275
|
+
view.components.map((comp) => /* @__PURE__ */ jsx6(NumberInput, { caption: comp.label, value: comp.value, onChange: (n) => ui8({ kind: "setComponent", index: comp.index, value: n }), disabled: view.bound }, comp.key)),
|
|
6276
|
+
view.alphaShown ? /* @__PURE__ */ jsx6(NumberInput, { caption: "A", label: "Alpha", min: 0, max: 100, value: view.alphaPercent, onChange: (n) => ui8({ kind: "setAlpha", percent: n }), disabled: view.bound }) : null,
|
|
6277
|
+
/* @__PURE__ */ jsx6(IconButton5, { size: "sm", icon: /* @__PURE__ */ jsx6(EyedropperIcon, {}), label: "Pick from screen", onClick: () => ui8({ kind: "eyedropper" }) })
|
|
6279
6278
|
] }),
|
|
6280
6279
|
view.hasTokens ? /* @__PURE__ */ jsx6(Field2, { label: "Token", htmlFor: "xeno-color-token", children: /* @__PURE__ */ jsxs5(Stack3, { direction: "row", pad: "none", gap: 4, children: [
|
|
6281
|
-
/* @__PURE__ */ jsx6(Select3, { size: "sm", label: "Bind token", value: view.boundTokenId, placeholder: "\u2014 raw \u2014", options: view.tokenOptions, onChange: (id) =>
|
|
6282
|
-
view.bound ? /* @__PURE__ */ jsx6(TextButton2, { onClick: () =>
|
|
6280
|
+
/* @__PURE__ */ jsx6(Select3, { size: "sm", label: "Bind token", value: view.boundTokenId, placeholder: "\u2014 raw \u2014", options: view.tokenOptions, onChange: (id) => ui8({ kind: "bindToken", tokenId: id }) }),
|
|
6281
|
+
view.bound ? /* @__PURE__ */ jsx6(TextButton2, { onClick: () => ui8({ kind: "unbindToken" }), children: "Unbind" }) : null
|
|
6283
6282
|
] }) }) : null,
|
|
6284
|
-
/* @__PURE__ */ jsx6(Section2, { title: "Swatches", flush: true, actions: /* @__PURE__ */ jsx6(TextButton2, { onClick: () =>
|
|
6285
|
-
view.hasRecent ? /* @__PURE__ */ jsx6(Section2, { title: "Recent", flush: true, children: /* @__PURE__ */ jsx6(SwatchGrid, { label: "Recent", children: view.recent.map((r) => /* @__PURE__ */ jsx6(ColorChip, { size: "grid", color: r.hex, label: r.hex, onClick: () =>
|
|
6283
|
+
/* @__PURE__ */ jsx6(Section2, { title: "Swatches", flush: true, actions: /* @__PURE__ */ jsx6(TextButton2, { onClick: () => ui8({ kind: "addSwatch" }), children: "+ Save" }), children: /* @__PURE__ */ jsx6(SwatchGrid, { label: "Swatches", children: view.swatches.map((sw) => /* @__PURE__ */ jsx6(ColorChip, { size: "grid", color: sw.hex, label: sw.hex, onClick: () => ui8({ kind: "selectColor", hex: sw.hex }), onContextMenu: () => ui8({ kind: "removeSwatch", hex: sw.hex }) }, sw.key)) }) }),
|
|
6284
|
+
view.hasRecent ? /* @__PURE__ */ jsx6(Section2, { title: "Recent", flush: true, children: /* @__PURE__ */ jsx6(SwatchGrid, { label: "Recent", children: view.recent.map((r) => /* @__PURE__ */ jsx6(ColorChip, { size: "grid", color: r.hex, label: r.hex, onClick: () => ui8({ kind: "selectColor", hex: r.hex }) }, r.key)) }) }) : null
|
|
6286
6285
|
] }) });
|
|
6287
6286
|
}
|
|
6288
6287
|
function ColorPicker({ controller }) {
|
|
@@ -8944,11 +8943,11 @@ var FindController = class {
|
|
|
8944
8943
|
* @param text - The new query text.
|
|
8945
8944
|
* @param immediate - Skip the debounce (a paste, or pressing Enter).
|
|
8946
8945
|
*/
|
|
8947
|
-
setText(
|
|
8948
|
-
if (
|
|
8949
|
-
this.text =
|
|
8946
|
+
setText(text8, immediate = false) {
|
|
8947
|
+
if (text8 === this.text) return;
|
|
8948
|
+
this.text = text8;
|
|
8950
8949
|
this.index = -1;
|
|
8951
|
-
if (
|
|
8950
|
+
if (text8 === "") {
|
|
8952
8951
|
this.clearResults("idle");
|
|
8953
8952
|
this.emitQuery(true);
|
|
8954
8953
|
return;
|
|
@@ -8976,8 +8975,8 @@ var FindController = class {
|
|
|
8976
8975
|
this.notify();
|
|
8977
8976
|
}
|
|
8978
8977
|
/** The replacement text. Never emitted on its own — a replacement is not a search. */
|
|
8979
|
-
setReplaceText(
|
|
8980
|
-
this.replaceText =
|
|
8978
|
+
setReplaceText(text8) {
|
|
8979
|
+
this.replaceText = text8;
|
|
8981
8980
|
this.notify();
|
|
8982
8981
|
}
|
|
8983
8982
|
/** Show or hide the replace row. */
|
|
@@ -9626,7 +9625,7 @@ function findRuntimeComponents(controller) {
|
|
|
9626
9625
|
function FindPanelView({ controller, showResults, placeholder }) {
|
|
9627
9626
|
useSyncExternalStore7(controller.subscribe, controller.getState, controller.getState);
|
|
9628
9627
|
const view = findViewState(controller, { showResults, placeholder });
|
|
9629
|
-
const
|
|
9628
|
+
const ui8 = (intent) => applyFindUi(controller, intent);
|
|
9630
9629
|
const renderRow = (row2) => /* @__PURE__ */ jsx9(
|
|
9631
9630
|
Row3,
|
|
9632
9631
|
{
|
|
@@ -9634,8 +9633,8 @@ function FindPanelView({ controller, showResults, placeholder }) {
|
|
|
9634
9633
|
selected: row2.current,
|
|
9635
9634
|
meta: row2.location,
|
|
9636
9635
|
label: /* @__PURE__ */ jsx9(Highlight, { segments: row2.segments }),
|
|
9637
|
-
onClick: () =>
|
|
9638
|
-
onContextMenuAt: (x, y) =>
|
|
9636
|
+
onClick: () => ui8({ kind: "select", matchId: row2.id }),
|
|
9637
|
+
onContextMenuAt: (x, y) => ui8({ kind: "contextMenu", matchId: row2.id, x, y })
|
|
9639
9638
|
},
|
|
9640
9639
|
row2.id
|
|
9641
9640
|
);
|
|
@@ -9643,11 +9642,11 @@ function FindPanelView({ controller, showResults, placeholder }) {
|
|
|
9643
9642
|
/* @__PURE__ */ jsx9(
|
|
9644
9643
|
Toolbar4,
|
|
9645
9644
|
{
|
|
9646
|
-
left: /* @__PURE__ */ jsx9(SearchField4, { value: view.text, placeholder: view.placeholder, onChange: (value) =>
|
|
9645
|
+
left: /* @__PURE__ */ jsx9(SearchField4, { value: view.text, placeholder: view.placeholder, onChange: (value) => ui8({ kind: "text", value }) }),
|
|
9647
9646
|
right: /* @__PURE__ */ jsxs8(ToolbarGroup2, { end: true, children: [
|
|
9648
|
-
/* @__PURE__ */ jsx9(IconButton6, { label: "Match case", active: view.caseSensitive, icon: /* @__PURE__ */ jsx9(CaseIcon, { size: 12 }), onClick: () =>
|
|
9649
|
-
/* @__PURE__ */ jsx9(IconButton6, { label: "Whole word", active: view.wholeWord, icon: /* @__PURE__ */ jsx9(WordIcon, { size: 12 }), onClick: () =>
|
|
9650
|
-
/* @__PURE__ */ jsx9(IconButton6, { label: "Regular expression", active: view.regex, icon: /* @__PURE__ */ jsx9(RegexIcon, { size: 12 }), onClick: () =>
|
|
9647
|
+
/* @__PURE__ */ jsx9(IconButton6, { label: "Match case", active: view.caseSensitive, icon: /* @__PURE__ */ jsx9(CaseIcon, { size: 12 }), onClick: () => ui8({ kind: "option", option: "caseSensitive" }) }),
|
|
9648
|
+
/* @__PURE__ */ jsx9(IconButton6, { label: "Whole word", active: view.wholeWord, icon: /* @__PURE__ */ jsx9(WordIcon, { size: 12 }), onClick: () => ui8({ kind: "option", option: "wholeWord" }) }),
|
|
9649
|
+
/* @__PURE__ */ jsx9(IconButton6, { label: "Regular expression", active: view.regex, icon: /* @__PURE__ */ jsx9(RegexIcon, { size: 12 }), onClick: () => ui8({ kind: "option", option: "regex" }) })
|
|
9651
9650
|
] })
|
|
9652
9651
|
}
|
|
9653
9652
|
),
|
|
@@ -9662,9 +9661,9 @@ function FindPanelView({ controller, showResults, placeholder }) {
|
|
|
9662
9661
|
view.countShown ? /* @__PURE__ */ jsx9(Text5, { role: "number", children: view.counter }) : null
|
|
9663
9662
|
] }),
|
|
9664
9663
|
right: /* @__PURE__ */ jsxs8(ToolbarGroup2, { end: true, children: [
|
|
9665
|
-
/* @__PURE__ */ jsx9(IconButton6, { label: "Previous match", disabled: !view.hasMatches, icon: /* @__PURE__ */ jsx9(Chevron, { direction: "up", size: 12 }), onClick: () =>
|
|
9666
|
-
/* @__PURE__ */ jsx9(IconButton6, { label: "Next match", disabled: !view.hasMatches, icon: /* @__PURE__ */ jsx9(Chevron, { direction: "down", size: 12 }), onClick: () =>
|
|
9667
|
-
/* @__PURE__ */ jsx9(TextButton3, { onClick: () =>
|
|
9664
|
+
/* @__PURE__ */ jsx9(IconButton6, { label: "Previous match", disabled: !view.hasMatches, icon: /* @__PURE__ */ jsx9(Chevron, { direction: "up", size: 12 }), onClick: () => ui8({ kind: "previous" }) }),
|
|
9665
|
+
/* @__PURE__ */ jsx9(IconButton6, { label: "Next match", disabled: !view.hasMatches, icon: /* @__PURE__ */ jsx9(Chevron, { direction: "down", size: 12 }), onClick: () => ui8({ kind: "next" }) }),
|
|
9666
|
+
/* @__PURE__ */ jsx9(TextButton3, { onClick: () => ui8({ kind: "toggleReplace" }), children: view.replaceLabel })
|
|
9668
9667
|
] })
|
|
9669
9668
|
}
|
|
9670
9669
|
),
|
|
@@ -9672,10 +9671,10 @@ function FindPanelView({ controller, showResults, placeholder }) {
|
|
|
9672
9671
|
view.replaceVisible ? /* @__PURE__ */ jsx9(
|
|
9673
9672
|
Toolbar4,
|
|
9674
9673
|
{
|
|
9675
|
-
left: /* @__PURE__ */ jsx9(SearchField4, { value: view.replaceText, placeholder: "Replace with", onChange: (value) =>
|
|
9674
|
+
left: /* @__PURE__ */ jsx9(SearchField4, { value: view.replaceText, placeholder: "Replace with", onChange: (value) => ui8({ kind: "replaceText", value }) }),
|
|
9676
9675
|
right: /* @__PURE__ */ jsxs8(ToolbarGroup2, { end: true, children: [
|
|
9677
|
-
/* @__PURE__ */ jsx9(TextButton3, { disabled: !view.canReplace, onClick: () =>
|
|
9678
|
-
/* @__PURE__ */ jsx9(TextButton3, { disabled: !view.canReplace, onClick: () =>
|
|
9676
|
+
/* @__PURE__ */ jsx9(TextButton3, { disabled: !view.canReplace, onClick: () => ui8({ kind: "replaceCurrent" }), children: "Replace" }),
|
|
9677
|
+
/* @__PURE__ */ jsx9(TextButton3, { disabled: !view.canReplace, onClick: () => ui8({ kind: "replaceAll" }), children: view.allLabel })
|
|
9679
9678
|
] })
|
|
9680
9679
|
}
|
|
9681
9680
|
) : null,
|
|
@@ -10574,37 +10573,37 @@ import { jsx as jsx10, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
|
10574
10573
|
function CommentsPanelView({ controller, ...options }) {
|
|
10575
10574
|
useSyncExternalStore8(controller.subscribe, controller.getState, controller.getState);
|
|
10576
10575
|
const view = commentsViewState(controller, options);
|
|
10577
|
-
const
|
|
10578
|
-
const card = (t) => /* @__PURE__ */ jsxs9(ThreadCard, { active: t.active, resolved: t.resolved, onContextMenuAt: (x, y) =>
|
|
10576
|
+
const ui8 = (intent) => applyCommentsUi(controller, intent);
|
|
10577
|
+
const card = (t) => /* @__PURE__ */ jsxs9(ThreadCard, { active: t.active, resolved: t.resolved, onContextMenuAt: (x, y) => ui8({ kind: "contextMenu", id: t.id, x, y }), children: [
|
|
10579
10578
|
/* @__PURE__ */ jsxs9(Stack4, { direction: "row", gap: 4, pad: "none", children: [
|
|
10580
10579
|
t.hasAnchorBadge ? /* @__PURE__ */ jsx10(Badge6, { tone: t.anchorTone, title: t.anchorTitle, children: t.anchorLabel }) : null,
|
|
10581
10580
|
t.resolved ? /* @__PURE__ */ jsx10(Badge6, { children: "resolved" }) : null,
|
|
10582
10581
|
/* @__PURE__ */ jsx10(Text6, { role: "caption", children: t.age })
|
|
10583
10582
|
] }),
|
|
10584
|
-
t.hasQuote ? /* @__PURE__ */ jsx10(Quote, { orphaned: t.orphaned, onActivate: () =>
|
|
10583
|
+
t.hasQuote ? /* @__PURE__ */ jsx10(Quote, { orphaned: t.orphaned, onActivate: () => ui8({ kind: "activate", id: t.id }), children: t.quote }) : null,
|
|
10585
10584
|
t.messages.map((m) => /* @__PURE__ */ jsx10(Message, { author: m.author, age: m.age, edited: m.edited, children: m.body }, m.id)),
|
|
10586
|
-
t.hasReactions ? /* @__PURE__ */ jsx10(Stack4, { direction: "row", gap: 4, pad: "none", children: t.reactions.map((r) => /* @__PURE__ */ jsx10(TextButton4, { onClick: () =>
|
|
10585
|
+
t.hasReactions ? /* @__PURE__ */ jsx10(Stack4, { direction: "row", gap: 4, pad: "none", children: t.reactions.map((r) => /* @__PURE__ */ jsx10(TextButton4, { onClick: () => ui8({ kind: "react", id: r.threadId, emoji: r.emoji, on: r.reactTo }), children: r.label }, r.emoji)) }) : null,
|
|
10587
10586
|
t.replying ? /* @__PURE__ */ jsxs9(Stack4, { direction: "row", gap: 4, pad: "none", children: [
|
|
10588
|
-
/* @__PURE__ */ jsx10(Input4, { value: t.replyDraft, placeholder: "Reply", autoFocus: true, label: "Reply", onChange: (value) =>
|
|
10589
|
-
/* @__PURE__ */ jsx10(TextButton4, { onClick: () =>
|
|
10587
|
+
/* @__PURE__ */ jsx10(Input4, { value: t.replyDraft, placeholder: "Reply", autoFocus: true, label: "Reply", onChange: (value) => ui8({ kind: "replyDraft", value }), onKeyDown: (e) => ui8({ kind: "replyKey", id: t.id, key: e.key, shift: e.shiftKey }) }),
|
|
10588
|
+
/* @__PURE__ */ jsx10(TextButton4, { onClick: () => ui8({ kind: "reply", id: t.id }), children: "Send" })
|
|
10590
10589
|
] }) : null,
|
|
10591
10590
|
t.idle ? /* @__PURE__ */ jsxs9(Stack4, { direction: "row", gap: 6, pad: "none", children: [
|
|
10592
|
-
/* @__PURE__ */ jsx10(TextButton4, { onClick: () =>
|
|
10593
|
-
/* @__PURE__ */ jsx10(TextButton4, { onClick: () =>
|
|
10594
|
-
/* @__PURE__ */ jsx10(TextButton4, { onClick: () =>
|
|
10591
|
+
/* @__PURE__ */ jsx10(TextButton4, { onClick: () => ui8({ kind: "startReply", id: t.id }), children: "Reply" }),
|
|
10592
|
+
/* @__PURE__ */ jsx10(TextButton4, { onClick: () => ui8({ kind: "resolve", id: t.id, resolved: t.resolveTo }), children: t.resolveLabel }),
|
|
10593
|
+
/* @__PURE__ */ jsx10(TextButton4, { onClick: () => ui8({ kind: "remove", id: t.id }), children: "Delete" })
|
|
10595
10594
|
] }) : null
|
|
10596
10595
|
] }, t.id);
|
|
10597
10596
|
return /* @__PURE__ */ jsxs9(Column6, { children: [
|
|
10598
10597
|
/* @__PURE__ */ jsx10(
|
|
10599
10598
|
Toolbar5,
|
|
10600
10599
|
{
|
|
10601
|
-
left: /* @__PURE__ */ jsx10(SegmentedControl2, { label: "Show", options: view.shows, value: view.show, onChange: (show) =>
|
|
10602
|
-
right: /* @__PURE__ */ jsx10(ToolbarGroup3, { end: true, children: /* @__PURE__ */ jsx10(SegmentedControl2, { label: "Sort", options: view.sorts, value: view.sort, onChange: (sort) =>
|
|
10600
|
+
left: /* @__PURE__ */ jsx10(SegmentedControl2, { label: "Show", options: view.shows, value: view.show, onChange: (show) => ui8({ kind: "show", show }) }),
|
|
10601
|
+
right: /* @__PURE__ */ jsx10(ToolbarGroup3, { end: true, children: /* @__PURE__ */ jsx10(SegmentedControl2, { label: "Sort", options: view.sorts, value: view.sort, onChange: (sort) => ui8({ kind: "sort", sort }) }) })
|
|
10603
10602
|
}
|
|
10604
10603
|
),
|
|
10605
10604
|
view.orphanedNotice ? /* @__PURE__ */ jsxs9(Note, { children: [
|
|
10606
10605
|
view.orphanedNotice,
|
|
10607
|
-
view.orphanedHidden ? /* @__PURE__ */ jsx10(TextButton4, { onClick: () =>
|
|
10606
|
+
view.orphanedHidden ? /* @__PURE__ */ jsx10(TextButton4, { onClick: () => ui8({ kind: "showOrphaned" }), children: "Show" }) : null
|
|
10608
10607
|
] }) : null,
|
|
10609
10608
|
/* @__PURE__ */ jsxs9(ScrollArea5, { children: [
|
|
10610
10609
|
view.filteredEmpty ? /* @__PURE__ */ jsx10(EmptyState6, { title: "Nothing matches this filter", hint: view.filteredHint }) : null,
|
|
@@ -10613,8 +10612,8 @@ function CommentsPanelView({ controller, ...options }) {
|
|
|
10613
10612
|
view.hasResolved ? /* @__PURE__ */ jsx10(Section4, { title: view.resolvedTitle, flush: true, children: view.resolved.map(card) }) : null
|
|
10614
10613
|
] }),
|
|
10615
10614
|
/* @__PURE__ */ jsxs9(Stack4, { gap: 2, pad: "gutter", className: "xeno-comments-composer", children: [
|
|
10616
|
-
/* @__PURE__ */ jsx10(TextArea2, { value: view.draft, placeholder: view.placeholder, disabled: view.composerDisabled, rows: 2, label: "New comment", onChange: (value) =>
|
|
10617
|
-
/* @__PURE__ */ jsx10(Toolbar5, { divided: false, right: /* @__PURE__ */ jsx10(ToolbarGroup3, { end: true, children: /* @__PURE__ */ jsx10(TextButton4, { strong: true, disabled: view.commentDisabled, onClick: () =>
|
|
10615
|
+
/* @__PURE__ */ jsx10(TextArea2, { value: view.draft, placeholder: view.placeholder, disabled: view.composerDisabled, rows: 2, label: "New comment", onChange: (value) => ui8({ kind: "draft", value }), onKeyDown: (e) => ui8({ kind: "draftKey", key: e.key, ctrl: e.ctrlKey, meta: e.metaKey }) }),
|
|
10616
|
+
/* @__PURE__ */ jsx10(Toolbar5, { divided: false, right: /* @__PURE__ */ jsx10(ToolbarGroup3, { end: true, children: /* @__PURE__ */ jsx10(TextButton4, { strong: true, disabled: view.commentDisabled, onClick: () => ui8({ kind: "create" }), children: "Comment" }) }) })
|
|
10618
10617
|
] }),
|
|
10619
10618
|
/* @__PURE__ */ jsx10(StatusBar6, { left: view.countLabel, right: view.staleLabel })
|
|
10620
10619
|
] });
|
|
@@ -12318,6 +12317,8 @@ var TreeController = class {
|
|
|
12318
12317
|
mode;
|
|
12319
12318
|
renaming = null;
|
|
12320
12319
|
drag = null;
|
|
12320
|
+
/** The scroller's measured viewport — the view state windows the rows from it (`tree/Scroller` reports it). */
|
|
12321
|
+
viewport = { height: 0, scrollTop: 0 };
|
|
12321
12322
|
/** Newest outstanding load request PER NODE. Anything else that arrives is stale. */
|
|
12322
12323
|
outstanding = /* @__PURE__ */ new Map();
|
|
12323
12324
|
/** Type-ahead buffer + the time it was last touched. */
|
|
@@ -12367,6 +12368,20 @@ var TreeController = class {
|
|
|
12367
12368
|
this.rowCache = null;
|
|
12368
12369
|
for (const listener of this.listeners) listener();
|
|
12369
12370
|
}
|
|
12371
|
+
/* ── Viewport ──────────────────────────────────────────────────────────── */
|
|
12372
|
+
/** The scroller reports its viewport; the view state windows the rows from it. */
|
|
12373
|
+
setViewport(height, scrollTop) {
|
|
12374
|
+
if (this.viewport.height === height && this.viewport.scrollTop === scrollTop) return;
|
|
12375
|
+
this.viewport = { height, scrollTop };
|
|
12376
|
+
this.notify();
|
|
12377
|
+
}
|
|
12378
|
+
getViewport() {
|
|
12379
|
+
return this.viewport;
|
|
12380
|
+
}
|
|
12381
|
+
/** The fixed row height the virtualizer and the drop resolver share. */
|
|
12382
|
+
getRowHeight() {
|
|
12383
|
+
return this.rowHeight;
|
|
12384
|
+
}
|
|
12370
12385
|
/* ── Rows ──────────────────────────────────────────────────────────────── */
|
|
12371
12386
|
/** The visible rows, flattened through the shared engine. */
|
|
12372
12387
|
rows() {
|
|
@@ -12740,12 +12755,12 @@ var TreeController = class {
|
|
|
12740
12755
|
}
|
|
12741
12756
|
if (event.key.length === 1 && !event.ctrlKey && !event.metaKey && !event.altKey) {
|
|
12742
12757
|
const fresh = now - this.typeAhead.at > this.typeAheadMs;
|
|
12743
|
-
const
|
|
12744
|
-
this.typeAhead = { text:
|
|
12758
|
+
const text8 = (fresh ? "" : this.typeAhead.text) + event.key.toLowerCase();
|
|
12759
|
+
this.typeAhead = { text: text8, at: now };
|
|
12745
12760
|
const from = fresh ? current : current + 1;
|
|
12746
12761
|
for (let i = 0; i < rows.length; i += 1) {
|
|
12747
12762
|
const candidate = rows[(from + i) % rows.length];
|
|
12748
|
-
if (candidate.node.label.toLowerCase().startsWith(
|
|
12763
|
+
if (candidate.node.label.toLowerCase().startsWith(text8)) {
|
|
12749
12764
|
this.focusedId = candidate.id;
|
|
12750
12765
|
this.select([candidate.id]);
|
|
12751
12766
|
return true;
|
|
@@ -12771,9 +12786,9 @@ var TreeController = class {
|
|
|
12771
12786
|
return true;
|
|
12772
12787
|
}
|
|
12773
12788
|
/** Update the rename draft. */
|
|
12774
|
-
updateRenameDraft(
|
|
12789
|
+
updateRenameDraft(text8) {
|
|
12775
12790
|
if (!this.renaming) return;
|
|
12776
|
-
this.renaming = { ...this.renaming, draft:
|
|
12791
|
+
this.renaming = { ...this.renaming, draft: text8 };
|
|
12777
12792
|
this.notify();
|
|
12778
12793
|
}
|
|
12779
12794
|
/**
|
|
@@ -13310,331 +13325,474 @@ var treeManifest = {
|
|
|
13310
13325
|
};
|
|
13311
13326
|
|
|
13312
13327
|
// src/edit/tree/react/TreePanelView.tsx
|
|
13313
|
-
import { useCallback as useCallback8, useEffect as useEffect8, useRef as useRef9,
|
|
13328
|
+
import { useCallback as useCallback8, useEffect as useEffect8, useRef as useRef9, useSyncExternalStore as useSyncExternalStore10 } from "react";
|
|
13314
13329
|
import {
|
|
13315
13330
|
Badge as Badge7,
|
|
13331
|
+
Column as Column7,
|
|
13316
13332
|
EmptyState as EmptyState8,
|
|
13317
13333
|
ErrorState,
|
|
13318
13334
|
IconButton as IconButton7,
|
|
13335
|
+
Input as Input5,
|
|
13319
13336
|
LoadingState,
|
|
13320
13337
|
Row as Row4,
|
|
13338
|
+
RowList as RowList4,
|
|
13321
13339
|
ScrollArea as ScrollArea6,
|
|
13322
13340
|
SearchField as SearchField5,
|
|
13323
13341
|
StatusBar as StatusBar8,
|
|
13342
|
+
Text as Text7,
|
|
13343
|
+
TextButton as TextButton5,
|
|
13324
13344
|
Toolbar as Toolbar7,
|
|
13325
|
-
ToolbarGroup as ToolbarGroup5
|
|
13345
|
+
ToolbarGroup as ToolbarGroup5,
|
|
13346
|
+
VirtualWindow as VirtualWindow3
|
|
13326
13347
|
} from "@xenosystem/components/chrome";
|
|
13348
|
+
|
|
13349
|
+
// src/edit/tree/declaration.ts
|
|
13327
13350
|
import { computeWindow as computeWindow3 } from "@xenosystem/tree-core";
|
|
13328
|
-
|
|
13329
|
-
function
|
|
13330
|
-
|
|
13331
|
-
|
|
13332
|
-
indentPx = 14,
|
|
13333
|
-
overscan = 6,
|
|
13334
|
-
showSearch = true,
|
|
13335
|
-
openOn = "double",
|
|
13336
|
-
columns,
|
|
13337
|
-
emptyHint
|
|
13338
|
-
}) {
|
|
13339
|
-
const state = useSyncExternalStore10(controller.subscribe, controller.getState, controller.getState);
|
|
13340
|
-
const scrollRef = useRef9(null);
|
|
13341
|
-
const [viewport, setViewport] = useState2({ height: 0, scrollTop: 0 });
|
|
13342
|
-
useEffect8(() => {
|
|
13343
|
-
const element = scrollRef.current;
|
|
13344
|
-
if (!element || typeof ResizeObserver === "undefined") return;
|
|
13345
|
-
const observer = new ResizeObserver(() => {
|
|
13346
|
-
setViewport((v) => ({ ...v, height: element.clientHeight }));
|
|
13347
|
-
});
|
|
13348
|
-
observer.observe(element);
|
|
13349
|
-
setViewport((v) => ({ ...v, height: element.clientHeight }));
|
|
13350
|
-
return () => observer.disconnect();
|
|
13351
|
-
}, []);
|
|
13352
|
-
const onScroll = useCallback8((event) => {
|
|
13353
|
-
const el = event.currentTarget;
|
|
13354
|
-
setViewport((v) => ({ ...v, scrollTop: el.scrollTop }));
|
|
13355
|
-
}, []);
|
|
13351
|
+
var iconHalf = (icon) => icon.kind === "text" ? { iconName: null, iconText: icon.value } : { iconName: icon.name, iconText: null };
|
|
13352
|
+
function treeViewState(c, options = {}) {
|
|
13353
|
+
const { overscan = 6, showSearch = true, columns, emptyHint } = options;
|
|
13354
|
+
const state = c.getState();
|
|
13356
13355
|
const source = state.source;
|
|
13357
13356
|
const sourceState = source?.sourceState ?? "idle";
|
|
13358
|
-
const
|
|
13359
|
-
|
|
13360
|
-
|
|
13357
|
+
const rowHeight = c.getRowHeight();
|
|
13358
|
+
const viewport = c.getViewport();
|
|
13359
|
+
const noSource = !source || sourceState === "idle";
|
|
13360
|
+
const loading = !noSource && sourceState === "loading" && state.rows.length === 0;
|
|
13361
|
+
const failed = !noSource && (sourceState === "error" || sourceState === "denied");
|
|
13362
|
+
const denied = sourceState === "denied";
|
|
13363
|
+
const bare = !noSource && !loading && !failed && state.rows.length === 0;
|
|
13364
|
+
const noMatches = bare && state.filter !== "";
|
|
13365
|
+
const emptyTree = bare && state.filter === "";
|
|
13366
|
+
const listShown = !noSource && !loading && !failed && state.rows.length > 0;
|
|
13367
|
+
const window_ = computeWindow3({
|
|
13368
|
+
scrollTop: viewport.scrollTop,
|
|
13369
|
+
viewportHeight: viewport.height || rowHeight * 24,
|
|
13370
|
+
rowHeight,
|
|
13371
|
+
rowCount: state.rows.length,
|
|
13372
|
+
overscan
|
|
13373
|
+
});
|
|
13374
|
+
const drag = state.drag;
|
|
13375
|
+
const renaming = state.renaming;
|
|
13376
|
+
const rows = listShown ? state.rows.slice(window_.startIndex, window_.endIndex).map((row2) => {
|
|
13377
|
+
const node = row2.node;
|
|
13378
|
+
const drop = drag?.targetId === row2.id ? drag : null;
|
|
13379
|
+
const error = node.error;
|
|
13380
|
+
const chipLoading = row2.container && row2.childState === "loading";
|
|
13381
|
+
const chipError = row2.container && !chipLoading && row2.childState === "error";
|
|
13382
|
+
const chipLoadMore = row2.container && !chipLoading && !chipError && !!node.hasMore && row2.expanded;
|
|
13383
|
+
const chipTruncated = row2.container && !chipLoading && !chipError && !chipLoadMore && node.truncatedAt !== void 0;
|
|
13384
|
+
const chipEmpty = row2.container && !chipLoading && !chipError && !chipLoadMore && !chipTruncated && row2.expanded && isEmptyContainer(node);
|
|
13385
|
+
return {
|
|
13386
|
+
id: row2.id,
|
|
13387
|
+
label: node.label,
|
|
13388
|
+
depth: row2.depth,
|
|
13389
|
+
level: row2.depth + 1,
|
|
13390
|
+
height: rowHeight,
|
|
13391
|
+
selected: state.selection.includes(row2.id),
|
|
13392
|
+
disabled: node.caps?.select === false,
|
|
13393
|
+
expanded: row2.container ? row2.expanded : void 0,
|
|
13394
|
+
dropHint: drop?.position ?? null,
|
|
13395
|
+
dropTitle: drop?.reason,
|
|
13396
|
+
renaming: renaming?.id === row2.id,
|
|
13397
|
+
draft: renaming?.id === row2.id ? renaming.draft : "",
|
|
13398
|
+
...iconHalf(node.icon ?? defaultIconFor(node.kind)),
|
|
13399
|
+
chipLoading,
|
|
13400
|
+
chipError,
|
|
13401
|
+
// The host's own sentence — never a regex over a message to guess the cause.
|
|
13402
|
+
chipErrorText: error?.code === "denied" ? "no access" : error?.code ?? "failed",
|
|
13403
|
+
chipLoadMore,
|
|
13404
|
+
chipTruncated,
|
|
13405
|
+
chipTruncatedText: `first ${node.truncatedAt ?? 0}`,
|
|
13406
|
+
chipEmpty,
|
|
13407
|
+
columns: (columns ?? []).map((key) => ({ key, text: node.columns?.[key] ?? "" })),
|
|
13408
|
+
glyphs: (node.glyphs ?? []).map((g) => ({ key: g.id, title: g.title, ...iconHalf(g.icon) })),
|
|
13409
|
+
badges: (node.badges ?? []).map((b) => ({ key: b.id, tone: b.tone, text: b.text })),
|
|
13410
|
+
actions: (node.actions ?? []).map((a) => ({ key: a.id, rowId: row2.id, actionId: a.id, label: a.label, disabled: !!a.disabled, ...iconHalf(a.icon) }))
|
|
13411
|
+
};
|
|
13412
|
+
}) : [];
|
|
13413
|
+
const count = state.rows.length;
|
|
13414
|
+
return {
|
|
13415
|
+
searchShown: showSearch,
|
|
13416
|
+
filter: state.filter,
|
|
13417
|
+
noSource,
|
|
13418
|
+
noSourceHint: emptyHint ?? "Connect a source to browse it.",
|
|
13419
|
+
loading,
|
|
13420
|
+
loadingLabel: source?.sourceMessage ?? "Loading\u2026",
|
|
13421
|
+
failed,
|
|
13422
|
+
failedTitle: denied ? "Access not granted" : "Could not read this source",
|
|
13423
|
+
// The HOST's sentence, verbatim. The panel never composes error prose.
|
|
13424
|
+
failedMessage: source?.sourceMessage,
|
|
13425
|
+
retryLabel: denied ? "Grant access" : "Retry",
|
|
13426
|
+
denied,
|
|
13427
|
+
noMatches,
|
|
13428
|
+
noMatchesHint: `Nothing matches \u201C${state.filter}\u201D.`,
|
|
13429
|
+
emptyTree,
|
|
13430
|
+
emptyHint: emptyHint ?? source?.sourceMessage ?? "This source has no items yet.",
|
|
13431
|
+
listShown,
|
|
13432
|
+
totalHeight: window_.totalHeight,
|
|
13433
|
+
offsetTop: window_.offsetTop,
|
|
13434
|
+
rows,
|
|
13435
|
+
countLabel: `${count} item${count === 1 ? "" : "s"}`,
|
|
13436
|
+
selectedLabel: state.selection.length > 0 ? `${state.selection.length} selected` : void 0
|
|
13437
|
+
};
|
|
13438
|
+
}
|
|
13439
|
+
function applyTreeUi(c, intent, options = {}) {
|
|
13440
|
+
switch (intent.kind) {
|
|
13441
|
+
case "filter":
|
|
13442
|
+
c.setFilter(intent.value);
|
|
13443
|
+
break;
|
|
13444
|
+
case "expandAll":
|
|
13445
|
+
c.expandAll();
|
|
13446
|
+
break;
|
|
13447
|
+
case "collapseAll":
|
|
13448
|
+
c.collapseAll();
|
|
13449
|
+
break;
|
|
13450
|
+
case "refresh":
|
|
13451
|
+
c.refresh();
|
|
13452
|
+
break;
|
|
13453
|
+
case "retry": {
|
|
13454
|
+
if (c.getState().source?.sourceState === "denied") c.requestConsent(void 0, "source denied");
|
|
13455
|
+
else c.refresh();
|
|
13456
|
+
break;
|
|
13361
13457
|
}
|
|
13362
|
-
|
|
13363
|
-
|
|
13458
|
+
case "toggleExpanded": {
|
|
13459
|
+
const row2 = c.getState().rows.find((r) => r.id === intent.id);
|
|
13460
|
+
if (row2) c.setExpanded(intent.id, !row2.expanded);
|
|
13461
|
+
break;
|
|
13364
13462
|
}
|
|
13365
|
-
|
|
13366
|
-
|
|
13367
|
-
|
|
13368
|
-
|
|
13369
|
-
title: sourceState === "denied" ? "Access not granted" : "Could not read this source",
|
|
13370
|
-
message: source.sourceMessage,
|
|
13371
|
-
onRetry: sourceState === "denied" ? () => controller.requestConsent(void 0, "source denied") : () => controller.refresh(),
|
|
13372
|
-
retryLabel: sourceState === "denied" ? "Grant access" : "Retry"
|
|
13373
|
-
}
|
|
13374
|
-
);
|
|
13463
|
+
case "click": {
|
|
13464
|
+
c.select([intent.id], { toggle: !!intent.ctrlKey || !!intent.metaKey, range: !!intent.shiftKey });
|
|
13465
|
+
if ((options.openOn ?? "double") === "single") c.open(intent.id, { alt: !!intent.altKey });
|
|
13466
|
+
break;
|
|
13375
13467
|
}
|
|
13376
|
-
|
|
13377
|
-
|
|
13378
|
-
|
|
13379
|
-
|
|
13380
|
-
|
|
13381
|
-
|
|
13382
|
-
|
|
13383
|
-
);
|
|
13468
|
+
case "doubleClick":
|
|
13469
|
+
if ((options.openOn ?? "double") === "double") c.open(intent.id);
|
|
13470
|
+
break;
|
|
13471
|
+
case "contextMenu": {
|
|
13472
|
+
const state = c.getState();
|
|
13473
|
+
c.requestContextMenu(state.selection.includes(intent.id) ? state.selection : [intent.id], intent.x, intent.y);
|
|
13474
|
+
break;
|
|
13384
13475
|
}
|
|
13385
|
-
|
|
13386
|
-
|
|
13387
|
-
|
|
13388
|
-
|
|
13389
|
-
|
|
13390
|
-
|
|
13391
|
-
|
|
13392
|
-
|
|
13393
|
-
|
|
13394
|
-
|
|
13476
|
+
case "loadMore":
|
|
13477
|
+
c.loadMore(intent.id);
|
|
13478
|
+
break;
|
|
13479
|
+
case "action":
|
|
13480
|
+
c.runAction(intent.id, intent.actionId);
|
|
13481
|
+
break;
|
|
13482
|
+
case "renameDraft":
|
|
13483
|
+
c.updateRenameDraft(intent.value);
|
|
13484
|
+
break;
|
|
13485
|
+
case "renameKey": {
|
|
13486
|
+
if (intent.key === "Enter") c.commitRename();
|
|
13487
|
+
else if (intent.key === "Escape") c.cancelRename();
|
|
13488
|
+
break;
|
|
13489
|
+
}
|
|
13490
|
+
case "commitRename":
|
|
13491
|
+
c.commitRename();
|
|
13492
|
+
break;
|
|
13493
|
+
}
|
|
13494
|
+
}
|
|
13495
|
+
var treeViewManifest = {
|
|
13496
|
+
id: treeManifest.id,
|
|
13497
|
+
version: "1.0.0",
|
|
13498
|
+
title: "Tree",
|
|
13499
|
+
category: "edit",
|
|
13500
|
+
layout: { slot: "side" },
|
|
13501
|
+
inputs: [{ id: "view", type: "object", label: "View state", description: "The TreeViewModel the runtime derives from the controller on every draw." }],
|
|
13502
|
+
outputs: [{ id: "ui", type: "object", label: "UI intent", description: "{ kind, id?, value?, key?, actionId?, x?, y?, ctrlKey?, metaKey?, shiftKey?, altKey? } \u2014 applied by the runtime to the controller." }],
|
|
13503
|
+
commands: []
|
|
13504
|
+
};
|
|
13505
|
+
var EMPTY7 = {
|
|
13506
|
+
searchShown: true,
|
|
13507
|
+
filter: "",
|
|
13508
|
+
noSource: true,
|
|
13509
|
+
noSourceHint: "Connect a source to browse it.",
|
|
13510
|
+
loading: false,
|
|
13511
|
+
loadingLabel: "Loading\u2026",
|
|
13512
|
+
failed: false,
|
|
13513
|
+
failedTitle: "",
|
|
13514
|
+
retryLabel: "Retry",
|
|
13515
|
+
denied: false,
|
|
13516
|
+
noMatches: false,
|
|
13517
|
+
noMatchesHint: "",
|
|
13518
|
+
emptyTree: false,
|
|
13519
|
+
emptyHint: "",
|
|
13520
|
+
listShown: false,
|
|
13521
|
+
totalHeight: 0,
|
|
13522
|
+
offsetTop: 0,
|
|
13523
|
+
rows: [],
|
|
13524
|
+
countLabel: "0 items"
|
|
13525
|
+
};
|
|
13526
|
+
var BEHAVIOURS7 = {
|
|
13527
|
+
"edit/treePanelView": (inputs) => inputs.view ?? EMPTY7
|
|
13528
|
+
};
|
|
13529
|
+
var text7 = (b) => ({ component: "text", props: { text: b } });
|
|
13530
|
+
var ui7 = (kind, fields = {}) => ({ emit: "ui", value: { object: { kind: { value: kind }, ...fields } } });
|
|
13531
|
+
var nodeIcon = () => ({
|
|
13532
|
+
component: "fragment",
|
|
13533
|
+
children: [
|
|
13534
|
+
{ component: "icons/TreeKind", when: { item: "iconName" }, props: { name: { item: "iconName" } } },
|
|
13535
|
+
{ component: "chrome/Text", when: { item: "iconText" }, props: { role: { value: "caption" } }, children: [text7({ item: "iconText" })] }
|
|
13536
|
+
]
|
|
13537
|
+
});
|
|
13538
|
+
var TREE_DECLARATION = {
|
|
13539
|
+
format: "xeno.block@1",
|
|
13540
|
+
manifest: treeViewManifest,
|
|
13541
|
+
behaviour: "edit/treePanelView",
|
|
13542
|
+
composition: {
|
|
13543
|
+
component: "chrome/Column",
|
|
13544
|
+
children: [
|
|
13395
13545
|
{
|
|
13396
|
-
|
|
13397
|
-
|
|
13398
|
-
|
|
13399
|
-
|
|
13400
|
-
|
|
13401
|
-
|
|
13402
|
-
|
|
13403
|
-
|
|
13404
|
-
|
|
13546
|
+
component: "chrome/Toolbar",
|
|
13547
|
+
props: {
|
|
13548
|
+
left: { node: { component: "chrome/SearchField", when: { input: "view.searchShown" }, props: { value: { input: "view.filter" }, placeholder: { value: "Filter\u2026" } }, on: { onChange: ui7("filter", { value: { arg: "" } }) } } },
|
|
13549
|
+
right: {
|
|
13550
|
+
node: {
|
|
13551
|
+
component: "chrome/ToolbarGroup",
|
|
13552
|
+
props: { end: { value: true } },
|
|
13553
|
+
children: [
|
|
13554
|
+
{ component: "chrome/IconButton", props: { icon: { node: { component: "icons/Expand" } }, label: { value: "Expand all" } }, on: { onClick: ui7("expandAll") } },
|
|
13555
|
+
{ component: "chrome/IconButton", props: { icon: { node: { component: "icons/Collapse" } }, label: { value: "Collapse all" } }, on: { onClick: ui7("collapseAll") } },
|
|
13556
|
+
{ component: "chrome/IconButton", props: { icon: { node: { component: "icons/Refresh" } }, label: { value: "Refresh" } }, on: { onClick: ui7("refresh") } }
|
|
13557
|
+
]
|
|
13558
|
+
}
|
|
13405
13559
|
}
|
|
13406
|
-
}
|
|
13407
|
-
|
|
13408
|
-
|
|
13560
|
+
}
|
|
13561
|
+
},
|
|
13562
|
+
{ component: "chrome/EmptyState", when: { input: "view.noSource" }, props: { title: { value: "No source" }, hint: { input: "view.noSourceHint" } } },
|
|
13563
|
+
{ component: "chrome/LoadingState", when: { input: "view.loading" }, props: { label: { input: "view.loadingLabel" } } },
|
|
13564
|
+
{ component: "chrome/ErrorState", when: { input: "view.failed" }, props: { title: { input: "view.failedTitle" }, message: { input: "view.failedMessage" }, retryLabel: { input: "view.retryLabel" } }, on: { onRetry: ui7("retry") } },
|
|
13565
|
+
{ component: "chrome/EmptyState", when: { input: "view.noMatches" }, props: { title: { value: "No matches" }, hint: { input: "view.noMatchesHint" } } },
|
|
13566
|
+
{ component: "chrome/EmptyState", when: { input: "view.emptyTree" }, props: { title: { value: "Nothing here" }, hint: { input: "view.emptyHint" } } },
|
|
13567
|
+
{
|
|
13568
|
+
component: "tree/Scroller",
|
|
13569
|
+
when: { input: "view.listShown" },
|
|
13570
|
+
children: [
|
|
13409
13571
|
{
|
|
13410
|
-
|
|
13411
|
-
|
|
13412
|
-
|
|
13413
|
-
|
|
13414
|
-
|
|
13415
|
-
|
|
13416
|
-
|
|
13417
|
-
|
|
13418
|
-
|
|
13419
|
-
|
|
13572
|
+
component: "chrome/RowList",
|
|
13573
|
+
props: { role: { value: "tree" }, "aria-label": { value: "Tree" }, "aria-multiselectable": { value: true } },
|
|
13574
|
+
children: [
|
|
13575
|
+
{
|
|
13576
|
+
component: "chrome/VirtualWindow",
|
|
13577
|
+
props: { totalHeight: { input: "view.totalHeight" }, offsetTop: { input: "view.offsetTop" } },
|
|
13578
|
+
children: [
|
|
13579
|
+
{
|
|
13580
|
+
component: "chrome/Row",
|
|
13581
|
+
each: { input: "view.rows", key: "id" },
|
|
13582
|
+
props: {
|
|
13583
|
+
"data-tree-row": { item: "id" },
|
|
13584
|
+
"aria-level": { item: "level" },
|
|
13585
|
+
height: { item: "height" },
|
|
13586
|
+
depth: { item: "depth" },
|
|
13587
|
+
selected: { item: "selected" },
|
|
13588
|
+
disabled: { item: "disabled" },
|
|
13589
|
+
expanded: { item: "expanded" },
|
|
13590
|
+
dropHint: { item: "dropHint" },
|
|
13591
|
+
title: { item: "dropTitle" },
|
|
13592
|
+
icon: { node: nodeIcon() },
|
|
13593
|
+
label: {
|
|
13594
|
+
node: {
|
|
13595
|
+
component: "fragment",
|
|
13596
|
+
children: [
|
|
13597
|
+
{ component: "chrome/Input", when: { item: "renaming" }, props: { autoFocus: { value: true }, value: { item: "draft" }, label: { value: "Name" } }, on: { onChange: ui7("renameDraft", { value: { arg: "" } }), onBlur: ui7("commitRename"), onKeyDown: ui7("renameKey", { key: { arg: "key" } }) } },
|
|
13598
|
+
{ component: "text", when: { not: { item: "renaming" } }, props: { text: { item: "label" } } }
|
|
13599
|
+
]
|
|
13600
|
+
}
|
|
13601
|
+
},
|
|
13602
|
+
meta: {
|
|
13603
|
+
node: {
|
|
13604
|
+
component: "fragment",
|
|
13605
|
+
children: [
|
|
13606
|
+
{ component: "chrome/Text", when: { item: "chipLoading" }, props: { role: { value: "caption" } }, children: [text7({ value: "loading\u2026" })] },
|
|
13607
|
+
{ component: "chrome/Badge", when: { item: "chipError" }, props: { tone: { value: "error" } }, children: [text7({ item: "chipErrorText" })] },
|
|
13608
|
+
{ component: "chrome/TextButton", when: { item: "chipLoadMore" }, children: [text7({ value: "load more\u2026" })], on: { onClick: ui7("loadMore", { id: { item: "id" } }) } },
|
|
13609
|
+
{ component: "chrome/Badge", when: { item: "chipTruncated" }, props: { tone: { value: "warning" } }, children: [text7({ item: "chipTruncatedText" })] },
|
|
13610
|
+
{ component: "chrome/Text", when: { item: "chipEmpty" }, props: { role: { value: "caption" } }, children: [text7({ value: "empty" })] }
|
|
13611
|
+
]
|
|
13612
|
+
}
|
|
13613
|
+
},
|
|
13614
|
+
trailing: {
|
|
13615
|
+
node: {
|
|
13616
|
+
component: "fragment",
|
|
13617
|
+
children: [
|
|
13618
|
+
{ component: "chrome/Text", each: { item: "columns", key: "key" }, props: { role: { value: "number" } }, children: [text7({ item: "text" })] },
|
|
13619
|
+
{ component: "chrome/Text", each: { item: "glyphs", key: "key" }, props: { role: { value: "meta" }, title: { item: "title" } }, children: [nodeIcon()] },
|
|
13620
|
+
{ component: "chrome/Badge", each: { item: "badges", key: "key" }, props: { tone: { item: "tone" } }, children: [text7({ item: "text" })] },
|
|
13621
|
+
{ component: "chrome/IconButton", each: { item: "actions", key: "key" }, props: { size: { value: "sm" }, icon: { node: nodeIcon() }, label: { item: "label" }, disabled: { item: "disabled" } }, on: { onClick: ui7("action", { id: { item: "rowId" }, actionId: { item: "actionId" } }) } }
|
|
13622
|
+
]
|
|
13623
|
+
}
|
|
13624
|
+
}
|
|
13625
|
+
},
|
|
13626
|
+
on: {
|
|
13627
|
+
onExpandedChange: ui7("toggleExpanded", { id: { item: "id" } }),
|
|
13628
|
+
onClick: ui7("click", { id: { item: "id" }, ctrlKey: { arg: "ctrlKey" }, metaKey: { arg: "metaKey" }, shiftKey: { arg: "shiftKey" }, altKey: { arg: "altKey" } }),
|
|
13629
|
+
onDoubleClick: ui7("doubleClick", { id: { item: "id" } }),
|
|
13630
|
+
onContextMenuAt: ui7("contextMenu", { id: { item: "id" }, x: { arg: "" }, y: { arg: "", index: 1 } })
|
|
13631
|
+
}
|
|
13632
|
+
}
|
|
13633
|
+
]
|
|
13634
|
+
}
|
|
13635
|
+
]
|
|
13636
|
+
}
|
|
13637
|
+
]
|
|
13638
|
+
},
|
|
13639
|
+
{
|
|
13640
|
+
component: "chrome/StatusBar",
|
|
13641
|
+
props: {
|
|
13642
|
+
left: { node: { component: "chrome/Text", props: { role: { value: "number" } }, children: [text7({ input: "view.countLabel" })] } },
|
|
13643
|
+
right: { node: { component: "chrome/Text", when: { input: "view.selectedLabel" }, props: { role: { value: "meta" } }, children: [text7({ input: "view.selectedLabel" })] } }
|
|
13644
|
+
}
|
|
13420
13645
|
}
|
|
13421
|
-
|
|
13422
|
-
}
|
|
13423
|
-
|
|
13646
|
+
]
|
|
13647
|
+
}
|
|
13648
|
+
};
|
|
13649
|
+
|
|
13650
|
+
// src/edit/tree/react/TreePanelView.tsx
|
|
13651
|
+
import { Fragment as Fragment8, jsx as jsx12, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
13652
|
+
var DRAG_THRESHOLD2 = 4;
|
|
13653
|
+
function TreePanelView({ controller, ...options }) {
|
|
13654
|
+
useSyncExternalStore10(controller.subscribe, controller.getState, controller.getState);
|
|
13655
|
+
const view = treeViewState(controller, options);
|
|
13656
|
+
const ui8 = (intent) => applyTreeUi(controller, intent, options);
|
|
13657
|
+
const icon = (name, textValue) => /* @__PURE__ */ jsxs11(Fragment8, { children: [
|
|
13658
|
+
name ? /* @__PURE__ */ jsx12(TreeIcon, { name }) : null,
|
|
13659
|
+
textValue ? /* @__PURE__ */ jsx12(Text7, { role: "caption", children: textValue }) : null
|
|
13660
|
+
] });
|
|
13661
|
+
const row2 = (r) => /* @__PURE__ */ jsx12(
|
|
13662
|
+
Row4,
|
|
13663
|
+
{
|
|
13664
|
+
"data-tree-row": r.id,
|
|
13665
|
+
"aria-level": r.level,
|
|
13666
|
+
height: r.height,
|
|
13667
|
+
depth: r.depth,
|
|
13668
|
+
selected: r.selected,
|
|
13669
|
+
disabled: r.disabled,
|
|
13670
|
+
expanded: r.expanded,
|
|
13671
|
+
dropHint: r.dropHint,
|
|
13672
|
+
title: r.dropTitle,
|
|
13673
|
+
icon: icon(r.iconName, r.iconText),
|
|
13674
|
+
label: /* @__PURE__ */ jsxs11(Fragment8, { children: [
|
|
13675
|
+
r.renaming ? /* @__PURE__ */ jsx12(Input5, { autoFocus: true, value: r.draft, label: "Name", onChange: (value) => ui8({ kind: "renameDraft", value }), onBlur: () => ui8({ kind: "commitRename" }), onKeyDown: (e) => ui8({ kind: "renameKey", key: e.key }) }) : null,
|
|
13676
|
+
!r.renaming ? r.label : null
|
|
13677
|
+
] }),
|
|
13678
|
+
meta: /* @__PURE__ */ jsxs11(Fragment8, { children: [
|
|
13679
|
+
r.chipLoading ? /* @__PURE__ */ jsx12(Text7, { role: "caption", children: "loading\u2026" }) : null,
|
|
13680
|
+
r.chipError ? /* @__PURE__ */ jsx12(Badge7, { tone: "error", children: r.chipErrorText }) : null,
|
|
13681
|
+
r.chipLoadMore ? /* @__PURE__ */ jsx12(TextButton5, { onClick: () => ui8({ kind: "loadMore", id: r.id }), children: "load more\u2026" }) : null,
|
|
13682
|
+
r.chipTruncated ? /* @__PURE__ */ jsx12(Badge7, { tone: "warning", children: r.chipTruncatedText }) : null,
|
|
13683
|
+
r.chipEmpty ? /* @__PURE__ */ jsx12(Text7, { role: "caption", children: "empty" }) : null
|
|
13684
|
+
] }),
|
|
13685
|
+
trailing: /* @__PURE__ */ jsxs11(Fragment8, { children: [
|
|
13686
|
+
r.columns.map((c) => /* @__PURE__ */ jsx12(Text7, { role: "number", children: c.text }, c.key)),
|
|
13687
|
+
r.glyphs.map((g) => /* @__PURE__ */ jsx12(Text7, { role: "meta", title: g.title, children: icon(g.iconName, g.iconText) }, g.key)),
|
|
13688
|
+
r.badges.map((b) => /* @__PURE__ */ jsx12(Badge7, { tone: b.tone, children: b.text }, b.key)),
|
|
13689
|
+
r.actions.map((a) => /* @__PURE__ */ jsx12(IconButton7, { size: "sm", icon: icon(a.iconName, a.iconText), label: a.label, disabled: a.disabled, onClick: () => ui8({ kind: "action", id: a.rowId, actionId: a.actionId }) }, a.key))
|
|
13690
|
+
] }),
|
|
13691
|
+
onExpandedChange: () => ui8({ kind: "toggleExpanded", id: r.id }),
|
|
13692
|
+
onClick: (e) => ui8({ kind: "click", id: r.id, ctrlKey: e.ctrlKey, metaKey: e.metaKey, shiftKey: e.shiftKey, altKey: e.altKey }),
|
|
13693
|
+
onDoubleClick: () => ui8({ kind: "doubleClick", id: r.id }),
|
|
13694
|
+
onContextMenuAt: (x, y) => ui8({ kind: "contextMenu", id: r.id, x, y })
|
|
13695
|
+
},
|
|
13696
|
+
r.id
|
|
13697
|
+
);
|
|
13698
|
+
return /* @__PURE__ */ jsxs11(Column7, { children: [
|
|
13424
13699
|
/* @__PURE__ */ jsx12(
|
|
13425
13700
|
Toolbar7,
|
|
13426
13701
|
{
|
|
13427
|
-
left:
|
|
13428
|
-
SearchField5,
|
|
13429
|
-
{
|
|
13430
|
-
value: state.filter,
|
|
13431
|
-
onChange: (term) => controller.setFilter(term),
|
|
13432
|
-
placeholder: "Filter\u2026"
|
|
13433
|
-
}
|
|
13434
|
-
) : void 0,
|
|
13702
|
+
left: view.searchShown ? /* @__PURE__ */ jsx12(SearchField5, { value: view.filter, placeholder: "Filter\u2026", onChange: (value) => ui8({ kind: "filter", value }) }) : null,
|
|
13435
13703
|
right: /* @__PURE__ */ jsxs11(ToolbarGroup5, { end: true, children: [
|
|
13436
|
-
/* @__PURE__ */ jsx12(IconButton7, { icon: /* @__PURE__ */ jsx12(ExpandGlyph, {}), label: "Expand all", onClick: () =>
|
|
13437
|
-
/* @__PURE__ */ jsx12(
|
|
13438
|
-
|
|
13439
|
-
{
|
|
13440
|
-
icon: /* @__PURE__ */ jsx12(CollapseGlyph, {}),
|
|
13441
|
-
label: "Collapse all",
|
|
13442
|
-
onClick: () => controller.collapseAll()
|
|
13443
|
-
}
|
|
13444
|
-
),
|
|
13445
|
-
/* @__PURE__ */ jsx12(IconButton7, { icon: /* @__PURE__ */ jsx12(RefreshGlyph, {}), label: "Refresh", onClick: () => controller.refresh() })
|
|
13704
|
+
/* @__PURE__ */ jsx12(IconButton7, { icon: /* @__PURE__ */ jsx12(ExpandGlyph, {}), label: "Expand all", onClick: () => ui8({ kind: "expandAll" }) }),
|
|
13705
|
+
/* @__PURE__ */ jsx12(IconButton7, { icon: /* @__PURE__ */ jsx12(CollapseGlyph, {}), label: "Collapse all", onClick: () => ui8({ kind: "collapseAll" }) }),
|
|
13706
|
+
/* @__PURE__ */ jsx12(IconButton7, { icon: /* @__PURE__ */ jsx12(RefreshGlyph, {}), label: "Refresh", onClick: () => ui8({ kind: "refresh" }) })
|
|
13446
13707
|
] })
|
|
13447
13708
|
}
|
|
13448
13709
|
),
|
|
13449
|
-
|
|
13450
|
-
/* @__PURE__ */ jsx12(
|
|
13451
|
-
|
|
13452
|
-
|
|
13453
|
-
|
|
13454
|
-
|
|
13455
|
-
|
|
13456
|
-
)
|
|
13710
|
+
view.noSource ? /* @__PURE__ */ jsx12(EmptyState8, { title: "No source", hint: view.noSourceHint }) : null,
|
|
13711
|
+
view.loading ? /* @__PURE__ */ jsx12(LoadingState, { label: view.loadingLabel }) : null,
|
|
13712
|
+
view.failed ? /* @__PURE__ */ jsx12(ErrorState, { title: view.failedTitle, message: view.failedMessage, retryLabel: view.retryLabel, onRetry: () => ui8({ kind: "retry" }) }) : null,
|
|
13713
|
+
view.noMatches ? /* @__PURE__ */ jsx12(EmptyState8, { title: "No matches", hint: view.noMatchesHint }) : null,
|
|
13714
|
+
view.emptyTree ? /* @__PURE__ */ jsx12(EmptyState8, { title: "Nothing here", hint: view.emptyHint }) : null,
|
|
13715
|
+
view.listShown ? /* @__PURE__ */ jsx12(TreeScroller, { controller, children: /* @__PURE__ */ jsx12(RowList4, { role: "tree", "aria-label": "Tree", "aria-multiselectable": true, children: /* @__PURE__ */ jsx12(VirtualWindow3, { totalHeight: view.totalHeight, offsetTop: view.offsetTop, children: view.rows.map(row2) }) }) }) : null,
|
|
13716
|
+
/* @__PURE__ */ jsx12(StatusBar8, { left: /* @__PURE__ */ jsx12(Text7, { role: "number", children: view.countLabel }), right: view.selectedLabel ? /* @__PURE__ */ jsx12(Text7, { role: "meta", children: view.selectedLabel }) : null })
|
|
13457
13717
|
] });
|
|
13458
13718
|
}
|
|
13459
|
-
function
|
|
13460
|
-
|
|
13461
|
-
|
|
13462
|
-
|
|
13463
|
-
|
|
13464
|
-
|
|
13465
|
-
|
|
13466
|
-
|
|
13467
|
-
|
|
13468
|
-
|
|
13469
|
-
|
|
13470
|
-
|
|
13471
|
-
|
|
13472
|
-
const
|
|
13473
|
-
|
|
13474
|
-
|
|
13475
|
-
|
|
13476
|
-
|
|
13477
|
-
|
|
13478
|
-
|
|
13479
|
-
|
|
13480
|
-
|
|
13481
|
-
|
|
13482
|
-
|
|
13483
|
-
|
|
13484
|
-
|
|
13485
|
-
|
|
13486
|
-
|
|
13487
|
-
|
|
13488
|
-
|
|
13489
|
-
|
|
13490
|
-
|
|
13491
|
-
|
|
13492
|
-
children: /* @__PURE__ */ jsx12(ChevronGlyph, { size: 9 })
|
|
13493
|
-
}
|
|
13494
|
-
) : (
|
|
13495
|
-
// A leaf still reserves the twisty column, so labels stay in ONE column across mixed rows.
|
|
13496
|
-
/* @__PURE__ */ jsx12("span", { style: { width: 12, flex: "0 0 auto" } })
|
|
13719
|
+
function TreeScroller({ controller, children }) {
|
|
13720
|
+
const scrollRef = useRef9(null);
|
|
13721
|
+
const pressRef = useRef9(null);
|
|
13722
|
+
useEffect8(() => {
|
|
13723
|
+
const el = scrollRef.current;
|
|
13724
|
+
if (!el) return;
|
|
13725
|
+
controller.setViewport(el.clientHeight, el.scrollTop);
|
|
13726
|
+
const RO = globalThis.ResizeObserver;
|
|
13727
|
+
if (!RO) return;
|
|
13728
|
+
const ro = new RO(() => controller.setViewport(el.clientHeight, el.scrollTop));
|
|
13729
|
+
ro.observe(el);
|
|
13730
|
+
return () => ro.disconnect();
|
|
13731
|
+
}, [controller]);
|
|
13732
|
+
const onScroll = useCallback8((e) => controller.setViewport(e.currentTarget.clientHeight, e.currentTarget.scrollTop), [controller]);
|
|
13733
|
+
const rowFromPoint = useCallback8((clientX, clientY) => {
|
|
13734
|
+
const el = document.elementFromPoint(clientX, clientY);
|
|
13735
|
+
const rowEl = el?.closest?.("[data-tree-row]");
|
|
13736
|
+
const id = rowEl?.getAttribute("data-tree-row");
|
|
13737
|
+
if (!rowEl || !id) return null;
|
|
13738
|
+
return { id, offsetY: clientY - rowEl.getBoundingClientRect().top };
|
|
13739
|
+
}, []);
|
|
13740
|
+
const onPointerDown = useCallback8(
|
|
13741
|
+
(e) => {
|
|
13742
|
+
if (e.button !== 0) return;
|
|
13743
|
+
const target = e.target;
|
|
13744
|
+
if (target?.closest?.("button,input")) return;
|
|
13745
|
+
const id = target?.closest?.("[data-tree-row]")?.getAttribute("data-tree-row");
|
|
13746
|
+
if (!id) return;
|
|
13747
|
+
const selection = controller.getState().selection;
|
|
13748
|
+
pressRef.current = { ids: selection.includes(id) ? selection : [id], x: e.clientX, y: e.clientY, dragging: false };
|
|
13749
|
+
e.currentTarget.setPointerCapture(e.pointerId);
|
|
13750
|
+
},
|
|
13751
|
+
[controller]
|
|
13497
13752
|
);
|
|
13498
|
-
|
|
13499
|
-
|
|
13500
|
-
|
|
13501
|
-
|
|
13502
|
-
|
|
13503
|
-
|
|
13504
|
-
|
|
13505
|
-
|
|
13506
|
-
|
|
13507
|
-
|
|
13508
|
-
|
|
13509
|
-
|
|
13510
|
-
|
|
13511
|
-
{
|
|
13512
|
-
role: "treeitem",
|
|
13513
|
-
"aria-expanded": row2.container ? row2.expanded : void 0,
|
|
13514
|
-
"aria-level": row2.depth + 1,
|
|
13515
|
-
selected,
|
|
13516
|
-
disabled: node.caps?.select === false,
|
|
13517
|
-
depth: 0,
|
|
13518
|
-
style: { height: rowHeight, paddingLeft: 6 + row2.depth * indentPx },
|
|
13519
|
-
onClick: (e) => {
|
|
13520
|
-
controller.select([row2.id], {
|
|
13521
|
-
toggle: e.ctrlKey || e.metaKey,
|
|
13522
|
-
range: e.shiftKey
|
|
13523
|
-
});
|
|
13524
|
-
if (openOn === "single") controller.open(row2.id, { alt: e.altKey });
|
|
13525
|
-
},
|
|
13526
|
-
onDoubleClick: () => {
|
|
13527
|
-
if (openOn === "double") controller.open(row2.id);
|
|
13528
|
-
},
|
|
13529
|
-
onContextMenu: (e) => {
|
|
13530
|
-
e.preventDefault();
|
|
13531
|
-
controller.requestContextMenu(selected ? state.selection : [row2.id], e.clientX, e.clientY);
|
|
13532
|
-
},
|
|
13533
|
-
onPointerDown: (e) => {
|
|
13534
|
-
if (e.button !== 0) return;
|
|
13535
|
-
controller.beginDrag(selected ? state.selection : [row2.id]);
|
|
13536
|
-
},
|
|
13537
|
-
onPointerMove: (e) => {
|
|
13538
|
-
if (!state.drag) return;
|
|
13539
|
-
const rect = e.currentTarget.getBoundingClientRect();
|
|
13540
|
-
controller.dragOver(row2.id, e.clientY - rect.top);
|
|
13541
|
-
},
|
|
13542
|
-
onPointerUp: () => {
|
|
13543
|
-
if (state.drag) controller.endDrag();
|
|
13544
|
-
},
|
|
13545
|
-
icon: /* @__PURE__ */ jsxs11(Fragment8, { children: [
|
|
13546
|
-
twisty,
|
|
13547
|
-
/* @__PURE__ */ jsx12(NodeIcon, { icon: node.icon ?? defaultIconFor(node.kind) })
|
|
13548
|
-
] }),
|
|
13549
|
-
label: renaming ? /* @__PURE__ */ jsx12(
|
|
13550
|
-
"input",
|
|
13551
|
-
{
|
|
13552
|
-
autoFocus: true,
|
|
13553
|
-
value: renaming.draft,
|
|
13554
|
-
onChange: (e) => controller.updateRenameDraft(e.target.value),
|
|
13555
|
-
onBlur: () => controller.commitRename(),
|
|
13556
|
-
onFocus: (e) => e.currentTarget.select(),
|
|
13557
|
-
onClick: (e) => e.stopPropagation(),
|
|
13558
|
-
onKeyDown: (e) => {
|
|
13559
|
-
e.stopPropagation();
|
|
13560
|
-
if (e.key === "Enter") controller.commitRename();
|
|
13561
|
-
else if (e.key === "Escape") controller.cancelRename();
|
|
13562
|
-
},
|
|
13563
|
-
style: {
|
|
13564
|
-
width: "100%",
|
|
13565
|
-
border: "none",
|
|
13566
|
-
outline: "none",
|
|
13567
|
-
background: "var(--xeno-canvas)",
|
|
13568
|
-
color: "inherit",
|
|
13569
|
-
font: "inherit",
|
|
13570
|
-
padding: 0
|
|
13571
|
-
}
|
|
13572
|
-
}
|
|
13573
|
-
) : node.label,
|
|
13574
|
-
meta: /* @__PURE__ */ jsx12(ChildStateChip, { row: row2, controller }),
|
|
13575
|
-
trailing: /* @__PURE__ */ jsxs11(Fragment8, { children: [
|
|
13576
|
-
columns?.map((columnId) => /* @__PURE__ */ jsx12("span", { style: { opacity: 0.7, fontVariantNumeric: "tabular-nums" }, children: node.columns?.[columnId] ?? "" }, columnId)),
|
|
13577
|
-
node.glyphs?.map((glyph) => /* @__PURE__ */ jsx12("span", { title: glyph.title, style: { display: "flex", opacity: 0.7 }, children: /* @__PURE__ */ jsx12(NodeIcon, { icon: glyph.icon }) }, glyph.id)),
|
|
13578
|
-
node.badges?.map((badge) => (
|
|
13579
|
-
// Opaque: the host formatted the text, the panel only places it.
|
|
13580
|
-
/* @__PURE__ */ jsx12(Badge7, { tone: badge.tone, className: badge.title ? void 0 : void 0, children: badge.text }, badge.id)
|
|
13581
|
-
)),
|
|
13582
|
-
node.actions?.map((action) => /* @__PURE__ */ jsx12(
|
|
13583
|
-
IconButton7,
|
|
13584
|
-
{
|
|
13585
|
-
size: "sm",
|
|
13586
|
-
icon: /* @__PURE__ */ jsx12(NodeIcon, { icon: action.icon }),
|
|
13587
|
-
label: action.label,
|
|
13588
|
-
disabled: action.disabled,
|
|
13589
|
-
onClick: () => controller.runAction(row2.id, action.id)
|
|
13590
|
-
},
|
|
13591
|
-
action.id
|
|
13592
|
-
))
|
|
13593
|
-
] })
|
|
13594
|
-
}
|
|
13595
|
-
)
|
|
13596
|
-
}
|
|
13753
|
+
const onPointerMove = useCallback8(
|
|
13754
|
+
(e) => {
|
|
13755
|
+
const press = pressRef.current;
|
|
13756
|
+
if (!press) return;
|
|
13757
|
+
if (!press.dragging) {
|
|
13758
|
+
if (Math.abs(e.clientX - press.x) + Math.abs(e.clientY - press.y) < DRAG_THRESHOLD2) return;
|
|
13759
|
+
press.dragging = true;
|
|
13760
|
+
controller.beginDrag(press.ids);
|
|
13761
|
+
}
|
|
13762
|
+
const hit = rowFromPoint(e.clientX, e.clientY);
|
|
13763
|
+
if (hit) controller.dragOver(hit.id, hit.offsetY);
|
|
13764
|
+
},
|
|
13765
|
+
[controller, rowFromPoint]
|
|
13597
13766
|
);
|
|
13598
|
-
|
|
13599
|
-
|
|
13600
|
-
|
|
13601
|
-
|
|
13602
|
-
|
|
13603
|
-
|
|
13604
|
-
|
|
13605
|
-
return /* @__PURE__ */ jsx12("span", { style: { opacity: 0.5, fontSize: 9 }, children: "loading\u2026" });
|
|
13606
|
-
}
|
|
13607
|
-
if (row2.childState === "error") {
|
|
13608
|
-
const error = row2.node.error;
|
|
13609
|
-
return /* @__PURE__ */ jsx12(Badge7, { tone: "error", children: error?.code === "denied" ? "no access" : error?.code ?? "failed" });
|
|
13610
|
-
}
|
|
13611
|
-
if (row2.node.hasMore && row2.expanded) {
|
|
13612
|
-
return /* @__PURE__ */ jsx12(
|
|
13613
|
-
"span",
|
|
13614
|
-
{
|
|
13615
|
-
role: "button",
|
|
13616
|
-
onClick: (e) => {
|
|
13617
|
-
e.stopPropagation();
|
|
13618
|
-
controller.loadMore(row2.id);
|
|
13619
|
-
},
|
|
13620
|
-
style: { cursor: "pointer", opacity: 0.7, fontSize: 9 },
|
|
13621
|
-
children: "load more\u2026"
|
|
13767
|
+
const onPointerUp = useCallback8(
|
|
13768
|
+
(e) => {
|
|
13769
|
+
const press = pressRef.current;
|
|
13770
|
+
pressRef.current = null;
|
|
13771
|
+
try {
|
|
13772
|
+
e.currentTarget.releasePointerCapture(e.pointerId);
|
|
13773
|
+
} catch {
|
|
13622
13774
|
}
|
|
13623
|
-
|
|
13624
|
-
|
|
13625
|
-
|
|
13626
|
-
|
|
13627
|
-
|
|
13628
|
-
|
|
13629
|
-
|
|
13630
|
-
|
|
13631
|
-
|
|
13775
|
+
if (press?.dragging) controller.endDrag();
|
|
13776
|
+
},
|
|
13777
|
+
[controller]
|
|
13778
|
+
);
|
|
13779
|
+
const onKeyDown = useCallback8(
|
|
13780
|
+
(e) => {
|
|
13781
|
+
if (controller.getState().renaming) return;
|
|
13782
|
+
if (controller.handleKey({ key: e.key, shiftKey: e.shiftKey, ctrlKey: e.ctrlKey, metaKey: e.metaKey, altKey: e.altKey })) {
|
|
13783
|
+
e.preventDefault();
|
|
13784
|
+
e.stopPropagation();
|
|
13785
|
+
}
|
|
13786
|
+
},
|
|
13787
|
+
[controller]
|
|
13788
|
+
);
|
|
13789
|
+
return /* @__PURE__ */ jsx12(ScrollArea6, { ref: scrollRef, onScroll, onKeyDown, onPointerDown, onPointerMove, onPointerUp, tabIndex: 0, children });
|
|
13632
13790
|
}
|
|
13633
|
-
|
|
13634
|
-
|
|
13635
|
-
|
|
13636
|
-
|
|
13637
|
-
|
|
13791
|
+
var TREE_RUNTIME_UNITS = ["tree/Scroller"];
|
|
13792
|
+
function treeRuntimeComponents(controller) {
|
|
13793
|
+
return {
|
|
13794
|
+
"tree/Scroller": ({ children }) => /* @__PURE__ */ jsx12(TreeScroller, { controller, children })
|
|
13795
|
+
};
|
|
13638
13796
|
}
|
|
13639
13797
|
|
|
13640
13798
|
// src/edit/tree/panel.ts
|
|
@@ -13895,11 +14053,15 @@ export {
|
|
|
13895
14053
|
NODEGRAPH_PANEL_ID,
|
|
13896
14054
|
NodeGraphPanelView,
|
|
13897
14055
|
SPACE_LABEL,
|
|
14056
|
+
BEHAVIOURS7 as TREE_BEHAVIOURS,
|
|
14057
|
+
TREE_DECLARATION,
|
|
13898
14058
|
TREE_PANEL_ID,
|
|
14059
|
+
TREE_RUNTIME_UNITS,
|
|
13899
14060
|
Thumbnail,
|
|
13900
14061
|
TreeController,
|
|
13901
14062
|
TreeIcon,
|
|
13902
14063
|
TreePanelView,
|
|
14064
|
+
TreeScroller,
|
|
13903
14065
|
VIEWPORT_PANEL_ID,
|
|
13904
14066
|
VIEWPORT_SLOTS,
|
|
13905
14067
|
VIEW_STATE_OPS,
|
|
@@ -13920,6 +14082,7 @@ export {
|
|
|
13920
14082
|
applyLayersUi,
|
|
13921
14083
|
applyPrecision,
|
|
13922
14084
|
applyTangentDrag,
|
|
14085
|
+
applyTreeUi,
|
|
13923
14086
|
ariaSliderProps,
|
|
13924
14087
|
boxesIntersect,
|
|
13925
14088
|
canConnect,
|
|
@@ -14081,6 +14244,9 @@ export {
|
|
|
14081
14244
|
totalCount,
|
|
14082
14245
|
treeManifest,
|
|
14083
14246
|
treePanel,
|
|
14247
|
+
treeRuntimeComponents,
|
|
14248
|
+
treeViewManifest,
|
|
14249
|
+
treeViewState,
|
|
14084
14250
|
usesLogScale,
|
|
14085
14251
|
valueExtent,
|
|
14086
14252
|
valueToPosition,
|