Skip to content

feature: add navbar with shadcn/ui theming#4

Merged
michellepace merged 5 commits intomainfrom
feat/shadcn-theme-nav
Dec 3, 2025
Merged

feature: add navbar with shadcn/ui theming#4
michellepace merged 5 commits intomainfrom
feat/shadcn-theme-nav

Conversation

@michellepace
Copy link
Owner

@michellepace michellepace commented Dec 2, 2025

Summary

  • Initialise shadcn/ui with theme configuration and CSS variables
  • Add sticky navbar with logo, search placeholder, and theme toggle
  • Refactor theme toggle to use shadcn/ui Button component
  • Apply custom orange primary colour and adjust theme tokens for contrast

Test plan

  • Verify navbar displays correctly on mobile and desktop
  • Verify theme toggle switches between light and dark modes
  • Verify E2E tests pass
  • Manual review of colour contrast in both themes

🤖 Generated with Claude Code

michellepace and others added 3 commits December 2, 2025 17:21
Dependencies:
- Add class-variance-authority, clsx, tailwind-merge for component styling
- Add lucide-react icon library
- Add tw-animate-css for animation utilities
- Pin TypeScript to 5.9.3

Configuration:
- Add components.json with new-york style and slate base colour
- Add cn() utility in lib/utils.ts
- Enable cacheComponents in next.config.ts for "use cache" directive

Styling:
- Import tw-animate-css in globals.css
- Reorganise @theme inline block placement
- Remove Consolas from mono font fallback stack
- Remove h1-bold class from home page heading

Sets up the foundation for adding shadcn/ui components. Enables Next.js
caching features including Partial Prerendering.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Theme Toggle:
- Replace custom SunIcon SVG with lucide-react Sun component
- Retain filled/outline behaviour based on active theme

Aligns with project icon library configuration in components.json.
Navigation:
- Create sticky navbar with three-column grid (logo, search placeholder, theme toggle)
- Move theme-toggle into components/navigation/ directory
- Refactor theme toggle to use shadcn/ui Button with ghost variant

Components:
- Add shadcn/ui button component with Radix slot support
- Remove unused demo button component

Theme:
- Set custom orange primary colour for brand identity
- Adjust background, sidebar, and foreground tokens for contrast
- Add hex comments to OKLCH values for debugging

Establishes site-wide navigation structure and introduces shadcn/ui as the
component foundation. Theme tokens provide distinct brand colour while
maintaining the centralised CSS variable architecture.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
@vercel
Copy link

vercel bot commented Dec 2, 2025

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

Project Deployment Preview Comments Updated (UTC)
devflow Ready Ready Preview Comment Dec 3, 2025 2:18am

@coderabbitai
Copy link

coderabbitai bot commented Dec 2, 2025

Summary by CodeRabbit

  • New Features

    • Added a sticky navigation bar with logo, site branding, and global search placeholder.
    • Introduced theme toggle functionality to switch between light and dark modes.
  • Style

    • Updated colour tokens and theme variables for improved visual consistency.
    • Refreshed UI styling across the application.
  • Chores

    • Added ShadCN UI component library integration and configuration.
    • Updated project dependencies and TypeScript version.

✏️ Tip: You can customize this high-level summary in your review settings.

Walkthrough

Adds a new sticky Navbar and a relocated ThemeToggle; introduces a CVA-based Button and a class merging utility; updates global theme tokens and colours in app/globals.css; adds ShadCN config and new dependencies; removes legacy button and theme-toggle files and adjusts layout and page styling.

Changes

Cohort / File(s) Summary
Global styles & theming
app/globals.css
Introduced an inline theme token block registering fonts, radii and comprehensive colour/semantic tokens for light and dark modes; adjusted many colour values and removed a previous theme-mapping block; minor whitespace/comment edits.
Layout & integration
app/layout.tsx, app/page.tsx
Imported and rendered new Navbar inside ThemeProvider; moved global CSS import order; removed h1 className from the home heading.
Navigation components
components/navigation/navbar/index.tsx, components/navigation/theme-toggle.tsx
Added Navbar (sticky top bar with logo, centre search placeholder, theme toggle) and a client ThemeToggle using next-themes with an SSR-safe mounted guard and accessible toggle button.
UI primitives & utils
components/ui/button.tsx, lib/utils.ts
Added a CVA-based Button component with variant/size tokens and asChild support; added cn util that composes classnames and applies tailwind-merge.
Removals & reorg
components/button.tsx, components/theme-toggle.tsx
Removed legacy components/button.tsx and the old components/theme-toggle.tsx implementation.
Config & deps
components.json, next.config.ts, package.json
Added components.json (ShadCN UI schema, aliases, Tailwind settings); added cacheComponents: true to Next config; added dependencies (@radix-ui/react-slot, class-variance-authority, clsx, lucide-react, tailwind-merge) and devDep tw-animate-css; bumped TypeScript.
Docs/template tweak
.claude/commands/commit.md
Minor commit-template text change: feature -> feat.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20–30 minutes

  • Review CSS theme token mappings and dark-mode overrides in app/globals.css.
  • Verify Button CVA variants and asChild behaviour in components/ui/button.tsx.
  • Confirm next-themes mounting guard and accessibility labels in components/navigation/theme-toggle.tsx.
  • Check import/alias alignment with components.json and new dependencies in package.json.

