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

App Layout

Scaffold your app using responsive layout components.

Source
Logo

5rahim

Chalk UI
<AppLayout>
    <AppLayoutHeader>
        {/*Header/Navbar*/}
    </AppLayoutHeader>
    <AppLayoutContent className="container max-w-7xl py-5">
        {/*Content*/}
    </AppLayoutContent>
    <AppLayoutFooter>
        {/*Footer*/}
    </AppLayoutFooter>
</AppLayout>

Installation

npx @rahimstack@latest add app-layout

Sidebar

  • AppLayoutSidebar is used to size and position the sidebar, it should not be styled.
  • AppSidebar will become a drawer on small screens. (under lg breakpoint)
  • AppSidebarProvider is used to share the sidebar state between AppSidebar and AppSidebarTrigger.
  • AppSidebarTrigger is used to open/close the sidebar on small screens. It is hidden on large screens.
Dashboard
Logo

5rahim

Chalk UI
<AppSidebarProvider>
    <AppLayout wideSidebar sidebarSize="md">
        <AppLayoutSidebar>
            <AppSidebar>
                {/*Sidebar content*/}
            </AppSidebar>
        </AppLayoutSidebar>
        <AppLayout>
            <AppLayoutHeader>
                <AppSidebarTrigger />
                {/*Header/Navbar*/}
            </AppLayoutHeader>
            <AppLayoutContent>
                {/*Content*/}
            </AppLayoutContent>
            <AppLayoutFooter>
                {/*Footer*/}
            </AppLayoutFooter>
        </AppLayout>
    </AppLayout>
</AppSidebarProvider>

Close mobile drawer

You might want to close the sidebar automatically when a link is clicked. You can do that by using the useAppSidebarContext hook.

// layout.tsx
export default function Layout() {
    return (
        <AppSidebarProvider>
            <AppLayout wideSidebar>
                <AppLayoutSidebar>
                    <CustomSidebar/>
                </AppLayoutSidebar>
                <AppLayout>
                    {/*...*/}
                </AppLayout>
            </AppLayout>
        </AppSidebarProvider>
    )
}
 
// custom-sidebar.tsx
"use client"
import {useAppSidebarContext} from "@/workshop/app-layout"
 
export function CustomSidebar() {
    const { setOpen } = useAppSidebarContext()
 
    return (
        <AppSidebar>
            <ScrollArea className="p-4 h-dvh">
                <AppSidebarNav>
                    <VerticalMenu
                        items={[...]}
                        onLinkItemClick={() => setOpen(false)}
                    />
                </AppSidebarNav>
            </ScrollArea>
        </AppSidebar>
    )
}

Sidebar context

You can use the useAppSidebarContext hook to access or control the sidebar state.

  • open: Whether the sidebar is open or closed.
  • setOpen: Set the sidebar state to open or closed.
  • size: The size of the sidebar. This overrides the sidebarSize prop of AppLayout.
  • setSize: Set the size of the sidebar. This overrides the sidebarSize prop of AppLayout.
  • isBelowBreakpoint: Whether the sidebar is below the lg breakpoint.

API Reference

