Skip to content

feat(shadcn): #50 rebuild Header; delete dead Sidebar#57

Closed
fray-cloud wants to merge 3 commits into
devfrom
shadcn/50-header-sidebar
Closed

feat(shadcn): #50 rebuild Header; delete dead Sidebar#57
fray-cloud wants to merge 3 commits into
devfrom
shadcn/50-header-sidebar

Conversation

@fray-cloud

@fray-cloud fray-cloud commented Apr 13, 2026

Copy link
Copy Markdown
Owner

Summary

Stacked on #56.

Header

Drops daisyUI navbar / bg-neutral / text-neutral-content / btn-ghost and rebuilds as a plain Tailwind flex row using shadcn <Button variant="ghost"> for the title link. bg-neutral-900 / text-neutral-100 preserves the dark-contrast originally supplied by daisyUI's neutral theme tokens.

Sidebar

Deleted. The component was pulled only via the new-component/ barrel and rendered nowhere (no consumers after the catch-all bridge and SiteRouter were removed in #35). new-component/index.ts drops its export.

Closes #50.

Test plan

  • npx nx affected -t lint test build --exclude web-e2e green
  • grep -rn Sidebar apps/web → zero remaining references

🤖 Generated with Claude Code

Summary by Sourcery

Introduce shadcn-style UI primitives and theming, rebuild the header using the new button component, and remove the unused sidebar component.

New Features:

  • Add shared shadcn-style UI primitives including Button, Card, Avatar, Progress, and Skeleton components for the web app.
  • Configure global CSS variables and Tailwind theme extensions for light/dark mode and semantic color tokens.
  • Add a utility helper for merging Tailwind class names across components.

Enhancements:

  • Rebuild the header layout using the new ghost Button variant instead of daisyUI navbar styles.
  • Enable Tailwind dark mode via class strategy and integrate tailwindcss-animate plugin.

Build:

  • Add Radix UI, class-variance-authority, clsx, tailwind-merge, lucide-react, and tailwindcss-animate dependencies for the new UI system.

Chores:

  • Remove the unused Sidebar component and stop exporting it from the new-component barrel.

Handcrafted shadcn init to preserve the front/* alias and Nx layout.
Scaffolding only — no call-site swaps; daisyUI plugin remains active.

- apps/web/components.json — shadcn schema 1, style default, rsc true,
  baseColor neutral, cssVariables, aliases mapped onto front/*
  (components → front/new-component, ui → front/new-component/ui,
   utils → front/lib/utils, lib → front/lib, hooks → front/hooks),
  iconLibrary lucide
- apps/web/src/lib/utils.ts — cn helper (clsx + tailwind-merge)
- apps/web/src/new-component/ui/ directory created (empty; #49 fills)
- apps/web/tailwind.config.js — darkMode ['class'], theme.extend.colors
  wired to hsl(var(--*)) shadcn tokens, theme.extend.borderRadius,
  plugins keep `require('daisyui')` and add `tailwindcss-animate`
- apps/web/app/globals.css — :root + .dark CSS variables under
  @layer base
- package.json — class-variance-authority, clsx, tailwind-merge,
  tailwindcss-animate, lucide-react added

- nx affected -t lint test build --exclude web-e2e green
  (4 projects, 10 tasks)
- daisyUI classes still render identically (coexistence by design
  through #54)

Refs #48
Five shadcn/ui components written directly into
apps/web/src/new-component/ui/ to match the aliases configured in
#48. Standard shadcn default-style implementations using cn(),
class-variance-authority (button only), and Radix primitives for
Avatar and Progress. No call-site swaps — files are unreferenced
until #50#54 consume them.

- button.tsx — variants (default/destructive/outline/secondary/ghost/
  link), sizes (default/sm/lg/icon), asChild via @radix-ui/react-slot
- card.tsx — Card + CardHeader/Title/Description/Content/Footer
- skeleton.tsx — animated muted placeholder
- avatar.tsx — Radix Avatar/Image/Fallback ("use client")
- progress.tsx — Radix Progress with translate-based indicator
  ("use client")
- package.json — @radix-ui/react-slot, @radix-ui/react-avatar,
  @radix-ui/react-progress added

- nx affected -t lint test build --exclude web-e2e green

Refs #49
…50)

Header:
- Drops daisyUI navbar/bg-neutral/text-neutral-content/btn-ghost and
  rebuilds as a plain Tailwind flex row using shadcn Button
  variant="ghost" for the title link
- bg-neutral-900 / text-neutral-100 token pair preserves the dark
  contrast originally supplied by daisyUI's neutral theme tokens

Sidebar:
- Deleted. The component was pulled only via the new-component/
  barrel export and rendered nowhere (no consumers after the
  catch-all bridge and SiteRouter were removed in #35).
- new-component/index.ts drops `export * from './sidebar'`.

- nx affected -t lint test build --exclude web-e2e green
- daisyUI plugin still present; coexists with shadcn through #54

Refs #50
@vercel

vercel Bot commented Apr 13, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
animal-project Error Error Apr 13, 2026 8:42am

@sourcery-ai

sourcery-ai Bot commented Apr 13, 2026

Copy link
Copy Markdown

Reviewer's Guide

Rebuilds the Header to use shadcn-style UI primitives and Tailwind design tokens, introduces shared shadcn utility components and Tailwind CSS variables/theme wiring (including dark mode via class), and deletes the unused Sidebar plus its barrel export while updating dependencies to support the new UI layer.

Class diagram for new shadcn-style UI primitives and utilities

classDiagram
  direction LR

  class cn {
    <<function>>
    +cn(inputs) ClassValue[]
  }

  class Button {
    <<ReactComponent>>
    +asChild boolean
    +variant string
    +size string
    +disabled boolean
    +onClick(event)
  }

  class buttonVariants {
    <<cvaConfig>>
    +variant default|destructive|outline|secondary|ghost|link
    +size default|sm|lg|icon
  }

  class Card {
    <<ReactComponent>>
    +children ReactNode
  }

  class CardHeader {
    <<ReactComponent>>
    +children ReactNode
  }

  class CardTitle {
    <<ReactComponent>>
    +children ReactNode
  }

  class CardDescription {
    <<ReactComponent>>
    +children ReactNode
  }

  class CardContent {
    <<ReactComponent>>
    +children ReactNode
  }

  class CardFooter {
    <<ReactComponent>>
    +children ReactNode
  }

  class Avatar {
    <<ReactComponent>>
    +children ReactNode
  }

  class AvatarImage {
    <<ReactComponent>>
    +src string
    +alt string
  }

  class AvatarFallback {
    <<ReactComponent>>
    +children ReactNode
  }

  class Progress {
    <<ReactComponent>>
    +value number
  }

  class Skeleton {
    <<ReactComponent>>
    +className string
  }

  class Header {
    <<ReactComponent>>
    +router NextRouter
  }

  %% Relationships
  cn <.. Button : uses
  cn <.. Card : uses
  cn <.. CardHeader : uses
  cn <.. CardTitle : uses
  cn <.. CardDescription : uses
  cn <.. CardContent : uses
  cn <.. CardFooter : uses
  cn <.. Avatar : uses
  cn <.. AvatarImage : uses
  cn <.. AvatarFallback : uses
  cn <.. Progress : uses
  cn <.. Skeleton : uses

  buttonVariants <.. Button : uses

  Card <|-- CardHeader
  Card <|-- CardTitle
  Card <|-- CardDescription
  Card <|-- CardContent
  Card <|-- CardFooter

  Avatar <|-- AvatarImage
  Avatar <|-- AvatarFallback

  Header --> Button : renders
  Header --> CountList : renders

  class CountList {
    <<ReactComponent>>
  }
Loading

File-Level Changes

Change Details Files
Introduce shadcn-compatible design tokens and Tailwind theme wiring, including class-based dark mode.
  • Add CSS custom properties for background/foreground, semantic colors, and radius on :root and .dark scopes in globals.css
  • Enable Tailwind darkMode='class' and extend the theme with color aliases that read from the CSS custom properties
  • Extend border radius values to derive from the configured --radius token
  • Register tailwindcss-animate plugin alongside existing daisyUI plugin
apps/web/app/globals.css
apps/web/tailwind.config.js
Add foundational shadcn-style UI primitives (button, card, avatar, progress, skeleton) and a shared cn() utility.
  • Create cn() helper that composes clsx and tailwind-merge for className merging
  • Add Button component using class-variance-authority for variant/size styling and Radix Slot support
  • Add Card, Avatar, Progress, and Skeleton components wired to the new Tailwind tokens and Radix primitives where appropriate
  • Introduce a components.json manifest for the shadcn UI layer
apps/web/src/lib/utils.ts
apps/web/src/new-component/ui/button.tsx
apps/web/src/new-component/ui/card.tsx
apps/web/src/new-component/ui/avatar.tsx
apps/web/src/new-component/ui/progress.tsx
apps/web/src/new-component/ui/skeleton.tsx
apps/web/components.json
Refactor Header to replace daisyUI navbar/button usage with shadcn Button and a Tailwind flex layout while preserving dark visual contrast.
  • Swap daisyUI navbar/container classes for an explicit flex layout with spacing, padding, and dark neutral background/text colors
  • Replace the daisyUI btn-ghost anchor with a shadcn Button using ghost variant and custom sizing/hover overrides
  • Keep existing CountList usage and navigation behavior via next/navigation router.push('/')
apps/web/src/new-component/header.tsx
Remove dead Sidebar component and its barrel export from new-component.
  • Delete Sidebar implementation file
  • Stop exporting Sidebar and bottom from the new-component index barrel, leaving only form and header exports
apps/web/src/new-component/sidebar.tsx
apps/web/src/new-component/index.ts
Add runtime dependencies needed for shadcn/Radix UI and Tailwind merging/animation support.
  • Include @radix-ui/react-avatar, @radix-ui/react-progress, and @radix-ui/react-slot for primitive components
  • Add class-variance-authority and clsx for variant-driven styling and class composition
  • Add lucide-react for potential icon usage in the shadcn layer
  • Add tailwind-merge and tailwindcss-animate to support class merging and animations
  • Regenerate package-lock.json to capture the new dependency graph
package.json
package-lock.json

Possibly linked issues


Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@nx-cloud

nx-cloud Bot commented Apr 13, 2026

Copy link
Copy Markdown

View your CI Pipeline Execution ↗ for commit 01fa96d

Command Status Duration Result
nx build web ✅ Succeeded <1s View ↗

☁️ Nx Cloud last updated this comment at 2026-04-13 08:44:12 UTC

@sourcery-ai sourcery-ai Bot 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.

Hey - I've found 1 issue, and left some high level feedback:

  • In ui/card.tsx, the CardTitle and CardDescription components have a mismatch between the generic element types (HTMLDivElement) and the props types (HTMLHeadingElement / HTMLParagraphElement) while rendering <div> elements; align the generics, props, and rendered tag (e.g., use <h3>/<p> or change the prop types) to avoid incorrect typings and potential ref issues.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- In `ui/card.tsx`, the `CardTitle` and `CardDescription` components have a mismatch between the generic element types (`HTMLDivElement`) and the props types (`HTMLHeadingElement` / `HTMLParagraphElement`) while rendering `<div>` elements; align the generics, props, and rendered tag (e.g., use `<h3>`/`<p>` or change the prop types) to avoid incorrect typings and potential ref issues.

## Individual Comments

### Comment 1
<location path="apps/web/src/new-component/ui/card.tsx" line_range="47-8" />
<code_context>
+));
+CardTitle.displayName = 'CardTitle';
+
+const CardDescription = React.forwardRef<
+  HTMLDivElement,
+  React.HTMLAttributes<HTMLParagraphElement>
+>(({ className, ...props }, ref) => (
+  <div
+    ref={ref}
</code_context>
<issue_to_address>
**issue:** Fix CardDescription typing to match the rendered element.

The ref and props types don’t match the rendered `<div>`, which can cause incorrect typings and complicate a future switch to a semantic `<p>`. Please either:
- Render a `<p>` and type as `HTMLParagraphElement` / `React.HTMLAttributes<HTMLParagraphElement>`, or
- Keep the `<div>` and type as `HTMLDivElement` / `React.HTMLAttributes<HTMLDivElement>`.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

const Card = React.forwardRef<
HTMLDivElement,
React.HTMLAttributes<HTMLDivElement>
>(({ className, ...props }, ref) => (

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

issue: Fix CardDescription typing to match the rendered element.

The ref and props types don’t match the rendered <div>, which can cause incorrect typings and complicate a future switch to a semantic <p>. Please either:

  • Render a <p> and type as HTMLParagraphElement / React.HTMLAttributes<HTMLParagraphElement>, or
  • Keep the <div> and type as HTMLDivElement / React.HTMLAttributes<HTMLDivElement>.

@fray-cloud

Copy link
Copy Markdown
Owner Author

Superseded by #61 — full #48#54 chain lands via #61.

@fray-cloud fray-cloud closed this Apr 13, 2026
@fray-cloud fray-cloud deleted the shadcn/50-header-sidebar branch April 13, 2026 14:38
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