Possibly related PRs

Poem

🐇✨ I hopped in code with an eager twitch,
Built a bar that sticks and a button rich,
Tokens twirl from light to night,
New utils tidy classes right,
DevFlow hums — the UI's bright!

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarises the main changes: introducing a navbar component and shadcn/ui theming, which are the primary objectives of this pull request.
Description check ✅ Passed The description is well-related to the changeset, detailing the shadcn/ui initialisation, navbar addition, theme toggle refactoring, and colour adjustments that are reflected in the file changes.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/shadcn-theme-nav

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Shortens the feature commit prefix from "feature:" to "feat:" for consistency
with conventional commit standards.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 5

📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f0036d1 and a66d3e4.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (12)
  • app/globals.css (5 hunks)
  • app/layout.tsx (2 hunks)
  • app/page.tsx (1 hunks)
  • components.json (1 hunks)
  • components/button.tsx (0 hunks)
  • components/navigation/navbar/index.tsx (1 hunks)
  • components/navigation/theme-toggle.tsx (1 hunks)
  • components/theme-toggle.tsx (0 hunks)
  • components/ui/button.tsx (1 hunks)
  • lib/utils.ts (1 hunks)
  • next.config.ts (1 hunks)
  • package.json (2 hunks)
💤 Files with no reviewable changes (2)
  • components/theme-toggle.tsx
  • components/button.tsx
🧰 Additional context used
📓 Path-based instructions (7)
**/*.{ts,tsx,js,jsx,md}

📄 CodeRabbit inference engine (CLAUDE.md)

Use British English spelling and conventions throughout the project

Files:

  • lib/utils.ts
  • components/ui/button.tsx
  • components/navigation/navbar/index.tsx
  • components/navigation/theme-toggle.tsx
  • next.config.ts
  • app/layout.tsx
  • app/page.tsx
**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Avoid manual useMemo/useCallback unless profiling shows need

Files:

  • lib/utils.ts
  • components/ui/button.tsx
  • components/navigation/navbar/index.tsx
  • components/navigation/theme-toggle.tsx
  • next.config.ts
  • app/layout.tsx
  • app/page.tsx
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Always use @/ import aliases, even for sibling imports (e.g., @/app/fonts instead of ./fonts)

Files:

  • lib/utils.ts
  • components/ui/button.tsx
  • components/navigation/navbar/index.tsx
  • components/navigation/theme-toggle.tsx
  • next.config.ts
  • app/layout.tsx
  • app/page.tsx
app/**

📄 CodeRabbit inference engine (CLAUDE.md)

Use Next.js 16 App Router (not Pages Router) for routing

Files:

  • app/layout.tsx
  • app/page.tsx
  • app/globals.css
app/**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Only add "use client" directive when interactivity is needed

Files:

  • app/layout.tsx
  • app/page.tsx
app/**/page.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Dynamic route params is a Promise and must be awaited in page components

Files:

  • app/page.tsx
**/*.{css,postcss}

📄 CodeRabbit inference engine (CLAUDE.md)

Use Tailwind v4 @import syntax (@import "tailwindcss") instead of @tailwind directives

Files:

  • app/globals.css
🧠 Learnings (4)
📚 Learning: 2025-12-01T13:45:33.949Z
Learnt from: CR
Repo: michellepace/devflow PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-01T13:45:33.949Z
Learning: Applies to **/*.test.{ts,tsx} : Use Vitest for unit tests

Applied to files:

  • package.json
📚 Learning: 2025-12-01T13:45:33.949Z
Learnt from: CR
Repo: michellepace/devflow PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-01T13:45:33.949Z
Learning: Use Lefthook for Git hooks with pre-commit checks (lint, typecheck, unit tests) and pre-push E2E tests

Applied to files:

  • package.json
📚 Learning: 2025-12-01T13:45:33.949Z
Learnt from: CR
Repo: michellepace/devflow PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-01T13:45:33.949Z
Learning: Enable React Compiler for automatic optimizations

Applied to files:

  • next.config.ts