const AppLayoutAnatomy = defineStyleAnatomy({
    root: cva([
        "UI-AppLayout__root appLayout",
        "flex w-full group/appLayout",
    ], {
        variants: {
            withSidebar: {
                true: "flex-row with-sidebar",
                false: "flex-col",
            },
            sidebarSize: {
                slim: "sidebar-slim",
                sm: "sidebar-sm",
                md: "sidebar-md",
                lg: "sidebar-lg",
                xl: "sidebar-xl",
            },
        },
        defaultVariants: {
            withSidebar: false,
            sidebarSize: "md",
        },
        compoundVariants: [
            { withSidebar: true, sidebarSize: "slim", className: "lg:[&>.appLayout]:pl-20" },
            { withSidebar: true, sidebarSize: "sm", className: "lg:[&>.appLayout]:pl-48" },
            { withSidebar: true, sidebarSize: "md", className: "lg:[&>.appLayout]:pl-64" },
            { withSidebar: true, sidebarSize: "lg", className: "lg:[&>.appLayout]:pl-[20rem]" },
            { withSidebar: true, sidebarSize: "xl", className: "lg:[&>.appLayout]:pl-[25rem]" },
        ],
    }),
})
const AppLayoutHeaderAnatomy = defineStyleAnatomy({
    root: cva([
        "UI-AppLayoutHeader__root",
        "relative w-full",
    ]),
})
const AppLayoutSidebarAnatomy = defineStyleAnatomy({
    root: cva([
        "UI-AppLayoutSidebar__root",
        "hidden lg:fixed lg:inset-y-0 lg:flex lg:flex-col grow-0 shrink-0 basis-0",
        "group-[.sidebar-slim]/appLayout:w-20",
        "group-[.sidebar-sm]/appLayout:w-48",
        "group-[.sidebar-md]/appLayout:w-64",
        "group-[.sidebar-lg]/appLayout:w-[20rem]",
        "group-[.sidebar-xl]/appLayout:w-[25rem]",
    ]),
})
const AppLayoutContentAnatomy = defineStyleAnatomy({
    root: cva([
        "UI-AppLayoutContent__root",
        "relative",
    ]),
})
const AppLayoutFooterAnatomy = defineStyleAnatomy({
    root: cva([
        "UI-AppLayoutFooter__root",
        "relative",
    ]),
})
const AppLayoutStackAnatomy = defineStyleAnatomy({
    root: cva([
        "UI-AppLayoutStack__root",
        "relative",
    ], {
        variants: {
            spacing: {
                sm: "space-y-2",
                md: "space-y-4",
                lg: "space-y-8",
                xl: "space-y-10",
            },
        },
        defaultVariants: {
            spacing: "md",
        },
    }),
})
const AppLayoutGridAnatomy = defineStyleAnatomy({
    root: cva([
        "UI-AppLayoutGrid__root",
        "relative flex flex-col",
    ], {
        variants: {
            breakBelow: {
                sm: "sm:grid sm:space-y-0",
                md: "md:grid md:space-y-0",
                lg: "lg:grid lg:space-y-0",
                xl: "xl:grid xl:space-y-0",
            },
            spacing: {
                sm: "gap-2",
                md: "gap-4",
                lg: "gap-8",
                xl: "gap-10",
            },
            cols: { 1: null, 2: null, 3: null, 4: null, 5: null, 6: null },
        },
        defaultVariants: {
            breakBelow: "xl",
            spacing: "md",
            cols: 3,
        },
        compoundVariants: [
            { breakBelow: "sm", cols: 1, className: "sm:grid-cols-1" },
            { breakBelow: "sm", cols: 2, className: "sm:grid-cols-2" },
            { breakBelow: "sm", cols: 3, className: "sm:grid-cols-3" },
            { breakBelow: "sm", cols: 4, className: "sm:grid-cols-4" },
            { breakBelow: "sm", cols: 5, className: "sm:grid-cols-5" },
            { breakBelow: "sm", cols: 6, className: "sm:grid-cols-6" },
            { breakBelow: "md", cols: 1, className: "md:grid-cols-1" },
            { breakBelow: "md", cols: 2, className: "md:grid-cols-2" },
            { breakBelow: "md", cols: 3, className: "md:grid-cols-3" },
            { breakBelow: "md", cols: 4, className: "md:grid-cols-4" },
            { breakBelow: "md", cols: 5, className: "md:grid-cols-5" },
            { breakBelow: "md", cols: 6, className: "md:grid-cols-6" },
            { breakBelow: "lg", cols: 1, className: "lg:grid-cols-1" },
            { breakBelow: "lg", cols: 2, className: "lg:grid-cols-2" },
            { breakBelow: "lg", cols: 3, className: "lg:grid-cols-3" },
            { breakBelow: "lg", cols: 4, className: "lg:grid-cols-4" },
            { breakBelow: "lg", cols: 5, className: "lg:grid-cols-5" },
            { breakBelow: "lg", cols: 6, className: "lg:grid-cols-6" },
            { breakBelow: "xl", cols: 1, className: "xl:grid-cols-1" },
            { breakBelow: "xl", cols: 2, className: "xl:grid-cols-2" },
            { breakBelow: "xl", cols: 3, className: "xl:grid-cols-3" },
            { breakBelow: "xl", cols: 4, className: "xl:grid-cols-4" },
            { breakBelow: "xl", cols: 5, className: "xl:grid-cols-5" },
            { breakBelow: "xl", cols: 6, className: "xl:grid-cols-6" },
        ],
    }),
})