Skip to content

feat(ui): add base-ui primitives to close design↔code gap#556

Open
seonghobae wants to merge 9 commits into
developfrom
vagabond-scallion
Open

feat(ui): add base-ui primitives to close design↔code gap#556
seonghobae wants to merge 9 commits into
developfrom
vagabond-scallion

Conversation

@seonghobae

Copy link
Copy Markdown
Collaborator

What

Adds nine shadcn base-nova style UI components backed by @base-ui/react, matching the existing ui/ conventions (data-slot, cn, JSDoc per component):

table, checkbox, switch, radio-group, accordion, label, dialog, select, tooltip.

Why

These components existed only in the Figma design system (marked "System Asset — no product code", a design↔code gap). This closes that gap; the Figma Dev Handoff is synced to Ready for each.

Verification

  • npx tsc --noEmit — clean
  • npx eslint src/components/ui/*.tsx — clean
  • ui-added.test.tsx — 9 jsdom render tests (mount + data-checked, switch thumb, radio items, accordion panel, dialog portal, select/tooltip triggers). Full src/components/ui/ suite: 16/16 pass.

Notes

Library components — not yet wired into app screens. Remaining design-first components (Snackbar, Step Indicator, Header, Footer, Main Menu, Breadcrumb, In-page Nav) are app-compositions and intentionally left for feature code.

🤖 Generated with Claude Code

https://claude.ai/code/session_01RjGVapDZ3k7V7zKYk16P4C

seonghobae and others added 9 commits July 5, 2026 13:16
Add nine shadcn base-nova style components backed by @base-ui/react,
matching the existing ui/ conventions (data-slot, cn, JSDoc): table,
checkbox, switch, radio-group, accordion, label, dialog, select,
tooltip. These previously existed only in the Figma design system as
"System Asset (no product code)"; the Figma Dev Handoff is now synced
to Ready.

Verified: tsc --noEmit and eslint clean; ui-added.test.tsx mounts and
renders all nine in jsdom (checked/indicator, thumb, radio items,
accordion panel, dialog portal, select/tooltip triggers).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RjGVapDZ3k7V7zKYk16P4C
Standard shadcn base-nova breadcrumb (nav/list/item/link/page/separator/
ellipsis) — pure composition, no primitive. Closes another design-first
gap. Verified: tsc + eslint clean; render test asserts links, current
page aria-current and separator.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RjGVapDZ3k7V7zKYk16P4C
Presentational stepper (StepIndicator/StepItem/StepIndicatorMarker/
StepTitle/StepSeparator) driven by a per-step `state`
(complete|current|upcoming) — maps to the analysis lifecycle. Verified:
tsc + eslint clean; render test asserts marker/title state and that a
completed step renders a check instead of its number.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RjGVapDZ3k7V7zKYk16P4C
Table-of-contents style in-page navigation (InPageNav/List/Item/Link).
Active link draws a left indicator bar (border-l-2) with a consistent
pl-3 indicator-to-label gap and sets aria-current="location". Verified:
tsc + eslint clean; render test asserts active indicator + aria-current.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RjGVapDZ3k7V7zKYk16P4C
Add sonner and a Toaster wrapper (Snackbar/Toast) matching the token
theme; export the `toast` helper. Theme follows OS preference (no
next-themes provider in this app). Stub window.matchMedia in the test
setup (jsdom lacks it) so theme="system" components render under test.

Verified: tsc + eslint clean; render test fires toast("분석 준비 완료")
and asserts it appears. Full suite 134 tests + 100% coverage gate pass.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RjGVapDZ3k7V7zKYk16P4C
Wire the sonner Toaster into App so toast() is usable app-wide. Always
rendered, no behavioural change until a toast fires. App.tsx coverage
gate stays at 100%.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RjGVapDZ3k7V7zKYk16P4C
Add Storybook 10 (react-vite builder) wired for this app: Tailwind v4
plugin and the "@" alias injected via viteFinal, tokens loaded from
index.css in preview. Stories for Button, Checkbox and Dialog. Exempt
*.stories.tsx from the strict jsdoc/require-jsdoc rule (same as tests)
and gitignore storybook-static.

Verified: `storybook build` completes; tsc, eslint and the full test
suite (100% coverage gate) stay green.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RjGVapDZ3k7V7zKYk16P4C
@base-ui/react Checkbox.Root renders a <span>, whose default display:inline
makes the size-4 width/height no-op, so the control collapsed to a 14×61
inline box (verified via Storybook + headless-Chrome getBoundingClientRect).
Add inline-flex items-center justify-center so size-4 applies and the
indicator centers → renders 16×16 as intended.

Found via real Storybook↔Figma implementation-parity measurement.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RjGVapDZ3k7V7zKYk16P4C
The separator is coarse FFT band-splitting (audio_separator.py: 'coarse
canonical frequency and percussion bands'), not source separation —
measured SI-SDR ~ -39 dB on a realistic mix vs ~+9 dB for demucs
(characterization tests in PR #557). 'rough stem previews' matches the
README's own hedged voice ('likely harmony', 'visible confidence') and
the existing scope disclaimer, without overclaiming DAW-grade separation.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RjGVapDZ3k7V7zKYk16P4C
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant