@almadar/ui 2.34.1 → 2.35.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.
@@ -0,0 +1,13 @@
1
+ /**
2
+ * EventFlowEdge
3
+ *
4
+ * React Flow edge for the V3 FlowCanvas. Shows the event name and
5
+ * optionally the trigger element (button label) that fires it.
6
+ *
7
+ * When the edge originates from a specific event source handle,
8
+ * the label shows "Button Label \u2192 EVENT" to make the connection
9
+ * between UI element and transition clear.
10
+ */
11
+ import React from 'react';
12
+ import { type EdgeProps } from '@xyflow/react';
13
+ export declare const EventFlowEdge: React.NamedExoticComponent<EdgeProps>;
@@ -0,0 +1,38 @@
1
+ /**
2
+ * OrbPreviewNode
3
+ *
4
+ * React Flow node that renders a real OrbPreview inside it.
5
+ * The canvas is always live and editable (like Figma). Clicking any
6
+ * rendered UI element selects its pattern and shows props in the
7
+ * TransitionPanel. No edit mode toggle needed.
8
+ *
9
+ * The header is the drag handle for React Flow. The content area
10
+ * passes clicks through to the pattern elements.
11
+ */
12
+ import React from 'react';
13
+ import { type NodeProps } from '@xyflow/react';
14
+ import type { PreviewNodeData, ScreenSize } from './avl-preview-types';
15
+ export declare const ScreenSizeContext: React.Context<ScreenSize>;
16
+ /** Selected pattern info, emitted when user clicks a UI element in the node. */
17
+ export interface SelectedPattern {
18
+ /** The pattern type (e.g., "button", "input", "stack"). */
19
+ patternType: string;
20
+ /** The DOM element's data-pattern-id if available. */
21
+ patternId?: string;
22
+ /** The node this pattern belongs to. */
23
+ nodeData: PreviewNodeData;
24
+ /** The source trait for this slot content. */
25
+ sourceTrait?: string;
26
+ /** Bounding rect relative to the node for floating inspector positioning. */
27
+ rect?: {
28
+ top: number;
29
+ left: number;
30
+ width: number;
31
+ height: number;
32
+ };
33
+ }
34
+ export declare const PatternSelectionContext: React.Context<{
35
+ selected: SelectedPattern | null;
36
+ select: (pattern: SelectedPattern | null) => void;
37
+ }>;
38
+ export declare const OrbPreviewNode: React.NamedExoticComponent<NodeProps>;
@@ -0,0 +1,35 @@
1
+ /**
2
+ * AVL Preview Converter
3
+ *
4
+ * Extracts render-ui pattern configs from OrbitalSchema transitions
5
+ * and builds React Flow graphs for the two FlowCanvas levels:
6
+ * - Overview: one node per orbital (INIT transition UI)
7
+ * - Expanded: one node per UI state within an orbital
8
+ *
9
+ * Key feature: detects interactive elements (buttons, links) inside
10
+ * patterns that fire events. These become per-element source handles
11
+ * so edges connect from the specific trigger element to the target screen.
12
+ *
13
+ * Uses @almadar/core types for schema-level constructs.
14
+ */
15
+ import type { Node, Edge } from '@xyflow/react';
16
+ import type { OrbitalSchema } from '@almadar/core';
17
+ import type { PreviewNodeData, EventEdgeData } from './avl-preview-types';
18
+ /**
19
+ * Build a React Flow graph for the overview level.
20
+ * Each orbital gets one node showing its INIT transition's UI.
21
+ */
22
+ export declare function schemaToOverviewGraph(schema: OrbitalSchema, mockData?: Record<string, unknown[]>): {
23
+ nodes: Node<PreviewNodeData>[];
24
+ edges: Edge<EventEdgeData>[];
25
+ };
26
+ /**
27
+ * Build a React Flow graph for the expanded level.
28
+ * Each transition with a render-ui effect gets a node.
29
+ * Edges connect from the specific button/pattern that fires the event
30
+ * to the target screen node.
31
+ */
32
+ export declare function orbitalToExpandedGraph(schema: OrbitalSchema, orbitalName: string, mockData?: Record<string, unknown[]>): {
33
+ nodes: Node<PreviewNodeData>[];
34
+ edges: Edge<EventEdgeData>[];
35
+ };
@@ -0,0 +1,108 @@
1
+ /**
2
+ * AVL Preview Types
3
+ *
4
+ * Types for the V3 FlowCanvas: UI projection mode.
5
+ * Nodes show rendered UI thumbnails, edges show events.
6
+ * Two levels: overview (one node per orbital) and expanded (one node per UI state).
7
+ *
8
+ * Uses @almadar/core types for schema-level constructs.
9
+ */
10
+ import type { Expression, UISlot } from '@almadar/core';
11
+ /** The two navigation levels of the FlowCanvas. */
12
+ export type ViewLevel = 'overview' | 'expanded';
13
+ /** Screen size preset for OrbPreview rendering inside nodes. */
14
+ export type ScreenSize = 'mobile' | 'tablet' | 'desktop';
15
+ /** Width for each screen size preset. Height is auto (expands to fit content). */
16
+ export declare const SCREEN_SIZE_PRESETS: Record<ScreenSize, {
17
+ width: number;
18
+ minHeight: number;
19
+ label: string;
20
+ icon: string;
21
+ }>;
22
+ /**
23
+ * An interactive element inside a render-ui pattern that fires an event.
24
+ * For example, a button with `event: "CHECKOUT"` is an event source.
25
+ * These are used to draw edges from the specific trigger element to the
26
+ * target screen, making the prototype flow concrete.
27
+ */
28
+ export interface PatternEventSource {
29
+ /** The event name fired by this element (e.g., "CHECKOUT"). */
30
+ event: string;
31
+ /** The pattern type of the trigger element (e.g., "button", "link", "icon-button"). */
32
+ patternType: string;
33
+ /** Human label if available (e.g., "Checkout", "Submit"). */
34
+ label?: string;
35
+ /**
36
+ * Path within the pattern tree (e.g., "children.2" means third child).
37
+ * Used to position the handle near the trigger element.
38
+ */
39
+ path: string;
40
+ /** Vertical position hint (0..1) for handle placement on the node. */
41
+ positionHint: number;
42
+ }
43
+ /** A slot + pattern config pair extracted from a render-ui effect. */
44
+ export interface RenderUIEntry {
45
+ slot: UISlot | string;
46
+ pattern: Record<string, unknown>;
47
+ }
48
+ /** Data for a preview node (used at both overview and expanded levels). */
49
+ export interface PreviewNodeData extends Record<string, unknown> {
50
+ /** Orbital this node belongs to. */
51
+ orbitalName: string;
52
+ /** Trait name (only at expanded level). */
53
+ traitName?: string;
54
+ /** State name after this transition fires (expanded level). */
55
+ stateName?: string;
56
+ /** Event that triggers this transition (expanded level). */
57
+ transitionEvent?: string;
58
+ /** From state (expanded level). */
59
+ fromState?: string;
60
+ /** To state (expanded level). */
61
+ toState?: string;
62
+ /**
63
+ * Render-ui patterns extracted from the transition's effects.
64
+ * Each entry is a slot + pattern config pair.
65
+ */
66
+ patterns: RenderUIEntry[];
67
+ /**
68
+ * Interactive elements within the patterns that fire events.
69
+ * Each one becomes a source handle on the node, allowing edges
70
+ * to connect from the specific button/link to the target screen.
71
+ */
72
+ eventSources: PatternEventSource[];
73
+ /** State role for visual indicator. */
74
+ stateRole?: 'initial' | 'terminal' | 'hub' | 'error' | 'default';
75
+ /** All effect types on this transition (for overlay). */
76
+ effectTypes?: string[];
77
+ /** Guard expression (for overlay). */
78
+ guard?: Expression | null;
79
+ entityName?: string;
80
+ persistence?: string;
81
+ fieldCount?: number;
82
+ traitCount?: number;
83
+ pageRoutes?: string[];
84
+ }
85
+ /** Data for event flow edges. */
86
+ export interface EventEdgeData extends Record<string, unknown> {
87
+ /** The event name displayed on the edge. */
88
+ event: string;
89
+ /** Source state name (expanded level). */
90
+ fromState?: string;
91
+ /** Target state name (expanded level). */
92
+ toState?: string;
93
+ /** Whether this is a backward/retry transition. */
94
+ isBackward?: boolean;
95
+ /** Whether this is a cross-orbital event wire (overview level). */
96
+ isCrossOrbital?: boolean;
97
+ /** Source trait (for cross-orbital wires). */
98
+ fromTrait?: string;
99
+ /** Target trait (for cross-orbital wires). */
100
+ toTrait?: string;
101
+ /**
102
+ * The pattern type that triggers this event (e.g., "button").
103
+ * Displayed on the edge label for context.
104
+ */
105
+ triggerPatternType?: string;
106
+ /** The trigger element's label (e.g., "Checkout"). */
107
+ triggerLabel?: string;
108
+ }
@@ -23,6 +23,10 @@ export { AvlEventWireEdge, type AvlEventWireEdgeData, type AvlEventWireFlowEdge
23
23
  export { AvlBackwardEdge } from './AvlBackwardEdge';
24
24
  export { AvlPageEdge } from './AvlPageEdge';
25
25
  export { AvlBindingEdge } from './AvlBindingEdge';
26
+ export { type ViewLevel, type PreviewNodeData, type EventEdgeData, type PatternEventSource, type RenderUIEntry, type ScreenSize, SCREEN_SIZE_PRESETS } from './avl-preview-types';
27
+ export { schemaToOverviewGraph, orbitalToExpandedGraph } from './avl-preview-converter';
28
+ export { OrbPreviewNode, ScreenSizeContext } from './OrbPreviewNode';
29
+ export { EventFlowEdge } from './EventFlowEdge';
26
30
  export { Avl3DOrbitalNode, type Avl3DOrbitalNodeProps } from './Avl3DOrbitalNode';
27
31
  export { Avl3DCrossWire, type Avl3DCrossWireProps } from './Avl3DCrossWire';
28
32
  export { Avl3DEntityCore, type Avl3DEntityCoreProps } from './Avl3DEntityCore';
@@ -1,9 +1,9 @@
1
1
  /**
2
- * AvlCosmicZoom — Interactive Zoomable Orbital Visualization
2
+ * AvlCosmicZoom — Interactive Orbital Visualization
3
3
  *
4
- * V3: Delegates to FlowCanvas, which renders AVL primitives inside
5
- * React Flow nodes with continuous semantic zoom. The Props interface
6
- * is preserved for backward compatibility with callers.
4
+ * V3: Delegates to FlowCanvas. Nodes are live OrbPreview renders
5
+ * of each orbital/transition. Two-level navigation (overview + expanded).
6
+ * Props interface preserved for backward compatibility with callers.
7
7
  */
8
8
  import React from 'react';
9
9
  import type { OrbitalSchema } from '@almadar/core';
@@ -1,32 +1,47 @@
1
1
  /**
2
- * FlowCanvas — Unified AVL + Flow canvas organism.
2
+ * FlowCanvas — V3 UI Projection Canvas
3
3
  *
4
- * One React Flow canvas with continuous semantic zoom. AVL primitives
5
- * render inside React Flow nodes. The ZoomBandContext drives node
6
- * rendering at different zoom levels.
4
+ * The canvas IS the app. Nodes show rendered UI thumbnails from
5
+ * render-ui effects. Edges show events connecting screens.
7
6
  *
8
- * Replaces both AvlCosmicZoom (SVG viewer) and OrbitalFlow (Flow editor).
7
+ * Two navigation levels:
8
+ * Level 1 (Overview): One node per orbital showing INIT UI
9
+ * Level 2 (Expanded): One node per UI state within an orbital
10
+ *
11
+ * Double-click to expand an orbital. Click a node for code callback.
12
+ * Escape to go back. AVL overlays on hover (future).
9
13
  */
10
14
  import React from 'react';
11
15
  import type { OrbitalSchema } from '@almadar/core';
12
- import type { ZoomLevel } from './avl-zoom-state';
16
+ import type { ViewLevel } from '../../molecules/avl/avl-preview-types';
13
17
  export interface FlowCanvasProps {
14
18
  schema: OrbitalSchema | string;
19
+ mockData?: Record<string, unknown[]>;
15
20
  className?: string;
16
- color?: string;
17
- animated?: boolean;
18
21
  width?: number | string;
19
22
  height?: number | string;
20
- onZoomChange?: (level: ZoomLevel, context: {
21
- orbital?: string;
23
+ onNodeClick?: (context: {
24
+ level: ViewLevel | 'code';
25
+ orbital: string;
22
26
  trait?: string;
27
+ transition?: string;
23
28
  }) => void;
29
+ onLevelChange?: (level: ViewLevel, orbital?: string) => void;
30
+ initialOrbital?: string;
31
+ /** @deprecated Use onNodeClick instead. Kept for AvlCosmicZoom compat. */
32
+ onZoomChange?: (level: string, context: Record<string, string | undefined>) => void;
33
+ /** @deprecated Not used in V3. */
24
34
  focusTarget?: {
25
- type: 'orbital' | 'trait';
35
+ type: string;
26
36
  name: string;
27
37
  };
28
- initialOrbital?: string;
38
+ /** @deprecated Not used in V3. */
39
+ color?: string;
40
+ /** @deprecated Not used in V3. */
41
+ animated?: boolean;
42
+ /** @deprecated Not used in V3. */
29
43
  initialTrait?: string;
30
- stateCoverage?: Record<string, 'covered' | 'uncovered' | 'partial'>;
44
+ /** @deprecated Not used in V3. */
45
+ stateCoverage?: Record<string, string>;
31
46
  }
32
47
  export declare const FlowCanvas: React.FC<FlowCanvasProps>;
@@ -0,0 +1,20 @@
1
+ /**
2
+ * TransitionPanel
3
+ *
4
+ * Shows the .orb transition details for a selected node in FlowCanvas.
5
+ * Built entirely with AVL primitives (AvlState, AvlEvent, AvlGuard,
6
+ * AvlEffect, AvlFieldType) so the developer learns the visual language
7
+ * while reading the code behind a screen.
8
+ *
9
+ * Renders in a side panel that appears when a node is clicked at Level 2.
10
+ */
11
+ import React from 'react';
12
+ import type { PreviewNodeData } from '../../molecules/avl/avl-preview-types';
13
+ export interface TransitionPanelProps {
14
+ node: PreviewNodeData;
15
+ onClose: () => void;
16
+ }
17
+ export declare function TransitionPanel({ node, onClose }: TransitionPanelProps): React.ReactElement;
18
+ export declare namespace TransitionPanel {
19
+ var displayName: string;
20
+ }
@@ -97,7 +97,7 @@ var Camera3D = React21.forwardRef(
97
97
  newCamera = new THREE6__namespace.PerspectiveCamera(fov, viewport.aspect, 0.1, 1e3);
98
98
  }
99
99
  newCamera.position.copy(initialPosition.current);
100
- newCamera.lookAt(initialTarget.current);
100
+ newCamera.lookAt(initialTarget.current.x, initialTarget.current.y, initialTarget.current.z);
101
101
  set({ camera: newCamera });
102
102
  if (mode === "top-down") {
103
103
  newCamera.position.set(0, 20 / zoom, 0);
@@ -128,7 +128,7 @@ var Camera3D = React21.forwardRef(
128
128
  },
129
129
  reset: () => {
130
130
  camera.position.copy(initialPosition.current);
131
- camera.lookAt(initialTarget.current);
131
+ camera.lookAt(initialTarget.current.x, initialTarget.current.y, initialTarget.current.z);
132
132
  if (controlsRef.current) {
133
133
  controlsRef.current.target.copy(initialTarget.current);
134
134
  controlsRef.current.update();
@@ -147,7 +147,7 @@ var Camera3D = React21.forwardRef(
147
147
  ref: controlsRef,
148
148
  camera,
149
149
  enabled: enableOrbit,
150
- target: initialTarget.current,
150
+ target: [initialTarget.current.x, initialTarget.current.y, initialTarget.current.z],
151
151
  minDistance,
152
152
  maxDistance,
153
153
  maxPolarAngle,
@@ -4204,7 +4204,7 @@ var Avl3DCrossWire = ({
4204
4204
  }, [from, to]);
4205
4205
  return /* @__PURE__ */ jsxRuntime.jsxs("group", { children: [
4206
4206
  /* @__PURE__ */ jsxRuntime.jsxs("mesh", { children: [
4207
- /* @__PURE__ */ jsxRuntime.jsx("tubeGeometry", { args: tubeArgs }),
4207
+ /* @__PURE__ */ jsxRuntime.jsx("tubeGeometry", { args: [tubeArgs[0], tubeArgs[1], tubeArgs[2], tubeArgs[3], tubeArgs[4]] }),
4208
4208
  /* @__PURE__ */ jsxRuntime.jsx(
4209
4209
  "meshStandardMaterial",
4210
4210
  {
@@ -4917,7 +4917,7 @@ var Avl3DTransitionArc = ({
4917
4917
  document.body.style.cursor = "auto";
4918
4918
  },
4919
4919
  children: [
4920
- /* @__PURE__ */ jsxRuntime.jsx("tubeGeometry", { args: tubeArgs }),
4920
+ /* @__PURE__ */ jsxRuntime.jsx("tubeGeometry", { args: [tubeArgs[0], tubeArgs[1], tubeArgs[2], tubeArgs[3], tubeArgs[4]] }),
4921
4921
  /* @__PURE__ */ jsxRuntime.jsx(
4922
4922
  "meshStandardMaterial",
4923
4923
  {
@@ -5502,7 +5502,7 @@ function CameraController2({ targetPosition, targetLookAt, animated }) {
5502
5502
  isAnimating.current = true;
5503
5503
  } else {
5504
5504
  camera.position.copy(targetPosVec.current);
5505
- camera.lookAt(targetLookVec.current);
5505
+ camera.lookAt(targetLookVec.current.x, targetLookVec.current.y, targetLookVec.current.z);
5506
5506
  }
5507
5507
  }
5508
5508
  }, [targetPosition, targetLookAt, animated, camera]);
@@ -73,7 +73,7 @@ var Camera3D = forwardRef(
73
73
  newCamera = new THREE6.PerspectiveCamera(fov, viewport.aspect, 0.1, 1e3);
74
74
  }
75
75
  newCamera.position.copy(initialPosition.current);
76
- newCamera.lookAt(initialTarget.current);
76
+ newCamera.lookAt(initialTarget.current.x, initialTarget.current.y, initialTarget.current.z);
77
77
  set({ camera: newCamera });
78
78
  if (mode === "top-down") {
79
79
  newCamera.position.set(0, 20 / zoom, 0);
@@ -104,7 +104,7 @@ var Camera3D = forwardRef(
104
104
  },
105
105
  reset: () => {
106
106
  camera.position.copy(initialPosition.current);
107
- camera.lookAt(initialTarget.current);
107
+ camera.lookAt(initialTarget.current.x, initialTarget.current.y, initialTarget.current.z);
108
108
  if (controlsRef.current) {
109
109
  controlsRef.current.target.copy(initialTarget.current);
110
110
  controlsRef.current.update();
@@ -123,7 +123,7 @@ var Camera3D = forwardRef(
123
123
  ref: controlsRef,
124
124
  camera,
125
125
  enabled: enableOrbit,
126
- target: initialTarget.current,
126
+ target: [initialTarget.current.x, initialTarget.current.y, initialTarget.current.z],
127
127
  minDistance,
128
128
  maxDistance,
129
129
  maxPolarAngle,
@@ -4180,7 +4180,7 @@ var Avl3DCrossWire = ({
4180
4180
  }, [from, to]);
4181
4181
  return /* @__PURE__ */ jsxs("group", { children: [
4182
4182
  /* @__PURE__ */ jsxs("mesh", { children: [
4183
- /* @__PURE__ */ jsx("tubeGeometry", { args: tubeArgs }),
4183
+ /* @__PURE__ */ jsx("tubeGeometry", { args: [tubeArgs[0], tubeArgs[1], tubeArgs[2], tubeArgs[3], tubeArgs[4]] }),
4184
4184
  /* @__PURE__ */ jsx(
4185
4185
  "meshStandardMaterial",
4186
4186
  {
@@ -4893,7 +4893,7 @@ var Avl3DTransitionArc = ({
4893
4893
  document.body.style.cursor = "auto";
4894
4894
  },
4895
4895
  children: [
4896
- /* @__PURE__ */ jsx("tubeGeometry", { args: tubeArgs }),
4896
+ /* @__PURE__ */ jsx("tubeGeometry", { args: [tubeArgs[0], tubeArgs[1], tubeArgs[2], tubeArgs[3], tubeArgs[4]] }),
4897
4897
  /* @__PURE__ */ jsx(
4898
4898
  "meshStandardMaterial",
4899
4899
  {
@@ -5478,7 +5478,7 @@ function CameraController2({ targetPosition, targetLookAt, animated }) {
5478
5478
  isAnimating.current = true;
5479
5479
  } else {
5480
5480
  camera.position.copy(targetPosVec.current);
5481
- camera.lookAt(targetLookVec.current);
5481
+ camera.lookAt(targetLookVec.current.x, targetLookVec.current.y, targetLookVec.current.z);
5482
5482
  }
5483
5483
  }
5484
5484
  }, [targetPosition, targetLookAt, animated, camera]);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@almadar/ui",
3
- "version": "2.34.1",
3
+ "version": "2.35.0",
4
4
  "description": "React UI components, hooks, and providers for Almadar",
5
5
  "type": "module",
6
6
  "main": "./dist/components/index.js",
@@ -84,6 +84,11 @@
84
84
  "import": "./dist/avl/index.js",
85
85
  "require": "./dist/avl/index.cjs"
86
86
  },
87
+ "./illustrations": {
88
+ "types": "./dist/avl/index.d.ts",
89
+ "import": "./dist/avl/index.js",
90
+ "require": "./dist/avl/index.cjs"
91
+ },
87
92
  "./flow": {
88
93
  "types": "./dist/flow/index.d.ts",
89
94
  "import": "./dist/flow/index.js",