Component Library (shadcn/ui)
Relevant source files
The following files were used as context for generating this wiki page:
The Greenline project utilizes shadcn/ui as its component library. This is not a traditional dependency-based library but a collection of reusable, composable, and unstyled components that are copied directly into the project's source code. This approach provides maximum control over styling and functionality. The components are built using Radix UI for accessibility and behavior, and styled with Tailwind CSS for a utility-first approach to design.
The core of the integration is defined through a set of configuration files that establish theming, styling, and path aliases. Components are located in client/src/components/ui/ and are used across the application to build complex user interfaces, such as the market overview portal and individual stock quote pages.
Configuration and Theming
The component library's look, feel, and behavior are managed by a combination of JSON configuration, Tailwind CSS extensions, and global CSS variables.
components.json
This file is the primary configuration for shadcn/ui, defining the styling dialect, component type, and path aliases for the project.
{
"$schema": "https://ui.shadcn.com/schema.json",
"style": "new-york",
"rsc": true,
"tsx": true,
"tailwind": {
"config": "tailwind.config.ts",
"css": "src/app/globals.css",
"baseColor": "zinc",
"cssVariables": true,
"prefix": ""
},
"aliases": {
"components": "@/components",
"utils": "@/lib/utils",
"ui": "@/components/ui",
"lib": "@/lib",
"hooks": "@/hooks"
}
}
Key configurations include:
style: "new-york" defines the visual style of the components.tailwind: Specifies the paths to the Tailwind CSS configuration and the global CSS file where theme variables are defined. It also setscssVariablestotrue, enabling theme support.aliases: Sets up import aliases for easy access to components and utilities.
The following table details the path aliases configured for the project:
| Alias | Path | Description |
|---|---|---|
@/components | src/components | Root directory for all components. |
@/utils | src/lib/utils | Utility functions, including the cn helper. |
@/ui | src/components/ui | Directory for shadcn/ui base components. |
@/lib | src/lib | General library code. |
@/hooks | src/hooks | Custom React hooks. |
Sources: client/components.json
Theming with Tailwind CSS and Global CSS
Styling is primarily handled by Tailwind CSS, with theme variables defined in globals.css.
The diagram below illustrates the relationship between the configuration files.
This diagram shows how components.json references tailwind.config.ts and globals.css, which in turn are processed by the Tailwind engine to style the UI components.
Sources: client/components.json, client/tailwind.config.ts, client/src/app/globals.css
tailwind.config.ts
This file extends the default Tailwind theme with colors, border radii, and animations required by the shadcn/ui components. Colors are defined using CSS variables, allowing for dynamic theme switching.
// client/tailwind.config.ts
const config: Config = {
darkMode: ["class"],
// ...
theme: {
extend: {
colors: {
background: 'hsl(var(--background))',
foreground: 'hsl(var(--foreground))',
card: {
DEFAULT: 'hsl(var(--card))',
foreground: 'hsl(var(--card-foreground))'
},
// ... other colors
},
borderRadius: {
lg: 'var(--radius)',
md: 'calc(var(--radius) - 2px)',
sm: 'calc(var(--radius) - 4px)'
},
keyframes: {
'accordion-down': {
from: { height: '0' },
to: { height: 'var(--radix-accordion-content-height)' }
},
'accordion-up': {
from: { height: 'var(--radix-accordion-content-height)' },
to: { height: '0' }
}
},
animation: {
'accordion-down': 'accordion-down 0.2s ease-out',
'accordion-up': 'accordion-up 0.2s ease-out',
}
}
},
plugins: [require("tailwindcss-animate"), /* ... */],
};
Sources: client/tailwind.config.ts:4-77
globals.css
This file defines the CSS variables for both light (:root) and dark (.dark) themes. These variables are consumed by Tailwind's hsl(var(...)) utility.
/* client/src/app/globals.css */
@layer base {
:root {
--background: 0 0% 100%;
--foreground: 240 10% 3.9%;
--card: 0 0% 100%;
--card-foreground: 240 10% 3.9%;
/* ... other light theme variables */
--radius: 0.5rem
}
.dark {
--background: 240 10% 3.9%;
--foreground: 0 0% 98%;
--card: 240 10% 3.9%;
--card-foreground: 0 0% 98%;
/* ... other dark theme variables */
}
}
Sources: client/src/app/globals.css:21-78
Core Dependencies
The functionality of the component library relies on several key packages listed in package.json.
| Dependency | Purpose |
|---|---|
@radix-ui/* | Provides the unstyled, accessible core components for primitives like Accordion, NavigationMenu, Progress, etc. |
class-variance-authority | Creates variants for component styles (e.g., button sizes and colors). |
clsx | A tiny utility for constructing className strings conditionally. |
tailwind-merge | Merges Tailwind CSS classes in JS without style conflicts. |
tailwindcss-animate | Adds enter/exit animations for Tailwind CSS. |
Sources: client/package.json:11-28
Base Components
The UI components are located in client/src/components/ui. They are standard React components that use React.forwardRef for proper ref handling and the cn utility function (from @/lib/utils) to combine base styles with custom classes.
Component Structure: Card
The Card component is a representative example. It is composed of several smaller parts (CardHeader, CardTitle, CardContent, etc.) that can be assembled to create a card layout.
// client/src/components/ui/card.tsx
import * as React from "react"
import { cn } from "@/lib/utils"
const Card = React.forwardRef<
HTMLDivElement,
React.HTMLAttributes<HTMLDivElement>
>(({ className, ...props }, ref) => (
<div
ref={ref}
className={cn(
"rounded-xl border bg-card text-card-foreground shadow",
className
)}
{...props}
/>
))
Card.displayName = "Card"
// ... other Card components like CardHeader, CardTitle, etc.
Sources: client/src/components/ui/card.tsx:3-15
The following diagram shows the compositional structure of the Card component.
This diagram illustrates that a Card can contain a CardHeader, CardContent, and CardFooter. The CardHeader itself can contain a CardTitle and CardDescription.
Sources: client/src/components/ui/card.tsx
Other Available Components
The repository includes several other base components, such as:
- Table: For displaying tabular data, composed of
Table,TableHeader,TableBody,TableRow,TableCell, etc. - NavigationMenu: For creating responsive navigation menus.
- Accordion: For creating vertically stacked sections of content.
- Badge: For displaying small pieces of information.
- Separator: For creating visual dividers.
- Progress: For displaying a progress bar.
Sources: client/src/components/ui/table.tsx, client/src/components/ui/navigation-menu.tsx, client/src/components/StockSummary/index.tsx:13-18, client/src/app/portal/page.tsx:10-11, client/src/components/StockRating/index.tsx:5-6
Component Usage
These base components are used throughout the application to build pages. For example, the portal page (client/src/app/portal/page.tsx) uses Card, CardHeader, CardTitle, CardContent, and Badge to display the market status.
The flow of component usage on the portal page is as follows:
This shows how the Portal Page composes the Navbar and a grid of Card components, which in turn use sub-components like CardHeader and custom components like StatusBadge to render the UI.
Sources: client/src/app/portal/page.tsx:1-248
Conclusion
The Greenline project's adoption of shadcn/ui provides a robust and flexible foundation for its user interface. By bringing components directly into the codebase, developers gain full control over their implementation, styling, and behavior. The combination of Radix UI primitives, Tailwind CSS utilities, and a clear theming strategy via CSS variables allows for the creation of a consistent, accessible, and maintainable design system that is tailored specifically to the application's needs.