Skip to content

feat(frontend): extract floating UI primitives into @infrahub/ui and adopt in path-traversal#9480

Closed
pa-lem wants to merge 30 commits into
developfrom
ple-floating-ui-primitives
Closed

feat(frontend): extract floating UI primitives into @infrahub/ui and adopt in path-traversal#9480
pa-lem wants to merge 30 commits into
developfrom
ple-floating-ui-primitives

Conversation

@pa-lem

@pa-lem pa-lem commented Jun 5, 2026

Copy link
Copy Markdown
Contributor

What

Extracts reusable floating-UI primitives into the @infrahub/ui design system and adopts them in the path-traversal feature, so path-traversal and the schema-visualizer can share one source of truth for their floating chrome.

New @infrahub/ui primitives (each composes existing DS items)

  • Toolbar + Toolbar.Divider — floating toolbar container (role="toolbar", requires aria-label) + vertical separator.
  • FloatingPanel — floating overlay built on Card/CardHeader/CardContent + Button: header (title/description/close) + scrollable body; optional dismissable (outside-click + Escape).
  • useDismiss — shared outside-pointerdown + Escape dismissal hook (dedups two prior copies).
  • The canvas-oriented primitives (Toolbar, FloatingPanel) live under src/components/graph/, separate from the regular primitives (Button, Card, Modal, …). They remain generic — no graph/ReactFlow coupling.
  • Establishes the first vitest browser test harness in @infrahub/ui (it had no tests before).

Note: there is no IconButton component. Icon-only buttons use the regular Button directly (variant="ghost" size="sm" shape="square" + aria-label) — a dedicated wrapper that only re-defaulted props wasn't worth the indirection.

path-traversal adoption

  • bottom-toolbar.tsx now uses Toolbar/Toolbar.Divider, the shared useDismiss (local copy deleted), and Button for icon-only controls.
  • path-traversal-page.tsx parameters panel now uses FloatingPanel (was an app-level Content.Card).

Test infra

  • frontend/app/vitest.config.ts: pre-bundle lucide-react via Vite optimizeDeps.include@infrahub/ui is consumed from source, so FloatingPanel's lucide-react import would otherwise be discovered mid-run and trigger a Vite reload that resets vi.mock() (breaking unrelated mocked tests).

Docs

  • dev/knowledge/frontend/design-system.md: documents that @infrahub/ui is consumed from source (not built output), and the cross-package Tailwind @source requirement for consumers.

Testing

  • @infrahub/ui: 12 tests · path-traversal: 13 tests (bottom-toolbar) — full app browser suite green.
  • biome clean; touched files typecheck clean.

Notes / follow-ups

  • The matching schema-visualizer adoption of these primitives is a companion PR in opsmill/infrahub-schema-visualizer (paused: that repo can't resolve @infrahub/ui standalone yet — pending a publish/resolution strategy).
  • The submodule pointer bump is intentionally not included here; it follows once the companion PR merges.
  • Pre-existing, unrelated: @infrahub/ui's pnpm build fails on a tsconfig TS5101 baseUrl deprecation already present on develop (the app consumes ui from source, so this doesn't affect the app).

🤖 Generated with Claude Code

@pa-lem pa-lem requested review from a team as code owners June 5, 2026 13:04
@github-actions github-actions Bot added type/documentation Improvements or additions to documentation group/frontend Issue related to the frontend (React) labels Jun 5, 2026

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

2 issues found across 22 files

Confidence score: 4/5

  • This PR is likely safe to merge: both findings are low severity (4/10 and 3/10) and mainly affect test/docs quality rather than production runtime behavior.
  • The most important issue is in frontend/packages/ui/src/components/floating-panel/floating-panel.test.tsx, where [role="heading"] does not match semantic <h2>; this can let the hidden-state test pass while a heading is still rendered, weakening regression detection.
  • In docs/superpowers/plans/2026-06-04-floating-ui-primitives.md, the success criteria reference a frontend/packages/ui build expectation that conflicts with the known TS5101 tsc -b state, so the plan can be misleading but is not merge-blocking.
  • Pay close attention to frontend/packages/ui/src/components/floating-panel/floating-panel.test.tsx and docs/superpowers/plans/2026-06-04-floating-ui-primitives.md - fix the heading selector assertion and align success criteria with current TypeScript build constraints.

