# Comwit UI Styled React components that the comwit-ui CLI copies into your project as source, on top of the headless @comwit/ui engine. Behavior (gestures, scroll rules, focus, keyboard, IME) lives in @comwit/ui; the copied files compose its parts and apply the design tokens, so restyling them never breaks behavior. Where a proven library already does the job, a component wraps it under a neutral name and installs it as an npm dependency (noted below). Independent of Comwit State. ## Install Requires React 18 or 19 and Tailwind CSS v4 (Next.js: App Router). ```bash npx comwit-ui@latest init npx comwit-ui@latest add button dialog input ``` init creates comwit.json, wires comwit-tokens.css and installs the base dependencies. add copies each component, plus the components and lib/* files it uses, into components/ui and lib (aliases in comwit.json, under src/ when tsconfig maps @/* to ./src/*), then installs its npm dependencies. Existing files are skipped: --overwrite replaces local edits, --dry previews, --no-install skips npm. ```tsx 'use client' import { Button } from '@/components/ui/button' ``` - The copied file is the API reference: read it for parts and props, and edit it directly. - Import from the copied files, never from @comwit/ui-templates. ScrollChromeProvider, useScrollChrome, useMobile and useMobileDevice come from @comwit/ui. - Default text (button labels, placeholders, screen-reader names) and the picker date locale live in one copied file, lib/ui-text.ts. `init --locale ko` installs the Korean version; edit that file to change wording, or pass the component's labels/placeholder props for one screen. - Set the --font-pretendard variable on (for example with next/font/local), or components fall back to the system font. - Mount once: the copied Toaster for toast (then call toast() from '@/components/ui/toast', not sonner's), OverlayProvider from overlay-kit for popup, ScrollChromeProvider around the scroller for app-bar and bottom-nav, PageTransition with RouteBoundary around the routed content for page-transition. - Style with the token utilities (bg-primary, text-muted-foreground, rounded-card …), not hardcoded colors, and merge classes with cn() from lib/utils; a plain twMerge drops token utilities. Keep your own global element rules inside @layer base. Give page content its side margins with px-gutter (the --page-gutter token, safe-area aware) so it lines up with the phone toasts. Theme by overriding the CSS variables; dark mode is the .dark class. ## Components Add any of them by name: npx comwit-ui@latest add . The gallery shows each one live with copyable code. ### Mobile app Chrome that behaves like a native app and gets out of the way while you read. - app-shell: The whole mobile shell in one piece: the only scroller, pull to refresh, shared scroll intent, page transitions and history-aware back. Installed for your router. - app-screen: One screen = app bar + body. Tab roots flow, details reveal with a glass back button that falls back to the parent route on direct entry. - app-bar: Glass top bar. Hides while you scroll down, returns the moment you scroll up. - bottom-nav: Floating tab capsule. The indicator springs between tabs; the bar shrinks as you scroll. - page-transition: Hero, zoom, drill or fade from the photo grid into the photo. One keyed boundary marks the page; your router or plain state drives it. Built on SSGOI. - bottom-sheet: Rises from the bottom. Drag the handle down to dismiss; the scrim fades as you pull. - pull-to-refresh: Pull down at the top to reload. Only the dial moves, so sticky bars stay put. - drag-scroller: Horizontal rail with drag, flick momentum, wheel and arrow keys. Taps still click. ### Chat Header, messages and composer that fill their parent. The list is virtualized and scrolls the way each kind of conversation expects. - chat: Messenger mode keeps you at the bottom; assistant mode lifts your message to the top and streams the answer under it. Built on React Virtuoso. ### Glass A refracting surface for everything that floats above content. - glass: Four materials: morphing lens, blur, frosted and fade. Put it under any container. - dropdown-menu: Menus on morphing glass. Hover tints the text instead of filling the row. - popover: Anchored glass panel for small tasks next to their trigger. ### Notifications Tell people what happened and what to do next. - toast: Glass toasts, one surface for every status. Full width at the top on phones, top right on desktop. Built on Sonner. - popup: await popup.confirm(), popup.alert() and popup.sheet() from anywhere, no state needed. Import from @/lib/popup. Built on overlay-kit. - alert: Inline callout in five tones. - empty-state: When a list is empty, offer the one thing to do next. ### Pickers A popover on desktop, a bottom sheet on phones. Same panel, same value. - date-picker: YYYY-MM-DD in, YYYY-MM-DD out. Min, max and any locale. - time-picker: Slot list that scrolls to the selected time. - month-picker: Year pages of twelve months for billing periods and reports. - calendar: Inline calendar for single dates and ranges. Built on React DayPicker. ### Selection Small controls with a physical response: ripples, springs and a drawn check. - segmented-control: A white pill on a sunken track for switching views and filters. - chip: Filters and tags with a ripple, a selected state and an optional remove button. - checkbox: The check draws itself in. A soft halo follows hover and press. - radio-group: The dot pops in on a spring, with arrow-key navigation. - pager: Numbered pages from just page and totalPages. ### Forms and data Inputs that handle Korean and Japanese IME composition, plus tables that never jump. - text-field: Label, helper text and error wired to the control for screen readers. - autocomplete: Type to filter, arrow keys to choose. - select: Pick one option from a list, with type-ahead and a brand check mark. - form: react-hook-form fields with accessible messages. Built on React Hook Form. - data-table: Server pagination with skeleton rows and a quiet refetch badge. The height never jumps. Built on TanStack Table. - editor: Rich text on tiptap with a compact toolbar. Built on Tiptap. ### Basics The everyday parts, styled with the same tokens. - button: Pill buttons that press in. - badge: Status labels. - input: Single-line text. - input-group: Input with icons or units. - textarea: Grows with its content. - label: Names a control. - switch: On or off, right away. - tabs: Segmented tabs. - accordion: Stacked sections that expand. - collapsible: Show or hide one region. - dialog: Modal window. - sheet: Panel from any edge. - card: Content container. - table: Plain table parts. - avatar: Image with a fallback. - separator: Hairline divider. - skeleton: Loading placeholder. - pagination: Composable page links. ## More - Installation guide, with page transitions, bottom sheet and chat in depth: https://library.comwit.io/ui/docs/installation - Components gallery: https://library.comwit.io/ui/components - Tokens and theming: https://library.comwit.io/ui/theming - Headless primitives (@comwit/ui without the styled files): https://library.comwit.io/ui/docs/primitives - Page transition rules and presets (SSGOI, same config shape): https://ssgoi.dev/llms.txt - State (separate library): https://library.comwit.io/state/llms.txt