# Rime > Rime is a React component kit with frosted-glass surfaces: Next.js App Router, TypeScript, CSS Modules and CSS custom properties, no Tailwind and no component library underneath. It installs like shadcn/ui (the shadcn CLI copies the source into your project) and names its items as shadcn does. Each project re-themes it with one theme.css made in Rime Studio (https://rime.mjsons.net/themes). Two presets, Rime Default (frosted glass in Frost blue) and Rime Flat, each in light and dark mode. Read the rules before writing UI code with these components: - Import primitives from "@/components/ui" (the barrel). Shells come from "@/components/shell/*". - Never restyle a primitive from a screen. Theme it with CSS custom properties (tokens) instead: system tokens in app/styles/tokens.css, per-component tokens (--button-radius, --input-height-md, --table-head-fill) at :root or on a wrapper. - CSS Modules only. No Tailwind, no inline colour values, no new component library. - No heavy rounding beyond the theme's scale, no scale-up or lift on hover, no bento grids, no left accent bars, no decorative background effects that do not derive from the product. - No eyebrow or small label stacked over a title. Text uses the full width of its column: no narrow measure caps. - Summary stats are one card with hairline cells, never a grid of separate stat cards. - Filters are dropdowns (Select chips) plus one full-width search, never a row of toggle chips. Sortable table headers are the whole cell; pagination is centred under the table. - One primary button (the brand gradient) per view. One table look everywhere. Modal and sheet headers keep one left edge. - Every list page is GlassPanel > FilterBar + Table + Pagination, with nothing above it. - Every component needs its loading, empty, error and disabled states; an empty state always says what to do next. - Text contrast 4.5:1 minimum (3:1 for focus rings and control edges). Fill colours like --brand-soft and --danger-base are never text. - In Next.js, gate access inside page.tsx, never in layout.tsx (a layout gate leaks the page into the RSC payload). - No em dashes in copy. ## Install - Everything: `npx shadcn@latest add KezLahd/rime/kit` - One component: `npx shadcn@latest add KezLahd/rime/` (item names follow shadcn: button, dialog, dropdown-menu, select, sheet, sonner...) - The agent docs and Claude skill for a project: `npx shadcn@latest add KezLahd/rime/agents` - Registry: https://rime.mjsons.net/r/registry.json. Namespace @rime for components.json: "@rime": "https://rime.mjsons.net/r/{name}.json". The shadcn MCP server (npx shadcn@latest mcp) then lists, searches and installs Rime items. - Styles, imported first in app/globals.css: app/styles/tokens.css, app/styles/base.css, app/styles/shadcn-bridge.css, then the project's theme.css. ## Coming from shadcn | shadcn | Rime | Install item | | --- | --- | --- | | button | Button (variant default→primary, destructive→danger, outline→secondary; link and icon sizes as in shadcn) | button | | button-group | ButtonGroup | button-group | | card | Card (+ CardHeader, CardTitle, CardContent...) (props (title, description, actions, footer) or the shadcn parts) | card | | dialog | Modal, ConfirmModal | dialog | | alert-dialog | AlertDialog | alert-dialog | | sheet, drawer | Sheet, Drawer | sheet | | dropdown-menu | Menu | dropdown-menu | | context-menu | ContextMenu | context-menu | | menubar | Menubar | menubar | | navigation-menu | NavigationMenu | navigation-menu | | popover | Popover | popover | | hover-card | HoverCard | hover-card | | tooltip | Tooltip, Toggletip | tooltip | | command | Command, CommandDialog | command | | input | TextInput | input | | input-group | InputGroup | input-group | | input-otp | OtpInput | input-otp | | textarea | Textarea | textarea | | label | Label | label | | field, form | Field, ErrorSummary | field | | checkbox | Checkbox | checkbox | | radio-group | RadioGroup | radio-group | | switch | Switch | switch | | slider | Slider | slider | | select | Select (searchable option) | select | | combobox | Combobox | combobox | | calendar, date-picker | Calendar, DateField, DateRangeFilter | date-field | | toggle, toggle-group | Toggle, ToggleGroup | toggle | | tabs | FolderTabs, SegmentedControl | tabs | | accordion | Accordion | accordion | | collapsible | Collapsible | collapsible | | breadcrumb | Breadcrumb | breadcrumb | | pagination | Pagination (in Table) | table | | table, data-table | Table + FilterBar + Pagination (the list page pattern) | table | | badge | Badge, StatusPill, CountBadge | badge | | avatar | Avatar | avatar | | separator | Divider | separator | | progress | Meter, ProgressBar | progress | | skeleton | Skeleton | skeleton | | spinner | Spinner | spinner | | kbd | Kbd | kbd | | alert | Alert | alert | | sonner, toast | Toast + ToastProvider | sonner | | empty | EmptyState | empty | | scroll-area | ScrollArea | scroll-area | | aspect-ratio | AspectRatio | aspect-ratio | | carousel | Carousel | carousel | | resizable | ResizablePanelGroup, ResizablePanel, ResizableHandle | resizable | | chart | LineChart, AreaChart, BarChart, DonutChart, ChartContainer | chart | | sidebar | SidebarShell (components/shell) | sidebar | shadcn CSS variable names are aliases of Rime tokens (app/styles/shadcn-bridge.css), one way only: | shadcn variable | Rime token | | --- | --- | | --background | --page-base | | --foreground | --ink-body | | --card / --card-foreground | --surface-solid / --ink-body | | --popover / --popover-foreground | --popover-surface / --ink-body | | --primary / --primary-foreground | --brand-action / --ink-inverse | | --secondary / --secondary-foreground | --surface-sunken / --ink-heading | | --muted / --muted-foreground | --surface-sunken / --ink-muted | | --accent / --accent-foreground | --wash-hover / --ink-heading | | --destructive | --danger-base-solid | | --border | --line | | --input | --line-input | | --ring | --focus-color | | --radius | --r-md | | --chart-1..5 | --chart-1..5 | | --sidebar* | --chrome-sidebar, --brand-action, --wash-active, --line-soft | | --font-sans / --font-heading | --font-body / --font-display | Dark mode is the .dark class or data-mode="dark" on ; Rime Flat is data-theme="flat". ## Docs - [Everything in one file](https://rime.mjsons.net/llms-full.txt): every component, pattern and rule - [Theming and tokens](https://rime.mjsons.net/md/theme.md): token layers, presets and modes, how to theme a project - [Patterns](https://rime.mjsons.net/md/patterns.md): composed patterns (list page, shells, sign-in, terms gate) - Any docs page as markdown: add .md to its URL (for example /components/button.md). ## Actions - [Button](https://rime.mjsons.net/md/button.md): The action control: primary gradient, glass secondary, ghost, and two danger forms, in three sizes. Install: `npx shadcn@latest add KezLahd/rime/button` - [ButtonGroup](https://rime.mjsons.net/md/button-group.md): Joins Buttons and IconButtons into one segmented row or column with shared outer corners. Install: `npx shadcn@latest add KezLahd/rime/button-group` - [IconButton](https://rime.mjsons.net/md/icon-button.md): A square action with only an icon, a required accessible label and a tooltip-friendly hit area. Install: `npx shadcn@latest add KezLahd/rime/icon-button` ## Forms - [Calendar](https://rime.mjsons.net/md/calendar.md): The month grid on its own: a single date or a range, one or two months, with month and year pickers. Install: `npx shadcn@latest add KezLahd/rime/date-field` - [Checkbox](https://rime.mjsons.net/md/checkbox.md): A native checkbox drawn as a gradient tick, plain or as a selectable card, with indeterminate. Install: `npx shadcn@latest add KezLahd/rime/checkbox` - [Combobox](https://rime.mjsons.net/md/combobox.md): A text field that filters a list of options as you type and picks one, with optional create. Install: `npx shadcn@latest add KezLahd/rime/combobox` - [DateField](https://rime.mjsons.net/md/date-field.md): A typed DD/MM/YYYY field with a calendar popover, min/max and a date-of-birth preset. Install: `npx shadcn@latest add KezLahd/rime/date-field` - [DateRangeFilter](https://rime.mjsons.net/md/date-range-filter.md): A date-range chip for filter rows: presets plus a two-month range calendar. Install: `npx shadcn@latest add KezLahd/rime/date-range-filter` - [DateTimeField and DateTimeRangeField](https://rime.mjsons.net/md/date-time-field.md): A date and a time of day on one row, each with its own popup; the range variant pairs a start and end. Install: `npx shadcn@latest add KezLahd/rime/date-time-field` - [ErrorSummary](https://rime.mjsons.net/md/error-summary.md): The list of form errors at the top of a form, focused on submit, each linking to its field. Install: `npx shadcn@latest add KezLahd/rime/error-summary` - [Field](https://rime.mjsons.net/md/field.md): Label, hint, error and required marker for any control, wired through context. Install: `npx shadcn@latest add KezLahd/rime/field` - [FileDrop](https://rime.mjsons.net/md/file-drop.md): A drop zone and file picker with type and size checks and per-file status chips. Install: `npx shadcn@latest add KezLahd/rime/file-drop` - [InputGroup](https://rime.mjsons.net/md/input-group.md): A text field with addons joined to it: a fixed text segment, an icon, or a button such as Copy. Install: `npx shadcn@latest add KezLahd/rime/input-group` - [Label](https://rime.mjsons.net/md/label.md): A standalone form label with required and optional markers, for controls outside a Field. Install: `npx shadcn@latest add KezLahd/rime/label` - [OtpInput](https://rime.mjsons.net/md/otp-input.md): A six-cell one-time code entry with paste, auto-advance and onComplete. Install: `npx shadcn@latest add KezLahd/rime/otp-input` - [PrefixedInput](https://rime.mjsons.net/md/prefixed-input.md): A fixed-format code with a set prefix: an invoice number, an account code, a membership number. Install: `npx shadcn@latest add KezLahd/rime/prefixed-input` - [RadioGroup](https://rime.mjsons.net/md/radio-group.md): One choice from a few: a list, inline, or cards in 1 to 3 columns. Install: `npx shadcn@latest add KezLahd/rime/radio-group` - [SearchField](https://rime.mjsons.net/md/search-field.md): Field-size search on the grey frosted recess: clear button, loading state and an optional key hint. Install: `npx shadcn@latest add KezLahd/rime/search-field` - [Select](https://rime.mjsons.net/md/select.md): A custom listbox: a recessed field or filter chip that opens a frosted popover, optionally searchable. Install: `npx shadcn@latest add KezLahd/rime/select` - [Slider](https://rime.mjsons.net/md/slider.md): Picks a number or a range by dragging along a track, with steps, marks and a value readout. Install: `npx shadcn@latest add KezLahd/rime/slider` - [Switch](https://rime.mjsons.net/md/switch.md): An on/off setting that takes effect immediately, with a loading state while it saves. Install: `npx shadcn@latest add KezLahd/rime/switch` - [Textarea](https://rime.mjsons.net/md/textarea.md): Multi-line text in the TextInput box, resizable vertically, with an optional character count. Install: `npx shadcn@latest add KezLahd/rime/textarea` - [TextInput](https://rime.mjsons.net/md/text-input.md): The text field: a white box with a tinted edge, a brand halo on focus, adornments and a password reveal. Install: `npx shadcn@latest add KezLahd/rime/text-input` - [TimeField and TimeRangeField](https://rime.mjsons.net/md/time-field.md): A time of day with typed input and a popup picker; the range variant pairs start and end on one row. Install: `npx shadcn@latest add KezLahd/rime/time-field` - [Toggle](https://rime.mjsons.net/md/toggle.md): A two-state button, pressed or not, for toolbar formatting and view options. Install: `npx shadcn@latest add KezLahd/rime/toggle` - [ToggleGroup](https://rime.mjsons.net/md/toggle-group.md): A set of toggles sharing one value: single (a clearable radio set) or multiple. Install: `npx shadcn@latest add KezLahd/rime/toggle` ## Data display - [Avatar](https://rime.mjsons.net/md/avatar.md): Initials on the brand gradient or a neutral disc, in three sizes. Install: `npx shadcn@latest add KezLahd/rime/avatar` - [Chart](https://rime.mjsons.net/md/chart.md): Themed charts on Recharts: line, area, bar and donut in one frame with a table view, plus sparklines and a stat strip. Install: `npx shadcn@latest add KezLahd/rime/charts` - [Kbd and KbdGroup](https://rime.mjsons.net/md/kbd.md): Keyboard keys as small raised key caps, alone or as a combination. Install: `npx shadcn@latest add KezLahd/rime/kbd` - [Meter and ProgressBar](https://rime.mjsons.net/md/meter.md): A segmented meter for small counts (seats used) and a bar for progress through a total. Install: `npx shadcn@latest add KezLahd/rime/meter` - [ProgressSteps](https://rime.mjsons.net/md/progress-steps.md): A horizontal track of steps with detail and meta lines, or a compact dot track for table cells. Install: `npx shadcn@latest add KezLahd/rime/progress-steps` - [StatusPill, Badge and CountBadge](https://rime.mjsons.net/md/status-pill.md): Status pills (tinted fill, tinted edge, deep ink), small uppercase tags, and count badges. Install: `npx shadcn@latest add KezLahd/rime/badge` - [Table](https://rime.mjsons.net/md/table.md): The one table look: neutral header row, whole-cell sortable headers, skeleton, empty and error states, and Pagination. Install: `npx shadcn@latest add KezLahd/rime/table` ## Navigation - [Breadcrumb](https://rime.mjsons.net/md/breadcrumb.md): Where this page sits: a trail of links ending on the current page, folding its middle into a menu when long. Install: `npx shadcn@latest add KezLahd/rime/breadcrumb` - [FilterBar](https://rime.mjsons.net/md/filter-bar.md): The one filter row above every table: a growing search, dropdown chips at the end, clear, and the list's own action. Install: `npx shadcn@latest add KezLahd/rime/filter-bar` - [FolderTabs and SegmentedControl](https://rime.mjsons.net/md/tabs.md): Folder tabs that sit on a glass panel with always-visible counts, and a segmented control for views. Install: `npx shadcn@latest add KezLahd/rime/tabs` - [NavigationMenu](https://rime.mjsons.net/md/navigation-menu.md): Top-level site navigation with frosted dropdown panels of described links, built as disclosure navigation. Install: `npx shadcn@latest add KezLahd/rime/navigation-menu` - [NavSearch and SmartSearch](https://rime.mjsons.net/md/nav-search.md): Top-bar search: NavSearch jumps to pages and actions; SmartSearch queries records with grouped results. Install: `npx shadcn@latest add KezLahd/rime/nav-search` - [Pagination](https://rime.mjsons.net/md/pagination.md): Centred page buttons with previous and next, gaps for long ranges, and a summary line at the left. Install: `npx shadcn@latest add KezLahd/rime/table` - [Stepper](https://rime.mjsons.net/md/stepper.md): The wizard's step list: lettered markers, states, and optional navigation back to finished steps. Install: `npx shadcn@latest add KezLahd/rime/stepper` ## Feedback - [Alert](https://rime.mjsons.net/md/alert.md): An inline message in a tone (info, success, warning, danger) or a quiet legal box for fixed wording, with an action and dismiss. Install: `npx shadcn@latest add KezLahd/rime/alert` - [EmptyState](https://rime.mjsons.net/md/empty-state.md): What an empty list means and what to do next: default, positive (all done) and filtered tones. Install: `npx shadcn@latest add KezLahd/rime/empty-state` - [ImpactPreview](https://rime.mjsons.net/md/impact-preview.md): What a destructive action will change, row by row, before it is confirmed. Install: `npx shadcn@latest add KezLahd/rime/impact-preview` - [Skeleton](https://rime.mjsons.net/md/skeleton.md): Loading placeholders shaped like the content they stand in for, with a soft shimmer. Install: `npx shadcn@latest add KezLahd/rime/skeleton` - [Spinner](https://rime.mjsons.net/md/spinner.md): A small brand-tinted spinner for in-flight work inside buttons, fields and panels. Install: `npx shadcn@latest add KezLahd/rime/spinner` - [Toast](https://rime.mjsons.net/md/toast.md): Frosted toasts for success, error, info and in-flight work, stacked as a deck that fans out on hover. Install: `npx shadcn@latest add KezLahd/rime/toast` ## Overlays - [AlertDialog](https://rime.mjsons.net/md/alert-dialog.md): A short interrupting confirm with Cancel and one action; focus starts on Cancel and the scrim never dismisses it. Install: `npx shadcn@latest add KezLahd/rime/alert-dialog` - [Command](https://rime.mjsons.net/md/command.md): A command palette: a search box over grouped actions with shortcuts, keyboard-first, inline or as a Ctrl+K dialog. Install: `npx shadcn@latest add KezLahd/rime/command` - [ContextMenu](https://rime.mjsons.net/md/context-menu.md): A menu of actions for a region, opened at the pointer with a right-click, Shift+F10 or a long press. Install: `npx shadcn@latest add KezLahd/rime/context-menu` - [HoverCard](https://rime.mjsons.net/md/hover-card.md): A rich preview on hover or keyboard focus of a link: a person, a project, a record. Install: `npx shadcn@latest add KezLahd/rime/hover-card` - [Menu](https://rime.mjsons.net/md/menu.md): An action menu from a button: groups, headings, separators, icons, links and danger items, in a frosted popover. Install: `npx shadcn@latest add KezLahd/rime/menu` - [Menubar](https://rime.mjsons.net/md/menubar.md): A desktop application menu bar (File, Edit, View) with keyboard navigation across and within its menus. Install: `npx shadcn@latest add KezLahd/rime/menubar` - [Modal](https://rime.mjsons.net/md/modal.md): A frosted dialog with a focus trap, scroll lock, inert page, scroll-aware edges and a bottom sheet on phones. Install: `npx shadcn@latest add KezLahd/rime/modal` - [Popover](https://rime.mjsons.net/md/popover.md): An anchored frosted panel for arbitrary content: a short form, a set of options, a details block. Install: `npx shadcn@latest add KezLahd/rime/popover` - [Sheet and Drawer](https://rime.mjsons.net/md/sheet.md): A panel that slides in from an edge over a scrim, and a bottom Drawer with a drag handle. Install: `npx shadcn@latest add KezLahd/rime/sheet` - [Tooltip and Toggletip](https://rime.mjsons.net/md/tooltip.md): Hover and focus tooltips (dark one-liners or light rich cards) and click-to-open toggletips for help. Install: `npx shadcn@latest add KezLahd/rime/tooltip` - [TypeToConfirmModal and DangerZone](https://rime.mjsons.net/md/type-to-confirm.md): The heaviest confirm: an impact preview and a typed phrase; and the Danger zone section that leads to it. Install: `npx shadcn@latest add KezLahd/rime/type-to-confirm` ## Layout and surfaces - [Accordion](https://rime.mjsons.net/md/accordion.md): Stacked sections that open and close in place: one at a time or several, on glass or plain hairlines. Install: `npx shadcn@latest add KezLahd/rime/accordion` - [AspectRatio](https://rime.mjsons.net/md/aspect-ratio.md): A box held to a width-to-height ratio, so media keeps its shape and never shifts the layout while loading. Install: `npx shadcn@latest add KezLahd/rime/aspect-ratio` - [Card](https://rime.mjsons.net/md/card.md): A solid card with a washed header, a lifted highlight tone, and a sunken muted tone. Install: `npx shadcn@latest add KezLahd/rime/card` - [Carousel](https://rime.mjsons.net/md/carousel.md): A row of slides on a native scroll-snap track, with frosted prev and next buttons, dots and arrow keys. Install: `npx shadcn@latest add KezLahd/rime/carousel` - [Collapsible](https://rime.mjsons.net/md/collapsible.md): One disclosure: a title row with a toggle, an always-visible summary and a region that opens beneath it. Install: `npx shadcn@latest add KezLahd/rime/collapsible` - [Divider](https://rime.mjsons.net/md/divider.md): A hairline rule, horizontal or vertical, optionally labelled, with spacing steps. Install: `npx shadcn@latest add KezLahd/rime/divider` - [GlassPanel](https://rime.mjsons.net/md/glass-panel.md): Frosted glass over the page field: page, light and nested variants, padding steps and an optional bloom. Install: `npx shadcn@latest add KezLahd/rime/glass-panel` - [Resizable](https://rime.mjsons.net/md/resizable.md): Panels split by draggable hairline handles, side by side or stacked, with keyboard resizing and minimum sizes. Install: `npx shadcn@latest add KezLahd/rime/resizable` - [ScrollArea, useScrollEdges and useScrollLock](https://rime.mjsons.net/md/scroll-area.md): The modal's scroll, made portable: thin tinted scrollbars, contained overscroll, edge shadows and a shared scroll lock. Install: `npx shadcn@latest add KezLahd/rime/scroll-area` ## Shell - [AuthCard and AuthLayout](https://rime.mjsons.net/md/auth-card.md): The sign-in card: a solid card on a deep field, with a logo slot, icon tile, title, footer strip and back link. Install: `npx shadcn@latest add KezLahd/rime/auth-card` - [PageHeader](https://rime.mjsons.net/md/page-header.md): A page's h1 with a back link, a meta line, a description and actions. Install: `npx shadcn@latest add KezLahd/rime/page-header` - [SidebarShell](https://rime.mjsons.net/md/sidebar-shell.md): The signed-in frame in four layouts: an expanded frosted sidebar, a collapsible icon rail, a header-only top nav, and a drawer on narrow screens. Install: `npx shadcn@latest add KezLahd/rime/sidebar-shell` ## Patterns - [List page](https://rime.mjsons.net/md/patterns.md#list-page): One glass panel holding the filter row, the table and the pagination. Nothing above it. - [Frosted glass shell](https://rime.mjsons.net/md/patterns.md#glass-shell): The signed-in frame: the page field painted once, a frosted sidebar and top bar over it, and glass panels inside. - [Shell: sidebar expanded](https://rime.mjsons.net/md/patterns.md#shell-sidebar): The default signed-in frame: a full-height frosted sidebar and top bar forming one glass L, the logo corner in the same glass. - [Shell: collapsible icon rail](https://rime.mjsons.net/md/patterns.md#shell-rail): The same frame with a panel button that folds the sidebar to a 68px icon rail, remembered across visits. - [Shell: header only](https://rime.mjsons.net/md/patterns.md#shell-header): No sidebar: the logo, a short horizontal nav and the profile in one frosted top bar, the page below at full width. - [Shell: mobile drawer](https://rime.mjsons.net/md/patterns.md#shell-drawer): On narrow screens the sidebar becomes an off-canvas drawer from a menu button, with a scrim, a focus hold and Esc to close. - [Summary card with cells](https://rime.mjsons.net/md/patterns.md#summary-card): One card of key figures: per cell a label, a big number and a muted line of context, separated by hairlines. - [Modal with scroll edges](https://rime.mjsons.net/md/patterns.md#modal-scroll): A long modal whose header and footer cast shadows only when content passes under them. - [Terms with scroll-gated accept](https://rime.mjsons.net/md/patterns.md#terms-gated): A terms dialog whose Accept stays disabled until the reader has scrolled to the end. - [Sign-in with multi-factor authentication](https://rime.mjsons.net/md/patterns.md#sign-in): A corporate sign-in: brand mark in the header, the form centred, a shield treatment and a security note in the footer, across the password, MFA code and authenticator setup steps. --- # Button > The action control: primary gradient, glass secondary, ghost, and two danger forms, in three sizes. Category: Actions. Docs page: https://rime.mjsons.net/components/button ## Installation ```bash npx shadcn@latest add KezLahd/rime/button ``` Button is every pressable action that is not an icon on its own. Primary carries the brand gesture (the brand gradient with a soft glow) and appears at most once per view. Secondary is glass on the page and a white tile with a brand ring inside solid surfaces (a Card, a Modal, an auth card), switched automatically by the nearest data-surface="solid" ancestor. Ghost is for low-emphasis actions in rows and toolbars. Danger is the irreversible action, in the danger gradient. dangerSecondary is its inverse (danger ink on the secondary's glass) for destructive steps that are not the last one, such as "Review deletion" before the final "Delete project". Pass href to render a Next Link with the same look. A disabled or loading link drops its href and leaves the tab order, as a disabled button would. Loading shows a spinner, sets aria-busy, blocks presses and can swap the label (loadingLabel). ## Usage ```tsx import { Button } from "@/components/ui"; ``` ## Props: Button | Prop | Type | Default | Description | | --- | --- | --- | --- | | `variant` | `ButtonVariant` | `"primary"` | primary = the one brand gradient per view. secondary = glass (white inside solid surfaces). | | `size` | `ButtonSize` | `"md"` | | | `loading` | `boolean` | | Shows a spinner, sets aria-busy and blocks further presses. | | `loadingLabel` | `string` | | Replaces the label while loading, e.g. "Submitting…". | | `iconStart` | `ReactNode` | | | | `iconEnd` | `ReactNode` | | | | `fullWidth` | `boolean` | | | | `className` | `string` | | | | `children` | `ReactNode` | | | | `href` | `undefined \| string` | | Renders a Next . Internal routes only. | | `asChild` | `boolean \| undefined` | | Render the single child element (a Next , an ) with the button's look, as shadcn's asChild. The child supplies its own content. | | `disabled` | `boolean` | | | | `prefetch` | `boolean` | | | | `replace` | `boolean` | | | | `scroll` | `boolean` | | | Also accepts the native attributes of: AnchorHTMLAttributes, AriaAttributes, ButtonHTMLAttributes, DOMAttributes, HTMLAttributes. ## Examples ### Variants One primary per view. Secondary switches to a white tile inside solid surfaces. ```tsx ``` ### Sizes sm for table rows and toolbars, md everywhere else, lg for the one action on an auth card. ```tsx ``` ### With icons ```tsx ``` ### Loading and disabled Loading keeps the fill, dulls it and swaps the label. Disabled is a flat tint, not a faded gradient. ```tsx ``` ### shadcn names shadcn's variant and size names work as aliases: default is primary, destructive is danger, outline is secondary; link is an inline text link; icon, icon-sm and icon-lg are square. buttonVariants is buttonClassName. ```tsx ``` ### asChild asChild renders the single child (a Next Link, an ) with the button's look, as shadcn does. href remains the shorter way for internal links. ```tsx import Link from "next/link"; ``` ## Theme tokens Per-component tokens. Undeclared by default: the default below is the fallback the CSS uses. Set any of them at :root or on a wrapper to restyle every instance. | Token | Default | | --- | --- | | `--button-case` | `none` | | `--button-danger-bg` | `var(--danger-gradient)` | | `--button-dur` | `var(--dur)` | | `--button-ease` | `var(--ease)` | | `--button-gap` | `8px` | | `--button-ghost-ink` | `var(--ink-brand)` | | `--button-height-lg` | `var(--control-h-lg)` | | `--button-height-md` | `var(--control-h-md)` | | `--button-height-sm` | `var(--control-h-sm)` | | `--button-hover-glow` | `var(--glow-md-hover)` | | `--button-hover-overlay` | `rgba(var(--rgb-white), 0.07)` | | `--button-lift` | `0px` | | `--button-link-ink` | `var(--ink-brand)` | | `--button-outline` | `var(--shadow-control)` | | `--button-outline-active` | `inset 0 0 0 1px rgba(var(--rgb-brand), 0.32)` | | `--button-outline-hover` | `0 3px 8px rgba(var(--rgb-brand-deep), 0.1), inset 0 0 0 1px rgba(var(--rgb-brand), 0.32)` | | `--button-pad-lg` | `calc(24px * var(--density))` | | `--button-pad-md` | `calc(18px * var(--density))` | | `--button-pad-sm` | `calc(12px * var(--density))` | | `--button-press-overlay` | `rgba(var(--rgb-shade), 0.14)` | | `--button-primary-bg` | `var(--brand-gradient)` | | `--button-primary-ink` | `var(--ink-inverse)` | | `--button-radius` | `var(--r-sm)` / `var(--r-md)` / `var(--r-lg)` | | `--button-secondary-bg` | `rgba(var(--rgb-white), 0.45)` | | `--button-secondary-hover-bg` | `rgba(var(--rgb-white), 0.68)` | | `--button-secondary-hover-shadow` | `inset 0 0 0 1px rgba(var(--rgb-white), 0.9), var(--shadow-specular), 0 4px 12px rgba(var(--rgb-brand-deep), 0.1)` | | `--button-secondary-ink` | `var(--ink-heading)` | | `--button-size-lg` | `15px` | | `--button-size-md` | `14px` | | `--button-size-sm` | `12.5px` | | `--button-tracking` | `-0.005em` | | `--button-trim` | `0em` | | `--button-weight` | `700` | System tokens it reads: `--blur-callout`, `--brand-deep`, `--brand-gradient`, `--control-h-lg`, `--control-h-md`, `--control-h-sm`, `--danger-fill`, `--danger-gradient`, `--danger-ink`, `--danger-line`, `--density`, `--dur`, `--ease`, `--focus-gap`, `--focus-ring`, `--font-body`, `--glass-edge`, `--glass-edge-strong`, `--glow-danger`, `--glow-danger-hover`, `--glow-md`, `--glow-md-hover`, `--glow-sm`, `--ink-brand`, `--ink-disabled`, `--ink-heading`, `--ink-inverse`, `--ink-muted`, `--r-2xs`, `--r-lg`, `--r-md`, `--r-sm`, `--rgb-brand`, `--rgb-brand-deep`, `--rgb-contact`, `--rgb-danger`, `--rgb-shade`, `--rgb-white`, `--shadow-control`, `--shadow-specular`, `--shadow-specular-dark`, `--surface-solid`, `--wash-active`, `--wash-hover`, `--wash-subtle`. ## Accessibility - Renders a real ``` ## Props: ButtonGroup | Prop | Type | Default | Description | | --- | --- | --- | --- | | `orientation` | `"horizontal" \| "vertical"` | `"horizontal"` | horizontal (default) joins left to right; vertical stacks top to bottom. | Also accepts the native attributes of: AriaAttributes, DOMAttributes, HTMLAttributes. ## Examples ### Groups and a split button ```tsx } /> ``` ### Vertical ```tsx ``` ## Theme tokens Per-component tokens. Undeclared by default: the default below is the fallback the CSS uses. Set any of them at :root or on a wrapper to restyle every instance. | Token | Default | | --- | --- | | `--button-group-join` | `0` | ## Accessibility - Renders role="group" with aria-orientation. Give it an aria-label that names the set ("Invoice actions"). - Every button stays a real, separately focusable button in reading order; hover and focus lift the button over its neighbours so its focus ring is drawn whole. ## Do - Keep a group to one variant, except a split button's primary half. - Group two to five actions that belong together. ## Don't - Don't use a ButtonGroup for a selected state; that is ToggleGroup or SegmentedControl. - Don't put two primary buttons in one group. Related: https://rime.mjsons.net/components/button, https://rime.mjsons.net/components/toggle-group --- # TextInput > The text field: a white box with a tinted edge, a brand halo on focus, adornments and a password reveal. Category: Forms. Docs page: https://rime.mjsons.net/components/text-input ## Installation ```bash npx shadcn@latest add KezLahd/rime/text-input ``` TextInput is the one box every text-like field wears: Textarea, Select's field trigger, DateField, SearchField and PrefixedInput all share its --input-* tokens, so one theme change moves them together. Focus is drawn on the whole box, adornments included (a leading icon, a trailing unit, the reveal button), never on the bare . Invalid warms the fill and turns the edge to the danger hue; read-only is a dashed sunken box; disabled is flat and sunken. It is a plain controlled or uncontrolled : every native attribute passes through (type, autoComplete, inputMode, maxLength). ## Usage ```tsx import { Field, TextInput } from "@/components/ui"; setEmail(e.target.value)} /> ``` ## Props: TextInput | Prop | Type | Default | Description | | --- | --- | --- | --- | | `leadingIcon` | `ReactNode` | | | | `trailing` | `ReactNode` | | Right-hand slot inside the box: a unit ("%"), a clear button. | | `mono` | `boolean` | | Monospace with slight tracking, for ID numbers, references, postcodes. | | `invalid` | `boolean` | | Overrides the Field's invalid state. | | `revealable` | `boolean` | | Adds a show/hide toggle. Only meaningful with type="password". | | `defaultRevealed` | `boolean` | `false` | Starts with the password readable. For the styleguide and review screens. | | `size` | `"sm" \| "md"` | `"md"` | | | `boxClassName` | `string` | | Class for the outer box rather than the . | Also accepts the native attributes of: AriaAttributes, DOMAttributes, HTMLAttributes, InputHTMLAttributes. ## Props: Field | Prop | Type | Default | Description | | --- | --- | --- | --- | | `label` (required) | `ReactNode` | | | | `hint` | `ReactNode` | | | | `error` | `ReactNode` | | Presence marks the control invalid. Say what to do, not just what is wrong. | | `required` | `boolean` | `false` | | | `optional` | `boolean` | | Shows "(optional)". Use on forms where most fields are required. | | `id` | `string` | | Pass to link a field to an ErrorSummary entry. Generated otherwise. | | `group` | `boolean` | | fieldset + legend, for RadioGroup, a checkbox list, OtpInput, DateField. | | `labelStyle` | `"sentence" \| "caps"` | `"sentence"` | sentence = 13px bold (default, reads well for long labels). caps = the reference 11.5px uppercase micro-label, for short auth/admin forms. | | `labelAction` | `ReactNode` | | Something on the label's right edge, e.g. a "Forgot password?" link. | | `hideLabel` | `boolean` | | | | `className` | `string` | | | | `children` (required) | `ReactNode` | | | ## Examples ### In a Field Label, hint and error come from Field; the input reads them from context. ```tsx ``` ### Adornments and reveal ```tsx } placeholder="Search" /> ``` ### States ```tsx ``` ## Theme tokens Per-component tokens. Undeclared by default: the default below is the fallback the CSS uses. Set any of them at :root or on a wrapper to restyle every instance. | Token | Default | | --- | --- | | `--field-focus-border` | `rgba(var(--rgb-brand), 0.7)` / `var(--focus-color)` | | `--field-focus-ring` | `var(--focus-halo)` | | `--field-focus-ring-invalid` | `0 0 0 4px rgba(var(--rgb-danger), 0.14)` | | `--field-hover-border` | `rgba(var(--rgb-brand-deep), 0.3)` | | `--input-bg` | `var(--surface-solid)` | | `--input-border` | `var(--line-input)` | | `--input-border-width` | `var(--border-w-field)` | | `--input-font-size` | `var(--text-input)` | | `--input-height-md` | `var(--field-h-md)` | | `--input-height-sm` | `var(--field-h-sm)` | | `--input-pad-x` | `calc(14px * var(--density))` | | `--input-radius` | `var(--r-md)` / `var(--r-sm)` | | `--input-shadow` | `var(--shadow-input)` | System tokens it reads: `--border-w-field`, `--danger-base`, `--danger-field-fill`, `--danger-ink`, `--density`, `--dur`, `--ease`, `--field-h-md`, `--field-h-sm`, `--focus-color`, `--focus-halo`, `--font-body`, `--font-mono`, `--ink-body`, `--ink-brand`, `--ink-disabled`, `--ink-muted`, `--ink-placeholder`, `--ink-secondary`, `--line-input`, `--r-md`, `--r-sm`, `--r-xs`, `--rgb-brand`, `--rgb-brand-deep`, `--rgb-danger`, `--shadow-input`, `--surface-solid`, `--surface-sunken`, `--text-body`, `--text-caption`, `--text-input`, `--text-small`, `--wash-subtle`. ## Accessibility - Wrap it in : Field wires the label, hint and error to the control (id, aria-describedby, aria-invalid) through context, so the control needs no ids of its own. - Placeholder ink holds 4.97:1 on the white box; never put instructions only in a placeholder. - revealable adds a real button inside the box whose name switches between "Show password" and "Hide password" (no aria-pressed, which would read as "Hide password, pressed"). - Set autoComplete on every personal-data field (WCAG 1.3.5). ## Do - Size the box to the content where the content is short (a postcode), with a className width. ## Don't - Don't style the itself; theme the box with --input-* tokens. - Don't show an error before the user has left the field or submitted. Related: https://rime.mjsons.net/components/select, https://rime.mjsons.net/components/textarea, https://rime.mjsons.net/components/search-field --- # Textarea > Multi-line text in the TextInput box, resizable vertically, with an optional character count. Category: Forms. Docs page: https://rime.mjsons.net/components/textarea ## Installation ```bash npx shadcn@latest add KezLahd/rime/textarea ``` Textarea wears the TextInput box and tokens. showCount with maxLength shows a live count that turns to warning ink near the limit. ## Usage ```tsx import { Field, Textarea } from "@/components/ui";