Shadow auto-approve: would not auto-approve because issues were found.

Re-trigger cubic

Comment thread frontend/packages/ui/src/components/floating-panel/floating-panel.test.tsx Outdated
Comment thread docs/superpowers/plans/2026-06-04-floating-ui-primitives.md Outdated
@pa-lem pa-lem removed request for a team June 5, 2026 13:25

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

0 issues found across 3 files (changes from recent commits).

Shadow auto-approve: would auto-approve. This PR extracts accessible, tested floating-UI primitives into the design system and adopts them in path-traversal, replacing a local hook and hand-rolled markup with shared components — all changes are in frontend UI code with 48 passing tests and zero impact on business logic, data, or infra-

Re-trigger cubic

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 issue found across 2 files (changes from recent commits).

Shadow auto-approve: would not auto-approve because issues were found.
Tip: Review your code locally with the cubic CLI to iterate faster.

Re-trigger cubic

Comment thread frontend/app/vitest.config.ts Outdated

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

0 issues found across 1 file (changes from recent commits).

Shadow auto-approve: would not auto-approve. Auto-approval blocked by 1 unresolved issue from previous reviews.

Re-trigger cubic

pa-lem and others added 19 commits June 6, 2026 16:01
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Cast `.element()` return to `HTMLElement` before calling `.click()` on lines
that simulate PNG/SVG export menu clicks — `.element()` returns
`HTMLElement | SVGElement` and `SVGElement` has no `.click()` method.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…reload

FloatingPanel (from @infrahub/ui workspace source) imports lucide-react,
which was not in Vite's pre-optimized dep list. When first encountered
mid-suite, Vite triggered a re-optimization + full page reload that reset
vi.mock() registry, causing remove-relationships.test.ts to fail with
"vi.mocked(...).mockResolvedValueOnce is not a function".

Adding lucide-react to test.deps.optimizer.web.include forces it to be
pre-bundled before any test runs, eliminating the reload entirely.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
… for vitest 4 browser mode)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@pa-lem pa-lem force-pushed the ple-floating-ui-primitives branch from 798ff67 to 2fed087 Compare June 6, 2026 14:04
…mponents/graph

IconButton only re-defaulted Button (ghost/sm/square + required aria-label);
replaced all usages with Button directly. Moved the canvas-oriented Toolbar and
FloatingPanel primitives into components/graph/ to separate them from the regular
primitives.

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

2 issues found across 12 files (changes from recent commits).

Shadow auto-approve: would not auto-approve because issues were found.
Tip: Review your code locally with the cubic CLI to iterate faster.

Re-trigger cubic

Comment thread frontend/packages/ui/package.json Outdated
Comment thread frontend/app/src/entities/path-traversal/ui/bottom-toolbar.tsx

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

0 issues found across 1 file (changes from recent commits).

Shadow auto-approve: would auto-approve. This PR is a well-structured extraction of floating UI primitives into the design system with thorough testing, documentation, and adoption in the path-traversal feature. It passes AI review, follows project patterns, and does not touch critical systems.

Re-trigger cubic

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

0 issues found across 1 file (changes from recent commits).

Shadow auto-approve: would require human review. Although the AI review found no issues and the PR includes tests, it is a refactoring that extracts and adopts shared UI primitives, reordering existing component logic and dependencies—a high-impact change that should be reviewed by a human to ensure correctness and no regressions.

Re-trigger cubic

@github-actions github-actions Bot removed the type/documentation Improvements or additions to documentation label Jun 8, 2026
Moves the canvas-overlay primitives out of @infrahub/ui into a dedicated
@infrahub/graph package (depends on @infrahub/ui for Card/Button/useDismiss) —
a home for future graph-specific components. Rewires path-traversal consumers;
useDismiss stays in @infrahub/ui.

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

2 issues found across 26 files (changes from recent commits).

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="frontend/packages/graph/oxlint.config.ts">

<violation number="1" location="frontend/packages/graph/oxlint.config.ts:32">
P2: Custom agent: **Flag AI Slop and Fabricated Changes**

Invalid oxlint rule key: plugin is registered as `react-perf` but this rule uses `react_perf` (underscore instead of hyphen). The mismatched prefix means oxlint will silently ignore the rule and the intended `jsx-no-new-function-as-prop` override will not apply.</violation>
</file>

<file name="frontend/packages/graph/src/index.css">

<violation number="1" location="frontend/packages/graph/src/index.css:9">
P3: `graph` duplicates global base CSS already defined in `@infrahub/ui`, which risks style drift and redundant maintenance.</violation>
</file>

Shadow auto-approve: would not auto-approve because issues were found.
Tip: Review your code locally with the cubic CLI to iterate faster.

Re-trigger cubic

"react/no-multi-comp": "off",
"react/only-export-components": "off",
"react/react-in-jsx-scope": "off",
"react_perf/jsx-no-new-function-as-prop": "off",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: Custom agent: Flag AI Slop and Fabricated Changes

Invalid oxlint rule key: plugin is registered as react-perf but this rule uses react_perf (underscore instead of hyphen). The mismatched prefix means oxlint will silently ignore the rule and the intended jsx-no-new-function-as-prop override will not apply.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At frontend/packages/graph/oxlint.config.ts, line 32:

<comment>Invalid oxlint rule key: plugin is registered as `react-perf` but this rule uses `react_perf` (underscore instead of hyphen). The mismatched prefix means oxlint will silently ignore the rule and the intended `jsx-no-new-function-as-prop` override will not apply.</comment>

<file context>
@@ -0,0 +1,39 @@
+    "react/no-multi-comp": "off",
+    "react/only-export-components": "off",
+    "react/react-in-jsx-scope": "off",
+    "react_perf/jsx-no-new-function-as-prop": "off",
+    "typescript/explicit-function-return-type": "off",
+    "typescript/explicit-module-boundary-types": "off",
</file context>

@source "./**/*.{js,ts,jsx,tsx}";
@source "../../ui/src/**/*.{js,ts,jsx,tsx}";

@font-face {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P3: graph duplicates global base CSS already defined in @infrahub/ui, which risks style drift and redundant maintenance.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At frontend/packages/graph/src/index.css, line 9:

<comment>`graph` duplicates global base CSS already defined in `@infrahub/ui`, which risks style drift and redundant maintenance.</comment>

<file context>
@@ -0,0 +1,24 @@
+@source "./**/*.{js,ts,jsx,tsx}";
+@source "../../ui/src/**/*.{js,ts,jsx,tsx}";
+
+@font-face {
+  font-family: InterVariable;
+  font-weight: 100 900;
</file context>

@infrahub/ui is now unchanged vs develop (less PR noise). useDismiss (+ test) and
the vitest harness live in @infrahub/graph alongside Toolbar/FloatingPanel.
path-traversal imports useDismiss from @infrahub/graph.
@cubic-dev-ai

cubic-dev-ai Bot commented Jun 8, 2026

Copy link
Copy Markdown
Contributor

You're iterating quickly on this pull request. To help protect your rate limits, cubic has paused automatic reviews on new pushes for now—when you're ready for another review, comment @cubic-dev-ai review.

pa-lem added 4 commits June 8, 2026 14:07
Extracts the PNG/SVG export popover into @infrahub/graph (self-contained: owns its
open state + outside-click/Escape dismiss). path-traversal's bottom-toolbar drops its
hand-rolled menu + dismiss state.
GraphControls (zoom/fit/edge-style/layout cluster) reads ReactFlow via an @xyflow/react
peer dep. Ports a Tooltip into @infrahub/ui so GraphControls keeps styled tooltips.
path-traversal's bottom-toolbar adopts both. The app's vitest excludes @infrahub/graph
from optimizeDeps so vi.mock reaches GraphControls' @xyflow/react import.
@pa-lem

pa-lem commented Jun 8, 2026

Copy link
Copy Markdown
Contributor Author

Split into stacked PRs for cleaner review: #9496 (Tooltip in @infrahub/ui) and the new @infrahub/graph PR (graph primitives + path-traversal). schema-visualizer adoption will be a third PR in its own repo.

@pa-lem pa-lem closed this Jun 8, 2026
@pa-lem pa-lem deleted the ple-floating-ui-primitives branch June 8, 2026 13:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

group/frontend Issue related to the frontend (React)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant