Skip to content

feat(ui): docs composites cycle 2 (A+B+C) + jsdom unit suite + Codecov#2

Merged
Sam Gammon (sgammon) merged 10 commits into
mainfrom
feat/docs-composites-2
Jul 6, 2026
Merged

feat(ui): docs composites cycle 2 (A+B+C) + jsdom unit suite + Codecov#2
Sam Gammon (sgammon) merged 10 commits into
mainfrom
feat/docs-composites-2

Conversation

@sgammon

Copy link
Copy Markdown
Member

Ports the remaining Tier-2 docs composites (groups A + B + C from COMPONENTS.md) from the authoritative Elide Docs.dc.html mockup, themed entirely from @elide/tokens. CommandPalette (group D) stays deferred pending the Command-primitive decision. Built via a parallel fan-out of scoped agents; spec at docs/superpowers/specs/2026-07-06-docs-composites-cycle-2-design.md.

Composites

Navigation shell: AppNav, SectionTabs, Sidebar (+ SectionSwitcher/SidebarGroup/SidebarItem), TableOfContents (scroll-spy), MobileNav (Sheet drawer).
Content & landing: CardGrid + FeatureCard, StatStrip, AiActions, CopyCommand.
API reference: StatusBadge, ApiMethod + ParamRow, SupportMatrix.

New Base-UI primitives pulled for the shell: Accordion, Select.

Testing

  • New jsdom unit suite in packages/ui (Vitest + Testing Library), separate from the Storybook browser-mode suite. Library build stays clean (test files excluded from the base tsconfig; tsconfig.test.json typechecks tests+stories).
  • Every composite ships a Storybook story (with a play interaction test where interactive) and a *.test.tsx unit test.
  • jsdom: 74/74 · Storybook browser: 47/47 · lint + tsc clean · build 3/3.

Coverage / CI

  • codecov.yml with ui-unit (jsdom) and ui-browser (Storybook) flags; both lcov.info reports uploaded from check.test.yml via codecov/codecov-action (SHA-pinned v7.0.0). Status is informational until coverage on main is representative.
  • ⚠️ Requires the CODECOV_TOKEN repo secret to be added before the upload steps work.

Notable fixes made during integration

  • CopyButton (shared, code-block): swallow clipboard rejections (no more unhandled rejection in headless) and reflect the copied state in aria-label so AT announces "Copied".
  • SectionTabs: preventDefault on controlled onSelect so it doesn't also hash-navigate (this was crashing the browser test page).
  • Mockup token names mapped to the real @elide/tokens vars (--fg-*--*-foreground, --syn-*--eld-syntax-*, --bg-elev*--card/--muted, --nav-bg--nav-background).

Visually spot-checked AppNav and the node:fs API-reference page in dark theme against the mockup.

🤖 Generated with Claude Code

Sam Gammon (sgammon) and others added 4 commits July 6, 2026 11:32
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Add a jsdom Vitest project in packages/ui (Testing Library, coverage via
  v8 → lcov) for pure component unit tests, separate from the Storybook
  browser-mode suite. Proven with badge.test.tsx.
- tsconfig.test.json typechecks tests+stories with vitest globals; base
  tsconfig excludes test files so the library build stays clean.
- Pre-generate Accordion + Select (shadcn Base UI), themed from tokens,
  for the cycle-2 sidebar/section-switcher composites.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ence

Ports the remaining Tier-2 docs composites from the Elide Docs mockup,
themed entirely from @elide/tokens. Each ships a Storybook story (with a
play interaction test where interactive) and a jsdom unit test.

Navigation shell:
- AppNav — brand, nav links, search trigger, theme/locale, changelog, install
- SectionTabs — top-level section bar with active underline + version dot
- Sidebar (+ SectionSwitcher, SidebarGroup, SidebarItem) — active/external/comingSoon
- TableOfContents — "On this page" with IntersectionObserver scroll-spy + mono variant
- MobileNav — condensed bar + Sheet drawer + persistent search bar

