File: README.md
coss.com/ui (formerly Origin UI)
About the Project
coss.com/ui is the official Cal.com Design System.
Repository Overview
This repository contains multiple products and applications that make up the coss.com ecosystem:
Apps and Packages
apps/www/- Main coss.com websiteapps/ui/- coss ui component library and documentationapps/origin/- Legacy Origin UI components (pre-acquisition)packages/ui/- Shared UI components packagepackages/typescript-config/- TypeScript configurationsbiome.json- Shared Biome configuration for linting and formatting
Each package/app is 100% TypeScript.
Environment Variables
This monorepo contains multiple Next.js applications that are designed to link to each other. For the navigation to work correctly, you must set up environment variables for both local development and production deployments.
Local Development
For local development, create a .env.local file in each of the app directories with the corresponding variables.
wwwappThis app needs to know the URLs of the other apps. Create a file at
apps/www/.env.local:sh# apps/www/.env.local NEXT_PUBLIC_APP_URL=http://localhost:3000 NEXT_PUBLIC_COSS_UI_URL=http://localhost:4000/uiuiappThis app needs to know the URLs of the other apps. Create a file at
apps/ui/.env.local:sh# apps/ui/.env.local NEXT_PUBLIC_APP_URL=http://localhost:4000/ui NEXT_PUBLIC_COSS_URL=http://localhost:3000 NEXT_PUBLIC_ORIGIN_URL=http://localhost:4001originappThis app needs to know the URLs of the other apps. Create a file at
apps/origin/.env.local:sh# apps/origin/.env.local NEXT_PUBLIC_APP_URL=http://localhost:4001/origin NEXT_PUBLIC_COSS_URL=http://localhost:3000 NEXT_PUBLIC_COSS_UI_URL=http://localhost:4000/ui
[!NOTE]
Turborepo is configured to watch for changes in.env*files, so it will automatically invalidate the cache when these variables change.
Development
This Turborepo has some additional tools already setup for you:
- TypeScript for static type checking
- Biome for linting and formatting
Build
To build all apps and packages:
bun run buildTo build a specific app:
bun run build --filter=www
bun run build --filter=ui
bun run build --filter=originDevelop
To develop all apps and packages:
bun run devTo develop a specific app:
bun run dev --filter=www
bun run dev --filter=ui
bun run dev --filter=origincoss ui
coss ui is a collection of beautifully designed, accessible, and composable components for your React apps. Built on top of Base UI and styled with Tailwind CSS, it's designed for you to copy, paste, and own.
We think Base UI is the best foundation for modern web applications. We've taken its powerful, unstyled primitives and given them a design system that's ready to go, right out of the box.
This is the component library we'll be progressively adopting for cal.com. We're building it in the open for anyone who wants to create beautiful, reliable user interfaces.
Origin UI Acquisition
This repository also includes the Origin UI components as a legacy snapshot. Origin UI was a pre-acquisition collection of Radix-based, shadcn-style components that remains available for use, but with limited support and maintenance. Active development now focuses on the new Particles components built on the coss ui primitives.
Contributing to coss ui
We're always looking for contributors to help improve our UI components. Whether it's a bug report, a new feature, or a documentation update, we appreciate your help.
Please see our Contributing Guidelines for more information on how to get involved.
Licensing
This repository uses a mixed licensing approach. The default license for this project is AGPLv3.0.
- MIT: The
apps/origin/andapps/ui/directories are licensed under their original MIT license - AGPLv3: All other directories are licensed under the GNU Affero General Public License v3.0
For detailed information, see our Licensing documentation.
Acknowledgements
Special thanks to:
- Tailwind CSS - For the utility-first CSS framework that powers our design system
- Base UI - For providing the robust, accessible primitives that form the foundation of our components
- shadcn/ui - For inspiring our copy-paste approach and component philosophy
- Fumadocs - For providing the documentation framework that powers our component docs
File: apps/www/README.md
This is a Next.js project bootstrapped with create-next-app.
Getting Started
First, run the development server:
npm run dev
# or
yarn dev
# or
pnpm dev
# or
bun run devOpen http://localhost:3000 with your browser to see the result.
You can start editing the page by modifying app/page.tsx. The page auto-updates as you edit the file.
This project uses next/font to automatically optimize and load Geist, a new font family for Vercel.
Learn More
To learn more about Next.js, take a look at the following resources:
- Next.js Documentation - learn about Next.js features and API.
- Learn Next.js - an interactive Next.js tutorial.
You can check out the Next.js GitHub repository - your feedback and contributions are welcome!
Deploy on Vercel
The easiest way to deploy your Next.js app is to use the Vercel Platform from the creators of Next.js.
Check out our Next.js deployment documentation for more details.
File: apps/ui/content/docs/components/accordion.mdx
title: Accordion links: doc: https://base-ui.com/react/components/accordion#api-reference
Installation
npx shadcn@latest add @coss/accordionnpm install @base-ui/reactUsage
import {
Accordion,
AccordionItem,
AccordionPanel,
AccordionTrigger,
} from "@/components/ui/accordion"<Accordion>
<AccordionItem value="item-1">
<AccordionTrigger>Is it accessible?</AccordionTrigger>
<AccordionPanel>
Yes. It adheres to the WAI-ARIA design pattern.
</AccordionPanel>
</AccordionItem>
</Accordion>API Reference
Accordion
Root component. Alias for Accordion.Root from Base UI.
AccordionItem
Individual accordion item container. Styled wrapper for Accordion.Item from Base UI with bottom border styling.
AccordionTrigger
Trigger button that toggles the accordion panel. Styled wrapper for Accordion.Trigger from Base UI. Includes a built-in chevron icon that rotates when expanded.
AccordionPanel
Collapsible content panel. Styled wrapper for Accordion.Panel from Base UI with animated height transitions. Also exported as AccordionContent.
Examples
Single Accordion
Multiple Accordion
Controlled Accordion
File: apps/ui/content/docs/components/alert.mdx
title: Alert
Installation
npx shadcn@latest add @coss/alert@theme inline {
--color-destructive-foreground: var(--destructive-foreground);
--color-info: var(--info);
--color-info-foreground: var(--info-foreground);
--color-success: var(--success);
--color-success-foreground: var(--success-foreground);
--color-warning: var(--warning);
--color-warning-foreground: var(--warning-foreground);
}
:root {
--destructive-foreground: var(--color-red-400);
--info: var(--color-blue-500);
--info-foreground: var(--color-blue-700);
--success: var(--color-emerald-500);
--success-foreground: var(--color-emerald-700);
--warning: var(--color-amber-500);
--warning-foreground: var(--color-amber-700);
}
.dark {
--destructive-foreground: var(--color-red-400);
--info: var(--color-blue-500);
--info-foreground: var(--color-blue-400);
--success: var(--color-emerald-500);
--success-foreground: var(--color-emerald-400);
--warning: var(--color-amber-500);
--warning-foreground: var(--color-amber-400);
}Usage
import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert"<Alert>
<AlertTitle>Heads up!</AlertTitle>
<AlertDescription>
You can add components and dependencies to your app using the cli.
</AlertDescription>
</Alert>API Reference
This is a custom component, not a Base UI wrapper.
Alert
Root container for the alert.
| Prop | Type | Default | Description |
|---|---|---|---|
variant |
"default" | "error" | "info" | "success" | "warning" |
"default" |
Controls the alert styling and color scheme |
AlertTitle
Title text for the alert. Renders as a styled div.
AlertDescription
Description text for the alert. Renders as a styled div with muted foreground color.
AlertAction
Container for action buttons. Automatically positions to the right on larger screens.
Examples
With Icon
With Icon and Action Buttons
Info Alert
Success Alert
Warning Alert
Error Alert
File: apps/ui/content/docs/components/alert-dialog.mdx
title: Alert Dialog links: doc: https://base-ui.com/react/components/alert-dialog#api-reference
Installation
npx shadcn@latest add @coss/alert-dialognpm install @base-ui/reactUsage
import {
AlertDialog,
AlertDialogClose,
AlertDialogDescription,
AlertDialogFooter,
AlertDialogHeader,
AlertDialogPopup,
AlertDialogTitle,
AlertDialogTrigger,
} from "@/components/ui/alert-dialog"<AlertDialog>
<AlertDialogTrigger>Delete Account</AlertDialogTrigger>
<AlertDialogPopup>
<AlertDialogHeader>
<AlertDialogTitle>Are you absolutely sure?</AlertDialogTitle>
<AlertDialogDescription>
This action cannot be undone. This will permanently delete your account
and remove your data from our servers.
</AlertDialogDescription>
</AlertDialogHeader>
<AlertDialogFooter>
<AlertDialogClose>Cancel</AlertDialogClose>
<AlertDialogClose>Delete Account</AlertDialogClose>
</AlertDialogFooter>
</AlertDialogPopup>
</AlertDialog>API Reference
AlertDialog
Root component. Alias for AlertDialog.Root from Base UI.
AlertDialogTrigger
Trigger button that opens the alert dialog. Alias for AlertDialog.Trigger from Base UI.
AlertDialogPopup
Popup container that displays the alert dialog content. Also exported as AlertDialogContent.
| Prop | Type | Default | Description |
|---|---|---|---|
bottomStickOnMobile |
boolean |
true |
When true, sticks to the bottom of the screen on mobile devices |
portalProps |
AlertDialog.Portal.Props |
- | Props forwarded to the internal portal (keepMounted, container, etc.); see Base UI Alert Dialog portal API |
AlertDialogHeader
Container for the alert dialog title and description.
AlertDialogFooter
Footer section for action buttons.
Unlike Dialog, alert dialog has no AlertDialogPanel. Put title and description in AlertDialogHeader, actions in AlertDialogFooter, and use a plain element with className if you need extra body content between them.
| Prop | Type | Default | Description |
|---|---|---|---|
variant |
"default" | "bare" |
"default" |
Controls the footer styling. default includes border and background, bare removes them |
Example:
// Default variant (with border and background)
<AlertDialogFooter>
<AlertDialogClose>Cancel</AlertDialogClose>
<AlertDialogClose>Delete</AlertDialogClose>
</AlertDialogFooter>
// Bare variant (no border or background)
<AlertDialogFooter variant="bare">
<AlertDialogClose>Cancel</AlertDialogClose>
<AlertDialogClose>Delete</AlertDialogClose>
</AlertDialogFooter>AlertDialogTitle
Title component. Alias for AlertDialog.Title from Base UI.
AlertDialogDescription
Description component. Alias for AlertDialog.Description from Base UI.
AlertDialogClose
Close button component. Alias for AlertDialog.Close from Base UI.
AlertDialogPortal
Portal component for rendering outside the DOM hierarchy. Alias for AlertDialog.Portal from Base UI.
AlertDialogBackdrop
Backdrop/overlay component. Also exported as AlertDialogOverlay. Alias for AlertDialog.Backdrop from Base UI.
AlertDialogViewport
Viewport component for positioning. Alias for AlertDialog.Viewport from Base UI.
Examples
Alert Dialog with Bare Footer
Close Confirmation
File: apps/ui/content/docs/components/autocomplete.mdx
title: Autocomplete links: doc: https://base-ui.com/react/components/autocomplete#api-reference
Installation
npx shadcn@latest add @coss/autocompletenpm install @base-ui/reactUsage
import {
Autocomplete,
AutocompleteEmpty,
AutocompleteInput,
AutocompleteItem,
AutocompleteList,
AutocompletePopup,
} from "@/components/ui/autocomplete"const items = [
{ value: "apple", label: "Apple" },
{ value: "banana", label: "Banana" },
{ value: "orange", label: "Orange" },
{ value: "grape", label: "Grape" },
]
<Autocomplete items={items}>
<AutocompleteInput placeholder="Search..." />
<AutocompletePopup>
<AutocompleteEmpty>No results found.</AutocompleteEmpty>
<AutocompleteList>
{(item) => <AutocompleteItem key={item.value} value={item}>{item.label}</AutocompleteItem>}
</AutocompleteList>
</AutocompletePopup>
</Autocomplete>API Reference
Autocomplete
The root autocomplete component. Manages the autocomplete state and provides context to child components.
| Prop | Type | Description |
|---|---|---|
items |
readonly unknown[] |
The array of items to display in the autocomplete |
open |
boolean |
Controls whether the popup is open |
...props |
React.ComponentProps<typeof Autocomplete> |
All Base UI Autocomplete props are supported |
AutocompleteInput
The input field component with extended features for size variants and addon support.
| Prop | Type | Default | Description |
|---|---|---|---|
size |
"sm" | "default" | "lg" |
"default" |
The size variant of the input field |
startAddon |
React.ReactNode |
- | Element to display at the start (left side) of the input, such as an icon |
showTrigger |
boolean |
false |
Whether to display a trigger button (chevron icon) on the right side of the input |
showClear |
boolean |
false |
Whether to display a clear button (X icon) on the right side of the input when there is a value |
triggerProps |
Autocomplete.Trigger.Props |
- | Props forwarded to the internal trigger button, useful for overriding aria-label |
clearProps |
Autocomplete.Clear.Props |
- | Props forwarded to the internal clear button, useful for overriding aria-label |
className |
string |
- | Additional CSS classes to apply to the component |
...props |
Base UI Autocomplete Input props | - | All standard autocomplete input attributes are supported |
AutocompletePopup
The popup container that displays the autocomplete suggestions.
| Prop | Type | Description |
|---|---|---|
className |
string |
Additional CSS classes to apply to the component |
portalProps |
Autocomplete.Portal.Props |
Props forwarded to the internal portal (keepMounted, container, etc.); see Base UI Combobox portal API (autocomplete reuses it) |
...props |
Base UI Autocomplete Popup props | All standard autocomplete popup attributes are supported |
AutocompleteList
A scrollable container for autocomplete items.
| Prop | Type | Description |
|---|---|---|
className |
string |
Additional CSS classes to apply to the component |
...props |
Base UI Autocomplete List props | All standard autocomplete list attributes are supported |
AutocompleteItem
An individual selectable autocomplete item.
| Prop | Type | Description |
|---|---|---|
value |
unknown |
The value of the item |
className |
string |
Additional CSS classes to apply to the component |
...props |
Base UI Autocomplete Item props | All standard autocomplete item attributes are supported |
AutocompleteEmpty
Displays a message when no results are found.
| Prop | Type | Description |
|---|---|---|
className |
string |
Additional CSS classes to apply to the component |
...props |
Base UI Autocomplete Empty props | All standard autocomplete empty attributes are supported |
AutocompleteGroup
Groups related autocomplete items together.
| Prop | Type | Description |
|---|---|---|
items |
readonly unknown[] |
The array of items in this group |
className |
string |
Additional CSS classes to apply to the component |
...props |
Base UI Autocomplete Group props | All standard autocomplete group attributes are supported |
AutocompleteGroupLabel
Displays a label for an autocomplete group.
| Prop | Type | Description |
|---|---|---|
className |
string |
Additional CSS classes to apply to the component |
...props |
Base UI Autocomplete Group Label props | All standard autocomplete group label attributes are supported |
AutocompleteCollection
Used to wrap items within a group for rendering.
| Prop | Type | Description |
|---|---|---|
...props |
Base UI Autocomplete Collection props | All standard autocomplete collection attributes are supported |
Examples
Disabled
Small Size
Large Size
With Label
Inline Autocomplete
Autofill the input with the highlighted item while navigating with arrow keys.
Auto Highlight
Automatically highlight the first matching option.
With Clear Button
With Trigger and Clear Buttons
With Start Addon
Display an icon or other element at the start of the input using the startAddon prop.
With Groups
With Limit Results
Async Search
Form Integration
File: apps/ui/content/docs/components/avatar.mdx
title: Avatar links: doc: https://base-ui.com/react/components/avatar#api-reference
Installation
npx shadcn@latest add @coss/avatarnpm install @base-ui/reactUsage
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"<Avatar>
<AvatarImage src="/avatars/01.png" alt="User avatar" />
<AvatarFallback>JD</AvatarFallback>
</Avatar>API Reference
Avatar
Root component. Styled wrapper for Avatar.Root from Base UI with default size of 32px (8 units) and rounded-full styling.
AvatarImage
Image element for the avatar. Styled wrapper for Avatar.Image from Base UI.
AvatarFallback
Fallback content displayed when the image fails to load. Styled wrapper for Avatar.Fallback from Base UI with muted background.
Examples
Fallback Only
Different Sizes
Different Radius
Group Avatars
File: apps/ui/content/docs/components/badge.mdx
title: Badge
Installation
npx shadcn@latest add @coss/badgenpm install @base-ui/react@theme inline {
--color-destructive-foreground: var(--destructive-foreground);
--color-info: var(--info);
--color-info-foreground: var(--info-foreground);
--color-success: var(--success);
--color-success-foreground: var(--success-foreground);
--color-warning: var(--warning);
--color-warning-foreground: var(--warning-foreground);
}
:root {
--destructive-foreground: var(--color-red-700);
--info: var(--color-blue-500);
--info-foreground: var(--color-blue-700);
--success: var(--color-emerald-500);
--success-foreground: var(--color-emerald-700);
--warning: var(--color-amber-500);
--warning-foreground: var(--color-amber-700);
}
.dark {
--destructive-foreground: var(--color-red-400);
--info: var(--color-blue-500);
--info-foreground: var(--color-blue-400);
--success: var(--color-emerald-500);
--success-foreground: var(--color-emerald-400);
--warning: var(--color-amber-500);
--warning-foreground: var(--color-amber-400);
}Usage
import { Badge } from "@/components/ui/badge"BadgeLink
You can use the render prop to make another component look like a badge. Here's an example of a link that looks like a badge.
import Link from "next/link"
import { Badge } from "@/components/ui/badge"
export function LinkAsBadge() {
return }>New
}API Reference
This is a custom component using Base UI's useRender hook, not a direct Base UI wrapper.
Badge
A badge component with variant and size options.
| Prop | Type | Default | Description |
|---|---|---|---|
variant |
"default" | "destructive" | "error" | "info" | "outline" | "secondary" | "success" | "warning" |
"default" |
Controls the badge styling and color scheme |
size |
"default" | "sm" | "lg" |
"default" |
Controls the badge size |
render |
React.ReactElement |
- | Render as a different element (e.g., Link) |
Examples
Outline
Secondary
Destructive
Info
Success
Warning
Error
Small
Large
With Icon
With Link
With Count
File: apps/ui/content/docs/components/breadcrumb.mdx
title: Breadcrumb
Installation
npx shadcn@latest add @coss/breadcrumbUsage
import {
Breadcrumb,
BreadcrumbEllipsis,
BreadcrumbItem,
BreadcrumbLink,
BreadcrumbList,
BreadcrumbPage,
BreadcrumbSeparator,
} from "@/components/ui/breadcrumb"Home
Components
BreadcrumbAPI Reference
This is a custom component, not a Base UI wrapper.
Breadcrumb
Root navigation container with aria-label="breadcrumb".
BreadcrumbList
Ordered list container for breadcrumb items.
BreadcrumbItem
Individual breadcrumb item container.
BreadcrumbLink
Link element for navigable breadcrumb items. Supports the render prop to use custom link components (e.g., Next.js Link).
| Prop | Type | Default | Description |
|---|---|---|---|
render |
React.ReactElement |
- | Render as a different element (e.g., Next.js Link) |
BreadcrumbPage
Non-interactive element representing the current page. Includes aria-current="page".
BreadcrumbSeparator
Separator between breadcrumb items. Defaults to a chevron icon but accepts custom children.
BreadcrumbEllipsis
Ellipsis indicator for collapsed breadcrumb items.
Examples
With custom separator
File: apps/ui/content/docs/components/button.mdx
title: Button
Installation
npx shadcn@latest add @coss/buttonnpm install @base-ui/react@theme inline {
--color-destructive-foreground: var(--destructive-foreground);
}
:root {
--destructive-foreground: var(--color-red-700);
}
.dark {
--destructive-foreground: var(--color-red-400);
}Usage
import { Button } from "@/components/ui/button"ButtonLink
You can use the render prop to make another component look like a button. Here's an example of a link that looks like a button.
import Link from "next/link"
import { Button } from "@/components/ui/button"
export function LinkAsButton() {
return }>Login
}API Reference
This is a custom component using Base UI's useRender hook, not a direct Base UI wrapper.
Button
A button component with variant, size, and loading states.
| Prop | Type | Default | Description |
|---|---|---|---|
variant |
"default" | "destructive" | "destructive-outline" | "ghost" | "link" | "outline" | "secondary" |
"default" |
Controls the button styling |
size |
"default" | "icon" | "icon-lg" | "icon-sm" | "icon-xl" | "icon-xs" | "lg" | "sm" | "xl" | "xs" |
"default" |
Controls the button size |
loading |
boolean |
false |
Shows a spinner and forces disabled button behavior while loading |
render |
React.ReactElement |
- | Render as a different element (e.g., Link) |
When loading is true, the component:
- Renders a spinner (
data-slot="button-loading-indicator") - Adds
data-loadingon the button root - Forces the native
disabledattribute - Sets
aria-disabled="true" - Preserves button width by hiding content visually instead of unmounting it