Components
Components
The 60 components in @whyhotel/ui-core-components. Each page renders the live React component with interactive prop controls beside its plain HTML markup, plus the full props and variants tables drawn from the generated manifest.
Accordion
Accordion — a set of stacked sections that each expand or collapse in place to reveal their content. Use it to condense long, scannable content (FAQs, policy details, optional settings) so people see the headings first and open only what they need. It stays in the page flow rather than floating over other content — reach for a Dialog when the content must interrupt the user. Set `allowMultiple` when several sections may be open at once. Triggers are real buttons with `aria-expanded`, and each content region is labelled by its trigger, so it is keyboard- and screen-reader-accessible by default.
Alert
Alert — a static, inline status message that stays on the page to explain a condition or outcome (a warning, a confirmation, an error to resolve). Use it for information tied to a region of the page that the user should notice but that does not demand an immediate modal decision; for transient confirmations that fade on their own, use a Toast instead. Pick the `tone` to match intent — `info`, `success`, `warning`, `danger`, or `brand` — and pass `onDismiss` when the alert should be dismissible. The `danger` tone announces assertively to assistive tech; the others announce politely.
Avatar
Avatar — a small square or circular chip that stands in for a person or entity with a photo or their initials (a guest, a teammate, a property). Use it in lists, headers, and comment rows to make ownership scannable at a glance. Pass `src` for a photo, or set `placeholder` with initials `children` when there is no image; pick a `shape` and `size` to match the surface, and add `status` to show online or offline presence. It is display only — wrap it in a Button or link when it needs to be actionable.
Badge
Badge — a small inline label that tags an element with a short status or count (e.g. "checked in", "3 new"). Use it beside a title, table cell, or list item to surface state at a glance; keep the text to a word or two. Choose a `tone` to signal meaning and a `size` to match the surrounding type, and add `dot` for a leading status dot. It is decorative labelling, not an interactive control — use a Button for actions.
Breadcrumbs
Breadcrumbs — a compact trail showing where a page sits in the hierarchy and a one-tap way back up it. Feed it `items` from root to current; each crumb with an `href` renders as a link, and the last crumb renders as plain text marked `aria-current="page"` so it reads as the place you are. Use it on deep pages (a reservation inside a stay inside a property) to keep orientation cheap; skip it on top-level screens where there is nowhere to go up. Pick a `size` to match the surrounding type, and pass an `icon` on a crumb for a leading glyph. The root is a labelled `<nav>` so assistive tech announces it as the breadcrumb.
Button
Button — the primary way a person triggers an action: submit a form, confirm a choice, or move to the next step. Use `variant` to signal importance — `primary` for the main action on a view, `secondary` for supporting actions, `accent` for an alternative emphasis in the brand accent color, `ghost` for low-emphasis or tertiary actions, and `danger` for destructive ones. Size with `sm`/`md`/`lg`, and set `fullWidth` when the button should span its container (common on mobile and in narrow forms). Keep one primary button per view so the main action stays obvious.
Card
Card — a container that groups related content and actions into a single surface, optionally with a header and footer. Use it to break a page into scannable units — a reservation, a room, a summary — where each unit has its own title, body, and actions. Choose `border` elevation for flat, dense layouts and `shadow` to lift a card off the page; set `interactive` when the whole card is clickable. Adjust `padding` and `tone` to fit the surrounding density and hierarchy.
Carousel
Carousel — a horizontally (or vertically) scrolling track of equal-status slides that snap into place as a person swipes or scrolls. Reach for it to browse a set where each item stands on its own — room photos, nearby attractions, amenity cards — rather than to walk someone through ordered steps. Pass the slides as `items`; each is wrapped in a `.carousel-item`, so give every node a width utility (e.g. `w-full`, `w-64`) in its own className to set how many show at once. Use `snap` to settle slides at the start, center, or end of the viewport, and `orientation="vertical"` for a scroll-down track. It scrolls with native CSS scroll-snap, so it is touch- and keyboard-scrollable with no JavaScript.
Chat
Chat — a single message in a conversation: an optional avatar, a header line, the message bubble, and a footer line. Use it to build message threads (guest messaging, support chat, front-desk handoffs) one entry at a time. Set `side` to place the message — `start` for the other person on the left, `end` for the current user on the right — and add a `tone` to tint the bubble when a message needs emphasis (a confirmation in `success`, an alert in `error`). Pass `header` for the sender and time, `footer` for a receipt, and `avatar` for the speaker's image; keep the bubble content to the message itself.
Checkbox
Checkbox — a single on/off control for an independent boolean choice, such as opting into an email or accepting a policy. Use it when each option stands alone; for one-of-many choices use radio controls, and for a compact on/off setting consider a switch. Supports an `indeterminate` (mixed) state for a "select all" row whose children are partly selected, and a required-true mode for must-check confirmations. Pair it with a `label`, and a `description` when the choice needs a line of explanation.
Countdown
Countdown — an animated number whose digits slide when the value changes, for live counters like the seconds left on a hold, minutes until check-in, or a rooms-remaining tally. Pass a `value` from 0 to 99 and update it over time (usually on an interval) to animate; the digits inherit their scale from the surrounding font size, so wrap it in a text-size utility for a larger display. It is a display element, not a timer — drive the value yourself and keep an accessible label nearby so the count reads clearly to assistive tech.
DataTable
DataTable — a typed, configuration-driven table for presenting rows of structured data (reservations, folios, arrivals) in aligned columns. Define columns once — header, alignment, width, and an optional custom cell renderer — and pass row data; the table handles layout, horizontal scrolling, and the empty state. Use `density="compact"` for dense operational views, and provide `onRowClick` when a row should open its detail. Reach for it whenever data is naturally tabular; for a handful of key/value pairs a simple list is lighter.
Dialog
Dialog — a modal panel that overlays the page to focus the user on a single task or decision (confirm a checkout, complete a short form) and blocks the rest of the UI until it is resolved. Use it when the interaction must interrupt the current flow; for non-blocking status, prefer an inline Alert or a Toast. It traps focus inside the panel, restores focus to the trigger on close, and dismisses on escape or a backdrop click, so keyboard and screen-reader users are handled correctly. Keep dialogs short — a title, one line of context, and a clear primary action.
Diff
Diff — a side-by-side comparison slider that stacks two panes and reveals one over the other as a person drags the handle between them. Use it to hold two versions of the same frame in place — a room before and after a refresh, a photo with and without an edit, two copy treatments — so the difference reads at a glance instead of side by side. Pass any node to `item1` and `item2`: images, text blocks, or whole layouts, as long as both fill the same box. The figure is focusable and the handle is keyboard-resizable, so the comparison works without a mouse. It is a display surface, not a control — reach for a Toggle or Tabs when you need to switch state.
Divider
Divider — a thin rule that separates two blocks of content, optionally with a short label sitting in the gap. Use the default horizontal rule between stacked sections (a folio total above a payment form, "or" between sign-in options), or set `orientation="vertical"` to split two side-by-side items in a flex row. Add a `tone` to tint the rule when the separation carries meaning, and use `placement` to push the label to the start or end. Keep labels lowercase and short; it is a separator, not a heading.
Dock
Dock — a fixed bar of destinations pinned to the bottom of the viewport, the primary way to move between the top-level areas of a mobile-first app (stays, calendar, keys, account). Feed it an `items` array of a label and optional icon, mark the current area with `active`, and handle taps with `onSelect`. Keep it to three to five destinations so each stays a comfortable tap target, and match `size` to the surrounding density. Each destination is a real `<button>` and the active one carries `aria-current`, so it is keyboard- and screen-reader-navigable by default.
Drawer
Drawer — a panel that slides in from the edge of the screen over the current view, dimming the main content behind an overlay. Use it for secondary navigation, filters, or a folio summary that should appear on demand without a full page change — reach for a Dialog when the task must be completed before anything else. It is uncontrolled by default: set `defaultOpen` and listen with `onOpenChange`, or pass `open` to drive it yourself. Clicking the overlay closes the panel, and the overlay carries a `close sidebar` label so it stays reachable by assistive tech. Set `placement="end"` to slide it from the trailing edge.
Dropdown
Dropdown — a button that reveals a small floating panel of actions or links beneath (or beside) it. Use it to tuck away secondary actions — a row's overflow menu, an account switcher, a "more" list — so the surface stays calm until someone asks for the options. It is built on the native `<details>`/`<summary>` disclosure, so it opens on click or Enter/Space, closes on Escape or an outside click, and needs no extra ARIA. Set `placement` to anchor the panel (bottom by default), `hover` to open it on pointer hover, and pass `open` only when you need to drive visibility from your own state. Fill the panel with a `menu` list of links or Buttons — keep it short and scannable.
Fab
Fab — a floating action button that pins the single most important action to the bottom-right of a view, then fans out into a speed-dial of related actions on focus or hover. Reach for it on task-focused screens (a reservation, a folio, a housekeeping board) where one action dominates — compose, add, check in — and a few supporting ones should stay one tap away without crowding the layout. Pass `icon` for the trigger glyph and `triggerLabel` for its accessible name; feed `actions` to reveal labelled buttons, and set `mainAction` when a primary affordance should slide into the trigger's place as the dial opens. The reveal is CSS-driven via `:focus-within`, so it is keyboard-reachable by default. Keep one Fab per view so the main action stays unmistakable.
Fieldset
Fieldset — a labelled wrapper that groups related fields into one section of a form, such as guest details or payment. Give it a `legend` for the section heading and an optional `label` caption to explain what the group is for, then pass the fields as children; it lays them out in a tidy vertical stack. Reach for it whenever a form has more than a handful of inputs and benefits from being read in chunks — it is structure, not a control, so it holds inputs but never carries a value of its own. Keep the legend to a short noun phrase and the caption to a single helpful line.
FileInput
FileInput — a field for picking one or more files from the device, such as a folio PDF, an ID scan, or a room photo. It reports the raw `FileList` through `onChange`, so the caller owns reading, previewing, and uploading. Set `accept` to constrain the file types and `multiple` to allow more than one, and mark `invalid` to show the error state when validation fails. Size with `sm`/`md`/`lg` to match the surrounding form, or use `ghost` for a borderless field on a tinted panel. Pair it with a form field for the label, help text, and error message.
Filter
Filter — a compact row of buttons for narrowing a list to one facet at a time: a room type, a rate plan, a reservation status. It renders as a radio group, so only one option is ever active, and a reset control appears once a choice is made to clear back to "all". Use it above a results list where the choices are few and worth showing at a glance; reach for a Select when the options are many or space is tight. Leave it uncontrolled to let it track its own selection, or pass `value` and `onChange` to drive it from state. Every option is a real labelled radio, so it is keyboard- and screen-reader-friendly.
Footer
Footer — the page's closing landmark, holding link columns, contact details, or a copyright line at the bottom of a view. Supply the columns as children (each a `<nav>` with a `footer-title` heading and `link link-hover` links); the Footer owns the grid so the columns align and space evenly. Use `orientation="horizontal"` to lay the columns in a row on wide surfaces, and `center` for a single-column, centered footer such as a copyright strip. It is a `<footer>` landmark, not a navigation bar — reach for it at the end of the page, not the top.
Header
Header — a section or page heading rendered in the theme's display type roles. Use `variant` to set the visual level: `display` for a hero or page title, `headline` for a major section, `title` for a card or subsection (the default), and `subtitle` for a secondary line paired with a title. The variant also picks a sensible heading element (h1–h4); override it with `as` (h1–h6) to keep the document outline correct when the visual size and the semantic level differ.
Hero
Hero — a full-width banner that opens a page with a headline, a line of copy, and a call to action, centered over a background. Use it once at the top of a landing or confirmation view to set the scene (a property photo behind a "your stay is booked" message); reach for a Card for anything smaller or repeated. Set `overlay` when a background image sits behind the content so the text stays legible, and set the image itself via `className` or `style` on the root. Keep the content to one idea — a heading, a sentence, one primary action.
Indicator
Indicator — a wrapper that pins a small badge or dot to a corner of whatever it wraps, so a count or status floats over an avatar, button, or card without shifting the layout. Use it to surface an unread count, a "new" flag, or a live status next to the thing it describes; pass the pinned node as `indicator` (usually a Badge) and the anchored content as `children`. Place it with the `vAlign` (top/middle/bottom) and `hAlign` (start/center/end) axes — top-end by default, the conventional notification corner. It only positions; the meaning lives in the node you pin, so keep that label short.
Input
Input — a single-line text field bound to `value`/`onChange` for capturing short free-form entries such as a name, email, or phone number. Choose the `type` (email, password, number, tel, …) to get the right keyboard and native validation, and set `invalid` to show the error state when validation fails. Size with `sm`/`md`/`lg` to match the surrounding form. Pair it with a form field for the label, help text, and error message; use a Select instead when the value must come from a fixed set of options.
Join
Join — groups a set of controls into a single segmented unit, squaring the inner corners and collapsing the shared borders so a button cluster or an input + button reads as one control (think a search field with a "go" button, or a paginator). Set `orientation` to `vertical` to stack the segments into a column instead of the default row. Join only groups and sets direction: every child supplies its own `join-item` class, either on the raw element or through a library component's `className` passthrough. Reach for it when adjacent controls act as one; use plain spacing when they are independent.
Kbd
Kbd — an inline key cap that shows a single keyboard input inside body copy (e.g. "press ⌘ K to search"). Use it in help text, tooltips, and command hints to name a key or a step in a shortcut; chain several with a "+" between them for a combination. Pick a `size` to match the surrounding type — xs and sm sit inside dense captions, md (the default) rides normal text, lg suits a standalone hint. It is a label, not a control — use a Button for something a person can click.
Label
Label — a short inline text accent rendered in the theme's small type roles. Use `label` (the default) for form-field and control labels, `caption` for secondary helper text beside a value, and `eyebrow` for the uppercase kicker that sits above a heading. It renders a `<span>`, so it stays inline; for a form control's actual `<label>` element, pass it as that field's label.
Link
Link — an inline text anchor for navigating somewhere else, whether that's another view, an external page, or an anchor further down the page. Reach for it inside running copy where a Button would feel heavy — "read the house rules", "manage your reservation". By default it inherits the theme's Cabana color that darkens toward Midnight on hover; set a `tone` to match a feedback context (say `danger` for a cancel-and-lose-your-hold path), and set `hover` to hold the underline until someone hovers, keeping dense copy calm. It's for navigation, not actions — use a Button to submit, save, or trigger something.
List
List — a vertical stack of rows that each pair optional media with a title, an optional subtitle, and optional trailing actions. Reach for it to lay out scannable records — reservations, room assignments, folio line items, teammates — where every row shares the same shape. Feed it a `items` array and it renders a divided `<ul>`; the title column grows to fill the width while media and actions hug their content. It is display, not navigation — wrap a row's title or an action in a link or Button when a row should be interactive.
Loading
Loading — an inline, self-animating indicator that signals a short, indefinite wait (fetching a folio, confirming a reservation). Drop it wherever content is pending; pick a `variant` for the shape, a `size` to match the surrounding type, and an optional `tone` to color it — otherwise it inherits the current text color. It carries `role="status"` and an `aria-label` so screen readers announce the wait; keep that label short and specific. For a wait tied to a button press, prefer the Button `loading` prop; reach for Loading when the spinner stands on its own.
Mask
Mask — clips its content to a decorative shape (squircle, circle, hexagon, star, heart, and more). Wrap a photo, avatar, or colored block to soften a grid of thumbnails or dress up a single hero image; the `shape` prop picks the silhouette and the caller sizes the mask through `className` (the clip scales to fit). Reach for `squircle` or `circle` for avatars and headshots, and the playful shapes sparingly for accents. It is pure decoration — never rely on the shape alone to convey meaning.
Menu
Menu — a vertical (or horizontal) list of navigation rows: links, section titles, and parents that reveal a nested submenu. Feed it an `items` tree and it renders the DaisyUI markup for you, marking the current row with `active`, dimming unavailable rows with `disabled`, and grouping rows under a `title` heading. Use it for sidebars, account navs, and folio sections; pick an `orientation` and `size` to fit the surface. Submenus are native `<details>` disclosures, so they expand and collapse by keyboard and pointer without extra wiring. Keep labels short and verb- or noun-first (check in, room keys, folio).
MockupBrowser
MockupBrowser — a decorative browser frame that wraps a screenshot or live preview in familiar window chrome, complete with a toolbar and address field. Use it in docs, marketing, and onboarding to show what a page looks like in a real browser without a real browser. Pass a `url` to label the address bar (e.g. a booking or check-in link) and put the page itself in `children`. It is a frame, not a viewport — it renders whatever you give it and adds no behavior.
MockupCode
MockupCode — a terminal-style frame that shows a short block of commands or code, complete with the window chrome and a gutter for per-line prefixes. Use it in docs and onboarding to demonstrate a command someone runs (`$ yarn install`) or the output they should expect; pass a `prefix` per line for the `$`/`>` markers and a `className` like `text-warning` to tint a status line. It is illustrative, not interactive — reach for a real code editor or copyable snippet when people need to run the commands themselves.
MockupPhone
MockupPhone — a phone-shaped device frame that wraps a preview so a screen looks like it is running on a handset. Use it in marketing pages, onboarding tours, or a styleguide to show a mobile flow in context — a booking confirmation, the room keys screen, a folio — without hand-drawing a bezel. Drop any content in as `children`: a screenshot `<img>`, an embedded page, or live components; the frame clips it to the rounded display and adds the camera notch. It is pure chrome, not an interactive control, so it carries no color axis — the screen supplies all the color.
MockupWindow
MockupWindow — a browser/app window frame for showing a screenshot or a live UI preview in context, complete with the title-bar dots. Use it in docs, onboarding, or marketing surfaces to present a screen as if captured in its own window — for example framing the guest check-in flow or a folio summary. Drop the content in as `children` and shape the inner panel (centering, height, padding) with `contentClassName`. It is a static frame, not an interactive window — the dots are decorative, so use real controls for anything a person needs to act on.
Navbar
Navbar — the horizontal bar across the top of a view that holds the brand, the primary navigation, and account or page actions. Fill any of three regions — `start`, `center`, `end` — and the bar spaces them apart; a region stays out of the DOM until you give it content, so a brand-plus-actions bar needs only `start` and `end`. It renders as a labelled navigation landmark, so drop links, a Button, or a Dropdown straight in. Keep it to one per view and reserve the `center` slot for a title or the main links, not a second row of actions.
Pagination
Pagination — lets a person move through a long, paged list (search results, a reservations table, an activity log) one page at a time. It renders a joined row of page buttons: the first and last page always show, a window sits around the current page, and `…` fills any gap so the control stays compact at scale. It is controlled — pass the current `page` and update it from `onPageChange` — and `siblingCount` widens the window around the current page. Size with `sm`/`md`/`lg` to match the surrounding density. The active page is marked with `aria-current="page"` and the whole row is a labelled navigation landmark, so it is screen-reader-accessible by default.
Progress
Progress — a slim horizontal bar that shows how far along a task is, from an upload to a multi-step check-in flow. Give it a `value` from 0 to `max` (100 by default) to fill the track; omit `value` for an indeterminate bar that animates while the amount of work is still unknown. Choose a `tone` to match the context — primary for a neutral task, success when it is nearly done, warning or danger to flag trouble. It is a status display, not a control — pair it with nearby text for the exact numbers.
RadialProgress
RadialProgress — a circular gauge that shows how far along a value is, from 0 to 100 (e.g. profile completeness, an upload, nights checked in). Pass `value` and it fills the ring and prints the percentage in the center; supply `children` to label it with something else, and `size`/`thickness` to fit the surface. Choose a `tone` to signal meaning — the ring paints with the theme color, so no colors are hard-coded. It reports progress as an ARIA `progressbar`; it is a display, not a control — use a slider for input.
Radio
Radio — a single control for a one-of-many choice, such as picking a rate plan or a room type. Use it when exactly one option in a set may be selected; for an independent on/off choice use a checkbox, and for a compact setting consider a switch. Radios are grouped by sharing the native `name` prop across the set, so selecting one clears the rest. Pair each with a `label`, and a `description` when the option needs a line of explanation.
Range
Range — a slider for picking a single number from a continuous span, such as a price ceiling, a party size, or a number of nights. Set `min`/`max`/`step` to bound and quantize the values, and read the choice through `onChange`, which hands back a plain number. Size with `xs`/`sm`/`md`/`lg` to match the surrounding form, and give it a `tone` to tint the filled track and thumb with a color role. Reach for a Range when the exact figure matters less than the sense of more-or-less; use an Input of type number when a person needs to type a precise value. Pair it with a form field for the label and a live read-out of the current value.
Rating
Rating — a row of stars for capturing or showing a score, such as how a guest rated their stay. Use it for a small, bounded scale (typically five) where the shape carries the meaning at a glance; for longer or non-symbolic scales reach for a slider or a select. It is a controlled input: pass `value` and handle `onChange`, which fires the chosen number. A leading clear input lets someone reset to no rating (`0`), `half` enables half-star precision, and `shape` swaps stars for hearts when you want a favorite rather than a score. Each star is a real radio sharing one group name, so it is keyboard- and screen-reader-friendly.
Select
Select — a dropdown for choosing one value from a fixed set of options (an arrival window, a room type, a status). Use it when the options are known and mutually exclusive and there are more than a couple of them; for two or three choices consider radios, and for many searchable options a typeahead. Pass `options` as strings or `{value, label}` pairs and a `placeholder` for the empty prompt, and set `invalid` to show the error state. Pair it with a form field for the label and error surface.
Skeleton
Skeleton — a shimmering placeholder that stands in for content while it loads, so the layout holds its shape instead of jumping when data arrives. Size it with `className` (Tailwind width/height/rounded utilities) to mirror the real element it replaces — a line of text, an avatar, a card — and set `shape="circle"` for round placeholders. Render one per incoming element and swap it for the real content once loaded; it is purely decorative, marked `aria-busy` so assistive tech announces the pending state rather than reading an empty box.
Stack
Stack — a layout container that lays its children in one cell so they overlap, front to back, with the ones behind peeking out. Use it to imply a pile or a count without a real list: a shuffle of key cards, a run of notification toasts, a couple of stacked receipts on a folio. The first child sits on top; give `placement` an edge (top, bottom, start, end) to choose which way the layers behind fan out. It is decorative arrangement, not a carousel — reach for a proper list or Carousel when the layers need to be read or navigated.
Stat
Stat — a compact group of headline metrics, each a title, a big value, and an optional supporting line. Use it to surface the numbers that matter at a glance — occupancy, revenue, nights booked — across the top of a dashboard or summary. Pass `orientation="vertical"` to stack the blocks in a narrow column instead of flowing them across. Hang an icon or badge off `figure` to give a metric a visual anchor. Keep titles short and lowercase, and let the value do the talking.
Status
Status — a tiny inline dot that signals the live state of a nearby thing (e.g. a room is available, a guest is checked in, a sync is running). Use it beside a label, avatar, or list row to surface state at a glance without taking up space. Choose a `tone` to carry the meaning and a `size` to match the type around it. It is a decorative indicator with no text of its own, so always give it an `aria-label`; for an action use a Button, and for a labelled tag use a Badge.
Steps
Steps — an ordered tracker that shows where someone is in a multi-part flow and how much is left, laid out as numbered nodes joined by connectors. Reach for it on a checkout, onboarding, or check-in wizard so people can see the whole path at a glance. Pass `items` for the sequence and `current` to mark the active step — every step up to and including it takes the `tone` color, the rest stay muted. Set `orientation` to `vertical` for a stacked layout in narrow columns, and give an item an `icon` to replace its auto number with a glyph. It is a status display, not a set of controls — use Tabs or a Button when a person needs to move between steps directly.
Swap
Swap — a single control that flips between two faces in place, such as play/pause, menu/close, or a lights-on/lights-off setting. Use it when one tap moves between two mirrored states and you want the transition to read as motion rather than a jump; for a labelled on/off form setting reach for a toggle instead. Choose the `effect` axis to spin the faces (`rotate`, the default) or turn them over (`flip`). It drives a real hidden checkbox, so it toggles on click and by keyboard and reports back through `onChange`. Keep the two faces the same size so nothing shifts as they trade places.
Tabs
Tabs — a horizontal set of views that share a region, where selecting a tab swaps the panel below it. Use tabs to divide related content into a few peer sections the user moves between (arrivals / departures / in-house) without leaving the page; don't use them for sequential steps — use a stepper — or for primary navigation. Choose the `underline` variant for in-page section switching and `pill` for a more contained, toolbar-like grouping. Left/Right and Home/End move focus and selection between enabled tabs, following the ARIA tablist pattern.
Textarea
Textarea — a multi-line text field bound to `value`/`onChange` for capturing longer free-form entries such as a guest note, special request, or feedback. Set `rows` to size the visible height, and set `invalid` to show the error state when validation fails. Size with `sm`/`md`/`lg` to match the surrounding form. Pair it with a form field for the label, help text, and error message; use an Input instead when a single line is enough.
TextBlock
TextBlock — a paragraph of body copy rendered in the theme's body type roles. Use it for readable running text — descriptions, help text, empty-state explanations. `regular` is the default; `small` steps the size down for dense or secondary passages. It renders a `<p>`, so use one TextBlock per paragraph rather than stacking line breaks.
Timeline
Timeline — an ordered track of events connected by a running line, each with an icon on the line and detail to one or both sides. Use it to show a sequence in time (a reservation's lifecycle, a stay's check-in to check-out, a delivery's status) so people can follow what happened and what comes next. Feed it an `items` array: each event supplies a `start` label, a `middle` marker, and an `end` detail, and the connectors between events are drawn for you. Set `orientation` to run it horizontally, `compact` to keep every event on one side, and clear an item's `boxed` flag when its detail should sit inline instead of in a card. It is read-only structure, not a control — reach for Steps when a person is moving through a process.
Toast
Toast — a brief, self-dismissing notification that confirms the result of an action ("request sent", "changes saved") without interrupting what the user is doing. Use it for transient, low-stakes feedback that does not need acknowledgement; for information that must persist on the page use an Alert, and for a decision that must block the flow use a Dialog. Set the `tone` to match the outcome and keep the message to one short line, optionally with a single inline action such as undo.
Toggle
Toggle — a switch for a setting that takes effect immediately, such as turning on housekeeping alerts or opting into text updates. Reach for it when the choice is a self-contained on/off with an obvious default; for choosing among options use radio controls, and for a boolean that only applies once a form is submitted prefer a checkbox. Tint the checked track with `tone` to match the surrounding context, and pair it with a `label`, adding a `description` when the setting needs a line of explanation.
Tooltip
Tooltip — a small hover/focus hint that explains the trigger it wraps (e.g. a terse icon button, a truncated folio line, a status badge). Wrap the trigger as `children` and pass the hint as `tip`; a string tip rides the `data-tip` attribute, while a richer node renders in a `.tooltip-content` bubble. Move it with `placement`, colour it with `tone` to echo the surface it annotates, and set `open` to pin it visible for a walkthrough or a screenshot. Keep tips to a phrase — they supplement the UI, they are not where the real content lives.