Content & landing:
- CardGrid + FeatureCard — responsive category cards with icon/badge/external
- StatStrip — bordered stat grid with primary emphasis
- AiActions — "Use with AI" panel (copy-as-markdown + external links)
- CopyCommand — one-line command block with copy affordance

API reference:
- StatusBadge — thin wrapper over Badge mapping ApiStatus tones
- ApiMethod + ParamRow — method entry with signature, params, example CodeBlock
- SupportMatrix — semantic status table (accessible, not color-only)

Also hardens the shared CopyButton (code-block): swallow clipboard
rejections and reflect the copied state in aria-label so assistive tech
announces it. SectionTabs preventDefault on controlled onSelect so it
doesn't double-navigate. Token names from the mockup mapped to the real
@elide/tokens vars (--fg-* → --*-foreground, --syn-* → --eld-syntax-*, etc.).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- codecov.yml: ui-unit (jsdom) and ui-browser (Storybook) flags, both
  carryforward, informational status while coverage fills in.
- apps/storybook/vitest.config.ts: v8 coverage output (allowExternal, since
  the instrumented sources live in packages/ui/src, outside this app root).
- check.test.yml: run both suites with `turbo run test -- --coverage`, then
  upload each lcov under its flag via codecov/codecov-action (SHA-pinned v7.0.0),
  fail_ci_if_error:false, token from secrets.CODECOV_TOKEN.
- README: Codecov badge.

Requires the CODECOV_TOKEN repo secret to be added.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@codecov

codecov Bot commented Jul 6, 2026

Copy link
Copy Markdown

Welcome to Codecov 🎉

Once you merge this PR into your default branch, you're all set! Codecov will compare coverage reports and display results in all future pull requests.

Thanks for integrating Codecov - We've got you covered ☂️

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Ports Tier-2 docs-site composite UI components (groups A+B+C) into packages/ui, adds a dedicated jsdom unit-test suite alongside the existing Storybook browser-mode suite, and wires up Codecov reporting for both coverage streams.

Changes:

  • Added docs composites + Base UI primitives (Accordion/Select), plus Storybook stories and Vitest jsdom unit tests.
  • Introduced packages/ui Vitest jsdom project (vitest.config.ts), test TSConfig, and shared test setup.
  • Added Codecov configuration, CI coverage uploads (unit + browser), and a README badge.

Reviewed changes

