Chalk UI
Getting started
Customization
Dark Mode
CLI
Components
Accordion
Address Input
Alert
App Layout
Autocomplete
Avatar
Badge
Breadcrumbs
Button
Calendar
Card
Carousel
Chart (Area)
Chart (Bar)
Chart (Donut)
Chart (Line)
Checkbox
Checkbox Group
Collapsible
Combobox
Command
Currency Input
DataGrid
Date Picker
Date Range Picker
Disclosure
Drawer
Dropdown Menu
Form
Horizontal Draggable Scroll
Hover Card
Loading Spinner
Loading Overlay
Modal
Native Select
Navigation Menu
Number Input
Page Header
Pagination
Phone Input
Popover
Progress Bar
Radio Group
Scroll Area
Select
Separator
Simple Dropzone
Skeleton
Static Tabs
Stats
Switch
Table
Tabs
Text Input
Textarea
Timeline
Toaster
Tooltip
Vertical Menu

Customization

Learn how to customize the appearance of all components

Globals

You can easily customize the appearance of components by modifying the CSS variables found in globals.css.

/* ... */
:root {
    /* ... */
 
    --border: theme('colors.gray.200');
    --ring: theme('colors.brand.500');
    
    --muted: theme('colors.gray.500');
    --muted-highlight: theme('colors.gray.700');
    
    --paper: theme('colors.white');
    --subtle: rgba(0, 0, 0, 0.04);
    --subtle-highlight: rgba(0, 0, 0, 0.08);
 
    .dark, [data-mode="dark"] {
        /* ... */
    }
}
/* ... */

Chalk UI uses these variables without shortcuts. For example, text-[--blue] instead of text-blue. This is a deliberate choice to easily identify them in the code and allow for easy refactoring.

Anatomy

Most components are styles are defined using the defineStyleAnatomy helper. This helper returns an object containing each part of the component's anatomy. Each part is represented by a distinct class-variance-authority function. For example, the PageHeader component has several parts such as body, title, description, etc..., each with its own styling. CVA offers features like variants and compoundVariants. Learn more about CVA.

This approach gives you a lot of flexibility when customizing components. For example, you can easily locate the part you want to customize by looking at the anatomy. You can also use the variants and compoundVariants features to effortlessly create new variants or customize the appearance of a component based on its props. Additionally, you can share anatomy styles between multiple components, allowing you to create a consistent design system without having to duplicate code.

Thanks to the ComponentAnatomy helper type, class props are automatically inferred from the anatomy, allowing targeted customization using Tailwind classes. For example, you can easily change the font weight of the title part of a specific PageHeader component, without affecting other PageHeader components by passing a titleClass prop.

Example
// @/components/ui/page-header/page-header.tsx
 
export const PageHeaderAnatomy = defineStyleAnatomy({
    // ...
    title: cva("UI-PageHeader__title font-bold text-gray-900 dark:text-gray-200", {
        variants: {
            size: { sm: "text-lg sm:text-xl", md: "text-xl sm:text-2xl", lg: "text-2xl sm:text-3xl", xl: "text-2xl sm:text-4xl" },
        },
        defaultVariants: { size: "md" },
    }),
    // ...
})
 
export type PageHeaderProps = React.ComponentPropsWithoutRef<"div"> &
    ComponentAnatomy<typeof PageHeaderAnatomy> & // Infers class props (in this case, `titleClass`)
    VariantProps<typeof PageHeaderAnatomy.title> & // Infers variants (in this case, `size`)
    { /* ... */ }
 
export const PageHeader = ({ title, size, titleClass }: PageHeaderProps) => {
    return (
        <div> {/*...*/}
           <h1 className={cn(PageHeaderAnatomy.title({ size }), titleClass)}>{title}</h1> {/* The styles are merged */}
           {/*...*/}
        </div>
    )
}
import { PageHeader } from "@/components/ui/page-header"
 
export const DashboardPageHeader = () => {
    return (
        <PageHeader
            title="Dashboard"
            size="xl"                // Change `size` variant
            titleClass="font-medium" // Overwrite `title` font weight
       />
    )
}

Good to know

  • root is a special part that does not produce a rootClass prop. Instead, it is merged with the component's main className.