UI Library (shadcn/ui)
Relevant source files
The following files were used as context for generating this wiki page:
The Character Sheet Maker project utilizes shadcn/ui as its foundational UI library. This is not a traditional component library distributed via npm, but rather a collection of reusable UI components that are copied directly into the project's source tree under src/components/ui. This approach allows for maximum control and customization of each component.
The library is built upon a stack of modern frontend technologies: Radix UI for accessible, unstyled primitives; Tailwind CSS for utility-first styling; and TypeScript for type safety. The integration is managed through a central configuration file, components.json, and relies on specific project setup for path aliases and CSS variable-based theming.
Core Configuration
The entire shadcn/ui setup is defined and managed through the components.json file at the root of the project. This file dictates how components are styled, where they are located, and what dependencies they use.
Sources: components.json
{
"$schema": "https://ui.shadcn.com/schema.json",
"style": "new-york",
"rsc": false,
"tsx": true,
"tailwind": {
"config": "",
"css": "src/index.css",
"baseColor": "neutral",
"cssVariables": true,
"prefix": ""
},
"iconLibrary": "lucide",
"aliases": {
"components": "@/components",
"utils": "@/lib/utils",
"ui": "@/components/ui",
"lib": "@/lib",
"hooks": "@/hooks"
},
"registries": {}
}
Sources: components.json:1-23
Configuration Properties
The table below breaks down the key properties defined in components.json.
| Property | Value | Description |
|---|---|---|
style | "new-york" | The visual style preset for the components. |
rsc | false | Indicates that React Server Components are not being used. |
tsx | true | Specifies that components should be generated as .tsx files. |
tailwind.css | "src/index.css" | Path to the main CSS file where Tailwind directives and CSS variables are defined. |
tailwind.baseColor | "neutral" | The base color palette used for generating shades. |
tailwind.cssVariables | true | Enables the use of CSS variables for theming, allowing for dynamic light/dark modes. |
iconLibrary | "lucide" | Specifies lucide-react as the default icon library. |
aliases.utils | "@/lib/utils" | Path alias for utility functions, including the important cn helper. |
aliases.ui | "@/components/ui" | Path alias for the directory where shadcn/ui components are stored. |
Sources: components.json:3-21
Styling and Theming
The project's styling is a combination of Tailwind CSS utility classes and a CSS variable-driven theming system. This allows for both granular control over individual elements and global theme switching (e.g., light/dark mode).
CSS Class Merging
A critical utility function, cn, is provided in src/lib/utils.ts. It uses clsx and tailwind-merge to intelligently merge Tailwind CSS classes, preventing style conflicts and allowing components to accept a className prop for overrides.
// src/lib/utils.ts
import { type ClassValue, clsx } from "clsx"
import { twMerge } from "tailwind-merge"
export function cn(...inputs: ClassValue[]) {
return twMerge(clsx(inputs))
}
Sources: src/lib/utils.ts:2-8
This function is used extensively within every UI component to combine base styles with props-based styles.
CSS Variables
Theming is achieved through CSS variables defined in src/index.css. A set of variables is declared in :root for the default (light) theme, and these are overridden within a .dark class selector for the dark theme. This is enabled by the "cssVariables": true setting in components.json.
The following diagram shows how a theme is applied.
This diagram illustrates how index.css defines CSS variables for both light and dark themes, which are then consumed by Tailwind's utility classes.
Sources: src/index.css:80-161, components.json:10
Component Architecture
The UI components reside in src/components/ui and are built as wrappers around Radix UI primitives. This pattern provides accessibility and functionality out-of-the-box while allowing complete styling control via Tailwind CSS.
Component Example: DropdownMenu
The DropdownMenu component is a clear example of this architecture. It imports primitives like DropdownMenuPrimitive.Root and DropdownMenuPrimitive.Content from @radix-ui/react-dropdown-menu and exports styled versions.
The following diagram illustrates the composition of a typical shadcn/ui component.
This flow shows how a Radix primitive is imported, wrapped into a styled component using the cn utility, and then consumed by the application.
Sources: package.json:14, src/components/ui/dropdown-menu.tsx:2,8-25, src/components/layout/TopBar.tsx:16-22
A code snippet from dropdown-menu.tsx shows how DropdownMenuPrimitive.Content is wrapped to apply styles:
// src/components/ui/dropdown-menu.tsx
function DropdownMenuContent({
className,
sideOffset = 4,
...props
}: React.ComponentProps<typeof DropdownMenuPrimitive.Content>) {
return (
<DropdownMenuPrimitive.Portal>
<DropdownMenuPrimitive.Content
data-slot="dropdown-menu-content"
sideOffset={sideOffset}
className={cn(
"bg-popover text-popover-foreground ... z-50 ... rounded-md border p-1 shadow-md",
className
)}
{...props}
/>
</DropdownMenuPrimitive.Portal>
)
}
Sources: src/components/ui/dropdown-menu.tsx:32-51
Available UI Components
The project includes several pre-built shadcn/ui components in the src/components/ui directory.
| Component | File | Description |
|---|---|---|
DropdownMenu | dropdown-menu.tsx | A popup menu for displaying a list of actions or options. Used for the "Export" button. |
Input | input.tsx | A styled form input element. Used for the sheet title. |
Label | label.tsx | A styled label for form elements, providing accessibility. |
Button | button.tsx | A styled button component with variants. (Note: button.tsx was not in the provided files but is a standard shadcn component used throughout the app). |
Sources: src/components/ui/dropdown-menu.tsx, src/components/ui/input.tsx, src/components/ui/label.tsx, src/components/layout/TopBar.tsx:11,17
Build & Tooling Integration
The shadcn/ui library requires specific configuration in the project's build tools and TypeScript settings to function correctly, primarily for resolving path aliases.
Path Aliases
Path aliases like @/* simplify import statements. They are configured consistently across the toolchain.
This diagram shows that both TypeScript and Vite are configured with the same path alias to ensure module resolution works during development and compilation.
- TypeScript: The
baseUrlandpathsare set intsconfig.app.jsonto allow the TypeScript compiler and IDEs to resolve the aliased paths. - Vite: The
resolve.aliasoption is configured invite.config.tsto ensure Vite's bundler can resolve the paths during development and production builds.
Sources: tsconfig.app.json:23-26, vite.config.ts:8-12
Summary
The Character Sheet Maker's UI is built on a solid and flexible foundation provided by shadcn/ui. By bringing components directly into the source code, the project gains full ownership over their appearance and behavior. The combination of Radix UI for accessibility, Tailwind CSS for styling, and a well-defined theming system using CSS variables results in a highly maintainable and customizable user interface. The entire system is glued together by configuration in components.json, tsconfig.app.json, and vite.config.ts.