Copilot reviewed 53 out of 55 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
README.md Adds Codecov badge.
packages/ui/vitest.config.ts New Vitest jsdom unit-suite config + coverage output.
packages/ui/tsconfig.test.json New TSConfig for typechecking tests/stories.
packages/ui/tsconfig.json Excludes test files from the library build TSConfig.
packages/ui/src/test-setup.ts Registers jest-dom matchers and Testing Library cleanup.
packages/ui/src/stories/TableOfContents.stories.tsx Story for TableOfContents composite + play assertions.
packages/ui/src/stories/SupportMatrix.stories.tsx Story for SupportMatrix composite.
packages/ui/src/stories/StatusBadge.stories.tsx Story for StatusBadge composite + play assertions.
packages/ui/src/stories/StatStrip.stories.tsx Story for StatStrip composite + play assertions.
packages/ui/src/stories/Sidebar.stories.tsx Story for Sidebar composite + interaction test for section switcher.
packages/ui/src/stories/SectionTabs.stories.tsx Story for SectionTabs composite + controlled-selection test.
packages/ui/src/stories/MobileNav.stories.tsx Story for MobileNav composite + portal-aware play assertions.
packages/ui/src/stories/CopyCommand.stories.tsx Story for CopyCommand composite + copied-state assertions.
packages/ui/src/stories/CardGrid.stories.tsx Story for CardGrid/FeatureCard composites + external-link checks.
packages/ui/src/stories/AppNav.stories.tsx Story for AppNav composite + callback assertions.
packages/ui/src/stories/ApiMethod.stories.tsx Story for ApiMethod composite (signature/params/example).
packages/ui/src/stories/AiActions.stories.tsx Story for AiActions composite + external-link checks.
packages/ui/src/index.ts Exports new primitives and composites from the public UI entrypoint.
packages/ui/src/components/table-of-contents.tsx Implements TableOfContents composite + optional scroll-spy behavior.
packages/ui/src/components/table-of-contents.test.tsx Unit tests for TableOfContents rendering/active state/callback.
packages/ui/src/components/support-matrix.tsx Implements SupportMatrix composite with accessible status labels.
packages/ui/src/components/support-matrix.test.tsx Unit tests for SupportMatrix structure/accessibility/custom columns.
packages/ui/src/components/status-badge.tsx Implements StatusBadge wrapper over Badge status tones.
packages/ui/src/components/status-badge.test.tsx Unit tests for StatusBadge defaults and overrides.
packages/ui/src/components/stat-strip.tsx Implements StatStrip composite for API landing metrics.
packages/ui/src/components/stat-strip.test.tsx Unit tests for StatStrip rendering/emphasis/aria-label.
packages/ui/src/components/sidebar.tsx Implements Sidebar + SectionSwitcher/Group/Item subcomponents.
packages/ui/src/components/sidebar.test.tsx Unit tests for Sidebar, groups/items, and section switching.
packages/ui/src/components/select.tsx Adds Base UI Select primitive wrapper styling.
packages/ui/src/components/section-tabs.tsx Implements SectionTabs composite with controlled routing support.
packages/ui/src/components/section-tabs.test.tsx Unit tests for SectionTabs behavior and callback.
packages/ui/src/components/mobile-nav.tsx Implements MobileNav composite with Sheet-based drawer.
packages/ui/src/components/mobile-nav.test.tsx Unit tests for MobileNav drawer behavior and search callback.
packages/ui/src/components/copy-command.tsx Implements CopyCommand composite using CodeBlock’s CopyButton.
packages/ui/src/components/copy-command.test.tsx Unit tests for CopyCommand rendering and clipboard write.
packages/ui/src/components/code-block.tsx Updates CopyButton to swallow clipboard rejections and improve aria-label.
packages/ui/src/components/card-grid.tsx Implements CardGrid + FeatureCard composites with keyboard support.
packages/ui/src/components/card-grid.test.tsx Unit tests for CardGrid/FeatureCard interactions and external-link behavior.
packages/ui/src/components/badge.test.tsx Adds baseline unit tests for Badge (used to validate new jsdom suite).
packages/ui/src/components/app-nav.tsx Implements AppNav composite (docs top navigation shell).
packages/ui/src/components/app-nav.test.tsx Unit tests for AppNav link rendering and callbacks.
packages/ui/src/components/api-method.tsx Implements ApiMethod + ParamRow composites for API reference pages.
packages/ui/src/components/api-method.test.tsx Unit tests for ApiMethod/ParamRow rendering and anchor linking.
packages/ui/src/components/ai-actions.tsx Implements AiActions composite (copy + external actions).
packages/ui/src/components/ai-actions.test.tsx Unit tests for AiActions clipboard and action rendering.
packages/ui/src/components/accordion.tsx Adds Base UI Accordion primitive wrapper styling.
packages/ui/package.json Adds Vitest/testing-library/jsdom deps and test scripts.
docs/superpowers/specs/2026-07-06-docs-composites-cycle-2-design.md Adds design/spec contract documenting scope and constraints.
COMPONENTS.md Marks new primitives/composites as done.
codecov.yml Adds Codecov flags + ignore rules for merged unit/browser coverage.
bun.lock Locks added dev dependencies for unit testing and coverage.
apps/storybook/vitest.config.ts Enables v8 coverage for Storybook browser-mode suite (allowExternal).
apps/storybook/package.json Adds test:coverage script for Storybook suite.
.gitignore Ignores coverage output directories.
.github/workflows/check.test.yml Runs both suites with coverage and uploads two flagged reports to Codecov.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread packages/ui/src/components/ai-actions.tsx
Comment thread packages/ui/src/components/stat-strip.tsx
Sam Gammon (sgammon) and others added 3 commits July 6, 2026 13:10
- CodeBlock now syntax-highlights `code` via prism-react-renderer with a
  Prism theme mapped onto the --eld-syntax-* tokens (TS, Bash, JSON, etc.),
  instead of rendering raw monochrome text. `children` still overrides for
  pre-highlighted markup. Composite code blocks (ApiMethod, CopyCommand) are
  now colored.
