@xenosystem/blocks 0.12.1 → 0.12.3
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/auth/index.d.ts +2 -2
- package/dist/edit/index.d.ts +163 -7
- package/dist/edit/index.js +376 -86
- package/package.json +3 -3
package/dist/auth/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import * as
|
|
1
|
+
import * as React from 'react';
|
|
2
2
|
import { ReactNode } from 'react';
|
|
3
3
|
import { PanelModule, PanelManifest, BlockDeclaration } from '@xenosystem/block-sdk';
|
|
4
4
|
import { PanelTone } from '@xenosystem/components/chrome';
|
|
@@ -314,7 +314,7 @@ interface AuthGateViewProps {
|
|
|
314
314
|
heroSrc?: string;
|
|
315
315
|
now?: () => number;
|
|
316
316
|
}
|
|
317
|
-
declare function AuthGateView$1({ controller, productName, children, heroSrc, now }: AuthGateViewProps):
|
|
317
|
+
declare function AuthGateView$1({ controller, productName, children, heroSrc, now }: AuthGateViewProps): React.JSX.Element;
|
|
318
318
|
|
|
319
319
|
/**
|
|
320
320
|
* The auth gate AS A DECLARATION — the first block written the way `xeno-apps/SPEC.md` §8d says every
|
package/dist/edit/index.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { PanelHost, PanelModule, PanelManifest } from '@xenosystem/block-sdk';
|
|
1
|
+
import { PanelHost, PanelModule, PanelManifest, BlockDeclaration } from '@xenosystem/block-sdk';
|
|
2
2
|
import { FlatRow as FlatRow$1, DropTarget, ThrottleClock, VirtualWindow, DropPosition } from '@xenosystem/tree-core';
|
|
3
3
|
export { DropPosition, DropTarget } from '@xenosystem/tree-core';
|
|
4
|
+
import * as React from 'react';
|
|
4
5
|
import { ReactElement, ReactNode } from 'react';
|
|
5
6
|
import { XenoTimebase, XenoTick } from '@xenosystem/time-core';
|
|
6
7
|
|
|
@@ -1360,7 +1361,14 @@ declare class InspectorPanelController {
|
|
|
1360
1361
|
* components cannot cross a sandbox RPC boundary, so a sandboxed host simply cannot supply them and
|
|
1361
1362
|
* `type:'custom'` fields degrade to their JSON representation (union spec §1.1).
|
|
1362
1363
|
*/
|
|
1363
|
-
|
|
1364
|
+
interface CreateInspectorPanelOptions extends InspectorPanelControllerOptions {
|
|
1365
|
+
/**
|
|
1366
|
+
* Draw the panel yourself — a host that mounts the block AS ITS DECLARATION renders
|
|
1367
|
+
* `INSPECTOR_DECLARATION` from `inspectorViewState(controller)` with `inspectorRuntimeComponents(controller)`
|
|
1368
|
+
* in its registry and applies `ui` intents with `applyInspectorUi`. Default: the code view.
|
|
1369
|
+
*/
|
|
1370
|
+
render?: (root: HTMLElement, controller: InspectorPanelController) => () => void;
|
|
1371
|
+
}
|
|
1364
1372
|
/**
|
|
1365
1373
|
* Build the Inspector panel module.
|
|
1366
1374
|
*
|
|
@@ -1469,6 +1477,149 @@ declare function nudgeValue(current: number, direction: number, options: Numeric
|
|
|
1469
1477
|
/** ARIA slider attributes for a numeric field (Sound ships the only accessible fields today). */
|
|
1470
1478
|
declare function ariaSliderProps(field: XenoInspectorField, value: number | null): Record<string, string | number | undefined>;
|
|
1471
1479
|
|
|
1480
|
+
/**
|
|
1481
|
+
* The inspector AS A DECLARATION — the fifth block written the §8d way (auth gate, agent, account,
|
|
1482
|
+
* transport, inspector), and the first whose rows carry a runtime-bound unit.
|
|
1483
|
+
*
|
|
1484
|
+
* Presentation contract: input `view` (an {@link InspectorViewState} the runtime derives from the
|
|
1485
|
+
* controller on every draw — sections already projected, every row flag already decided), output
|
|
1486
|
+
* `ui` (an {@link InspectorUiIntent}) applied by the runtime to the controller's own methods. The
|
|
1487
|
+
* declaration composes the SHELL: search and target chip, the multi-select banner, sections with
|
|
1488
|
+
* their enable switch / badge / actions / add menu, one `Field` row per property with the keyframe
|
|
1489
|
+
* cluster leading and easing / chip / bind-token / reset trailing, the empty state.
|
|
1490
|
+
*
|
|
1491
|
+
* What a declaration cannot hold is the CELL: scrub gestures on an axis label, select-on-focus,
|
|
1492
|
+
* wheel and arrow nudges, a draft that commits on blur. That is `inspector/FieldWidget`, a unit the
|
|
1493
|
+
* runtime registers bound to its controller (see {@link inspectorRuntimeComponents}) — the same
|
|
1494
|
+
* shape as `slot`: the declaration names it and binds `field: { item: '' }`; the runtime supplies it.
|
|
1495
|
+
*
|
|
1496
|
+
* The code view (`InspectorPanelView`) draws the same model; the test holds the two byte-identical.
|
|
1497
|
+
*/
|
|
1498
|
+
|
|
1499
|
+
/** One projected row — the field plus every flag the row's chrome reads, decided by the runtime. */
|
|
1500
|
+
interface InspectorViewField {
|
|
1501
|
+
id: string;
|
|
1502
|
+
sectionId: string;
|
|
1503
|
+
label: string;
|
|
1504
|
+
title: string;
|
|
1505
|
+
focused: boolean;
|
|
1506
|
+
bound: boolean;
|
|
1507
|
+
unbound: boolean;
|
|
1508
|
+
tokenLabel?: string;
|
|
1509
|
+
tokenTitle?: string;
|
|
1510
|
+
showKeyframes: boolean;
|
|
1511
|
+
animated: boolean;
|
|
1512
|
+
onKeyframe: boolean;
|
|
1513
|
+
prevDisabled: boolean;
|
|
1514
|
+
nextDisabled: boolean;
|
|
1515
|
+
keyframeLabel: string;
|
|
1516
|
+
keyframeOp: 'add' | 'remove';
|
|
1517
|
+
showEasing: boolean;
|
|
1518
|
+
easing: string;
|
|
1519
|
+
easingOptions: {
|
|
1520
|
+
value: string;
|
|
1521
|
+
label: string;
|
|
1522
|
+
}[];
|
|
1523
|
+
keyframeChip: string;
|
|
1524
|
+
showToken: boolean;
|
|
1525
|
+
tokenActionLabel: string;
|
|
1526
|
+
showReset: boolean;
|
|
1527
|
+
showInfoNote: boolean;
|
|
1528
|
+
infoNote?: string;
|
|
1529
|
+
/** The field record itself — what `inspector/FieldWidget` renders. */
|
|
1530
|
+
field: XenoInspectorField;
|
|
1531
|
+
}
|
|
1532
|
+
interface InspectorViewSection {
|
|
1533
|
+
id: string;
|
|
1534
|
+
title: string;
|
|
1535
|
+
collapsible: boolean;
|
|
1536
|
+
collapsed: boolean;
|
|
1537
|
+
hasEnabled: boolean;
|
|
1538
|
+
enabled?: boolean;
|
|
1539
|
+
badge?: string;
|
|
1540
|
+
actions: {
|
|
1541
|
+
id: string;
|
|
1542
|
+
sectionId: string;
|
|
1543
|
+
label: string;
|
|
1544
|
+
glyph: string;
|
|
1545
|
+
disabled?: boolean;
|
|
1546
|
+
}[];
|
|
1547
|
+
hasAddMenu: boolean;
|
|
1548
|
+
hasActions: boolean;
|
|
1549
|
+
addLabel: string;
|
|
1550
|
+
addOptions: {
|
|
1551
|
+
value: string;
|
|
1552
|
+
label: string;
|
|
1553
|
+
disabled?: boolean;
|
|
1554
|
+
group?: string;
|
|
1555
|
+
}[];
|
|
1556
|
+
showEmptyHint: boolean;
|
|
1557
|
+
emptyHint?: string;
|
|
1558
|
+
labelWidth: number;
|
|
1559
|
+
fields: InspectorViewField[];
|
|
1560
|
+
}
|
|
1561
|
+
/** What the runtime pushes on `view`. */
|
|
1562
|
+
interface InspectorViewState {
|
|
1563
|
+
searchShown: boolean;
|
|
1564
|
+
filter: string;
|
|
1565
|
+
hasTarget: boolean;
|
|
1566
|
+
targetLabel: string;
|
|
1567
|
+
multi: boolean;
|
|
1568
|
+
banner: string;
|
|
1569
|
+
sections: InspectorViewSection[];
|
|
1570
|
+
empty: boolean;
|
|
1571
|
+
emptyTitle: string;
|
|
1572
|
+
}
|
|
1573
|
+
type InspectorUiIntent = {
|
|
1574
|
+
kind: 'filter';
|
|
1575
|
+
value: string;
|
|
1576
|
+
} | {
|
|
1577
|
+
kind: 'toggleSectionCollapsed';
|
|
1578
|
+
sectionId: string;
|
|
1579
|
+
} | {
|
|
1580
|
+
kind: 'toggleSectionEnabled';
|
|
1581
|
+
sectionId: string;
|
|
1582
|
+
} | {
|
|
1583
|
+
kind: 'runAction';
|
|
1584
|
+
sectionId: string;
|
|
1585
|
+
actionId: string;
|
|
1586
|
+
} | {
|
|
1587
|
+
kind: 'addItem';
|
|
1588
|
+
sectionId: string;
|
|
1589
|
+
itemId: string;
|
|
1590
|
+
} | {
|
|
1591
|
+
kind: 'focusField';
|
|
1592
|
+
fieldId: string;
|
|
1593
|
+
} | {
|
|
1594
|
+
kind: 'contextMenu';
|
|
1595
|
+
fieldId: string;
|
|
1596
|
+
x: number;
|
|
1597
|
+
y: number;
|
|
1598
|
+
} | {
|
|
1599
|
+
kind: 'keyframe';
|
|
1600
|
+
fieldId: string;
|
|
1601
|
+
op: 'toggleAnim' | 'prev' | 'next' | 'add' | 'remove';
|
|
1602
|
+
} | {
|
|
1603
|
+
kind: 'setEasing';
|
|
1604
|
+
fieldId: string;
|
|
1605
|
+
easing: string;
|
|
1606
|
+
} | {
|
|
1607
|
+
kind: 'bindToken';
|
|
1608
|
+
fieldId: string;
|
|
1609
|
+
} | {
|
|
1610
|
+
kind: 'resetField';
|
|
1611
|
+
fieldId: string;
|
|
1612
|
+
};
|
|
1613
|
+
/** Derive the view state from the live controller — the runtime calls this on every draw. */
|
|
1614
|
+
declare function inspectorViewState(c: InspectorPanelController): InspectorViewState;
|
|
1615
|
+
/** Apply a `ui` intent to the controller — the runtime's half of the contract. */
|
|
1616
|
+
declare function applyInspectorUi(c: InspectorPanelController, intent: InspectorUiIntent): void;
|
|
1617
|
+
declare const inspectorViewManifest: PanelManifest;
|
|
1618
|
+
declare const BEHAVIOURS: {
|
|
1619
|
+
'edit/inspectorPanelView': (inputs: Record<string, unknown>) => InspectorViewState;
|
|
1620
|
+
};
|
|
1621
|
+
declare const INSPECTOR_DECLARATION: BlockDeclaration;
|
|
1622
|
+
|
|
1472
1623
|
/**
|
|
1473
1624
|
* `InspectorPanelView` — the React rendering half of the Inspector panel.
|
|
1474
1625
|
*
|
|
@@ -1484,12 +1635,17 @@ interface InspectorPanelViewProps {
|
|
|
1484
1635
|
controller: InspectorPanelController;
|
|
1485
1636
|
}
|
|
1486
1637
|
/**
|
|
1487
|
-
* The inspector shell over the chrome family
|
|
1488
|
-
*
|
|
1489
|
-
*
|
|
1490
|
-
* intent stay in the controller.
|
|
1638
|
+
* The inspector shell over the chrome family, drawn from the SAME view state as `INSPECTOR_DECLARATION`
|
|
1639
|
+
* (`inspectorViewState(controller)`) — the declaration test holds the two byte-identical. The keyboard
|
|
1640
|
+
* model and every intent stay in the controller; the cell is `FieldWidget`, bound to it.
|
|
1491
1641
|
*/
|
|
1492
1642
|
declare function InspectorPanelView({ controller }: InspectorPanelViewProps): ReactElement;
|
|
1643
|
+
/**
|
|
1644
|
+
* The units the runtime registers for `INSPECTOR_DECLARATION`, bound to ITS controller: the cell
|
|
1645
|
+
* (`inspector/FieldWidget`), the keyboard group (`inspector/Properties`), and the glyphs. A
|
|
1646
|
+
* declaration can name them and bind their data props; only the runtime can supply the controller.
|
|
1647
|
+
*/
|
|
1648
|
+
declare function inspectorRuntimeComponents(controller: InspectorPanelController): Record<string, React.ComponentType<any>>;
|
|
1493
1649
|
|
|
1494
1650
|
/**
|
|
1495
1651
|
* The canonical History wire contract (union spec §3): `XenoHistoryState` in,
|
|
@@ -6461,4 +6617,4 @@ declare function TreeIcon({ name, size }: {
|
|
|
6461
6617
|
size?: number;
|
|
6462
6618
|
}): ReactNode;
|
|
6463
6619
|
|
|
6464
|
-
export { type BlendModeGroup, type BlendModeOption, type Box, COLOR_SPACES, COMMENTS_PANEL_ID, CURVE_PANEL_ID, type ChannelId, ColorPanelController, type ColorPanelControllerOptions, type ColorPanelSerialized, ColorPanelView, type ColorPanelViewProps, type ColorSpace, type ColorStopSink, type ColorToken, CommentsController, type CommentsControllerOptions, type CommentsHostBridge, type CommentsPanelState, CommentsPanelView, type CommentsPanelViewProps, type CommentsRenderContext, type CommentsThreadView, type CommentsViewState, type ConnectRules, type ConnectVerdict, type CreateColorPanelOptions, type CreateCommentsPanelOptions, type CreateCurvePanelOptions, type CreateFindPanelOptions, type CreateHistoryPanelOptions, type CreateInspectorPanelOptions, type CreateLayersPanelOptions, type CreateNodeGraphPanelOptions, type CreateTreePanelOptions, type CreateViewportPanelOptions, CurveController, type CurveControllerOptions, type CurveDragKind, type CurveDragState, type CurveHostBridge, type CurvePanelState, CurvePanelView, type CurvePanelViewProps, type CurvePreview, type CurveRenderConfig, type CurveRenderContext, type CurveViewState, DEFAULT_BLEND_MODES, DEFAULT_CURVE_ZOOM, DEFAULT_GRAPH_ZOOM, DEFAULT_ICON_MAP, DEFAULT_ORIGINAL_LABEL, type DropInput, EASING_PRESETS, EDIT_SPACES, EMPTY_HISTORY, EMPTY_SCHEMA, EMPTY_TREE, EMPTY_TREE_SOURCE, FIND_PANEL_ID, FindController, type FindControllerOptions, type FindHostBridge, type FindPanelState, FindPanelView, type FindPanelViewProps, type FindRenderContext, type FindViewState, type FlatRow, type FlattenOptions, GENERIC_ICON, GraphController, type GraphControllerOptions, type GraphDragKind, type GraphDragState, type GraphHostBridge, type GraphPanelState, type GraphPreview, type GraphRenderConfig, type GraphRenderContext, type GraphViewState, type HistoryKeyEvent, HistoryPanelController, type HistoryPanelControllerOptions, type HistoryPanelSerialized, HistoryPanelView, type HistoryPanelViewProps, type ProjectOptions as HistoryProjectOptions, type HistoryRow, type Hsl, type Hsv, IMPLEMENTED_TREE_MODES, type InspectorKeyEvent, InspectorPanelController, type InspectorPanelControllerOptions, type InspectorPanelSerialized, InspectorPanelView, type InspectorPanelViewProps, type ProjectOptions$1 as InspectorProjectOptions, LAYER_COLUMNS, type LayerColumn, type LayersKeyEvent, LayersPanelController, type LayersPanelControllerOptions, type LayersPanelSerialized, LayersPanelView, type LayersPanelViewProps, MIXED, NODEGRAPH_PANEL_ID, NodeGraphPanelView, type NodeGraphPanelViewProps, type NumericConstraints, type OklchDisplay, type ParseResult, type ProjectedSection, type Rgba, type ScrubOptions, type SelectMods, TREE_PANEL_ID, type TangentEdit, Thumbnail, type ThumbnailProps, TreeController, type TreeControllerOptions, type TreeHostBridge, TreeIcon, type TreeKeyEvent, type TreePanelState, TreePanelView, type TreePanelViewProps, type TreeRenderContext, type TreeRow, type TreeViewState, VIEWPORT_PANEL_ID, VIEWPORT_SLOTS, VIEW_STATE_OPS, ViewportController, type ViewportControllerOptions, type ViewportHostBridge, type ViewportPanelState, ViewportPanelView, type ViewportPanelViewProps, type ViewportRenderContext, type ViewportViewState, type XenoAddMenuItem, type XenoAnchorState, type XenoColorValue, type XenoCommentAuthor, type XenoCommentFilter, type XenoCommentMessage, type XenoCommentOp, type XenoCommentReaction, type XenoCommentSort, type XenoCommentThread, type XenoCommitPolicy, type XenoContextMenuRequest, type XenoCurveChannel, type XenoCurveInterpolation, type XenoCurveKey, type XenoCurveKeyRef, type XenoCurveOp, type XenoCurvePoint, XenoCurveScale, type XenoCurveScaleGeometry, type XenoCurveScaleState, type XenoCurveSelection, type XenoCurveSet, type XenoCurveViewport, type XenoCurveZoom, type XenoEasingPreset, type XenoEdge, type XenoFieldAnim, type XenoFieldFocus, type XenoFieldOption, type XenoFieldToken, type XenoFieldType, type XenoFieldValue, type XenoFindMatch, type XenoFindNavigate, type XenoFindOptions, type XenoFindQuery, type XenoFindReplace, type XenoFindResults, type XenoFindStatus, type XenoGradient, type XenoGraph, type XenoGraphOp, XenoGraphScale, type XenoGraphScaleGeometry, type XenoGraphScaleState, type XenoGraphSelection, type XenoGraphViewport, type XenoGraphZoom, type XenoHistoryEntry, type XenoHistoryIntent, type XenoHistoryMemory, type XenoHistoryOrder, type XenoHistoryScope, type XenoHistorySnapshot, type XenoHistorySource, type XenoHistoryState, type XenoHistoryStatus, type XenoInspectorEdit, type XenoInspectorField, type XenoInspectorSchema, type XenoInspectorSection, type XenoInspectorTarget, type XenoInspectorToken, type XenoKeyframeKind, type XenoLayerAdornment, type XenoLayerCap, type XenoLayerKind, type XenoLayerNode, type XenoLayerOp, type XenoLayerTree, type XenoNavigateRequest, type XenoNode, XenoNodeIndex, type XenoPort, type XenoPortDirection, type XenoPortRef, type XenoSectionAction, type XenoTangent, type XenoTangentMode, type XenoTangentSide, type XenoThreadActivate, type XenoThumbnailRequest, type XenoThumbnailResponse, type XenoTreeAction, type XenoTreeBadge, type XenoTreeCaps, type XenoTreeChildState, type XenoTreeChildrenResponse, type XenoTreeError, type XenoTreeGlyph, type XenoTreeIcon, type XenoTreeInvalidate, type XenoTreeMode, type XenoTreeModifiers, type XenoTreeNode, type XenoTreeNodeKind, type XenoTreeOp, type XenoTreeReveal, type XenoTreeSource, type XenoTreeSourceKind, type XenoTreeSourceState, type XenoViewportClient, type XenoViewportKey, type XenoViewportPointer, type XenoViewportSlot, type XenoViewportStats, type XenoViewportSurface, allFields, allIds, anchorStateOf, appliedCount, applyPrecision, applyTangentDrag, ariaSliderProps, boxesIntersect, canConnect, canRedo, canUndo, childStateOf, clamp, clampAlpha, clampTangent, collectDescendants, colorManifest, colorPanel, commentsManifest, commentsPanel, commitPolicyOf, componentsForSpace, computeSurfaceSize, constraintsOf, countIsMeaningful, createColorPanel, createCommentsPanel, createCurvePanel, createFindPanel, createHistoryPanel, createInspectorPanel, createLayersPanel, createNodeGraphPanel, createTreePanel, createViewportPanel, createsCycle, currentRowIndex, curveManifest, curvePanel, defaultIconFor, displayOrder, distanceToEdge, easeAt, easingPreset, edgeBounds, edgeKey, edgePath, edgesToReplace, edgesTouching, evaluateChannel, fieldMatches, findField, findManifest, findPanel, findPort, findSectionOf, fitToBounds, fitValueRange, flattenVisible, focusOrder, formatAge, formatNumeric, getAncestors, graphBounds, groupMatches, hasCap, hasDraggableTangents, hasTreeCap, hexFromHsv, highlightSegments, historyManifest, historyPanel, hslToRgb, hsvFromHex, hsvToRgb, inspectorManifest, inspectorPanel, interpolateSegment, isAncestorOf, isAnimated, isCollapsed, isColorSpace, isContainer, isEmptyContainer, isFieldEditable, isFieldMixed, isJumpable, isKeyEditable, isLayerColumn, isMixedValue, isOrphaned, isTreeContainer, isValidHex, isViewStateOp, keyRefId, layersManifest, layersPanel, liveEdges, makeColorValue, matchesFilter, messagesOf, mirrorTangent, nodeBounds, nodegraphManifest, nodegraphPanel, normalizeColorInput, normalizeHistoryState, normalizeKindKey, normalizeNumeric, normalizeRanges, normalizeSchema, normalizeTree, nudgeValue, oklchToRgb, parseCssColor, parseHexColor, parseNumeric, passesFilter, patternError, portHasRoom, portRefId, positionToValue, projectRows, projectSections, rangeBetween, resolveDropTarget, resolveIconName, rgbToHex, rgbToHsl, rgbToHsv, rgbToOklch, rgbaToCssHex, roundRgb, rowIndexOf, rowIndexOfEntry, safeAddColorStop, safeAddColorStops, sameKey, sampleChannel, scrubValue, segmentsAround, solveBezierT, sortThreads, surfaceChanged, tangentsForMode, tangentsToControlPoints, toViewportCoords, totalCount, treeManifest, treePanel, usesLogScale, valueExtent, valueToPosition, valuesEqual, viewportManifest, viewportPanel, visibleEdges, walkTree, wheelZoomFactor, zoomAboutCursor, zoomTimeAboutCursor, zoomValueAboutCursor };
|
|
6620
|
+
export { type BlendModeGroup, type BlendModeOption, type Box, COLOR_SPACES, COMMENTS_PANEL_ID, CURVE_PANEL_ID, type ChannelId, ColorPanelController, type ColorPanelControllerOptions, type ColorPanelSerialized, ColorPanelView, type ColorPanelViewProps, type ColorSpace, type ColorStopSink, type ColorToken, CommentsController, type CommentsControllerOptions, type CommentsHostBridge, type CommentsPanelState, CommentsPanelView, type CommentsPanelViewProps, type CommentsRenderContext, type CommentsThreadView, type CommentsViewState, type ConnectRules, type ConnectVerdict, type CreateColorPanelOptions, type CreateCommentsPanelOptions, type CreateCurvePanelOptions, type CreateFindPanelOptions, type CreateHistoryPanelOptions, type CreateInspectorPanelOptions, type CreateLayersPanelOptions, type CreateNodeGraphPanelOptions, type CreateTreePanelOptions, type CreateViewportPanelOptions, CurveController, type CurveControllerOptions, type CurveDragKind, type CurveDragState, type CurveHostBridge, type CurvePanelState, CurvePanelView, type CurvePanelViewProps, type CurvePreview, type CurveRenderConfig, type CurveRenderContext, type CurveViewState, DEFAULT_BLEND_MODES, DEFAULT_CURVE_ZOOM, DEFAULT_GRAPH_ZOOM, DEFAULT_ICON_MAP, DEFAULT_ORIGINAL_LABEL, type DropInput, EASING_PRESETS, EDIT_SPACES, EMPTY_HISTORY, EMPTY_SCHEMA, EMPTY_TREE, EMPTY_TREE_SOURCE, FIND_PANEL_ID, FindController, type FindControllerOptions, type FindHostBridge, type FindPanelState, FindPanelView, type FindPanelViewProps, type FindRenderContext, type FindViewState, type FlatRow, type FlattenOptions, GENERIC_ICON, GraphController, type GraphControllerOptions, type GraphDragKind, type GraphDragState, type GraphHostBridge, type GraphPanelState, type GraphPreview, type GraphRenderConfig, type GraphRenderContext, type GraphViewState, type HistoryKeyEvent, HistoryPanelController, type HistoryPanelControllerOptions, type HistoryPanelSerialized, HistoryPanelView, type HistoryPanelViewProps, type ProjectOptions as HistoryProjectOptions, type HistoryRow, type Hsl, type Hsv, IMPLEMENTED_TREE_MODES, BEHAVIOURS as INSPECTOR_BEHAVIOURS, INSPECTOR_DECLARATION, type InspectorKeyEvent, InspectorPanelController, type InspectorPanelControllerOptions, type InspectorPanelSerialized, InspectorPanelView, type InspectorPanelViewProps, type ProjectOptions$1 as InspectorProjectOptions, type InspectorUiIntent, type InspectorViewField, type InspectorViewSection, type InspectorViewState, LAYER_COLUMNS, type LayerColumn, type LayersKeyEvent, LayersPanelController, type LayersPanelControllerOptions, type LayersPanelSerialized, LayersPanelView, type LayersPanelViewProps, MIXED, NODEGRAPH_PANEL_ID, NodeGraphPanelView, type NodeGraphPanelViewProps, type NumericConstraints, type OklchDisplay, type ParseResult, type ProjectedSection, type Rgba, type ScrubOptions, type SelectMods, TREE_PANEL_ID, type TangentEdit, Thumbnail, type ThumbnailProps, TreeController, type TreeControllerOptions, type TreeHostBridge, TreeIcon, type TreeKeyEvent, type TreePanelState, TreePanelView, type TreePanelViewProps, type TreeRenderContext, type TreeRow, type TreeViewState, VIEWPORT_PANEL_ID, VIEWPORT_SLOTS, VIEW_STATE_OPS, ViewportController, type ViewportControllerOptions, type ViewportHostBridge, type ViewportPanelState, ViewportPanelView, type ViewportPanelViewProps, type ViewportRenderContext, type ViewportViewState, type XenoAddMenuItem, type XenoAnchorState, type XenoColorValue, type XenoCommentAuthor, type XenoCommentFilter, type XenoCommentMessage, type XenoCommentOp, type XenoCommentReaction, type XenoCommentSort, type XenoCommentThread, type XenoCommitPolicy, type XenoContextMenuRequest, type XenoCurveChannel, type XenoCurveInterpolation, type XenoCurveKey, type XenoCurveKeyRef, type XenoCurveOp, type XenoCurvePoint, XenoCurveScale, type XenoCurveScaleGeometry, type XenoCurveScaleState, type XenoCurveSelection, type XenoCurveSet, type XenoCurveViewport, type XenoCurveZoom, type XenoEasingPreset, type XenoEdge, type XenoFieldAnim, type XenoFieldFocus, type XenoFieldOption, type XenoFieldToken, type XenoFieldType, type XenoFieldValue, type XenoFindMatch, type XenoFindNavigate, type XenoFindOptions, type XenoFindQuery, type XenoFindReplace, type XenoFindResults, type XenoFindStatus, type XenoGradient, type XenoGraph, type XenoGraphOp, XenoGraphScale, type XenoGraphScaleGeometry, type XenoGraphScaleState, type XenoGraphSelection, type XenoGraphViewport, type XenoGraphZoom, type XenoHistoryEntry, type XenoHistoryIntent, type XenoHistoryMemory, type XenoHistoryOrder, type XenoHistoryScope, type XenoHistorySnapshot, type XenoHistorySource, type XenoHistoryState, type XenoHistoryStatus, type XenoInspectorEdit, type XenoInspectorField, type XenoInspectorSchema, type XenoInspectorSection, type XenoInspectorTarget, type XenoInspectorToken, type XenoKeyframeKind, type XenoLayerAdornment, type XenoLayerCap, type XenoLayerKind, type XenoLayerNode, type XenoLayerOp, type XenoLayerTree, type XenoNavigateRequest, type XenoNode, XenoNodeIndex, type XenoPort, type XenoPortDirection, type XenoPortRef, type XenoSectionAction, type XenoTangent, type XenoTangentMode, type XenoTangentSide, type XenoThreadActivate, type XenoThumbnailRequest, type XenoThumbnailResponse, type XenoTreeAction, type XenoTreeBadge, type XenoTreeCaps, type XenoTreeChildState, type XenoTreeChildrenResponse, type XenoTreeError, type XenoTreeGlyph, type XenoTreeIcon, type XenoTreeInvalidate, type XenoTreeMode, type XenoTreeModifiers, type XenoTreeNode, type XenoTreeNodeKind, type XenoTreeOp, type XenoTreeReveal, type XenoTreeSource, type XenoTreeSourceKind, type XenoTreeSourceState, type XenoViewportClient, type XenoViewportKey, type XenoViewportPointer, type XenoViewportSlot, type XenoViewportStats, type XenoViewportSurface, allFields, allIds, anchorStateOf, appliedCount, applyInspectorUi, applyPrecision, applyTangentDrag, ariaSliderProps, boxesIntersect, canConnect, canRedo, canUndo, childStateOf, clamp, clampAlpha, clampTangent, collectDescendants, colorManifest, colorPanel, commentsManifest, commentsPanel, commitPolicyOf, componentsForSpace, computeSurfaceSize, constraintsOf, countIsMeaningful, createColorPanel, createCommentsPanel, createCurvePanel, createFindPanel, createHistoryPanel, createInspectorPanel, createLayersPanel, createNodeGraphPanel, createTreePanel, createViewportPanel, createsCycle, currentRowIndex, curveManifest, curvePanel, defaultIconFor, displayOrder, distanceToEdge, easeAt, easingPreset, edgeBounds, edgeKey, edgePath, edgesToReplace, edgesTouching, evaluateChannel, fieldMatches, findField, findManifest, findPanel, findPort, findSectionOf, fitToBounds, fitValueRange, flattenVisible, focusOrder, formatAge, formatNumeric, getAncestors, graphBounds, groupMatches, hasCap, hasDraggableTangents, hasTreeCap, hexFromHsv, highlightSegments, historyManifest, historyPanel, hslToRgb, hsvFromHex, hsvToRgb, inspectorManifest, inspectorPanel, inspectorRuntimeComponents, inspectorViewManifest, inspectorViewState, interpolateSegment, isAncestorOf, isAnimated, isCollapsed, isColorSpace, isContainer, isEmptyContainer, isFieldEditable, isFieldMixed, isJumpable, isKeyEditable, isLayerColumn, isMixedValue, isOrphaned, isTreeContainer, isValidHex, isViewStateOp, keyRefId, layersManifest, layersPanel, liveEdges, makeColorValue, matchesFilter, messagesOf, mirrorTangent, nodeBounds, nodegraphManifest, nodegraphPanel, normalizeColorInput, normalizeHistoryState, normalizeKindKey, normalizeNumeric, normalizeRanges, normalizeSchema, normalizeTree, nudgeValue, oklchToRgb, parseCssColor, parseHexColor, parseNumeric, passesFilter, patternError, portHasRoom, portRefId, positionToValue, projectRows, projectSections, rangeBetween, resolveDropTarget, resolveIconName, rgbToHex, rgbToHsl, rgbToHsv, rgbToOklch, rgbaToCssHex, roundRgb, rowIndexOf, rowIndexOfEntry, safeAddColorStop, safeAddColorStops, sameKey, sampleChannel, scrubValue, segmentsAround, solveBezierT, sortThreads, surfaceChanged, tangentsForMode, tangentsToControlPoints, toViewportCoords, totalCount, treeManifest, treePanel, usesLogScale, valueExtent, valueToPosition, valuesEqual, viewportManifest, viewportPanel, visibleEdges, walkTree, wheelZoomFactor, zoomAboutCursor, zoomTimeAboutCursor, zoomValueAboutCursor };
|
package/dist/edit/index.js
CHANGED
|
@@ -1871,8 +1871,8 @@ function constraintsOf(field) {
|
|
|
1871
1871
|
scale: field.scale
|
|
1872
1872
|
};
|
|
1873
1873
|
}
|
|
1874
|
-
function parseNumeric(
|
|
1875
|
-
const trimmed = String(
|
|
1874
|
+
function parseNumeric(text2) {
|
|
1875
|
+
const trimmed = String(text2).trim();
|
|
1876
1876
|
if (trimmed.length === 0) return { ok: false, reason: "empty" };
|
|
1877
1877
|
const match = /^[+-]?(\d+\.?\d*|\.\d+)(?:[eE][+-]?\d+)?/.exec(trimmed);
|
|
1878
1878
|
if (!match) return { ok: false, reason: "nan" };
|
|
@@ -1897,8 +1897,8 @@ function normalizeNumeric(value, c) {
|
|
|
1897
1897
|
function formatNumeric(value, field) {
|
|
1898
1898
|
if (!Number.isFinite(value)) return "";
|
|
1899
1899
|
const precision = field.precision;
|
|
1900
|
-
const
|
|
1901
|
-
return field.unit ? `${
|
|
1900
|
+
const text2 = typeof precision === "number" && Number.isFinite(precision) ? value.toFixed(Math.max(0, Math.floor(precision))) : String(value);
|
|
1901
|
+
return field.unit ? `${text2}${field.unit}` : text2;
|
|
1902
1902
|
}
|
|
1903
1903
|
function usesLogScale(c) {
|
|
1904
1904
|
return c.scale === "log" && typeof c.min === "number" && typeof c.max === "number" && c.min > 0 && c.max > c.min;
|
|
@@ -2232,44 +2232,44 @@ var InspectorPanelController = class {
|
|
|
2232
2232
|
if (!field || !isFieldEditable(field)) return;
|
|
2233
2233
|
const mixed = isFieldMixed(field);
|
|
2234
2234
|
const value = this.getFieldValue(fieldId);
|
|
2235
|
-
const
|
|
2236
|
-
this.drafts.set(fieldId, { text, original: value });
|
|
2235
|
+
const text2 = mixed ? "" : field.type === "number" && typeof value === "number" ? formatNumeric(value, field) : value === void 0 || value === null ? "" : String(value);
|
|
2236
|
+
this.drafts.set(fieldId, { text: text2, original: value });
|
|
2237
2237
|
this.focusedFieldId = fieldId;
|
|
2238
2238
|
this.emitFieldFocus(fieldId);
|
|
2239
2239
|
this.notify();
|
|
2240
2240
|
}
|
|
2241
2241
|
/** Update the draft text (typing). Emits nothing under the `blur` policy. */
|
|
2242
|
-
setDraft(fieldId,
|
|
2242
|
+
setDraft(fieldId, text2) {
|
|
2243
2243
|
const draft = this.drafts.get(fieldId);
|
|
2244
2244
|
if (!draft) {
|
|
2245
|
-
this.drafts.set(fieldId, { text, original: this.getFieldValue(fieldId) });
|
|
2245
|
+
this.drafts.set(fieldId, { text: text2, original: this.getFieldValue(fieldId) });
|
|
2246
2246
|
} else {
|
|
2247
|
-
draft.text =
|
|
2247
|
+
draft.text = text2;
|
|
2248
2248
|
}
|
|
2249
2249
|
const field = this.getField(fieldId);
|
|
2250
2250
|
if (field && commitPolicyOf(field) === "live") {
|
|
2251
|
-
const parsed = this.parseDraft(fieldId,
|
|
2251
|
+
const parsed = this.parseDraft(fieldId, text2);
|
|
2252
2252
|
if (parsed.ok) this.emitSet(fieldId, parsed.value);
|
|
2253
2253
|
}
|
|
2254
2254
|
this.notify();
|
|
2255
2255
|
}
|
|
2256
2256
|
/** Parse a draft string into a field-appropriate value. */
|
|
2257
|
-
parseDraft(fieldId,
|
|
2257
|
+
parseDraft(fieldId, text2) {
|
|
2258
2258
|
const field = this.getField(fieldId);
|
|
2259
2259
|
if (!field) return { ok: false };
|
|
2260
2260
|
if (field.type === "number") {
|
|
2261
|
-
const parsed = parseNumeric(
|
|
2261
|
+
const parsed = parseNumeric(text2);
|
|
2262
2262
|
if (!parsed.ok) return { ok: false };
|
|
2263
2263
|
return { ok: true, value: normalizeNumeric(parsed.value, constraintsOf(field)) };
|
|
2264
2264
|
}
|
|
2265
2265
|
if (field.type === "json") {
|
|
2266
2266
|
try {
|
|
2267
|
-
return { ok: true, value: JSON.parse(
|
|
2267
|
+
return { ok: true, value: JSON.parse(text2) };
|
|
2268
2268
|
} catch {
|
|
2269
2269
|
return { ok: false };
|
|
2270
2270
|
}
|
|
2271
2271
|
}
|
|
2272
|
-
return { ok: true, value:
|
|
2272
|
+
return { ok: true, value: text2 };
|
|
2273
2273
|
}
|
|
2274
2274
|
/**
|
|
2275
2275
|
* Commit the draft (Enter / blur). Invalid input reverts instead of committing garbage.
|
|
@@ -2810,6 +2810,271 @@ var InspectorPanelController = class {
|
|
|
2810
2810
|
|
|
2811
2811
|
// src/edit/inspector/react/InspectorPanelView.tsx
|
|
2812
2812
|
import { useCallback as useCallback3, useSyncExternalStore as useSyncExternalStore2 } from "react";
|
|
2813
|
+
|
|
2814
|
+
// src/edit/inspector/declaration.ts
|
|
2815
|
+
function inspectorViewState(c) {
|
|
2816
|
+
const targets = c.getTargets();
|
|
2817
|
+
const multi = targets.length > 1;
|
|
2818
|
+
const blocked = multi && !c.canEditTargets();
|
|
2819
|
+
const showKeyframes = c.areKeyframesShown();
|
|
2820
|
+
const showTokens = c.areTokensShown();
|
|
2821
|
+
const focusedId = c.getFocused();
|
|
2822
|
+
const labelWidth = c.getLabelWidth();
|
|
2823
|
+
const sections = c.getSections().map((p) => {
|
|
2824
|
+
const s = p.section;
|
|
2825
|
+
return {
|
|
2826
|
+
id: s.id,
|
|
2827
|
+
title: s.title,
|
|
2828
|
+
collapsible: !!s.collapsible,
|
|
2829
|
+
collapsed: p.collapsed,
|
|
2830
|
+
hasEnabled: s.enabled !== void 0,
|
|
2831
|
+
enabled: s.enabled?.value,
|
|
2832
|
+
badge: s.badge,
|
|
2833
|
+
actions: (s.actions ?? []).map((a) => ({ id: a.id, sectionId: s.id, label: a.label, glyph: a.label.slice(0, 1), disabled: a.disabled })),
|
|
2834
|
+
hasAddMenu: !!s.addMenu && s.addMenu.length > 0,
|
|
2835
|
+
hasActions: (s.actions?.length ?? 0) > 0 || !!s.addMenu && s.addMenu.length > 0,
|
|
2836
|
+
addLabel: `Add to ${s.title}`,
|
|
2837
|
+
addOptions: (s.addMenu ?? []).map((i) => ({ value: i.id, label: i.label, disabled: i.disabled, group: i.group })),
|
|
2838
|
+
showEmptyHint: p.empty && !!s.emptyHint,
|
|
2839
|
+
emptyHint: s.emptyHint,
|
|
2840
|
+
labelWidth,
|
|
2841
|
+
fields: p.fields.map((field) => {
|
|
2842
|
+
const anim = field.anim;
|
|
2843
|
+
const sk = showKeyframes && !!anim;
|
|
2844
|
+
const bound = !!field.token?.tokenId;
|
|
2845
|
+
const easing = anim?.easing ?? "";
|
|
2846
|
+
const easingOptions = anim?.easingOptions ?? [];
|
|
2847
|
+
const easingAll = easingOptions.some((o) => o.value === easing) ? easingOptions : [{ value: easing, label: easing || "\u2014" }, ...easingOptions];
|
|
2848
|
+
const tokenName = field.token?.tokenName ?? field.token?.tokenId ?? void 0;
|
|
2849
|
+
return {
|
|
2850
|
+
id: field.id,
|
|
2851
|
+
sectionId: s.id,
|
|
2852
|
+
label: field.label,
|
|
2853
|
+
title: field.description ?? field.label,
|
|
2854
|
+
focused: focusedId === field.id,
|
|
2855
|
+
bound,
|
|
2856
|
+
unbound: !bound,
|
|
2857
|
+
tokenLabel: tokenName,
|
|
2858
|
+
tokenTitle: bound ? `Bound to ${tokenName}` : void 0,
|
|
2859
|
+
showKeyframes: sk,
|
|
2860
|
+
animated: sk && !!anim.animated,
|
|
2861
|
+
onKeyframe: sk && !!anim.onKeyframe,
|
|
2862
|
+
prevDisabled: sk ? anim.canPrev === false : false,
|
|
2863
|
+
nextDisabled: sk ? anim.canNext === false : false,
|
|
2864
|
+
keyframeLabel: sk && anim.onKeyframe ? "Remove keyframe" : "Add keyframe",
|
|
2865
|
+
keyframeOp: sk && anim.onKeyframe ? "remove" : "add",
|
|
2866
|
+
showEasing: sk && !!anim.animated && !!anim.onKeyframe,
|
|
2867
|
+
easing,
|
|
2868
|
+
easingOptions: easingAll.map((o) => ({ value: o.value, label: o.label })),
|
|
2869
|
+
keyframeChip: sk ? c.keyframeChip(field.id) : "",
|
|
2870
|
+
showToken: showTokens && field.token?.bindable !== false,
|
|
2871
|
+
tokenActionLabel: bound ? "Unbind token" : "Bind token",
|
|
2872
|
+
showReset: field.defaultValue !== void 0 && isFieldEditable(field),
|
|
2873
|
+
showInfoNote: !!field.description && field.type === "info",
|
|
2874
|
+
infoNote: field.description,
|
|
2875
|
+
field
|
|
2876
|
+
};
|
|
2877
|
+
})
|
|
2878
|
+
};
|
|
2879
|
+
});
|
|
2880
|
+
return {
|
|
2881
|
+
searchShown: c.isSearchShown(),
|
|
2882
|
+
filter: c.getFilter(),
|
|
2883
|
+
hasTarget: targets.length > 0,
|
|
2884
|
+
targetLabel: multi ? `${targets.length} selected` : targets[0]?.label ?? targets[0]?.id ?? "",
|
|
2885
|
+
multi,
|
|
2886
|
+
banner: blocked ? `${targets.length} selected \u2014 multi-editing is disabled` : `${targets.length} selected \xB7 shared values shown`,
|
|
2887
|
+
sections,
|
|
2888
|
+
empty: sections.length === 0,
|
|
2889
|
+
emptyTitle: targets.length === 0 ? "Nothing selected" : "No properties"
|
|
2890
|
+
};
|
|
2891
|
+
}
|
|
2892
|
+
function applyInspectorUi(c, intent) {
|
|
2893
|
+
switch (intent.kind) {
|
|
2894
|
+
case "filter":
|
|
2895
|
+
c.setFilter(intent.value);
|
|
2896
|
+
break;
|
|
2897
|
+
case "toggleSectionCollapsed":
|
|
2898
|
+
c.toggleSectionCollapsed(intent.sectionId);
|
|
2899
|
+
break;
|
|
2900
|
+
case "toggleSectionEnabled":
|
|
2901
|
+
c.toggleSectionEnabled(intent.sectionId);
|
|
2902
|
+
break;
|
|
2903
|
+
case "runAction":
|
|
2904
|
+
c.runAction(intent.sectionId, intent.actionId);
|
|
2905
|
+
break;
|
|
2906
|
+
case "addItem":
|
|
2907
|
+
c.addItem(intent.sectionId, intent.itemId);
|
|
2908
|
+
break;
|
|
2909
|
+
case "focusField":
|
|
2910
|
+
c.focusField(intent.fieldId);
|
|
2911
|
+
break;
|
|
2912
|
+
case "contextMenu":
|
|
2913
|
+
c.requestContextMenu(intent.fieldId, intent.x, intent.y);
|
|
2914
|
+
break;
|
|
2915
|
+
case "keyframe":
|
|
2916
|
+
c.keyframe(intent.fieldId, intent.op);
|
|
2917
|
+
break;
|
|
2918
|
+
case "setEasing":
|
|
2919
|
+
c.keyframe(intent.fieldId, "setEasing", intent.easing);
|
|
2920
|
+
break;
|
|
2921
|
+
case "bindToken": {
|
|
2922
|
+
const bound = !!c.getSections().flatMap((p) => p.fields).find((f) => f.id === intent.fieldId)?.token?.tokenId;
|
|
2923
|
+
c.bindToken(intent.fieldId, bound ? null : c.getTokens()[0]?.id ?? null);
|
|
2924
|
+
break;
|
|
2925
|
+
}
|
|
2926
|
+
case "resetField":
|
|
2927
|
+
c.resetField(intent.fieldId);
|
|
2928
|
+
break;
|
|
2929
|
+
}
|
|
2930
|
+
}
|
|
2931
|
+
var inspectorViewManifest = {
|
|
2932
|
+
id: inspectorManifest.id,
|
|
2933
|
+
version: "1.0.0",
|
|
2934
|
+
title: "Inspector",
|
|
2935
|
+
category: "edit",
|
|
2936
|
+
layout: { slot: "side" },
|
|
2937
|
+
inputs: [{ id: "view", type: "object", label: "View state", description: "The InspectorViewState the runtime derives from the controller on every draw." }],
|
|
2938
|
+
outputs: [{ id: "ui", type: "object", label: "UI intent", description: "{ kind, sectionId?, fieldId?, \u2026 } \u2014 applied by the runtime to the controller." }],
|
|
2939
|
+
commands: []
|
|
2940
|
+
};
|
|
2941
|
+
var EMPTY = { searchShown: true, filter: "", hasTarget: false, targetLabel: "", multi: false, banner: "", sections: [], empty: true, emptyTitle: "Nothing selected" };
|
|
2942
|
+
var BEHAVIOURS = {
|
|
2943
|
+
"edit/inspectorPanelView": (inputs) => inputs.view ?? EMPTY
|
|
2944
|
+
};
|
|
2945
|
+
var text = (b) => ({ component: "text", props: { text: b } });
|
|
2946
|
+
var ui = (kind, fields = {}) => ({ emit: "ui", value: { object: { kind: { value: kind }, ...fields } } });
|
|
2947
|
+
var iconButton = (glyph, label, emit, extra = {}) => ({
|
|
2948
|
+
component: "chrome/IconButton",
|
|
2949
|
+
...extra.when ? { when: extra.when } : {},
|
|
2950
|
+
props: { size: { value: "sm" }, icon: { node: { component: `inspector/${glyph}` } }, label, ...extra.props ?? {} },
|
|
2951
|
+
on: { onClick: emit }
|
|
2952
|
+
});
|
|
2953
|
+
var INSPECTOR_DECLARATION = {
|
|
2954
|
+
format: "xeno.block@1",
|
|
2955
|
+
manifest: inspectorViewManifest,
|
|
2956
|
+
behaviour: "edit/inspectorPanelView",
|
|
2957
|
+
composition: {
|
|
2958
|
+
component: "chrome/Column",
|
|
2959
|
+
props: { className: { value: "xeno-inspector-panel" } },
|
|
2960
|
+
children: [
|
|
2961
|
+
{
|
|
2962
|
+
component: "chrome/Stack",
|
|
2963
|
+
when: { input: "view.searchShown" },
|
|
2964
|
+
props: { direction: { value: "row" }, gap: { value: 6 } },
|
|
2965
|
+
children: [
|
|
2966
|
+
{ component: "chrome/SearchField", props: { value: { input: "view.filter" }, placeholder: { value: "Search properties" }, label: { value: "Search properties" } }, on: { onChange: ui("filter", { value: { arg: "" } }) } },
|
|
2967
|
+
{ component: "chrome/Badge", when: { input: "view.hasTarget" }, children: [text({ input: "view.targetLabel" })] }
|
|
2968
|
+
]
|
|
2969
|
+
},
|
|
2970
|
+
{ component: "chrome/Stack", when: { input: "view.multi" }, props: { pad: { value: "inset" } }, children: [{ component: "chrome/Text", props: { role: { value: "caption" } }, children: [text({ input: "view.banner" })] }] },
|
|
2971
|
+
{
|
|
2972
|
+
component: "chrome/ScrollArea",
|
|
2973
|
+
children: [
|
|
2974
|
+
{
|
|
2975
|
+
component: "inspector/Properties",
|
|
2976
|
+
children: [
|
|
2977
|
+
{
|
|
2978
|
+
component: "chrome/Section",
|
|
2979
|
+
each: { input: "view.sections", key: "id" },
|
|
2980
|
+
props: {
|
|
2981
|
+
title: { item: "title" },
|
|
2982
|
+
flush: { value: true },
|
|
2983
|
+
collapsible: { item: "collapsible" },
|
|
2984
|
+
collapsed: { item: "collapsed" },
|
|
2985
|
+
enabled: { item: "enabled" },
|
|
2986
|
+
badge: { node: { component: "chrome/Badge", when: { item: "badge" }, children: [text({ item: "badge" })] } },
|
|
2987
|
+
actions: {
|
|
2988
|
+
node: {
|
|
2989
|
+
component: "fragment",
|
|
2990
|
+
when: { item: "hasActions" },
|
|
2991
|
+
children: [
|
|
2992
|
+
{
|
|
2993
|
+
component: "chrome/IconButton",
|
|
2994
|
+
each: { item: "actions", key: "id" },
|
|
2995
|
+
props: { size: { value: "sm" }, icon: { node: { component: "inspector/ActionGlyph", props: { glyph: { item: "glyph" } } } }, label: { item: "label" }, disabled: { item: "disabled" } },
|
|
2996
|
+
on: { onClick: ui("runAction", { sectionId: { item: "sectionId" }, actionId: { item: "id" } }) }
|
|
2997
|
+
},
|
|
2998
|
+
{
|
|
2999
|
+
component: "chrome/Select",
|
|
3000
|
+
when: { item: "hasAddMenu" },
|
|
3001
|
+
props: { size: { value: "sm" }, placeholder: { value: "\uFF0B" }, options: { item: "addOptions" }, value: { value: "" }, label: { item: "addLabel" } },
|
|
3002
|
+
on: { onChange: ui("addItem", { sectionId: { item: "id" }, itemId: { arg: "" } }) }
|
|
3003
|
+
}
|
|
3004
|
+
]
|
|
3005
|
+
}
|
|
3006
|
+
}
|
|
3007
|
+
},
|
|
3008
|
+
on: {
|
|
3009
|
+
onCollapsedChange: ui("toggleSectionCollapsed", { sectionId: { item: "id" } }),
|
|
3010
|
+
onEnabledChange: ui("toggleSectionEnabled", { sectionId: { item: "id" } })
|
|
3011
|
+
},
|
|
3012
|
+
children: [
|
|
3013
|
+
{ component: "chrome/Stack", when: { item: "showEmptyHint" }, props: { pad: { value: "inset" } }, children: [{ component: "chrome/Text", props: { role: { value: "caption" } }, children: [text({ item: "emptyHint" })] }] },
|
|
3014
|
+
{
|
|
3015
|
+
component: "chrome/FieldGroup",
|
|
3016
|
+
props: { labelWidth: { item: "labelWidth" } },
|
|
3017
|
+
children: [
|
|
3018
|
+
{
|
|
3019
|
+
component: "fragment",
|
|
3020
|
+
each: { item: "fields", key: "id" },
|
|
3021
|
+
children: [
|
|
3022
|
+
{
|
|
3023
|
+
component: "chrome/Field",
|
|
3024
|
+
props: {
|
|
3025
|
+
label: { item: "label" },
|
|
3026
|
+
title: { item: "title" },
|
|
3027
|
+
focused: { item: "focused" },
|
|
3028
|
+
leading: {
|
|
3029
|
+
node: {
|
|
3030
|
+
component: "fragment",
|
|
3031
|
+
when: { item: "showKeyframes" },
|
|
3032
|
+
children: [
|
|
3033
|
+
iconButton("StopwatchIcon", { value: "Toggle animation" }, ui("keyframe", { fieldId: { item: "id" }, op: { value: "toggleAnim" } }), { props: { active: { item: "animated" } } }),
|
|
3034
|
+
iconButton("PrevIcon", { value: "Previous keyframe" }, ui("keyframe", { fieldId: { item: "id" }, op: { value: "prev" } }), { when: { item: "animated" }, props: { disabled: { item: "prevDisabled" } } }),
|
|
3035
|
+
{ component: "chrome/IconButton", when: { item: "animated" }, props: { size: { value: "sm" }, icon: { node: { component: "inspector/DiamondIcon", props: { filled: { item: "onKeyframe" } } } }, label: { item: "keyframeLabel" } }, on: { onClick: ui("keyframe", { fieldId: { item: "id" }, op: { item: "keyframeOp" } }) } },
|
|
3036
|
+
iconButton("NextIcon", { value: "Next keyframe" }, ui("keyframe", { fieldId: { item: "id" }, op: { value: "next" } }), { when: { item: "animated" }, props: { disabled: { item: "nextDisabled" } } })
|
|
3037
|
+
]
|
|
3038
|
+
}
|
|
3039
|
+
},
|
|
3040
|
+
trailing: {
|
|
3041
|
+
node: {
|
|
3042
|
+
component: "fragment",
|
|
3043
|
+
children: [
|
|
3044
|
+
{ component: "chrome/Select", when: { item: "showEasing" }, props: { size: { value: "sm" }, options: { item: "easingOptions" }, value: { item: "easing" }, label: { value: "Easing" } }, on: { onChange: ui("setEasing", { fieldId: { item: "id" }, easing: { arg: "" } }) } },
|
|
3045
|
+
{ component: "chrome/Badge", when: { item: "showKeyframes" }, props: { size: { value: "sm" } }, children: [text({ item: "keyframeChip" })] },
|
|
3046
|
+
iconButton("LinkIcon", { item: "tokenActionLabel" }, ui("bindToken", { fieldId: { item: "id" } }), { when: { item: "showToken" }, props: { active: { item: "bound" } } }),
|
|
3047
|
+
iconButton("ResetIcon", { value: "Reset to default" }, ui("resetField", { fieldId: { item: "id" } }), { when: { item: "showReset" } })
|
|
3048
|
+
]
|
|
3049
|
+
}
|
|
3050
|
+
}
|
|
3051
|
+
},
|
|
3052
|
+
on: {
|
|
3053
|
+
onLabelClick: ui("focusField", { fieldId: { item: "id" } }),
|
|
3054
|
+
onContextMenu: ui("contextMenu", { fieldId: { item: "id" }, x: { arg: "" }, y: { arg: "", index: 1 } })
|
|
3055
|
+
},
|
|
3056
|
+
children: [
|
|
3057
|
+
{ component: "chrome/Badge", when: { item: "bound" }, props: { title: { item: "tokenTitle" } }, children: [text({ item: "tokenLabel" })] },
|
|
3058
|
+
{ component: "inspector/FieldWidget", when: { item: "unbound" }, props: { field: { item: "field" } } }
|
|
3059
|
+
]
|
|
3060
|
+
},
|
|
3061
|
+
{ component: "chrome/Stack", when: { item: "showInfoNote" }, props: { pad: { value: "inset" } }, children: [{ component: "chrome/Text", props: { role: { value: "caption" } }, children: [text({ item: "infoNote" })] }] }
|
|
3062
|
+
]
|
|
3063
|
+
}
|
|
3064
|
+
]
|
|
3065
|
+
}
|
|
3066
|
+
]
|
|
3067
|
+
},
|
|
3068
|
+
{ component: "chrome/EmptyState", when: { input: "view.empty" }, props: { title: { input: "view.emptyTitle" } } }
|
|
3069
|
+
]
|
|
3070
|
+
}
|
|
3071
|
+
]
|
|
3072
|
+
}
|
|
3073
|
+
]
|
|
3074
|
+
}
|
|
3075
|
+
};
|
|
3076
|
+
|
|
3077
|
+
// src/edit/inspector/react/InspectorPanelView.tsx
|
|
2813
3078
|
import { Badge as Badge2, Column as Column2, EmptyState as EmptyState2, Field, FieldGroup, IconButton as IconButton3, ScrollArea as ScrollArea2, SearchField as SearchField2, Section, Select as Select2, Stack as Stack2, Text as Text3 } from "@xenosystem/components/chrome";
|
|
2814
3079
|
|
|
2815
3080
|
// src/edit/inspector/react/icons.tsx
|
|
@@ -2979,7 +3244,7 @@ function NumberWidget({ field, controller, component }) {
|
|
|
2979
3244
|
},
|
|
2980
3245
|
[controller, editable, field.id, component]
|
|
2981
3246
|
);
|
|
2982
|
-
const
|
|
3247
|
+
const text2 = component !== void 0 ? (() => {
|
|
2983
3248
|
const raw = controller.getFieldValue(field.id);
|
|
2984
3249
|
const v = Array.isArray(raw) ? raw[component] : void 0;
|
|
2985
3250
|
return typeof v === "number" ? formatNumeric(v, field) : "";
|
|
@@ -2991,7 +3256,7 @@ function NumberWidget({ field, controller, component }) {
|
|
|
2991
3256
|
Input2,
|
|
2992
3257
|
{
|
|
2993
3258
|
inputMode: "decimal",
|
|
2994
|
-
value:
|
|
3259
|
+
value: text2,
|
|
2995
3260
|
placeholder: mixed ? controller.getMixedPlaceholder() : field.placeholder,
|
|
2996
3261
|
mixed,
|
|
2997
3262
|
readOnly: !editable,
|
|
@@ -3180,8 +3445,20 @@ function InspectorPanelView({ controller }) {
|
|
|
3180
3445
|
const subscribe = useCallback3((cb) => controller.subscribe(cb), [controller]);
|
|
3181
3446
|
const getSnapshot = useCallback3(() => controller.getRevision(), [controller]);
|
|
3182
3447
|
useSyncExternalStore2(subscribe, getSnapshot, getSnapshot);
|
|
3183
|
-
const
|
|
3184
|
-
|
|
3448
|
+
const view = inspectorViewState(controller);
|
|
3449
|
+
return /* @__PURE__ */ jsxs5(Column2, { className: "xeno-inspector-panel", children: [
|
|
3450
|
+
view.searchShown ? /* @__PURE__ */ jsxs5(Stack2, { direction: "row", gap: 6, children: [
|
|
3451
|
+
/* @__PURE__ */ jsx6(SearchField2, { value: view.filter, onChange: (v) => controller.setFilter(v), placeholder: "Search properties", label: "Search properties" }),
|
|
3452
|
+
view.hasTarget ? /* @__PURE__ */ jsx6(Badge2, { children: view.targetLabel }) : null
|
|
3453
|
+
] }) : null,
|
|
3454
|
+
view.multi ? /* @__PURE__ */ jsx6(Stack2, { pad: "inset", children: /* @__PURE__ */ jsx6(Text3, { role: "caption", children: view.banner }) }) : null,
|
|
3455
|
+
/* @__PURE__ */ jsx6(ScrollArea2, { children: /* @__PURE__ */ jsxs5(InspectorProperties, { controller, children: [
|
|
3456
|
+
view.sections.map((section) => /* @__PURE__ */ jsx6(SectionView, { section, controller }, section.id)),
|
|
3457
|
+
view.empty ? /* @__PURE__ */ jsx6(EmptyState2, { title: view.emptyTitle }) : null
|
|
3458
|
+
] }) })
|
|
3459
|
+
] });
|
|
3460
|
+
}
|
|
3461
|
+
function InspectorProperties({ controller, children }) {
|
|
3185
3462
|
const onKeyDown = useCallback3(
|
|
3186
3463
|
(e) => {
|
|
3187
3464
|
if (controller.handleKey({ key: e.key, ctrl: e.ctrlKey, meta: e.metaKey, shift: e.shiftKey, alt: e.altKey })) {
|
|
@@ -3191,83 +3468,66 @@ function InspectorPanelView({ controller }) {
|
|
|
3191
3468
|
},
|
|
3192
3469
|
[controller]
|
|
3193
3470
|
);
|
|
3194
|
-
|
|
3195
|
-
const blocked = multi && !controller.canEditTargets();
|
|
3196
|
-
return /* @__PURE__ */ jsxs5(Column2, { className: "xeno-inspector-panel", children: [
|
|
3197
|
-
controller.isSearchShown() ? /* @__PURE__ */ jsxs5(Stack2, { direction: "row", gap: 6, children: [
|
|
3198
|
-
/* @__PURE__ */ jsx6(SearchField2, { value: controller.getFilter(), onChange: (v) => controller.setFilter(v), placeholder: "Search properties", label: "Search properties" }),
|
|
3199
|
-
targets.length > 0 ? /* @__PURE__ */ jsx6(Badge2, { children: multi ? `${targets.length} selected` : targets[0]?.label ?? targets[0]?.id }) : null
|
|
3200
|
-
] }) : null,
|
|
3201
|
-
multi ? /* @__PURE__ */ jsx6(Stack2, { pad: "inset", children: /* @__PURE__ */ jsx6(Text3, { role: "caption", children: blocked ? `${targets.length} selected \u2014 multi-editing is disabled` : `${targets.length} selected \xB7 shared values shown` }) }) : null,
|
|
3202
|
-
/* @__PURE__ */ jsx6(ScrollArea2, { children: /* @__PURE__ */ jsxs5("div", { onKeyDown, tabIndex: 0, role: "group", "aria-label": "Properties", className: "xeno-inspector-properties", children: [
|
|
3203
|
-
sections.map((projected) => /* @__PURE__ */ jsx6(SectionView, { projected, controller }, projected.section.id)),
|
|
3204
|
-
sections.length === 0 ? /* @__PURE__ */ jsx6(EmptyState2, { title: targets.length === 0 ? "Nothing selected" : "No properties" }) : null
|
|
3205
|
-
] }) })
|
|
3206
|
-
] });
|
|
3471
|
+
return /* @__PURE__ */ jsx6("div", { onKeyDown, tabIndex: 0, role: "group", "aria-label": "Properties", className: "xeno-inspector-properties", children });
|
|
3207
3472
|
}
|
|
3208
|
-
function
|
|
3209
|
-
|
|
3473
|
+
function ActionGlyph({ glyph }) {
|
|
3474
|
+
return /* @__PURE__ */ jsx6("span", { "aria-hidden": true, children: glyph });
|
|
3475
|
+
}
|
|
3476
|
+
function SectionView({ section, controller }) {
|
|
3477
|
+
const ui2 = (intent) => applyInspectorUi(controller, intent);
|
|
3478
|
+
const hasActions = section.actions.length > 0 || section.hasAddMenu;
|
|
3210
3479
|
return /* @__PURE__ */ jsxs5(
|
|
3211
3480
|
Section,
|
|
3212
3481
|
{
|
|
3213
3482
|
title: section.title,
|
|
3214
3483
|
flush: true,
|
|
3215
3484
|
collapsible: section.collapsible,
|
|
3216
|
-
collapsed,
|
|
3217
|
-
onCollapsedChange: () =>
|
|
3218
|
-
enabled: section.enabled
|
|
3219
|
-
onEnabledChange:
|
|
3485
|
+
collapsed: section.collapsed,
|
|
3486
|
+
onCollapsedChange: () => ui2({ kind: "toggleSectionCollapsed", sectionId: section.id }),
|
|
3487
|
+
enabled: section.enabled,
|
|
3488
|
+
onEnabledChange: () => ui2({ kind: "toggleSectionEnabled", sectionId: section.id }),
|
|
3220
3489
|
badge: section.badge ? /* @__PURE__ */ jsx6(Badge2, { children: section.badge }) : null,
|
|
3221
|
-
actions: /* @__PURE__ */ jsxs5(Fragment3, { children: [
|
|
3222
|
-
section.actions
|
|
3223
|
-
section.
|
|
3224
|
-
] }),
|
|
3490
|
+
actions: hasActions ? /* @__PURE__ */ jsxs5(Fragment3, { children: [
|
|
3491
|
+
section.actions.map((action) => /* @__PURE__ */ jsx6(IconButton3, { size: "sm", icon: /* @__PURE__ */ jsx6(ActionGlyph, { glyph: action.glyph }), label: action.label, disabled: action.disabled, onClick: () => ui2({ kind: "runAction", sectionId: section.id, actionId: action.id }) }, action.id)),
|
|
3492
|
+
section.hasAddMenu ? /* @__PURE__ */ jsx6(Select2, { size: "sm", placeholder: "\uFF0B", options: section.addOptions, value: "", label: section.addLabel, onChange: (id) => ui2({ kind: "addItem", sectionId: section.id, itemId: id }) }) : null
|
|
3493
|
+
] }) : null,
|
|
3225
3494
|
children: [
|
|
3226
|
-
|
|
3227
|
-
/* @__PURE__ */ jsx6(FieldGroup, { labelWidth:
|
|
3495
|
+
section.showEmptyHint ? /* @__PURE__ */ jsx6(Stack2, { pad: "inset", children: /* @__PURE__ */ jsx6(Text3, { role: "caption", children: section.emptyHint }) }) : null,
|
|
3496
|
+
/* @__PURE__ */ jsx6(FieldGroup, { labelWidth: section.labelWidth, children: section.fields.map((row) => /* @__PURE__ */ jsx6(FieldRow, { row, controller }, row.id)) })
|
|
3228
3497
|
]
|
|
3229
3498
|
}
|
|
3230
3499
|
);
|
|
3231
3500
|
}
|
|
3232
|
-
function
|
|
3233
|
-
const
|
|
3234
|
-
return /* @__PURE__ */ jsx6(Select2, { size: "sm", placeholder: "\uFF0B", options, value: "", label: `Add to ${section.title}`, onChange: (id) => controller.addItem(section.id, id) });
|
|
3235
|
-
}
|
|
3236
|
-
function FieldRow({ field, controller }) {
|
|
3237
|
-
const focused = controller.getFocused() === field.id;
|
|
3238
|
-
const bound = !!field.token?.tokenId;
|
|
3239
|
-
const anim = field.anim;
|
|
3240
|
-
const showKeyframes = controller.areKeyframesShown() && !!anim;
|
|
3241
|
-
const easingOptions = anim?.easingOptions ?? [];
|
|
3242
|
-
const easing = anim?.easing ?? "";
|
|
3243
|
-
const easingAll = easingOptions.some((o) => o.value === easing) ? easingOptions : [{ value: easing, label: easing || "\u2014" }, ...easingOptions];
|
|
3501
|
+
function FieldRow({ row, controller }) {
|
|
3502
|
+
const ui2 = (intent) => applyInspectorUi(controller, intent);
|
|
3244
3503
|
return /* @__PURE__ */ jsxs5(Fragment3, { children: [
|
|
3245
|
-
/* @__PURE__ */
|
|
3504
|
+
/* @__PURE__ */ jsxs5(
|
|
3246
3505
|
Field,
|
|
3247
3506
|
{
|
|
3248
|
-
label:
|
|
3249
|
-
title:
|
|
3250
|
-
focused,
|
|
3251
|
-
onLabelClick: () =>
|
|
3252
|
-
onContextMenu: (x, y) =>
|
|
3253
|
-
leading: showKeyframes ? /* @__PURE__ */ jsxs5(Fragment3, { children: [
|
|
3254
|
-
/* @__PURE__ */ jsx6(IconButton3, { size: "sm", icon: /* @__PURE__ */ jsx6(StopwatchIcon, {}), label: "Toggle animation", active:
|
|
3255
|
-
|
|
3256
|
-
|
|
3257
|
-
|
|
3258
|
-
/* @__PURE__ */ jsx6(IconButton3, { size: "sm", icon: /* @__PURE__ */ jsx6(NextIcon, {}), label: "Next keyframe", disabled: anim.canNext === false, onClick: () => controller.keyframe(field.id, "next") })
|
|
3259
|
-
] }) : null
|
|
3507
|
+
label: row.label,
|
|
3508
|
+
title: row.title,
|
|
3509
|
+
focused: row.focused,
|
|
3510
|
+
onLabelClick: () => ui2({ kind: "focusField", fieldId: row.id }),
|
|
3511
|
+
onContextMenu: (x, y) => ui2({ kind: "contextMenu", fieldId: row.id, x, y }),
|
|
3512
|
+
leading: row.showKeyframes ? /* @__PURE__ */ jsxs5(Fragment3, { children: [
|
|
3513
|
+
/* @__PURE__ */ jsx6(IconButton3, { size: "sm", icon: /* @__PURE__ */ jsx6(StopwatchIcon, {}), label: "Toggle animation", active: row.animated, onClick: () => ui2({ kind: "keyframe", fieldId: row.id, op: "toggleAnim" }) }),
|
|
3514
|
+
row.animated ? /* @__PURE__ */ jsx6(IconButton3, { size: "sm", icon: /* @__PURE__ */ jsx6(PrevIcon, {}), label: "Previous keyframe", disabled: row.prevDisabled, onClick: () => ui2({ kind: "keyframe", fieldId: row.id, op: "prev" }) }) : null,
|
|
3515
|
+
row.animated ? /* @__PURE__ */ jsx6(IconButton3, { size: "sm", icon: /* @__PURE__ */ jsx6(DiamondIcon, { filled: row.onKeyframe }), label: row.keyframeLabel, onClick: () => ui2({ kind: "keyframe", fieldId: row.id, op: row.keyframeOp }) }) : null,
|
|
3516
|
+
row.animated ? /* @__PURE__ */ jsx6(IconButton3, { size: "sm", icon: /* @__PURE__ */ jsx6(NextIcon, {}), label: "Next keyframe", disabled: row.nextDisabled, onClick: () => ui2({ kind: "keyframe", fieldId: row.id, op: "next" }) }) : null
|
|
3260
3517
|
] }) : null,
|
|
3261
3518
|
trailing: /* @__PURE__ */ jsxs5(Fragment3, { children: [
|
|
3262
|
-
|
|
3263
|
-
showKeyframes ? /* @__PURE__ */ jsx6(Badge2, { size: "sm", children:
|
|
3264
|
-
|
|
3265
|
-
|
|
3519
|
+
row.showEasing ? /* @__PURE__ */ jsx6(Select2, { size: "sm", options: row.easingOptions, value: row.easing, label: "Easing", onChange: (v) => ui2({ kind: "setEasing", fieldId: row.id, easing: v }) }) : null,
|
|
3520
|
+
row.showKeyframes ? /* @__PURE__ */ jsx6(Badge2, { size: "sm", children: row.keyframeChip }) : null,
|
|
3521
|
+
row.showToken ? /* @__PURE__ */ jsx6(IconButton3, { size: "sm", icon: /* @__PURE__ */ jsx6(LinkIcon, {}), label: row.tokenActionLabel, active: row.bound, onClick: () => ui2({ kind: "bindToken", fieldId: row.id }) }) : null,
|
|
3522
|
+
row.showReset ? /* @__PURE__ */ jsx6(IconButton3, { size: "sm", icon: /* @__PURE__ */ jsx6(ResetIcon, {}), label: "Reset to default", onClick: () => ui2({ kind: "resetField", fieldId: row.id }) }) : null
|
|
3266
3523
|
] }),
|
|
3267
|
-
children:
|
|
3524
|
+
children: [
|
|
3525
|
+
row.bound ? /* @__PURE__ */ jsx6(Badge2, { title: row.tokenTitle, children: row.tokenLabel }) : null,
|
|
3526
|
+
row.unbound ? /* @__PURE__ */ jsx6(FieldWidget, { field: row.field, controller }) : null
|
|
3527
|
+
]
|
|
3268
3528
|
}
|
|
3269
3529
|
),
|
|
3270
|
-
|
|
3530
|
+
row.showInfoNote ? /* @__PURE__ */ jsx6(Stack2, { pad: "inset", children: /* @__PURE__ */ jsx6(Text3, { role: "caption", children: row.infoNote }) }) : null
|
|
3271
3531
|
] });
|
|
3272
3532
|
}
|
|
3273
3533
|
function FieldWidget({
|
|
@@ -3308,17 +3568,39 @@ function FieldWidget({
|
|
|
3308
3568
|
return /* @__PURE__ */ jsx6(JsonWidget, { field, controller });
|
|
3309
3569
|
}
|
|
3310
3570
|
}
|
|
3571
|
+
function inspectorRuntimeComponents(controller) {
|
|
3572
|
+
return {
|
|
3573
|
+
"inspector/FieldWidget": ({ field }) => /* @__PURE__ */ jsx6(FieldWidget, { field, controller }),
|
|
3574
|
+
"inspector/Properties": ({ children }) => /* @__PURE__ */ jsx6(InspectorProperties, { controller, children }),
|
|
3575
|
+
"inspector/ActionGlyph": ActionGlyph,
|
|
3576
|
+
"inspector/StopwatchIcon": StopwatchIcon,
|
|
3577
|
+
"inspector/DiamondIcon": DiamondIcon,
|
|
3578
|
+
"inspector/PrevIcon": PrevIcon,
|
|
3579
|
+
"inspector/NextIcon": NextIcon,
|
|
3580
|
+
"inspector/LinkIcon": LinkIcon,
|
|
3581
|
+
"inspector/ResetIcon": ResetIcon
|
|
3582
|
+
};
|
|
3583
|
+
}
|
|
3311
3584
|
|
|
3312
3585
|
// src/edit/inspector/panel.ts
|
|
3313
3586
|
function createInspectorPanel(options = {}) {
|
|
3314
3587
|
return {
|
|
3315
3588
|
manifest: inspectorManifest,
|
|
3316
3589
|
activate(host) {
|
|
3317
|
-
const
|
|
3590
|
+
const { render: customRender, ...controllerOptions } = options;
|
|
3591
|
+
const controller = new InspectorPanelController(host, controllerOptions);
|
|
3318
3592
|
void controller.load();
|
|
3319
3593
|
let root = null;
|
|
3594
|
+
let unrender = null;
|
|
3320
3595
|
return {
|
|
3321
3596
|
render(el) {
|
|
3597
|
+
if (customRender) {
|
|
3598
|
+
unrender = customRender(el, controller);
|
|
3599
|
+
return () => {
|
|
3600
|
+
unrender?.();
|
|
3601
|
+
unrender = null;
|
|
3602
|
+
};
|
|
3603
|
+
}
|
|
3322
3604
|
root = createRoot2(el);
|
|
3323
3605
|
root.render(createElement2(InspectorPanelView, { controller }));
|
|
3324
3606
|
return () => {
|
|
@@ -3341,6 +3623,8 @@ function createInspectorPanel(options = {}) {
|
|
|
3341
3623
|
dispose() {
|
|
3342
3624
|
root?.unmount();
|
|
3343
3625
|
root = null;
|
|
3626
|
+
unrender?.();
|
|
3627
|
+
unrender = null;
|
|
3344
3628
|
controller.dispose();
|
|
3345
3629
|
}
|
|
3346
3630
|
};
|
|
@@ -8314,11 +8598,11 @@ var FindController = class {
|
|
|
8314
8598
|
* @param text - The new query text.
|
|
8315
8599
|
* @param immediate - Skip the debounce (a paste, or pressing Enter).
|
|
8316
8600
|
*/
|
|
8317
|
-
setText(
|
|
8318
|
-
if (
|
|
8319
|
-
this.text =
|
|
8601
|
+
setText(text2, immediate = false) {
|
|
8602
|
+
if (text2 === this.text) return;
|
|
8603
|
+
this.text = text2;
|
|
8320
8604
|
this.index = -1;
|
|
8321
|
-
if (
|
|
8605
|
+
if (text2 === "") {
|
|
8322
8606
|
this.clearResults("idle");
|
|
8323
8607
|
this.emitQuery(true);
|
|
8324
8608
|
return;
|
|
@@ -8346,8 +8630,8 @@ var FindController = class {
|
|
|
8346
8630
|
this.notify();
|
|
8347
8631
|
}
|
|
8348
8632
|
/** The replacement text. Never emitted on its own — a replacement is not a search. */
|
|
8349
|
-
setReplaceText(
|
|
8350
|
-
this.replaceText =
|
|
8633
|
+
setReplaceText(text2) {
|
|
8634
|
+
this.replaceText = text2;
|
|
8351
8635
|
this.notify();
|
|
8352
8636
|
}
|
|
8353
8637
|
/** Show or hide the replace row. */
|
|
@@ -11983,12 +12267,12 @@ var TreeController = class {
|
|
|
11983
12267
|
}
|
|
11984
12268
|
if (event.key.length === 1 && !event.ctrlKey && !event.metaKey && !event.altKey) {
|
|
11985
12269
|
const fresh = now - this.typeAhead.at > this.typeAheadMs;
|
|
11986
|
-
const
|
|
11987
|
-
this.typeAhead = { text, at: now };
|
|
12270
|
+
const text2 = (fresh ? "" : this.typeAhead.text) + event.key.toLowerCase();
|
|
12271
|
+
this.typeAhead = { text: text2, at: now };
|
|
11988
12272
|
const from = fresh ? current : current + 1;
|
|
11989
12273
|
for (let i = 0; i < rows.length; i += 1) {
|
|
11990
12274
|
const candidate = rows[(from + i) % rows.length];
|
|
11991
|
-
if (candidate.node.label.toLowerCase().startsWith(
|
|
12275
|
+
if (candidate.node.label.toLowerCase().startsWith(text2)) {
|
|
11992
12276
|
this.focusedId = candidate.id;
|
|
11993
12277
|
this.select([candidate.id]);
|
|
11994
12278
|
return true;
|
|
@@ -12014,9 +12298,9 @@ var TreeController = class {
|
|
|
12014
12298
|
return true;
|
|
12015
12299
|
}
|
|
12016
12300
|
/** Update the rename draft. */
|
|
12017
|
-
updateRenameDraft(
|
|
12301
|
+
updateRenameDraft(text2) {
|
|
12018
12302
|
if (!this.renaming) return;
|
|
12019
|
-
this.renaming = { ...this.renaming, draft:
|
|
12303
|
+
this.renaming = { ...this.renaming, draft: text2 };
|
|
12020
12304
|
this.notify();
|
|
12021
12305
|
}
|
|
12022
12306
|
/**
|
|
@@ -13208,6 +13492,8 @@ export {
|
|
|
13208
13492
|
HistoryPanelController,
|
|
13209
13493
|
HistoryPanelView,
|
|
13210
13494
|
IMPLEMENTED_TREE_MODES,
|
|
13495
|
+
BEHAVIOURS as INSPECTOR_BEHAVIOURS,
|
|
13496
|
+
INSPECTOR_DECLARATION,
|
|
13211
13497
|
InspectorPanelController,
|
|
13212
13498
|
InspectorPanelView,
|
|
13213
13499
|
LAYER_COLUMNS,
|
|
@@ -13233,6 +13519,7 @@ export {
|
|
|
13233
13519
|
allIds,
|
|
13234
13520
|
anchorStateOf,
|
|
13235
13521
|
appliedCount,
|
|
13522
|
+
applyInspectorUi,
|
|
13236
13523
|
applyPrecision,
|
|
13237
13524
|
applyTangentDrag,
|
|
13238
13525
|
ariaSliderProps,
|
|
@@ -13306,6 +13593,9 @@ export {
|
|
|
13306
13593
|
hsvToRgb,
|
|
13307
13594
|
inspectorManifest,
|
|
13308
13595
|
inspectorPanel,
|
|
13596
|
+
inspectorRuntimeComponents,
|
|
13597
|
+
inspectorViewManifest,
|
|
13598
|
+
inspectorViewState,
|
|
13309
13599
|
interpolateSegment,
|
|
13310
13600
|
isAncestorOf,
|
|
13311
13601
|
isAnimated,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xenosystem/blocks",
|
|
3
|
-
"version": "0.12.
|
|
3
|
+
"version": "0.12.3",
|
|
4
4
|
"description": "XENO Blocks — rung 3 of the front ladder: components composed into a contract-bearing unit (manifest: ports, intents, commands, agent surface), rendered by @xenosystem/workbench. ONE package, one subpath per family (/auth, /edit, /data, /time, /ops, /trust, /agent), one named export per block — XENO PACKAGE NAMING - STANDARD.md.",
|
|
5
5
|
"license": "UNLICENSED",
|
|
6
6
|
"type": "module",
|
|
@@ -59,7 +59,7 @@
|
|
|
59
59
|
},
|
|
60
60
|
"peerDependencies": {
|
|
61
61
|
"@duckdb/duckdb-wasm": ">=1.28.0",
|
|
62
|
-
"@xenosystem/block-sdk": ">=0.3.
|
|
62
|
+
"@xenosystem/block-sdk": ">=0.3.3 <1",
|
|
63
63
|
"@xenosystem/components": ">=0.16.0 <1",
|
|
64
64
|
"@xenosystem/data-core": "^0.1.0",
|
|
65
65
|
"@xenosystem/elements-react": ">=0.0.1",
|
|
@@ -75,7 +75,7 @@
|
|
|
75
75
|
"@types/node": "^22.0.0",
|
|
76
76
|
"@types/react": "^19.0.0",
|
|
77
77
|
"@types/react-dom": "^19.0.0",
|
|
78
|
-
"@xenosystem/block-sdk": "^0.3.
|
|
78
|
+
"@xenosystem/block-sdk": "^0.3.3",
|
|
79
79
|
"@xenosystem/components": "^0.16.0",
|
|
80
80
|
"@xenosystem/data-core": "^0.1.0",
|
|
81
81
|
"@xenosystem/elements-react": "0.0.1",
|