feat(apollo-react): add ExpressionEditor field type for NodeManifestPanel#793
feat(apollo-react): add ExpressionEditor field type for NodeManifestPanel#7931980computer wants to merge 1 commit into
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Dependency License Review
License distribution
Excluded packages
|
ee7c2f6 to
da95c64
Compare
8ef5f19 to
9577354
Compare
da95c64 to
bd8104b
Compare
c6a7eab to
cfc1b2f
Compare
60208e7 to
479392b
Compare
bd8104b to
cd91c52
Compare
There was a problem hiding this comment.
Pull request overview
This PR introduces new canvas UI components and Storybook updates in apollo-react, notably a new NodePropertyPanel (manifest-driven MetadataForm rendering) and a new ProbeCard (floating debug watch/inspect card). It also adds a standalone ExpressionField demoed in Storybook, but does not appear to implement the PR description’s promised MetadataForm “custom field type” (type: 'custom') backed by Monaco/CodeMirror.
Changes:
- Added ProbeCard (draggable/resizable watch list UI) plus supporting hooks and unit tests.
- Added NodePropertyPanel (renders a node’s
FormSchemafromNodeRegistryProvider, with single-page + multi-step tab support) plus tests and stories. - Added ExpressionField (read-only code display + mode toggle) and a Storybook “Expression Editor” story, and updated Storybook nav ordering.
Reviewed changes
Copilot reviewed 15 out of 15 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| packages/apollo-react/src/canvas/components/ProbeCard/useLatestRef.ts | Adds a small “latest value” ref hook using an isomorphic layout effect. |
| packages/apollo-react/src/canvas/components/ProbeCard/useDragSession.ts | Adds a reusable window-listener-based mouse drag session hook with cleanup. |
| packages/apollo-react/src/canvas/components/ProbeCard/ProbeResizeHandles.tsx | Adds resize handle UI that wires into useDragSession. |
| packages/apollo-react/src/canvas/components/ProbeCard/ProbeCard.tsx | Introduces the ProbeCard component (watch list rendering + drag/resize + wheel forwarding + keyboard delete). |
| packages/apollo-react/src/canvas/components/ProbeCard/ProbeCard.test.tsx | Adds unit tests covering keyboard shortcuts, wheel forwarding, and drag cleanup behavior. |
| packages/apollo-react/src/canvas/components/ProbeCard/index.ts | Exports ProbeCard and related public types. |
| packages/apollo-react/src/canvas/components/NodePropertyPanel/NodePropertyPanel.types.ts | Defines NodePropertyPanelProps. |
| packages/apollo-react/src/canvas/components/NodePropertyPanel/NodePropertyPanel.tsx | Implements manifest-driven FormSchema rendering with tabs for multi-step forms. |
| packages/apollo-react/src/canvas/components/NodePropertyPanel/NodePropertyPanel.test.tsx | Adds unit tests for title bar, close behavior, empty states, and multi-step tab rendering. |
| packages/apollo-react/src/canvas/components/NodePropertyPanel/NodePropertyPanel.stories.tsx | Adds extensive Storybook stories for NodePropertyPanel and an “Expression Editor” demo using ExpressionField. |
| packages/apollo-react/src/canvas/components/NodePropertyPanel/index.ts | Re-exports NodePropertyPanel and ExpressionField APIs. |
| packages/apollo-react/src/canvas/components/NodePropertyPanel/ExpressionField.tsx | Adds a read-only code display component with mode toggle and UI chrome. |
| packages/apollo-react/src/canvas/components/NodePropertiesPanel/NodePropertiesPanel.stories.tsx | Adds a new “Inspector” canvas story variant and supporting imports. |
| packages/apollo-react/src/canvas/components/index.ts | Re-exports ProbeCard and NodePropertyPanel from the canvas components barrel. |
| apps/storybook/.storybook/preview.tsx | Updates Storybook sidebar ordering to include “Node Property Panel”. |
| /** | ||
| * ExpressionField — syntax-highlighted expression editor with mode switcher. | ||
| * | ||
| * Phase 1: read-only display with Expr / JSON mode toggle, undo/redo chrome, | ||
| * AI assist button, and Insert variable affordance. | ||
| * | ||
| * Phase 2: live editing via Monaco/CodeMirror with variable binding ({x} pill), | ||
| * real-time validation, and IntelliSense. | ||
| */ |
| /** Short description shown below the editor. */ | ||
| description?: string; | ||
| /** Called when the expression value changes (Phase 2 — editing not yet wired). */ | ||
| onChange?: (value: string) => void; | ||
| /** Called when the user switches between expr and json modes. */ | ||
| onModeChange?: (mode: ExpressionMode) => void; |
| <button | ||
| type="button" | ||
| onClick={() => onModeChange?.('expr')} | ||
| className="rounded px-2 py-0.5 text-[11px] transition" | ||
| style={{ | ||
| color: activeMode === 'expr' ? 'var(--foreground)' : 'var(--foreground-subtle)', | ||
| fontWeight: activeMode === 'expr' ? 600 : 400, | ||
| }} | ||
| > | ||
| expr | ||
| </button> | ||
| <button | ||
| type="button" | ||
| onClick={() => onModeChange?.('json')} | ||
| className="rounded px-2 py-0.5 text-[11px] transition" | ||
| style={{ | ||
| color: activeMode === 'json' ? 'var(--foreground)' : 'var(--foreground-subtle)', | ||
| fontWeight: activeMode === 'json' ? 600 : 400, | ||
| }} | ||
| > | ||
| json | ||
| </button> |
📊 Coverage + size by packagePer-package coverage and bundle size on this PR. New-line coverage = of the source lines this PR adds or changes, the % hit by tests.
"Coverage" is each package's own |
cd91c52 to
68ad46b
Compare
Scaffolds four Storybook stories for the Node Property Panel expression editor variants: - Editor Full: expanded panel with toolbar, mode switcher, undo/redo, AI assist, and Insert variable affordance - Editor Compact: collapsed field rows that expand inline on click - Editor Inline: single-line fx inputs with variable pill support - Inline Editing: node title and description editable directly in the identity row (click to edit, Enter/blur to confirm) Downgrades Storybook app Vite from 8 to 7 to resolve a pre-bundling incompatibility between Vite 8, MUI, and Emotion that caused all story previews to show a white screen. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
68ad46b to
fa02c32
Compare
| const meta: Meta = { | ||
| title: 'Components/Panels/Node Property Panel', | ||
| parameters: { | ||
| layout: 'fullscreen', | ||
| }, | ||
| }; | ||
|
|
||
| export default meta; | ||
| type Story = StoryObj; |
| <button | ||
| type="button" | ||
| className="grid size-7 place-items-center rounded-lg text-foreground-subtle transition hover:bg-surface-overlay hover:text-foreground" | ||
| > | ||
| <Sparkles size={12} /> | ||
| </button> |
| "storybook": "^10.4.1", | ||
| "tailwindcss": "^4.1.17", | ||
| "typescript": "^5.9.3", | ||
| "vite": "^8.0.0", | ||
| "vite": "^7.3.5", | ||
| "vite-plugin-svgr": "^4.5.0" |
| /** Editor mode — JavaScript expression or JSON template. Defaults to 'expr'. */ | ||
| mode?: ExpressionMode; | ||
| /** Short description shown below the editor. */ | ||
| description?: string; | ||
| /** Called when the expression value changes (Phase 2 — editing not yet wired). */ | ||
| onChange?: (value: string) => void; | ||
| /** Called when the user switches between expr and json modes. */ | ||
| onModeChange?: (mode: ExpressionMode) => void; |
Summary
Adds an
ExpressionEditorcustom field type for use withNodeManifestPanelviaMetadataForm's plugin/custom component system.Previously implemented as a standalone
ExpressionField.tsx(removed in #760 during the FormSchema migration). This PR re-introduces expression editing as a propertype: 'custom'field, backed by Monaco/CodeMirror.What this will add
ExpressionEditor— custom MetadataForm field component registered via the plugin systemexprmode (JavaScript/TypeScript) andjsonmode (JSON template)ExpressionEditorstory added to Node Property PanelDepends on
Not yet included
{x}bind button — Phase 2🤖 Generated with Claude Code