feat(apollo-react): add NodePropertyPanel with FormSchema support (Phase 1)#760
Merged
1980computer merged 2 commits intoJun 11, 2026
Merged
Conversation
Contributor
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Contributor
Dependency License Review
License distribution
Excluded packages
|
a9b2cfc to
c862813
Compare
b12cb77 to
b0f7264
Compare
8 tasks
96c6e06 to
aaf1f3f
Compare
5705e3b to
3b7ae8b
Compare
3b7ae8b to
38b0e57
Compare
CalinaCristian
left a comment
Collaborator
There was a problem hiding this comment.
This PR is hard to review, it seems to have commits from #781 , can you clean it up to only have the diffs? Or what's the difference?
28181f4 to
af82409
Compare
af82409 to
8ef5f19
Compare
8ef5f19 to
9577354
Compare
CalinaCristian
added a commit
that referenced
this pull request
Jun 11, 2026
Floating probe/watch card for canvas debugging — drag-to-reposition and resize via ProbeResizeHandles, keyboard shortcuts, wheel-event forwarding guarded by handler presence, drag-session cleanup via useDragSession, and useLatestRef for stable handler refs. Includes 8 unit tests. Extracted from the original PR #760 branch; content unchanged. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
CalinaCristian
added a commit
that referenced
this pull request
Jun 11, 2026
…ase 1)
Docked properties panel that renders a node's form: FormSchema (from
@uipath/apollo-wind) directly from its manifest in NodeRegistryProvider —
no prop drilling. Multi-step schemas (steps) render as tabs; single-page
schemas (sections) render as a flat MetadataForm; empty state when the
manifest has no form. onSubmit is async-compatible. Includes 8 unit tests
and Multi-step / SinglePage / NoSchema stories.
Variable binding ({x} bind button / variable picker) is Phase 2.
Extracted from the original PR #760 branch; content unchanged.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
CalinaCristian
added a commit
that referenced
this pull request
Jun 11, 2026
- Derive uncontrolled behavior/layout defaults from behaviorOptions[0] / layoutOptions[0] instead of hardcoded values - Skip scroll events originating inside the portalled menu so it remains scrollable (close only on outside scroll / resize) - Remove role='menuitem' from preset and save-preset buttons (they are plain buttons, not menu items) - Deleting a preset no longer closes the menu (matches story helper) - Tests updated to match the new roles and delete behavior Extracted from the original PR #760 branch (Copilot review rounds); the CustomOptions story added in #781 is intentionally kept. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
71f60b5 to
f2ade91
Compare
Contributor
📦 Dev Packages
|
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 16 out of 16 changed files in this pull request and generated 5 comments.
Comments suppressed due to low confidence (1)
packages/apollo-react/src/canvas/controls/NodePropertyTrigger/NodePropertyTrigger.tsx:324
- Inside a
role="menu"container, the "Save as preset" action should be arole="menuitem"for correct ARIA semantics.
<button
type="button"
onClick={() => {
onSavePreset?.();
setMenuOpen(false);
}}
className="flex w-full items-center gap-2 px-3 py-2 text-xs text-foreground-muted transition hover:bg-surface-overlay hover:text-foreground"
CalinaCristian
added a commit
that referenced
this pull request
Jun 11, 2026
…opdownMenu
Replaces the hand-rolled popover (portal, fixed positioning, outside-click/
Escape/scroll/resize listeners) with the same Radix-based DropdownMenu the
canvas package already composes (CanvasDropdownMenu, NodeContextMenu),
gaining arrow-key navigation, typeahead, and focus management. modal={false}
for the React Flow foreignObject reason documented in CanvasDropdownMenu.
Consumer extensibility:
- `children` fully replace the built-in sections (the i18n/extension path).
Exported design-matched subcomponents: NodePropertyTriggerCheckboxItem
(keeps menu open by default, closeOnSelect opt-out),
NodePropertyTriggerRadioItem, NodePropertyTriggerSectionLabel,
NodePropertyTriggerSeparator — composable with any wind primitive.
- Data props survive as the prefab (rendered when no children), built on the
same subcomponents.
- NodePropertyTriggerItem gains a stable `id`; onPanelToggle receives
`id ?? label` so localized labels are never the toggle identity.
- `showMenu={false}` renders a label-only pill for secondary triggers.
- Controlled `open`/`onOpenChange`.
- Empty sections collapse (heading + separator included); the presets
empty-state stays while canSavePreset is true.
Absorbs the NodePropertyTrigger refinements from PR #760 (uncontrolled
defaults from options[0], delete-preset keeps the menu open); the scroll and
role fixes there are obsolete under Radix. Preset delete buttons stop
pointerdown/pointerup propagation so Radix's pointerup-select doesn't apply
the preset and close the menu.
Tests rewritten: 24 passing. Stories: the 200-line inline popover fake is
replaced by the controlled `open` prop; adds Composed and LabelOnlyPill.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Floating probe/watch card for canvas debugging — drag-to-reposition and resize via ProbeResizeHandles, keyboard shortcuts, wheel-event forwarding guarded by handler presence, drag-session cleanup via useDragSession, and useLatestRef for stable handler refs. Includes 8 unit tests. Extracted from the original PR #760 branch; content unchanged. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ase 1)
Docked properties panel that renders a node's form: FormSchema (from
@uipath/apollo-wind) directly from its manifest in NodeRegistryProvider —
no prop drilling. Multi-step schemas (steps) render as tabs; single-page
schemas (sections) render as a flat MetadataForm; empty state when the
manifest has no form. onSubmit is async-compatible. Includes 8 unit tests
and Multi-step / SinglePage / NoSchema stories.
Variable binding ({x} bind button / variable picker) is Phase 2.
Extracted from the original PR #760 branch; content unchanged.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
NodePropertyPanel— a docked properties panel that renders a node'sform: FormSchema(from
@uipath/apollo-wind) directly from its manifest inNodeRegistryProvider. No propdrilling; the panel looks up the manifest by
nodeTypefrom the nearest provider in the tree.steps): each step becomes a tab — titles and field types are fullyconsumer-defined in the manifest. The panel resets the active tab whenever
nodeTypechanges.sections): rendered as a flat scrollable form viaMetadataForm.formor thestepsarray is empty.onSubmitis async-compatible:onSubmit?: (data: unknown) => void | Promise<void>.NodePropertiesPanelfrom@emotion/styledto Tailwind CSS. TheNodePropertiesPanel.styles.tsfile is deleted.Components/Panels/.NodePropertyTriggerimprovements — named constants (no magic numbers), extensible uniontypes (
(string & {})), uncontrolled fallback state, Escape/scroll/resize close, ARIA roles.TextField,SelectField,NumberFieldnow useborder-(--canvas-border)/focus:border-(--canvas-primary)instead of the invalidtheme()fallback syntax.ProbeCard—stopPropagationandpreventDefaultguarded by handler presence so wheelevents bubble correctly when no canvas handlers are wired;
useLatestRefdep array fixed.NodePropertyPanel.test.tsx(8 tests) andProbeCard.test.tsx(8 tests)covering keyboard shortcuts, wheel forwarding, and drag-session cleanup.
What this is NOT (Phase 2)
Variable binding for form fields (the
{x}bind button / variable picker popover) is deferred toPhase 2. The multi-step form currently renders an independent
MetadataFormper tab — sharedcross-tab state is a Phase 2 concern. A comment in the component acknowledges this limitation.
Test plan
Components/Panels/Node Property Panel > Multi-step— node header, tabs, fields rendernodeTypeprop — active tab resets to the first tab of the new node typeComponents/Panels/Node Property Panel > SinglePage— flat form rendersComponents/Panels/Node Property Panel > NoSchema— empty-state message shownComponents/Panels/Node Flyout Panel > Default— existing panel story still worksComponents/Controls/Node Property Trigger > Default— popover opens/closes on clickand closes on Escape, scroll, or resize; behavior and layout selections update correctly
🤖 Generated with Claude Code