@xenosystem/blocks 0.13.34 → 0.14.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -955,6 +955,17 @@ interface XenoInspectorField {
955
955
  options?: XenoFieldOption[];
956
956
  /** Whether the select renders its searchable variant. */
957
957
  searchable?: boolean;
958
+ /**
959
+ * For `list`: the sub-schema of ONE item. When set, the value is `XenoListItem[]` (each item carries
960
+ * a stable `id` plus one value per sub-field) and every sub-field is reachable as a VIRTUAL field
961
+ * `${listId}[${itemId}].${subId}` — drafts, gestures, nudges and mixed all work on it unchanged,
962
+ * and a commit rewrites the whole list and emits ONE `set` for the LIST field, so a host sees the
963
+ * same contract it would for any other value. This is what a fill / stroke / effect STACK needs
964
+ * (Canvas found it first, 2026-09-18: without it a list could only hold strings).
965
+ */
966
+ itemFields?: XenoInspectorField[];
967
+ /** For a structured `list`: the label drawn on each item row (e.g. `Fill`, `Shadow`). */
968
+ itemLabel?: string;
958
969
  /** Axis labels for `vector` (e.g. `['X','Y']`). */
959
970
  components?: string[];
960
971
  /** Scalar ⇔ per-element expander (Canvas's corner radius). */
@@ -981,7 +992,6 @@ interface XenoSectionAction {
981
992
  icon?: string;
982
993
  disabled?: boolean;
983
994
  }
984
- /** An entry in a section's searchable grouped Add menu (engine's Add Component). */
985
995
  interface XenoAddMenuItem {
986
996
  id: string;
987
997
  label: string;
@@ -1162,6 +1172,12 @@ declare function isCollapsed(section: XenoInspectorSection, collapsedSet: Readon
1162
1172
  /** Every field in the schema, flattened (regardless of collapse/filter). */
1163
1173
  declare function allFields(schema: XenoInspectorSchema): XenoInspectorField[];
1164
1174
  /** Look up a field by id across every section. */
1175
+ /** `listId[itemId].subId` → its three parts, or null for an ordinary field id. */
1176
+ declare function parseListFieldId(fieldId: string): {
1177
+ listId: string;
1178
+ itemId: string;
1179
+ subId: string;
1180
+ } | null;
1165
1181
  declare function findField(schema: XenoInspectorSchema, fieldId: string): XenoInspectorField | undefined;
1166
1182
  /** The section containing a field. */
1167
1183
  declare function findSectionOf(schema: XenoInspectorSchema, fieldId: string): XenoInspectorSection | undefined;
@@ -7600,4 +7616,4 @@ declare function TreeIcon({ name, size }: {
7600
7616
  size?: number;
7601
7617
  }): ReactNode;
7602
7618
 
7603
- export { type BlendModeGroup, type BlendModeOption, type Box, BEHAVIOURS$6 as COLOR_BEHAVIOURS, COLOR_DECLARATION, COLOR_RUNTIME_UNITS, COLOR_SPACES, BEHAVIOURS$2 as COMMENTS_BEHAVIOURS, COMMENTS_DECLARATION, COMMENTS_PANEL_ID, COMMENTS_RUNTIME_UNITS, BEHAVIOURS$5 as CURVE_BEHAVIOURS, CURVE_DECLARATION, CURVE_PANEL_ID, CURVE_RUNTIME_UNITS, type ChannelId, ColorPanelController, type ColorPanelControllerOptions, type ColorPanelSerialized, ColorPanelView, type ColorPanelViewProps, type ColorSpace, type ColorStopSink, type ColorToken, type ColorUiIntent, type ColorViewState, CommentsController, type CommentsControllerOptions, type CommentsHostBridge, type CommentsPanelState, CommentsPanelView, type CommentsPanelViewProps, type CommentsRenderContext, type CommentsThreadView, type CommentsUiIntent, type CommentsViewMessage, type CommentsViewModel, type CommentsViewOptions, type CommentsViewReaction, type CommentsViewState, type CommentsViewThread, 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, CurveSurface, type CurveUiIntent, type CurveViewModel, type CurveViewOptions, 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, BEHAVIOURS$3 as FIND_BEHAVIOURS, FIND_DECLARATION, FIND_PANEL_ID, FIND_RUNTIME_UNITS, FindController, type FindControllerOptions, type FindHostBridge, FindKeys, type FindPanelState, FindPanelView, type FindPanelViewProps, type FindRenderContext, type FindUiIntent, type FindViewGroup, type FindViewModel, type FindViewOptions, type FindViewRow, 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, BEHAVIOURS$7 as HISTORY_BEHAVIOURS, HISTORY_DECLARATION, HISTORY_RUNTIME_UNITS, type HistoryKeyEvent, HistoryPanelController, type HistoryPanelControllerOptions, type HistoryPanelSerialized, HistoryPanelView, type HistoryPanelViewProps, type ProjectOptions as HistoryProjectOptions, type HistoryRow, type HistoryUiIntent, type HistoryViewRow, type HistoryViewState, type Hsl, type Hsv, IMPLEMENTED_TREE_MODES, BEHAVIOURS$8 as INSPECTOR_BEHAVIOURS, INSPECTOR_DECLARATION, INSPECTOR_RUNTIME_UNITS, type InspectorKeyEvent, InspectorPanelController, type InspectorPanelControllerOptions, type InspectorPanelSerialized, InspectorPanelView, type InspectorPanelViewProps, type ProjectOptions$1 as InspectorProjectOptions, type InspectorUiIntent, type InspectorViewField, type InspectorViewSection, type InspectorViewState, BEHAVIOURS$9 as LAYERS_BEHAVIOURS, LAYERS_DECLARATION, LAYERS_RUNTIME_UNITS, LAYER_COLUMNS, type LayerColumn, type LayersKeyEvent, LayersPanelController, type LayersPanelControllerOptions, type LayersPanelSerialized, LayersPanelView, type LayersPanelViewProps, type LayersUiIntent, type LayersViewRow, type LayersViewState, MIXED, BEHAVIOURS$1 as NODEGRAPH_BEHAVIOURS, NODEGRAPH_DECLARATION, NODEGRAPH_PANEL_ID, NODEGRAPH_RUNTIME_UNITS, NodeGraphPanelView, type NodeGraphPanelViewProps, NodeGraphSurface, type NodeGraphUiIntent, type NodeGraphViewModel, type NodeGraphViewOptions, type NumericConstraints, type OklchDisplay, type ParseResult, type ProjectedSection, type Rgba, SPACE_LABEL, type ScrubOptions, type SelectMods, BEHAVIOURS as TREE_BEHAVIOURS, TREE_DECLARATION, TREE_PANEL_ID, TREE_RUNTIME_UNITS, type TangentEdit, Thumbnail, type ThumbnailProps, TreeController, type TreeControllerOptions, type TreeHostBridge, TreeIcon, type TreeKeyEvent, type TreePanelState, TreePanelView, type TreePanelViewProps, type TreeRenderContext, type TreeRow, TreeScroller, type TreeUiIntent, type TreeViewAction, type TreeViewModel, type TreeViewOptions, type TreeViewRow, type TreeViewState, BEHAVIOURS$4 as VIEWPORT_BEHAVIOURS, VIEWPORT_DECLARATION, VIEWPORT_PANEL_ID, VIEWPORT_RUNTIME_UNITS, VIEWPORT_SLOTS, VIEW_STATE_OPS, ViewportController, type ViewportControllerOptions, type ViewportHostBridge, type ViewportPanelState, ViewportPanelView, type ViewportPanelViewProps, type ViewportRenderContext, ViewportSurface, type ViewportViewModel, type ViewportViewOptions, 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, applyColorUi, applyCommentsUi, applyCurveUi, applyFindUi, applyHistoryUi, applyInspectorUi, applyLayersUi, applyNodeGraphUi, applyPrecision, applyTangentDrag, applyTreeUi, ariaSliderProps, boxesIntersect, canConnect, canRedo, canUndo, childStateOf, clamp, clampAlpha, clampTangent, collectDescendants, colorManifest, colorPanel, colorRuntimeComponents, colorViewManifest, colorViewState, commentsManifest, commentsPanel, commentsViewManifest, commentsViewState, commitPolicyOf, componentsForSpace, computeSurfaceSize, constraintsOf, countIsMeaningful, createColorPanel, createCommentsPanel, createCurvePanel, createFindPanel, createHistoryPanel, createInspectorPanel, createLayersPanel, createNodeGraphPanel, createTreePanel, createViewportPanel, createsCycle, currentRowIndex, curveManifest, curvePanel, curveRuntimeComponents, curveViewManifest, curveViewState, defaultIconFor, displayOrder, distanceToEdge, easeAt, easingPreset, edgeBounds, edgeKey, edgePath, edgesToReplace, edgesTouching, evaluateChannel, fieldMatches, findField, findManifest, findPanel, findPort, findRuntimeComponents, findSectionOf, findViewManifest, findViewState, fitToBounds, fitValueRange, flattenVisible, focusOrder, formatAge, formatNumeric, getAncestors, graphBounds, groupMatches, hasCap, hasDraggableTangents, hasTreeCap, hexFromHsv, highlightSegments, historyManifest, historyPanel, historyRuntimeComponents, historyViewManifest, historyViewState, 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, layersRuntimeComponents, layersViewManifest, layersViewState, liveEdges, makeColorValue, matchesFilter, messagesOf, mirrorTangent, nodeBounds, nodegraphManifest, nodegraphPanel, nodegraphRuntimeComponents, nodegraphViewManifest, nodegraphViewState, 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, treeRuntimeComponents, treeViewManifest, treeViewState, usesLogScale, valueExtent, valueToPosition, valuesEqual, viewportManifest, viewportPanel, viewportRuntimeComponents, viewportViewManifest, viewportViewState, visibleEdges, walkTree, wheelZoomFactor, zoomAboutCursor, zoomTimeAboutCursor, zoomValueAboutCursor };
7619
+ export { type BlendModeGroup, type BlendModeOption, type Box, BEHAVIOURS$6 as COLOR_BEHAVIOURS, COLOR_DECLARATION, COLOR_RUNTIME_UNITS, COLOR_SPACES, BEHAVIOURS$2 as COMMENTS_BEHAVIOURS, COMMENTS_DECLARATION, COMMENTS_PANEL_ID, COMMENTS_RUNTIME_UNITS, BEHAVIOURS$5 as CURVE_BEHAVIOURS, CURVE_DECLARATION, CURVE_PANEL_ID, CURVE_RUNTIME_UNITS, type ChannelId, ColorPanelController, type ColorPanelControllerOptions, type ColorPanelSerialized, ColorPanelView, type ColorPanelViewProps, type ColorSpace, type ColorStopSink, type ColorToken, type ColorUiIntent, type ColorViewState, CommentsController, type CommentsControllerOptions, type CommentsHostBridge, type CommentsPanelState, CommentsPanelView, type CommentsPanelViewProps, type CommentsRenderContext, type CommentsThreadView, type CommentsUiIntent, type CommentsViewMessage, type CommentsViewModel, type CommentsViewOptions, type CommentsViewReaction, type CommentsViewState, type CommentsViewThread, 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, CurveSurface, type CurveUiIntent, type CurveViewModel, type CurveViewOptions, 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, BEHAVIOURS$3 as FIND_BEHAVIOURS, FIND_DECLARATION, FIND_PANEL_ID, FIND_RUNTIME_UNITS, FindController, type FindControllerOptions, type FindHostBridge, FindKeys, type FindPanelState, FindPanelView, type FindPanelViewProps, type FindRenderContext, type FindUiIntent, type FindViewGroup, type FindViewModel, type FindViewOptions, type FindViewRow, 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, BEHAVIOURS$7 as HISTORY_BEHAVIOURS, HISTORY_DECLARATION, HISTORY_RUNTIME_UNITS, type HistoryKeyEvent, HistoryPanelController, type HistoryPanelControllerOptions, type HistoryPanelSerialized, HistoryPanelView, type HistoryPanelViewProps, type ProjectOptions as HistoryProjectOptions, type HistoryRow, type HistoryUiIntent, type HistoryViewRow, type HistoryViewState, type Hsl, type Hsv, IMPLEMENTED_TREE_MODES, BEHAVIOURS$8 as INSPECTOR_BEHAVIOURS, INSPECTOR_DECLARATION, INSPECTOR_RUNTIME_UNITS, type InspectorKeyEvent, InspectorPanelController, type InspectorPanelControllerOptions, type InspectorPanelSerialized, InspectorPanelView, type InspectorPanelViewProps, type ProjectOptions$1 as InspectorProjectOptions, type InspectorUiIntent, type InspectorViewField, type InspectorViewSection, type InspectorViewState, BEHAVIOURS$9 as LAYERS_BEHAVIOURS, LAYERS_DECLARATION, LAYERS_RUNTIME_UNITS, LAYER_COLUMNS, type LayerColumn, type LayersKeyEvent, LayersPanelController, type LayersPanelControllerOptions, type LayersPanelSerialized, LayersPanelView, type LayersPanelViewProps, type LayersUiIntent, type LayersViewRow, type LayersViewState, MIXED, BEHAVIOURS$1 as NODEGRAPH_BEHAVIOURS, NODEGRAPH_DECLARATION, NODEGRAPH_PANEL_ID, NODEGRAPH_RUNTIME_UNITS, NodeGraphPanelView, type NodeGraphPanelViewProps, NodeGraphSurface, type NodeGraphUiIntent, type NodeGraphViewModel, type NodeGraphViewOptions, type NumericConstraints, type OklchDisplay, type ParseResult, type ProjectedSection, type Rgba, SPACE_LABEL, type ScrubOptions, type SelectMods, BEHAVIOURS as TREE_BEHAVIOURS, TREE_DECLARATION, TREE_PANEL_ID, TREE_RUNTIME_UNITS, type TangentEdit, Thumbnail, type ThumbnailProps, TreeController, type TreeControllerOptions, type TreeHostBridge, TreeIcon, type TreeKeyEvent, type TreePanelState, TreePanelView, type TreePanelViewProps, type TreeRenderContext, type TreeRow, TreeScroller, type TreeUiIntent, type TreeViewAction, type TreeViewModel, type TreeViewOptions, type TreeViewRow, type TreeViewState, BEHAVIOURS$4 as VIEWPORT_BEHAVIOURS, VIEWPORT_DECLARATION, VIEWPORT_PANEL_ID, VIEWPORT_RUNTIME_UNITS, VIEWPORT_SLOTS, VIEW_STATE_OPS, ViewportController, type ViewportControllerOptions, type ViewportHostBridge, type ViewportPanelState, ViewportPanelView, type ViewportPanelViewProps, type ViewportRenderContext, ViewportSurface, type ViewportViewModel, type ViewportViewOptions, 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, applyColorUi, applyCommentsUi, applyCurveUi, applyFindUi, applyHistoryUi, applyInspectorUi, applyLayersUi, applyNodeGraphUi, applyPrecision, applyTangentDrag, applyTreeUi, ariaSliderProps, boxesIntersect, canConnect, canRedo, canUndo, childStateOf, clamp, clampAlpha, clampTangent, collectDescendants, colorManifest, colorPanel, colorRuntimeComponents, colorViewManifest, colorViewState, commentsManifest, commentsPanel, commentsViewManifest, commentsViewState, commitPolicyOf, componentsForSpace, computeSurfaceSize, constraintsOf, countIsMeaningful, createColorPanel, createCommentsPanel, createCurvePanel, createFindPanel, createHistoryPanel, createInspectorPanel, createLayersPanel, createNodeGraphPanel, createTreePanel, createViewportPanel, createsCycle, currentRowIndex, curveManifest, curvePanel, curveRuntimeComponents, curveViewManifest, curveViewState, defaultIconFor, displayOrder, distanceToEdge, easeAt, easingPreset, edgeBounds, edgeKey, edgePath, edgesToReplace, edgesTouching, evaluateChannel, fieldMatches, findField, findManifest, findPanel, findPort, findRuntimeComponents, findSectionOf, findViewManifest, findViewState, fitToBounds, fitValueRange, flattenVisible, focusOrder, formatAge, formatNumeric, getAncestors, graphBounds, groupMatches, hasCap, hasDraggableTangents, hasTreeCap, hexFromHsv, highlightSegments, historyManifest, historyPanel, historyRuntimeComponents, historyViewManifest, historyViewState, 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, layersRuntimeComponents, layersViewManifest, layersViewState, liveEdges, makeColorValue, matchesFilter, messagesOf, mirrorTangent, nodeBounds, nodegraphManifest, nodegraphPanel, nodegraphRuntimeComponents, nodegraphViewManifest, nodegraphViewState, normalizeColorInput, normalizeHistoryState, normalizeKindKey, normalizeNumeric, normalizeRanges, normalizeSchema, normalizeTree, nudgeValue, oklchToRgb, parseCssColor, parseHexColor, parseListFieldId, 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, treeRuntimeComponents, treeViewManifest, treeViewState, usesLogScale, valueExtent, valueToPosition, valuesEqual, viewportManifest, viewportPanel, viewportRuntimeComponents, viewportViewManifest, viewportViewState, visibleEdges, walkTree, wheelZoomFactor, zoomAboutCursor, zoomTimeAboutCursor, zoomValueAboutCursor };
@@ -1990,12 +1990,23 @@ function allFields(schema) {
1990
1990
  for (const section of schema.sections) out.push(...section.fields);
1991
1991
  return out;
1992
1992
  }
1993
+ function parseListFieldId(fieldId) {
1994
+ const m = /^(.+?)\[([^\]]+)\]\.(.+)$/.exec(fieldId);
1995
+ return m ? { listId: m[1], itemId: m[2], subId: m[3] } : null;
1996
+ }
1993
1997
  function findField(schema, fieldId) {
1994
1998
  for (const section of schema.sections) {
1995
1999
  const found = section.fields.find((f) => f.id === fieldId);
1996
2000
  if (found) return found;
1997
2001
  }
1998
- return void 0;
2002
+ const v = parseListFieldId(fieldId);
2003
+ if (!v) return void 0;
2004
+ const list = findField(schema, v.listId);
2005
+ const sub = list?.itemFields?.find((f) => f.id === v.subId);
2006
+ if (!list || !sub) return void 0;
2007
+ const item = (Array.isArray(list.value) ? list.value : []).find((it) => it?.id === v.itemId);
2008
+ if (!item) return void 0;
2009
+ return { ...sub, id: fieldId, value: item[v.subId], disabled: sub.disabled || list.disabled, readOnly: sub.readOnly || list.readOnly };
1999
2010
  }
2000
2011
  function findSectionOf(schema, fieldId) {
2001
2012
  return schema.sections.find((s) => s.fields.some((f) => f.id === fieldId));
@@ -2335,6 +2346,13 @@ var InspectorPanelController = class {
2335
2346
  if (!force && !mixed && valuesEqual(value, this.getFieldValue(fieldId))) return false;
2336
2347
  const targetIds = this.targetIds();
2337
2348
  const id = gestureId ?? (targetIds.length > 1 ? this.nextGestureId() : void 0);
2349
+ const virtual = parseListFieldId(fieldId);
2350
+ if (virtual) {
2351
+ const items = this.getFieldValue(virtual.listId) ?? [];
2352
+ const next = items.map((it) => it.id === virtual.itemId ? { ...it, [virtual.subId]: value } : it);
2353
+ this.emit(id ? { type: "set", targetIds, fieldId: virtual.listId, value: next, gestureId: id } : { type: "set", targetIds, fieldId: virtual.listId, value: next });
2354
+ return true;
2355
+ }
2338
2356
  this.emit(id ? { type: "set", targetIds, fieldId, value, gestureId: id } : { type: "set", targetIds, fieldId, value });
2339
2357
  return true;
2340
2358
  }
@@ -3226,6 +3244,7 @@ import { Badge as Badge2, Column as Column2, EmptyState as EmptyState2, Field, F
3226
3244
 
3227
3245
  // src/edit/inspector/react/widgets.tsx
3228
3246
  import { useCallback as useCallback2, useRef as useRef3 } from "react";
3247
+ import { Fragment as Fragment2 } from "react";
3229
3248
  import {
3230
3249
  AxisLabel,
3231
3250
  IconButton as IconButton2,
@@ -3240,7 +3259,7 @@ import {
3240
3259
  TextButton,
3241
3260
  Toggle
3242
3261
  } from "@xenosystem/components/chrome";
3243
- import { Fragment as Fragment2, jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
3262
+ import { Fragment as Fragment3, jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
3244
3263
  function displayText(field, controller) {
3245
3264
  const draft = controller.getDraft(field.id);
3246
3265
  if (draft !== void 0) return draft;
@@ -3492,7 +3511,13 @@ function ColorWidget({ field, controller }) {
3492
3511
  }
3493
3512
  );
3494
3513
  }
3495
- function ListWidget({ field, controller }) {
3514
+ var listSeq = 0;
3515
+ function newListItem(field) {
3516
+ const item = { id: `i${Date.now().toString(36)}${listSeq += 1}` };
3517
+ for (const sub of field.itemFields ?? []) item[sub.id] = sub.defaultValue;
3518
+ return item;
3519
+ }
3520
+ function ListWidget({ field, controller, renderField }) {
3496
3521
  const editable = isFieldEditable(field);
3497
3522
  const raw = controller.getFieldValue(field.id);
3498
3523
  const items = Array.isArray(raw) ? raw : [];
@@ -3503,16 +3528,23 @@ function ListWidget({ field, controller }) {
3503
3528
  next.splice(to, 0, moved);
3504
3529
  write(next);
3505
3530
  };
3531
+ const structured = !!field.itemFields?.length;
3506
3532
  return /* @__PURE__ */ jsxs2(Stack, { gap: 2, pad: "none", children: [
3507
3533
  items.map((item, i) => /* @__PURE__ */ jsxs2(Stack, { direction: "row", gap: 2, pad: "none", children: [
3508
- /* @__PURE__ */ jsx3(Text2, { role: "meta", children: typeof item === "string" ? item : JSON.stringify(item) }),
3509
- editable ? /* @__PURE__ */ jsxs2(Fragment2, { children: [
3534
+ structured && renderField ? /* @__PURE__ */ jsxs2(Stack, { gap: 2, pad: "none", children: [
3535
+ field.itemLabel ? /* @__PURE__ */ jsx3(Text2, { role: "caption", children: `${field.itemLabel} ${i + 1}` }) : null,
3536
+ field.itemFields.map((sub) => {
3537
+ const virtual = controller.getField(`${field.id}[${item.id}].${sub.id}`);
3538
+ return virtual ? /* @__PURE__ */ jsx3(Fragment2, { children: renderField(virtual) }, sub.id) : null;
3539
+ })
3540
+ ] }) : /* @__PURE__ */ jsx3(Text2, { role: "meta", children: typeof item === "string" ? item : JSON.stringify(item) }),
3541
+ editable ? /* @__PURE__ */ jsxs2(Fragment3, { children: [
3510
3542
  /* @__PURE__ */ jsx3(IconButton2, { size: "sm", icon: /* @__PURE__ */ jsx3("span", { "aria-hidden": true, children: "\u2191" }), label: "Move up", disabled: i === 0, onClick: () => move(i, i - 1) }),
3511
3543
  /* @__PURE__ */ jsx3(IconButton2, { size: "sm", icon: /* @__PURE__ */ jsx3("span", { "aria-hidden": true, children: "\u2193" }), label: "Move down", disabled: i === items.length - 1, onClick: () => move(i, i + 1) }),
3512
3544
  /* @__PURE__ */ jsx3(IconButton2, { size: "sm", icon: /* @__PURE__ */ jsx3(XIcon2, {}), label: "Remove", onClick: () => write(items.filter((_, j) => j !== i)) })
3513
3545
  ] }) : null
3514
- ] }, i)),
3515
- editable ? /* @__PURE__ */ jsx3(TextButton, { onClick: () => write([...items, ""]), children: "+ Add" }) : null
3546
+ ] }, structured ? item.id : i)),
3547
+ editable ? /* @__PURE__ */ jsx3(TextButton, { onClick: () => write([...items, structured ? newListItem(field) : ""]), children: "+ Add" }) : null
3516
3548
  ] });
3517
3549
  }
3518
3550
  function InfoWidget({ field, controller }) {
@@ -3539,7 +3571,7 @@ function JsonWidget({ field, controller }) {
3539
3571
  }
3540
3572
 
3541
3573
  // src/edit/inspector/react/InspectorPanelView.tsx
3542
- import { Fragment as Fragment3, jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
3574
+ import { Fragment as Fragment4, jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
3543
3575
  function InspectorPanelView({ controller }) {
3544
3576
  const subscribe = useCallback3((cb) => controller.subscribe(cb), [controller]);
3545
3577
  const getSnapshot = useCallback3(() => controller.getRevision(), [controller]);
@@ -3586,7 +3618,7 @@ function SectionView({ section, controller }) {
3586
3618
  enabled: section.enabled,
3587
3619
  onEnabledChange: () => ui10({ kind: "toggleSectionEnabled", sectionId: section.id }),
3588
3620
  badge: section.badge ? /* @__PURE__ */ jsx4(Badge2, { children: section.badge }) : null,
3589
- actions: hasActions ? /* @__PURE__ */ jsxs3(Fragment3, { children: [
3621
+ actions: hasActions ? /* @__PURE__ */ jsxs3(Fragment4, { children: [
3590
3622
  section.actions.map((action) => /* @__PURE__ */ jsx4(IconButton3, { size: "sm", icon: /* @__PURE__ */ jsx4(ActionGlyph, { glyph: action.glyph }), label: action.label, disabled: action.disabled, onClick: () => ui10({ kind: "runAction", sectionId: section.id, actionId: action.id }) }, action.id)),
3591
3623
  section.hasAddMenu ? /* @__PURE__ */ jsx4(Menu, { size: "sm", trigger: "\uFF0B", items: section.addItems, label: section.addLabel, align: "end", onSelect: (id) => ui10({ kind: "addItem", sectionId: section.id, itemId: id }) }) : null
3592
3624
  ] }) : null,
@@ -3599,7 +3631,7 @@ function SectionView({ section, controller }) {
3599
3631
  }
3600
3632
  function FieldRow({ row: row2, controller }) {
3601
3633
  const ui10 = (intent) => applyInspectorUi(controller, intent);
3602
- return /* @__PURE__ */ jsxs3(Fragment3, { children: [
3634
+ return /* @__PURE__ */ jsxs3(Fragment4, { children: [
3603
3635
  /* @__PURE__ */ jsxs3(
3604
3636
  Field,
3605
3637
  {
@@ -3608,13 +3640,13 @@ function FieldRow({ row: row2, controller }) {
3608
3640
  focused: row2.focused,
3609
3641
  onLabelClick: () => ui10({ kind: "focusField", fieldId: row2.id }),
3610
3642
  onContextMenu: (x, y) => ui10({ kind: "contextMenu", fieldId: row2.id, x, y }),
3611
- leading: row2.showKeyframes ? /* @__PURE__ */ jsxs3(Fragment3, { children: [
3643
+ leading: row2.showKeyframes ? /* @__PURE__ */ jsxs3(Fragment4, { children: [
3612
3644
  /* @__PURE__ */ jsx4(IconButton3, { size: "sm", icon: /* @__PURE__ */ jsx4(StopwatchIcon, {}), label: "Toggle animation", active: row2.animated, onClick: () => ui10({ kind: "keyframe", fieldId: row2.id, op: "toggleAnim" }) }),
3613
3645
  row2.animated ? /* @__PURE__ */ jsx4(IconButton3, { size: "sm", icon: /* @__PURE__ */ jsx4(PrevIcon, {}), label: "Previous keyframe", disabled: row2.prevDisabled, onClick: () => ui10({ kind: "keyframe", fieldId: row2.id, op: "prev" }) }) : null,
3614
3646
  row2.animated ? /* @__PURE__ */ jsx4(IconButton3, { size: "sm", icon: /* @__PURE__ */ jsx4(DiamondIcon, { filled: row2.onKeyframe }), label: row2.keyframeLabel, onClick: () => ui10({ kind: "keyframe", fieldId: row2.id, op: row2.keyframeOp }) }) : null,
3615
3647
  row2.animated ? /* @__PURE__ */ jsx4(IconButton3, { size: "sm", icon: /* @__PURE__ */ jsx4(NextIcon, {}), label: "Next keyframe", disabled: row2.nextDisabled, onClick: () => ui10({ kind: "keyframe", fieldId: row2.id, op: "next" }) }) : null
3616
3648
  ] }) : null,
3617
- trailing: /* @__PURE__ */ jsxs3(Fragment3, { children: [
3649
+ trailing: /* @__PURE__ */ jsxs3(Fragment4, { children: [
3618
3650
  row2.showEasing ? /* @__PURE__ */ jsx4(Select2, { size: "sm", options: row2.easingOptions, value: row2.easing, label: "Easing", onChange: (v) => ui10({ kind: "setEasing", fieldId: row2.id, easing: v }) }) : null,
3619
3651
  row2.showKeyframes ? /* @__PURE__ */ jsx4(Badge2, { size: "sm", children: row2.keyframeChip }) : null,
3620
3652
  row2.showToken ? /* @__PURE__ */ jsx4(IconButton3, { size: "sm", icon: /* @__PURE__ */ jsx4(LinkIcon, {}), label: row2.tokenActionLabel, active: row2.bound, onClick: () => ui10({ kind: "bindToken", fieldId: row2.id }) }) : null,
@@ -3647,7 +3679,7 @@ function FieldWidget({
3647
3679
  case "color":
3648
3680
  return /* @__PURE__ */ jsx4(ColorWidget, { field, controller });
3649
3681
  case "list":
3650
- return /* @__PURE__ */ jsx4(ListWidget, { field, controller });
3682
+ return /* @__PURE__ */ jsx4(ListWidget, { field, controller, renderField: (f) => /* @__PURE__ */ jsx4(FieldWidget, { field: f, controller }) });
3651
3683
  case "info":
3652
3684
  return /* @__PURE__ */ jsx4(InfoWidget, { field, controller });
3653
3685
  case "text":
@@ -4863,7 +4895,7 @@ var HISTORY_DECLARATION = {
4863
4895
 
4864
4896
  // src/edit/history/react/HistoryPanelView.tsx
4865
4897
  import { Badge as Badge3, Column as Column3, EmptyState as EmptyState3, IconButton as IconButton4, InlineConfirm, RowList as RowList2, Row as Row2, ScrollArea as ScrollArea3, SearchField as SearchField3, Spinner, StatusBar as StatusBar2, Text as Text4, Toolbar as Toolbar2, VirtualWindow as VirtualWindow2 } from "@xenosystem/components/chrome";
4866
- import { Fragment as Fragment4, jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
4898
+ import { Fragment as Fragment5, jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
4867
4899
  function HistoryPanelView({ controller }) {
4868
4900
  const subscribe = useCallback4((cb) => controller.subscribe(cb), [controller]);
4869
4901
  const getSnapshot = useCallback4(() => controller.getRevision(), [controller]);
@@ -4874,11 +4906,11 @@ function HistoryPanelView({ controller }) {
4874
4906
  /* @__PURE__ */ jsx5(
4875
4907
  Toolbar2,
4876
4908
  {
4877
- left: /* @__PURE__ */ jsxs4(Fragment4, { children: [
4909
+ left: /* @__PURE__ */ jsxs4(Fragment5, { children: [
4878
4910
  /* @__PURE__ */ jsx5(IconButton4, { size: "sm", icon: /* @__PURE__ */ jsx5(UndoIcon, {}), label: "Undo", disabled: !view.canUndo, onClick: () => ui10({ kind: "undo" }) }),
4879
4911
  /* @__PURE__ */ jsx5(IconButton4, { size: "sm", icon: /* @__PURE__ */ jsx5(RedoIcon, {}), label: "Redo", disabled: !view.canRedo, onClick: () => ui10({ kind: "redo" }) })
4880
4912
  ] }),
4881
- right: /* @__PURE__ */ jsxs4(Fragment4, { children: [
4913
+ right: /* @__PURE__ */ jsxs4(Fragment5, { children: [
4882
4914
  /* @__PURE__ */ jsx5(Text4, { role: "number", children: view.counter }),
4883
4915
  view.clearAllowed ? /* @__PURE__ */ jsx5(IconButton4, { size: "sm", icon: /* @__PURE__ */ jsx5(TrashIcon, {}), label: "Clear history", onClick: () => ui10({ kind: "requestClear" }) }) : null
4884
4916
  ] }),
@@ -4959,7 +4991,7 @@ function HistoryRowView({ row: row2, controller }) {
4959
4991
  meta: row2.meta,
4960
4992
  "data-history-row": row2.key,
4961
4993
  title: row2.label,
4962
- trailing: /* @__PURE__ */ jsxs4(Fragment4, { children: [
4994
+ trailing: /* @__PURE__ */ jsxs4(Fragment5, { children: [
4963
4995
  row2.pending ? /* @__PURE__ */ jsx5(Spinner, {}) : null,
4964
4996
  row2.failed ? /* @__PURE__ */ jsx5(Badge3, { size: "sm", tone: "error", children: "failed" }) : null,
4965
4997
  row2.showSource ? /* @__PURE__ */ jsx5(Badge3, { size: "sm", title: row2.sourceTitle, children: row2.sourceGlyph }) : null,
@@ -7784,7 +7816,7 @@ var CURVE_DECLARATION = {
7784
7816
  };
7785
7817
 
7786
7818
  // src/edit/curve/react/CurvePanelView.tsx
7787
- import { Fragment as Fragment5, jsx as jsx7, jsxs as jsxs6 } from "react/jsx-runtime";
7819
+ import { Fragment as Fragment6, jsx as jsx7, jsxs as jsxs6 } from "react/jsx-runtime";
7788
7820
  var DASHES = ["none", "4 2", "1 2", "6 2 1 2"];
7789
7821
  function CurvePanelView({ controller, ...options }) {
7790
7822
  useSyncExternalStore5(controller.subscribe, controller.getState, controller.getState);
@@ -8002,7 +8034,7 @@ function Handles({
8002
8034
  scale
8003
8035
  }) {
8004
8036
  const sides = ["in", "out"];
8005
- return /* @__PURE__ */ jsx7(Fragment5, { children: sides.map((side) => {
8037
+ return /* @__PURE__ */ jsx7(Fragment6, { children: sides.map((side) => {
8006
8038
  const tangent = side === "in" ? keyframe.tangentIn : keyframe.tangentOut;
8007
8039
  if (!tangent) return null;
8008
8040
  const hx = scale.tickToX(keyframe.tick + tangent.x);
@@ -9671,7 +9703,7 @@ var FIND_DECLARATION = {
9671
9703
  };
9672
9704
 
9673
9705
  // src/edit/find/react/FindPanelView.tsx
9674
- import { Fragment as Fragment6, jsx as jsx9, jsxs as jsxs8 } from "react/jsx-runtime";
9706
+ import { Fragment as Fragment7, jsx as jsx9, jsxs as jsxs8 } from "react/jsx-runtime";
9675
9707
  var CaseIcon = ICONS["icons/Case"];
9676
9708
  var WordIcon = ICONS["icons/WholeWord"];
9677
9709
  var RegexIcon = ICONS["icons/Regex"];
@@ -9726,7 +9758,7 @@ function FindPanelView({ controller, showResults, placeholder }) {
9726
9758
  Toolbar4,
9727
9759
  {
9728
9760
  divided: false,
9729
- left: /* @__PURE__ */ jsxs8(Fragment6, { children: [
9761
+ left: /* @__PURE__ */ jsxs8(Fragment7, { children: [
9730
9762
  view.invalid ? /* @__PURE__ */ jsx9(Badge5, { tone: "error", title: view.message ?? void 0, children: "invalid pattern" }) : null,
9731
9763
  view.failed ? /* @__PURE__ */ jsx9(Badge5, { tone: "error", title: view.message ?? void 0, children: "search failed" }) : null,
9732
9764
  view.searchingBadge ? /* @__PURE__ */ jsx9(Badge5, { children: "searching\u2026" }) : null,
@@ -11925,7 +11957,7 @@ var NODEGRAPH_DECLARATION = {
11925
11957
  };
11926
11958
 
11927
11959
  // src/edit/nodegraph/react/NodeGraphPanelView.tsx
11928
- import { Fragment as Fragment7, jsx as jsx11, jsxs as jsxs10 } from "react/jsx-runtime";
11960
+ import { Fragment as Fragment8, jsx as jsx11, jsxs as jsxs10 } from "react/jsx-runtime";
11929
11961
  var HEADER_H2 = 24;
11930
11962
  var PORT_ROW_H2 = 18;
11931
11963
  function NodeGraphPanelView({ controller, ...options }) {
@@ -12142,7 +12174,7 @@ function NodeRect({ node, selected, zoom }) {
12142
12174
  children: node.title
12143
12175
  }
12144
12176
  ),
12145
- node.collapsed ? null : /* @__PURE__ */ jsxs10(Fragment7, { children: [
12177
+ node.collapsed ? null : /* @__PURE__ */ jsxs10(Fragment8, { children: [
12146
12178
  node.inputs.map((port, i) => /* @__PURE__ */ jsx11(
12147
12179
  Port,
12148
12180
  {
@@ -13752,13 +13784,13 @@ var TREE_DECLARATION = {
13752
13784
  };
13753
13785
 
13754
13786
  // src/edit/tree/react/TreePanelView.tsx
13755
- import { Fragment as Fragment8, jsx as jsx12, jsxs as jsxs11 } from "react/jsx-runtime";
13787
+ import { Fragment as Fragment9, jsx as jsx12, jsxs as jsxs11 } from "react/jsx-runtime";
13756
13788
  var DRAG_THRESHOLD2 = 4;
13757
13789
  function TreePanelView({ controller, ...options }) {
13758
13790
  useSyncExternalStore10(controller.subscribe, controller.getState, controller.getState);
13759
13791
  const view = treeViewState(controller, options);
13760
13792
  const ui10 = (intent) => applyTreeUi(controller, intent, options);
13761
- const icon = (name, textValue) => /* @__PURE__ */ jsxs11(Fragment8, { children: [
13793
+ const icon = (name, textValue) => /* @__PURE__ */ jsxs11(Fragment9, { children: [
13762
13794
  name ? /* @__PURE__ */ jsx12(TreeIcon, { name }) : null,
13763
13795
  textValue ? /* @__PURE__ */ jsx12(Text9, { role: "caption", children: textValue }) : null
13764
13796
  ] });
@@ -13775,18 +13807,18 @@ function TreePanelView({ controller, ...options }) {
13775
13807
  dropHint: r.dropHint,
13776
13808
  title: r.dropTitle,
13777
13809
  icon: icon(r.iconName, r.iconText),
13778
- label: /* @__PURE__ */ jsxs11(Fragment8, { children: [
13810
+ label: /* @__PURE__ */ jsxs11(Fragment9, { children: [
13779
13811
  r.renaming ? /* @__PURE__ */ jsx12(Input5, { autoFocus: true, value: r.draft, label: "Name", onChange: (value) => ui10({ kind: "renameDraft", value }), onBlur: () => ui10({ kind: "commitRename" }), onKeyDown: (e) => ui10({ kind: "renameKey", key: e.key }) }) : null,
13780
13812
  !r.renaming ? r.label : null
13781
13813
  ] }),
13782
- meta: /* @__PURE__ */ jsxs11(Fragment8, { children: [
13814
+ meta: /* @__PURE__ */ jsxs11(Fragment9, { children: [
13783
13815
  r.chipLoading ? /* @__PURE__ */ jsx12(Text9, { role: "caption", children: "loading\u2026" }) : null,
13784
13816
  r.chipError ? /* @__PURE__ */ jsx12(Badge8, { tone: "error", children: r.chipErrorText }) : null,
13785
13817
  r.chipLoadMore ? /* @__PURE__ */ jsx12(TextButton7, { onClick: () => ui10({ kind: "loadMore", id: r.id }), children: "load more\u2026" }) : null,
13786
13818
  r.chipTruncated ? /* @__PURE__ */ jsx12(Badge8, { tone: "warning", children: r.chipTruncatedText }) : null,
13787
13819
  r.chipEmpty ? /* @__PURE__ */ jsx12(Text9, { role: "caption", children: "empty" }) : null
13788
13820
  ] }),
13789
- trailing: /* @__PURE__ */ jsxs11(Fragment8, { children: [
13821
+ trailing: /* @__PURE__ */ jsxs11(Fragment9, { children: [
13790
13822
  r.columns.map((c) => /* @__PURE__ */ jsx12(Text9, { role: "number", children: c.text }, c.key)),
13791
13823
  r.glyphs.map((g) => /* @__PURE__ */ jsx12(Text9, { role: "meta", title: g.title, children: icon(g.iconName, g.iconText) }, g.key)),
13792
13824
  r.badges.map((b) => /* @__PURE__ */ jsx12(Badge8, { tone: b.tone, children: b.text }, b.key)),
@@ -14334,6 +14366,7 @@ export {
14334
14366
  oklchToRgb,
14335
14367
  parseCssColor,
14336
14368
  parseHexColor,
14369
+ parseListFieldId,
14337
14370
  parseNumeric,
14338
14371
  passesFilter,
14339
14372
  patternError,
@@ -2855,7 +2855,7 @@ var timelineManifest = {
2855
2855
 
2856
2856
  // src/time/timeline/react/TimelinePanelView.tsx
2857
2857
  import { useCallback as useCallback2, useEffect as useEffect2, useRef as useRef2, useSyncExternalStore as useSyncExternalStore2 } from "react";
2858
- import { Column as Column2, DrawnSurface, EmptyState, FilterChip, SegmentedControl, StatusBar, Text, TextButton as TextButton2, Toolbar, ToolbarGroup } from "@xenosystem/components/chrome";
2858
+ import { Clip, Column as Column2, DrawnSurface, EmptyState, FilterChip, Lane, Marquee, Playhead, Ruler, SegmentedControl, StatusBar, Text, TextButton as TextButton2, Tick, Toolbar, ToolbarGroup } from "@xenosystem/components/chrome";
2859
2859
 
2860
2860
  // src/time/timeline/declaration.ts
2861
2861
  import { formatTick as formatTick4 } from "@xenosystem/time-core";
@@ -3076,96 +3076,29 @@ function TimelineSurface({ controller }) {
3076
3076
  onPointerCancel: onPointerUp,
3077
3077
  onKeyDown,
3078
3078
  children: [
3079
- /* @__PURE__ */ jsx2("div", { style: { ...RULER, height: RULER_PX }, children: ticks.map((tick) => /* @__PURE__ */ jsx2(
3080
- "div",
3081
- {
3082
- style: {
3083
- position: "absolute",
3084
- left: Math.floor(tick.x),
3085
- bottom: 0,
3086
- width: 1,
3087
- height: tick.weight === "major" ? 8 : tick.weight === "medium" ? 5 : 3,
3088
- background: "var(--xeno-active)"
3089
- },
3090
- children: tick.label ? /* @__PURE__ */ jsx2("span", { style: TICK_LABEL, className: "tabular-nums", children: tick.label }) : null
3091
- },
3092
- tick.tick
3093
- )) }),
3079
+ /* @__PURE__ */ jsx2(Ruler, { height: RULER_PX, children: ticks.map((tick) => /* @__PURE__ */ jsx2(Tick, { x: tick.x, weight: tick.weight, label: tick.label ?? void 0 }, tick.tick)) }),
3094
3080
  /* @__PURE__ */ jsxs2("div", { style: { position: "absolute", inset: `${RULER_PX}px 0 0 0`, overflow: "hidden" }, children: [
3095
- state.visible.map((row) => {
3096
- const top = row.topPx - scale.scrollTopPx;
3097
- return /* @__PURE__ */ jsxs2("div", { style: { position: "absolute", left: 0, right: 0, top, height: row.heightPx }, children: [
3098
- /* @__PURE__ */ jsx2("div", { style: { ...GUTTER, width: scale.gutterPx }, children: /* @__PURE__ */ jsx2("span", { style: TRACK_NAME, children: row.track.name }) }),
3099
- /* @__PURE__ */ jsx2("div", { "data-canvas": "timeline-lane", style: { ...LANE, left: scale.gutterPx }, children: row.clips.map((clip) => {
3100
- const shown = preview?.clips[clip.id] ?? clip;
3101
- const x = scale.tickToX(shown.startTick);
3102
- const width = Math.max(1, scale.durationToPx(shown.endTick - shown.startTick));
3103
- return /* @__PURE__ */ jsx2(
3104
- ClipRect,
3105
- {
3106
- clip,
3107
- left: x - scale.gutterPx,
3108
- width,
3109
- selected: selected.has(clip.id)
3110
- },
3111
- clip.id
3112
- );
3113
- }) })
3114
- ] }, row.track.id);
3115
- }),
3081
+ state.visible.map((row) => /* @__PURE__ */ jsx2(Lane, { top: row.topPx - scale.scrollTopPx, height: row.heightPx, gutterWidth: scale.gutterPx, name: row.track.name, children: row.clips.map((clip) => {
3082
+ const shown = preview?.clips[clip.id] ?? clip;
3083
+ const x = scale.tickToX(shown.startTick);
3084
+ const width = Math.max(1, scale.durationToPx(shown.endTick - shown.startTick));
3085
+ return /* @__PURE__ */ jsx2(Clip, { id: clip.id, left: x - scale.gutterPx, width, selected: selected.has(clip.id), name: clip.name ?? clip.id, color: clip.color }, clip.id);
3086
+ }) }, row.track.id)),
3116
3087
  preview?.marquee ? /* @__PURE__ */ jsx2(
3117
- "div",
3088
+ Marquee,
3118
3089
  {
3119
- style: {
3120
- ...MARQUEE,
3121
- left: Math.min(scale.tickToX(preview.marquee.fromTick), scale.tickToX(preview.marquee.toTick)),
3122
- width: Math.abs(
3123
- scale.tickToX(preview.marquee.toTick) - scale.tickToX(preview.marquee.fromTick)
3124
- ),
3125
- top: Math.min(preview.marquee.fromY, preview.marquee.toY) - scale.scrollTopPx,
3126
- height: Math.abs(preview.marquee.toY - preview.marquee.fromY)
3127
- }
3090
+ left: Math.min(scale.tickToX(preview.marquee.fromTick), scale.tickToX(preview.marquee.toTick)),
3091
+ width: Math.abs(scale.tickToX(preview.marquee.toTick) - scale.tickToX(preview.marquee.fromTick)),
3092
+ top: Math.min(preview.marquee.fromY, preview.marquee.toY) - scale.scrollTopPx,
3093
+ height: Math.abs(preview.marquee.toY - preview.marquee.fromY)
3128
3094
  }
3129
3095
  ) : null
3130
3096
  ] }),
3131
- /* @__PURE__ */ jsx2("div", { style: { ...PLAYHEAD, left: Math.floor(scale.tickToX(state.playheadTick)) } })
3097
+ /* @__PURE__ */ jsx2(Playhead, { x: scale.tickToX(state.playheadTick) })
3132
3098
  ]
3133
3099
  }
3134
3100
  );
3135
3101
  }
3136
- function ClipRect({
3137
- clip,
3138
- left,
3139
- width,
3140
- selected
3141
- }) {
3142
- return /* @__PURE__ */ jsx2(
3143
- "div",
3144
- {
3145
- "data-clip-id": clip.id,
3146
- title: clip.name ?? clip.id,
3147
- style: {
3148
- position: "absolute",
3149
- left,
3150
- width,
3151
- top: 2,
3152
- bottom: 2,
3153
- // Rectangles with a corner radius. Never a circle.
3154
- borderRadius: 2,
3155
- background: selected ? "var(--xeno-control)" : "var(--xeno-border)",
3156
- border: `1px solid ${selected ? "var(--xeno-active)" : "var(--xeno-control)"}`,
3157
- overflow: "hidden",
3158
- fontSize: 10,
3159
- lineHeight: "14px",
3160
- padding: width >= 40 ? "0 4px" : 0,
3161
- whiteSpace: "nowrap",
3162
- color: "var(--xeno-text)",
3163
- boxSizing: "border-box"
3164
- },
3165
- children: width >= 40 ? clip.name ?? "" : null
3166
- }
3167
- );
3168
- }
3169
3102
  function hitTest(state, x, y) {
3170
3103
  const scale = state.scale;
3171
3104
  if (x < scale.gutterPx) return { target: { kind: "lane" }, trackIndex: -1 };
@@ -3190,61 +3123,6 @@ function hitTest(state, x, y) {
3190
3123
  }
3191
3124
  return { target: { kind: "lane" }, trackIndex: -1 };
3192
3125
  }
3193
- var RULER = {
3194
- position: "absolute",
3195
- top: 0,
3196
- left: 0,
3197
- right: 0,
3198
- borderBottom: "1px solid var(--xeno-border)"
3199
- };
3200
- var TICK_LABEL = {
3201
- position: "absolute",
3202
- left: 3,
3203
- top: -12,
3204
- fontSize: 9,
3205
- color: "var(--xeno-active)",
3206
- whiteSpace: "nowrap"
3207
- };
3208
- var GUTTER = {
3209
- position: "absolute",
3210
- left: 0,
3211
- top: 0,
3212
- bottom: 0,
3213
- borderRight: "1px solid var(--xeno-border)",
3214
- borderBottom: "1px solid var(--xeno-border-subtle)",
3215
- display: "flex",
3216
- alignItems: "center",
3217
- padding: "0 6px",
3218
- boxSizing: "border-box"
3219
- };
3220
- var TRACK_NAME = {
3221
- fontSize: 10,
3222
- color: "var(--xeno-text)",
3223
- overflow: "hidden",
3224
- textOverflow: "ellipsis",
3225
- whiteSpace: "nowrap"
3226
- };
3227
- var LANE = {
3228
- position: "absolute",
3229
- right: 0,
3230
- top: 0,
3231
- bottom: 0,
3232
- borderBottom: "1px solid var(--xeno-border-subtle)"
3233
- };
3234
- var MARQUEE = {
3235
- position: "absolute",
3236
- border: "1px solid var(--xeno-active)",
3237
- background: "var(--xeno-border-subtle)",
3238
- pointerEvents: "none"
3239
- };
3240
- var PLAYHEAD = {
3241
- position: "absolute",
3242
- top: 0,
3243
- bottom: 0,
3244
- width: 1,
3245
- background: "var(--xeno-text)",
3246
- pointerEvents: "none"
3247
- };
3248
3126
  var TIMELINE_RUNTIME_UNITS = ["timeline/Surface"];
3249
3127
  function timelineRuntimeComponents(controller) {
3250
3128
  return { "timeline/Surface": () => /* @__PURE__ */ jsx2(TimelineSurface, { controller }) };
package/package.json CHANGED
@@ -1,114 +1,114 @@
1
- {
2
- "name": "@xenosystem/blocks",
3
- "version": "0.13.34",
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
- "license": "UNLICENSED",
6
- "type": "module",
7
- "sideEffects": false,
8
- "exports": {
9
- ".": {
10
- "types": "./dist/index.d.ts",
11
- "import": "./dist/index.js"
12
- },
13
- "./auth": {
14
- "types": "./dist/auth/index.d.ts",
15
- "import": "./dist/auth/index.js"
16
- },
17
- "./trust": {
18
- "types": "./dist/trust/index.d.ts",
19
- "import": "./dist/trust/index.js"
20
- },
21
- "./ops": {
22
- "types": "./dist/ops/index.d.ts",
23
- "import": "./dist/ops/index.js"
24
- },
25
- "./time": {
26
- "types": "./dist/time/index.d.ts",
27
- "import": "./dist/time/index.js"
28
- },
29
- "./data": {
30
- "types": "./dist/data/index.d.ts",
31
- "import": "./dist/data/index.js"
32
- },
33
- "./data/duckdb": {
34
- "types": "./dist/data/duckdb.d.ts",
35
- "import": "./dist/data/duckdb.js"
36
- },
37
- "./icons": {
38
- "types": "./dist/icons/index.d.ts",
39
- "import": "./dist/icons/index.js"
40
- },
41
- "./edit": {
42
- "types": "./dist/edit/index.d.ts",
43
- "import": "./dist/edit/index.js"
44
- },
45
- "./agent": {
46
- "types": "./dist/agent/index.d.ts",
47
- "import": "./dist/agent/index.js"
48
- },
49
- "./agent/host-source": {
50
- "types": "./dist/agent/host-source.d.ts",
51
- "import": "./dist/agent/host-source.js"
52
- }
53
- },
54
- "files": [
55
- "dist",
56
- "README.md",
57
- "LICENSE"
58
- ],
59
- "scripts": {
60
- "build": "tsup",
61
- "typecheck": "tsc --noEmit",
62
- "test": "vitest run"
63
- },
64
- "peerDependencies": {
65
- "@duckdb/duckdb-wasm": ">=1.28.0",
66
- "@xenosystem/block-sdk": ">=0.3.4 <1",
67
- "@xenosystem/components": ">=0.32.0 <1",
68
- "@xenosystem/data-core": "^0.1.0",
69
- "@xenosystem/elements": ">=0.0.1",
70
- "@xenosystem/elements-react": ">=0.0.1",
71
- "@xenosystem/time-core": "^0.1.0",
72
- "@xenosystem/tree-core": "^0.1.0",
73
- "@xenosystem/workbench": "^1.0.0",
74
- "@xterm/addon-fit": ">=0.10.0",
75
- "@xterm/xterm": ">=5.5.0",
76
- "react": ">=18.0.0",
77
- "react-dom": ">=18.0.0"
78
- },
79
- "devDependencies": {
80
- "@types/node": "^22.0.0",
81
- "@types/react": "^19.0.0",
82
- "@types/react-dom": "^19.0.0",
83
- "@xenosystem/block-sdk": "^0.3.4",
84
- "@xenosystem/components": "^0.32.0",
85
- "@xenosystem/data-core": "^0.1.0",
86
- "@xenosystem/elements": "0.0.1",
87
- "@xenosystem/elements-react": "0.0.1",
88
- "@xenosystem/time-core": "^0.1.0",
89
- "@xenosystem/tree-core": "^0.1.0",
90
- "@xenosystem/workbench": "^1.2.1",
91
- "@xterm/addon-fit": "^0.11.0",
92
- "@xterm/xterm": "^6.0.0",
93
- "jsdom": "^26.0.0",
94
- "react": "^19.0.0",
95
- "react-dom": "^19.0.0",
96
- "tsup": "^8.0.0",
97
- "typescript": "^5.4.0",
98
- "vitest": "^4.1.0"
99
- },
100
- "publishConfig": {
101
- "access": "public"
102
- },
103
- "peerDependenciesMeta": {
104
- "@xterm/xterm": {
105
- "optional": true
106
- },
107
- "@xterm/addon-fit": {
108
- "optional": true
109
- },
110
- "@duckdb/duckdb-wasm": {
111
- "optional": true
112
- }
113
- }
114
- }
1
+ {
2
+ "name": "@xenosystem/blocks",
3
+ "version": "0.14.0",
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
+ "license": "UNLICENSED",
6
+ "type": "module",
7
+ "sideEffects": false,
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "import": "./dist/index.js"
12
+ },
13
+ "./auth": {
14
+ "types": "./dist/auth/index.d.ts",
15
+ "import": "./dist/auth/index.js"
16
+ },
17
+ "./trust": {
18
+ "types": "./dist/trust/index.d.ts",
19
+ "import": "./dist/trust/index.js"
20
+ },
21
+ "./ops": {
22
+ "types": "./dist/ops/index.d.ts",
23
+ "import": "./dist/ops/index.js"
24
+ },
25
+ "./time": {
26
+ "types": "./dist/time/index.d.ts",
27
+ "import": "./dist/time/index.js"
28
+ },
29
+ "./data": {
30
+ "types": "./dist/data/index.d.ts",
31
+ "import": "./dist/data/index.js"
32
+ },
33
+ "./data/duckdb": {
34
+ "types": "./dist/data/duckdb.d.ts",
35
+ "import": "./dist/data/duckdb.js"
36
+ },
37
+ "./icons": {
38
+ "types": "./dist/icons/index.d.ts",
39
+ "import": "./dist/icons/index.js"
40
+ },
41
+ "./edit": {
42
+ "types": "./dist/edit/index.d.ts",
43
+ "import": "./dist/edit/index.js"
44
+ },
45
+ "./agent": {
46
+ "types": "./dist/agent/index.d.ts",
47
+ "import": "./dist/agent/index.js"
48
+ },
49
+ "./agent/host-source": {
50
+ "types": "./dist/agent/host-source.d.ts",
51
+ "import": "./dist/agent/host-source.js"
52
+ }
53
+ },
54
+ "files": [
55
+ "dist",
56
+ "README.md",
57
+ "LICENSE"
58
+ ],
59
+ "scripts": {
60
+ "build": "tsup",
61
+ "typecheck": "tsc --noEmit",
62
+ "test": "vitest run"
63
+ },
64
+ "peerDependencies": {
65
+ "@duckdb/duckdb-wasm": ">=1.28.0",
66
+ "@xenosystem/block-sdk": ">=0.3.4 <1",
67
+ "@xenosystem/components": ">=0.33.0 <1",
68
+ "@xenosystem/data-core": "^0.1.0",
69
+ "@xenosystem/elements": ">=0.0.1",
70
+ "@xenosystem/elements-react": ">=0.0.1",
71
+ "@xenosystem/time-core": "^0.1.0",
72
+ "@xenosystem/tree-core": "^0.1.0",
73
+ "@xenosystem/workbench": "^1.0.0",
74
+ "@xterm/addon-fit": ">=0.10.0",
75
+ "@xterm/xterm": ">=5.5.0",
76
+ "react": ">=18.0.0",
77
+ "react-dom": ">=18.0.0"
78
+ },
79
+ "devDependencies": {
80
+ "@types/node": "^22.0.0",
81
+ "@types/react": "^19.0.0",
82
+ "@types/react-dom": "^19.0.0",
83
+ "@xenosystem/block-sdk": "^0.3.4",
84
+ "@xenosystem/components": "^0.33.0",
85
+ "@xenosystem/data-core": "^0.1.0",
86
+ "@xenosystem/elements": "0.0.1",
87
+ "@xenosystem/elements-react": "0.0.1",
88
+ "@xenosystem/time-core": "^0.1.0",
89
+ "@xenosystem/tree-core": "^0.1.0",
90
+ "@xenosystem/workbench": "^1.2.1",
91
+ "@xterm/addon-fit": "^0.11.0",
92
+ "@xterm/xterm": "^6.0.0",
93
+ "jsdom": "^26.0.0",
94
+ "react": "^19.0.0",
95
+ "react-dom": "^19.0.0",
96
+ "tsup": "^8.0.0",
97
+ "typescript": "^5.4.0",
98
+ "vitest": "^4.1.0"
99
+ },
100
+ "publishConfig": {
101
+ "access": "public"
102
+ },
103
+ "peerDependenciesMeta": {
104
+ "@xterm/xterm": {
105
+ "optional": true
106
+ },
107
+ "@xterm/addon-fit": {
108
+ "optional": true
109
+ },
110
+ "@duckdb/duckdb-wasm": {
111
+ "optional": true
112
+ }
113
+ }
114
+ }