📚 Learning: 2025-12-01T13:45:33.949Z
Learnt from: CR
Repo: michellepace/devflow PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-01T13:45:33.949Z
Learning: Applies to **/*.{css,postcss} : Use Tailwind v4 import syntax (import "tailwindcss") instead of tailwind directives

Applied to files:

  • app/globals.css
🧬 Code graph analysis (1)
app/layout.tsx (1)
components/navigation/navbar/index.tsx (1)
  • Navbar (5-30)
🔇 Additional comments (5)
app/page.tsx (1)

3-3: Heading now relies on global typography – all good

Removing the bespoke className and relying on the global h1 styles in app/globals.css keeps the markup simple and consistent with the new typography system.

app/layout.tsx (1)

5-8: Navbar placement within ThemeProvider is appropriate

Rendering <Navbar /> inside the ThemeProvider and above {children} gives the theme toggle access to context and ensures the navigation appears consistently across routes. Keeping app/layout.tsx as a server component without a "use client" directive also matches the guideline of only opting into client mode where interactivity is actually needed.

Also applies to: 27-35

next.config.ts (1)

4-8: React Compiler and Cache Components are properly configured

The reactCompiler: true and cacheComponents: true settings are both valid and officially supported in Next.js 16.0.6. The comments accurately reflect the enabled directives ("use cache", cacheLife(), cacheTag()) and Partial Prerendering semantics. No changes required.

components.json (1)

1-22: Update css path in Tailwind configuration to "app/globals.css"

The tailwind.css path in components.json should be "app/globals.css", not "globals.css". The shadcn/ui CLI with Tailwind v4 expects the full path relative to the project root so it can correctly inject utilities into your global stylesheet during component generation. Since app/globals.css exists in this repository, update line 7 to resolve the path properly.

⛔ Skipped due to learnings
Learnt from: CR
Repo: michellepace/devflow PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-01T13:45:33.949Z
Learning: Applies to **/*.{css,postcss} : Use Tailwind v4 import syntax (import "tailwindcss") instead of tailwind directives
package.json (1)

25-36: New UI/theming dependencies integrate correctly – TypeScript pinning is supported and intentional

The runtime dependencies (@radix-ui/react-slot, class-variance-authority, clsx, lucide-react, tailwind-merge) and devDependency tw-animate-css are properly integrated into the Button component and cn utility, confirming coherent shadcn/ui‑style wiring. The cn function correctly chains clsx and twMerge per standard practice.

TypeScript 5.9.3 is pinned (not a range) and is fully supported by Next.js 16.0.6 and React 19.2.0 (Next.js 16 requires TypeScript 5.1+). No known incompatibilities exist between any of these versions or the paired dependencies. The pinning is intentional and appropriate for production stability.

- Add aria-label to nav element for screen reader landmark identification
- Fix logo alt text capitalisation to match "DevFlow" branding

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a66d3e4 and f6e53e6.

📒 Files selected for processing (2)
  • .claude/commands/commit.md (1 hunks)
  • components/navigation/navbar/index.tsx (1 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
**/*.{ts,tsx,js,jsx,md}

📄 CodeRabbit inference engine (CLAUDE.md)

Use British English spelling and conventions throughout the project

Files:

  • components/navigation/navbar/index.tsx
**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Avoid manual useMemo/useCallback unless profiling shows need

Files:

  • components/navigation/navbar/index.tsx
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Always use @/ import aliases, even for sibling imports (e.g., @/app/fonts instead of ./fonts)

Files:

  • components/navigation/navbar/index.tsx
🧬 Code graph analysis (1)
components/navigation/navbar/index.tsx (1)
components/navigation/theme-toggle.tsx (1)
  • ThemeToggle (8-32)
🔇 Additional comments (4)
.claude/commands/commit.md (1)

48-48: LGTM! Aligns with conventional commit standards.

The change from "feature:" to "feat:" is consistent with widely adopted conventional commit conventions and matches the concise style of other prefixes in the template.

components/navigation/navbar/index.tsx (3)

1-3: Excellent use of import aliases.

All imports correctly use the @/ alias convention, including the sibling ThemeToggle import, which aligns with the project's coding guidelines.


5-9: Past review feedback successfully implemented.

The aria-label="Primary navigation" has been added as requested in the previous review, improving screen reader accessibility for the navigation landmark.


14-14: Past review feedback successfully implemented.

The logo alt text now uses "DevFlow logo" with proper capitalisation (capital D and F), matching the branding consistently as requested in the previous review.

Comment on lines +18 to +20
<h2 className="hidden font-display text-2xl font-semibold text-sidebar-foreground sm:block">
Dev<span className="text-primary">Flow</span>
</h2>
Copy link

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

Consider revising heading level for improved document outline.

Using h2 for the site logo text may create heading hierarchy issues. Consider using h1 (if this is the primary page heading) or a span with appropriate styling if the logo is purely decorative.

Example refactor using span:

-      <h2 className="hidden font-display text-2xl font-semibold text-sidebar-foreground sm:block">
+      <span className="hidden font-display text-2xl font-semibold text-sidebar-foreground sm:block">
         Dev<span className="text-primary">Flow</span>
-      </h2>
+      </span>
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<h2 className="hidden font-display text-2xl font-semibold text-sidebar-foreground sm:block">
Dev<span className="text-primary">Flow</span>
</h2>
<span className="hidden font-display text-2xl font-semibold text-sidebar-foreground sm:block">
Dev<span className="text-primary">Flow</span>
</span>
🤖 Prompt for AI Agents
In components/navigation/navbar/index.tsx around lines 18 to 20, the logo text
is currently an h2 which can break document heading hierarchy; decide whether
this is the primary page heading—if it is, change the element to h1 preserving
the existing classes; if it is purely decorative or repeated across pages,
change the element to a span (or similar non-heading) preserving styling and
mark it appropriately (aria-hidden="true" or provide a separate visually hidden
h1 elsewhere for page title) to maintain correct semantic outline and
accessibility.

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