- Add ElideLogo/ElideMark/ElideWordmark — the real brand marks inlined as SVG
  (no external asset request, so they render in SSR/Storybook/Chromatic). Used
  as AppNav's default logo in place of the placeholder glyph.
- Self-host fonts via @fontsource (Inter/Instrument Sans/JetBrains Mono)
  instead of a remote Google Fonts @import, which Chromatic's capture env
  blocks — snapshots were falling back to system fonts.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Accessibility (Storybook a11y / Chromatic):
- Accent text used --primary (#d4007f), which fails WCAG AA on the dark
  surfaces (3.87:1). Switch text usages to --primary-emphasis (the design
  system's on-surface accent — magenta-400 on dark), leaving bg/border accents
  alone. Fixes SectionTabs, ApiMethod/ParamRow, SupportMatrix, MobileNav,
  TableOfContents, Sidebar, StatStrip, AiActions.
- --subtle-foreground was neutral-500 (#737373) in dark, failing AA for the
  small mono micro-labels; step it up to neutral-400 (light unchanged).
- MobileNav's Sheet drawer (role=dialog) had no accessible name -> add aria-label.

Copilot review:
- ai-actions: swallow clipboard writeText rejection (matches CopyButton).
- stat-strip: emit <dt> before <dd> for valid <dl> markup; order-* preserves
  the value-on-top layout.

Story/test class assertions updated to the -emphasis token to match.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Both Vitest suites emit JUnit XML (test-report.junit.xml); check.test.yml
  uploads them via codecov/test-results-action (SHA-pinned v1.2.1), running on
  failure too so failing/flaky tests surface in Codecov Test Analytics.
- Storybook Vite build runs @codecov/vite-plugin (bundleName elide-storybook)
  for Bundle Analysis, gated on CODECOV_TOKEN; job.storybook.yml passes the
  token into the build env.

The @elide/ui library is built with tsup (esbuild), which has no first-party
Codecov bundler plugin, so bundle analysis covers the Storybook build only.
Both features use the existing CODECOV_TOKEN secret.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
ApiMethod rendered the signature function-name and ParamRow type using the
code-surface syntax tokens (--eld-syntax-function pale yellow, --eld-syntax-type
teal). Those are tuned for the always-dark code surface and become unreadable on
the light page background. Use theme-aware tokens: the signature name -> the
--primary-emphasis accent, the param type -> muted-foreground. Clears the
remaining light-theme color-contrast violations (Chromatic tests both themes).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 60 out of 62 changed files in this pull request and generated 1 comment.

Comment thread packages/ui/src/components/elide-logo.tsx
Sam Gammon (sgammon) and others added 2 commits July 6, 2026 13:36
Break every string a component renders itself (labels, placeholders, ARIA
names, status text) out of the components into a default English dictionary
(src/i18n/messages.ts), read via useMessages(). Consumers translate the catalog
by wrapping in <MessagesProvider messages={locale}> — a PartialMessages dict
deep-merged (two levels) over the defaults. Explicit props (e.g. AppNav
searchPlaceholder, AiActions title) still override per-instance.

Wired: AppNav, MobileNav, SectionTabs, Sidebar, TableOfContents, CodeBlock/
CopyButton, AiActions, SupportMatrix, StatusBadge. Exues MessagesProvider,
useMessages, defaultMessages, Messages, PartialMessages.

Also: the nav search placeholder default is now "Search or ask" (was
"Search or ask AI…").

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
ElideLogo aria-hidden'd both the mark and the wordmark in the default case, so
the brand lockup announced nothing. Keep the mark exposed (role="img"
aria-label="Elide") with the wordmark decorative, so it's announced once.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@sgammon Sam Gammon (sgammon) merged commit 29161cc into main Jul 6, 2026
7 checks passed
@sgammon Sam Gammon (sgammon) deleted the feat/docs-composites-2 branch July 6, 2026 20:52
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.

2 participants