Add a screenshot, product preview, media block, chart, form, or illustration.
`;
const shellPreview = `
Header slotPublic page content
`;
// Markup rendered beside the mount instead of inside its slot -- for host
// components that have no slot but need controls to demonstrate them.
const withBefore =
(before) =>
(title, description, props = {}, slots = {}) => ({
eyebrow: "Recommended",
title,
description,
props,
slots,
before,
});
const standard = (title, description, props = {}, slots = {}) => ({
eyebrow: "Recommended",
title,
description,
props,
slots,
});
const compact = (title, description, props = {}, slots = {}) => ({
eyebrow: "Compact",
title,
description,
props,
slots,
});
const advanced = (title, description, props = {}, slots = {}) => ({
eyebrow: "Advanced",
title,
description,
props,
slots,
});
const TOASTER_DEMO_BUTTONS =
'';
const DATATABLE_COLUMNS_PLAIN =
'[{"key": "name", "label": "Account", "sortable": true}, {"key": "plan", "label": "Plan", "sortable": true}, {"key": "owner", "label": "Owner"}, {"key": "seats", "label": "Seats", "align": "end", "sortable": true}, {"key": "status", "label": "Status", "align": "center"}]';
const DATATABLE_COLUMNS_NARROW =
'[{"key": "name", "label": "Account", "sortable": true, "width": "40%"}, {"key": "seats", "label": "Seats", "align": "end", "sortable": true, "width": "20%"}, {"key": "plan", "label": "Plan", "align": "center", "width": "20%"}, {"key": "status", "label": "Status", "align": "end", "width": "20%"}]';
const DATATABLE_COLUMNS_INBOX =
'[{"key": "owner", "label": "From", "sortable": true}, {"key": "name", "label": "Subject", "sortable": true}, {"key": "plan", "label": "Folder", "align": "center"}, {"key": "statusHtml", "label": "State", "align": "center", "html": true}]';
const DATATABLE_COLUMNS_COMPARE =
'[{"key": "name", "label": "Plan"}, {"key": "plan", "label": "Tier"}, {"key": "owner", "label": "Owner"}, {"key": "seats", "label": "Seats", "align": "end", "type": "number"}, {"key": "status", "label": "Status", "align": "center"}]';
const DATATABLE_ACTIONS =
'[{"id": "refresh", "label": "Refresh", "icon": "icon-[lucide--refresh-cw]", "when": "always"}, {"id": "read", "label": "Mark as read", "icon": "icon-[lucide--mail-open]", "when": "selection"}, {"id": "archive", "label": "Archive", "icon": "icon-[lucide--archive]", "when": "selection"}, {"id": "delete", "label": "Delete", "icon": "icon-[lucide--trash-2]", "when": "selection", "tone": "danger"}]';
const DATATABLE_COLUMNS =
'[{"key": "name", "label": "Account", "sortable": true}, {"key": "plan", "label": "Plan", "sortable": true}, {"key": "owner", "label": "Owner"}, {"key": "seats", "label": "Seats", "align": "end", "sortable": true}, {"key": "statusHtml", "label": "Status", "align": "center", "html": true}]';
const DATATABLE_ROWS =
'[{"id": 1, "name": "Northwind", "plan": "Scale", "owner": "A. Okafor", "seats": 6, "status": "Active", "statusHtml": "Active"}, {"id": 2, "name": "Acme Industrial", "plan": "Team", "owner": "R. Silva", "seats": 13, "status": "Trial", "statusHtml": "Trial"}, {"id": 3, "name": "Globex", "plan": "Enterprise", "owner": "M. Chen", "seats": 20, "status": "Past due", "statusHtml": "Past due"}, {"id": 4, "name": "Initech", "plan": "Starter", "owner": "J. Dubois", "seats": 27, "status": "Active", "statusHtml": "Active"}, {"id": 5, "name": "Umbrella", "plan": "Scale", "owner": "P. Novak", "seats": 34, "status": "Trial", "statusHtml": "Trial"}, {"id": 6, "name": "Stark Labs", "plan": "Team", "owner": "A. Okafor", "seats": 41, "status": "Past due", "statusHtml": "Past due"}, {"id": 7, "name": "Wayne Foods", "plan": "Enterprise", "owner": "R. Silva", "seats": 48, "status": "Active", "statusHtml": "Active"}, {"id": 8, "name": "Soylent", "plan": "Starter", "owner": "M. Chen", "seats": 55, "status": "Trial", "statusHtml": "Trial"}, {"id": 9, "name": "Hooli", "plan": "Scale", "owner": "J. Dubois", "seats": 62, "status": "Past due", "statusHtml": "Past due"}, {"id": 10, "name": "Vehement", "plan": "Team", "owner": "P. Novak", "seats": 69, "status": "Active", "statusHtml": "Active"}, {"id": 11, "name": "Massive Dynamic", "plan": "Enterprise", "owner": "A. Okafor", "seats": 76, "status": "Trial", "statusHtml": "Trial"}, {"id": 12, "name": "Cyberdyne", "plan": "Starter", "owner": "R. Silva", "seats": 83, "status": "Past due", "statusHtml": "Past due"}, {"id": 13, "name": "Tyrell", "plan": "Scale", "owner": "M. Chen", "seats": 90, "status": "Active", "statusHtml": "Active"}, {"id": 14, "name": "Aperture", "plan": "Team", "owner": "J. Dubois", "seats": 97, "status": "Trial", "statusHtml": "Trial"}, {"id": 15, "name": "Black Mesa", "plan": "Enterprise", "owner": "P. Novak", "seats": 104, "status": "Past due", "statusHtml": "Past due"}]';
export const componentProfiles = {
Accordion: {
demos: [
standard(
"Plain disclosure rows",
"Unframed questions with trailing chevrons and aligned answers.",
{},
),
compact("Bordered group", "One shared border with leading indicators.", {}),
advanced("Separate panels", "Individually framed rows; multiple answers can stay open.", {}),
],
},
Alert: {
demos: [
standard("Success message", "A concise confirmation that can be dismissed.", {}),
compact("Informational notice", "One useful message without unnecessary actions.", {}),
advanced("Action required", "A warning with one relevant next step.", {}),
],
},
Carousel: {
demos: [
standard(
"Full-width, unframed",
"An edge-to-edge carousel without a card, border, or outer padding.",
{ framed: false },
),
compact(
"Framed gallery",
"Opt into a contained gallery when the surrounding layout needs it.",
{ framed: true },
),
advanced("Draggable slides", "Move between slides with dragging, arrows, or pagination.", {
framed: false,
isDraggable: true,
}),
],
},
Navbar: {
demos: [
standard(
"Brand, links and actions",
"The everyday shape: a brand, a row of links with the current page marked, and calls to action on the right. Arrow keys move along the menu bar.",
{
brand: { label: "Northwind", description: "Console", href: "/" },
items: [
{ label: "Overview", href: "/", value: "overview" },
{ label: "Projects", href: "/projects", value: "projects" },
{ label: "Reports", href: "/reports", value: "reports" },
],
actions: [
{ label: "Sign in", href: "/login", variant: "link" },
{ label: "Start free", href: "/signup", variant: "primary" },
],
active: "projects",
label: "Primary navigation",
},
),
advanced(
"Dropdown and mega panel",
"An item carrying children opens a panel built from native details and summary, so it is keyboard operable without any extra script. Give a child its own children to get a titled column inside the panel.",
{
brand: { label: "Northwind", icon: "icon-[lucide--box]", href: "/" },
items: [
{ label: "Overview", href: "/", value: "overview" },
{
label: "Products",
value: "products",
columns: 2,
description: "Everything in the platform.",
children: [
{
label: "Platform",
children: [
{
label: "Runtime",
href: "/runtime",
description: "The browser half.",
icon: "icon-[lucide--cpu]",
},
{
label: "Compiler",
href: "/compiler",
description: "WRN to JavaScript.",
icon: "icon-[lucide--hammer]",
},
],
},
{
label: "Tooling",
children: [
{ label: "CLI", href: "/cli", description: "Scaffold and deploy." },
{ label: "Editor", href: "/editor", description: "Language server." },
],
},
],
},
{ label: "Pricing", href: "/pricing", value: "pricing" },
],
actions: [{ label: "Book a demo", href: "/demo", variant: "primary" }],
active: "overview",
},
),
compact(
"Sticky and compact",
"Sticky keeps the bar pinned while the page scrolls. The toggle appears below the tablet breakpoint and the links collapse behind it.",
{
brand: { label: "Acme", href: "/" },
items: [
{ label: "Docs", href: "/docs", value: "docs" },
{ label: "Support", href: "/support", value: "support" },
],
actions: [{ label: "Dashboard", href: "/app", variant: "primary" }],
active: "docs",
sticky: true,
size: "sm",
mobileLabel: "Toggle navigation",
},
),
],
},
LayoutSplitter: {
demos: [
standard(
"Drag or arrow the divider",
"Two panes with a movable divider. Drag it, or focus it and use the arrow keys; Home and End go to the bounds. The size is resolved in the runtime and written onto the container as a custom property, because a pointermove fires far too often to route through a client function.",
{ size: 40, minSize: 20, step: 5, orientation: "horizontal", label: "Resize panels" },
),
advanced(
"Stacked panes",
"Vertical orientation splits top from bottom and switches the arrow keys to up and down. Below the small breakpoint both orientations stack, because two panes side by side stop making sense on a phone.",
{ size: 60, minSize: 25, step: 10, orientation: "vertical", label: "Resize rows" },
),
],
},
CustomScrollbar: {
demos: [
standard(
"Themed scrolling region",
"Scrollbar appearance is CSS rather than script: scrollbar-width and scrollbar-color are the standard properties, with webkit rules for the engines that still need them. The thumb follows the component colour.",
{ axis: "vertical", thickness: 8, maxHeight: "14rem", radius: "999px" },
{
default: `
Line 1. A scrolling region only shows its scrollbar when the content actually overflows, so this demo ships enough of it.
Line 2. A scrolling region only shows its scrollbar when the content actually overflows, so this demo ships enough of it.
Line 3. A scrolling region only shows its scrollbar when the content actually overflows, so this demo ships enough of it.
Line 4. A scrolling region only shows its scrollbar when the content actually overflows, so this demo ships enough of it.
Line 5. A scrolling region only shows its scrollbar when the content actually overflows, so this demo ships enough of it.
Line 6. A scrolling region only shows its scrollbar when the content actually overflows, so this demo ships enough of it.
Line 7. A scrolling region only shows its scrollbar when the content actually overflows, so this demo ships enough of it.
Line 8. A scrolling region only shows its scrollbar when the content actually overflows, so this demo ships enough of it.
Line 9. A scrolling region only shows its scrollbar when the content actually overflows, so this demo ships enough of it.
Line 10. A scrolling region only shows its scrollbar when the content actually overflows, so this demo ships enough of it.
Line 11. A scrolling region only shows its scrollbar when the content actually overflows, so this demo ships enough of it.
Line 12. A scrolling region only shows its scrollbar when the content actually overflows, so this demo ships enough of it.
`,
},
),
advanced(
"Horizontal, thicker track",
"A horizontal region with a heavier track. thickness is clamped, since it arrives as an attribute and a scrollbar wider than its content helps nobody.",
{ axis: "horizontal", thickness: 14, maxHeight: "8rem", radius: "4px", color: "info" },
{
default: `
`,
},
),
],
},
Scrollspy: {
demos: [
{
eyebrow: "Recommended",
title: "Follows the reader",
description:
"Scroll the page and the marker moves to whichever section is in view. The sections below are real page content, because the runtime observes against the viewport -- a table of contents inside a small scrolling box would have nothing to react to.",
before:
'
Overview
Scroll this page and watch the marker in the list move. The runtime observes these sections against the viewport, so the current link follows whatever you are reading.
Installation
Each link points at one of these ids. Nothing is connected up by hand -- the component only renders the links, and the runtime moves aria-current.
Usage
The active link is marked with aria-current="location", which is what a screen reader announces, and styled through data-active.
API
Clicking a link jumps to its section and marks it immediately, so the control responds even before the scroll settles.
',
props: {
heading: "On this page",
items: [
{ label: "Overview", href: "#overview" },
{ label: "Installation", href: "#installation" },
{ label: "Usage", href: "#usage" },
{ label: "API", href: "#api" },
],
active: "#overview",
},
slots: {},
},
advanced(
"Compact rail",
"On a phone the rail becomes a horizontal strip that scrolls, so a long contents list costs one line rather than a screenful.",
{
heading: "Sections",
size: "sm",
items: [
{ label: "Overview", href: "#overview" },
{ label: "Installation", href: "#installation" },
{ label: "Usage", href: "#usage" },
],
active: "#installation",
},
),
],
},
MegaMenu: {
demos: [
standard(
"Grouped columns",
"One level deep by design: a mega menu shows breadth flat so everything is one click away. Nesting inside the panel would bury content behind hover-within-hover. Use Nav when you want cascading submenus.",
{
label: "Products",
icon: "icon-[lucide--box]",
columns: [
{
heading: "Platform",
items: [
{
label: "Runtime",
href: "/runtime",
description: "The browser half of the framework.",
},
{ label: "Compiler", href: "/compiler", description: "WRN to JavaScript." },
],
},
{
heading: "Tooling",
items: [
{ label: "CLI", href: "/cli", description: "Scaffold, build and deploy." },
{ label: "Editor", href: "/editor", description: "Language server and syntax." },
],
},
],
},
),
advanced(
"With a footer note",
"The panel is anchored, so the runtime clamp pulls it back inside the viewport instead of letting it hang off a wide layout. On a phone it stops floating and joins the flow.",
{
label: "Solutions",
columns: [
{
heading: "By team",
items: [
{ label: "Engineering", href: "/eng", icon: "icon-[lucide--code]" },
{ label: "Design", href: "/design", icon: "icon-[lucide--palette]" },
{ label: "Support", href: "/support", icon: "icon-[lucide--life-buoy]" },
],
},
{
heading: "By size",
items: [
{ label: "Startup", href: "/startup" },
{ label: "Enterprise", href: "/enterprise" },
],
},
],
footer: "Not sure where to start? Talk to us.",
},
),
],
},
Sidebar: {
demos: [
standard(
"Groups and nested levels",
"An entry is a single link, a labelled group, or a branch nested up to three levels. Arrow keys move down the rail.",
{
label: "Workspace",
items: [
{ label: "Dashboard", href: "/", value: "dash", icon: "icon-[lucide--gauge]" },
{
heading: "Projects",
items: [
{ label: "Active", href: "/active", value: "active", badge: "4" },
{
label: "Archive",
value: "archive",
items: [
{ label: "2025", href: "/a/2025", value: "a2025" },
{ label: "2024", href: "/a/2024", value: "a2024" },
],
},
],
},
{
heading: "Account",
items: [
{
label: "Settings",
href: "/settings",
value: "settings",
icon: "icon-[lucide--settings]",
},
],
},
],
active: "active",
},
),
advanced(
"Drawer on small screens",
"Below the tablet breakpoint the rail is replaced by a launcher that opens a Drawer. Composing Drawer rather than reimplementing it means the focus trap and the body scroll lock come from one place.",
{
label: "Operations",
mobileLabel: "Open navigation",
drawerTitle: "Operations",
items: [
{ label: "Queue", href: "/queue", value: "queue", icon: "icon-[lucide--inbox]" },
{
label: "Reports",
href: "/reports",
value: "reports",
icon: "icon-[lucide--chart-no-axes-column]",
},
],
active: "queue",
},
),
],
},
Nav: {
demos: [
standard(
"Horizontal links",
"A flat link bar. The active item is marked with aria-current, and the arrow keys move between items.",
{
items: [
{ label: "Home", href: "/", value: "home", icon: "icon-[lucide--house]" },
{ label: "Inbox", href: "/inbox", value: "inbox", badge: "9" },
{ label: "Reports", href: "/reports", value: "reports" },
{ label: "Archive", href: "/archive", value: "archive", disabled: true },
],
active: "inbox",
},
),
advanced(
"Nested submenus",
"An item carrying its own items array opens a submenu on hover or focus, to a maximum of three levels. On a phone the submenus stack inline instead of floating, because a hover-opened overlay is unreachable on touch.",
{
items: [
{ label: "Home", href: "/", value: "home" },
{
label: "Products",
value: "products",
items: [
{ label: "Overview", href: "/p", value: "p-overview" },
{
label: "Platform",
value: "p-platform",
items: [
{ label: "Runtime", href: "/p/runtime", value: "runtime" },
{ label: "Compiler", href: "/p/compiler", value: "compiler" },
],
},
],
},
],
active: "p-overview",
},
),
standard("Vertical rail", "Vertical orientation switches the arrow keys to up and down.", {
items: [
{ label: "Dashboard", href: "/", value: "dash", icon: "icon-[lucide--gauge]" },
{ label: "Team", href: "/team", value: "team", icon: "icon-[lucide--users]" },
{
label: "Settings",
href: "/settings",
value: "settings",
icon: "icon-[lucide--settings]",
},
],
active: "team",
orientation: "vertical",
collapsible: false,
}),
],
},
Stepper: {
demos: [
standard(
"Horizontal progress",
"Steps before the active one read as complete, the active one is highlighted, and the rest are muted.",
{
steps: [
{ label: "Account", description: "Your details" },
{ label: "Billing", description: "Payment method" },
{ label: "Confirm", description: "Review and submit" },
],
active: 1,
clickable: false,
showPanel: false,
controls: false,
allowSkip: false,
nextDisabled: false,
backLabel: "Back",
nextLabel: "Next",
skipLabel: "Skip",
finishLabel: "Finish",
},
),
standard(
"Vertical with icons",
"Vertical orientation suits a sidebar or a narrow column. Any step may carry an iconify class instead of its number.",
{
steps: [
{ label: "Cloned", icon: "icon-[lucide--git-branch]" },
{ label: "Built", icon: "icon-[lucide--hammer]" },
{ label: "Deployed", icon: "icon-[lucide--rocket]" },
],
active: 2,
orientation: "vertical",
clickable: false,
showPanel: false,
controls: false,
allowSkip: false,
nextDisabled: false,
backLabel: "Back",
nextLabel: "Next",
skipLabel: "Skip",
finishLabel: "Finish",
},
),
advanced(
"Wizard with content and controls",
"showPanel renders each step body and shows only the active one, the same contract Tabs uses. controls adds Back, Skip and Next, which becomes Finish on the last step.",
{
steps: [
{ label: "Account", title: "Your details", content: "Name, email and a password." },
{ label: "Billing", title: "How you pay", content: "Card or invoice." },
{ label: "Confirm", title: "Review", content: "Check everything before submitting." },
],
active: 1,
clickable: false,
showPanel: true,
controls: true,
allowSkip: true,
nextDisabled: false,
backLabel: "Back",
nextLabel: "Next",
skipLabel: "Skip",
finishLabel: "Finish",
},
),
advanced(
"Held until the step is valid",
"The same wizard with nextDisabled set. The component never validates anything itself: the page owns the form, sets this while the step is incomplete, and clears it once the step passes.",
{
steps: [
{ label: "Account", title: "Your details", content: "This step is not complete yet." },
{ label: "Billing", title: "How you pay", content: "Card or invoice." },
],
active: 0,
clickable: false,
showPanel: true,
controls: true,
allowSkip: false,
nextDisabled: true,
backLabel: "Back",
nextLabel: "Next",
skipLabel: "Skip",
finishLabel: "Finish",
},
),
advanced(
"Clickable steps",
"With clickable the steps emit a change output and take arrow-key roving focus. Without it the stepper is read-only and stays out of the tab order.",
{
steps: [{ label: "One" }, { label: "Two" }, { label: "Three" }],
active: 0,
clickable: true,
showPanel: false,
controls: false,
allowSkip: false,
nextDisabled: false,
backLabel: "Back",
nextLabel: "Next",
skipLabel: "Skip",
finishLabel: "Finish",
},
),
],
},
Pagination: {
demos: [
standard(
"Compact arrows",
"The default: previous and next with a page counter, and a summary of the range in view.",
{ page: 2, pageSize: 10, total: 137, variant: "compact" },
),
standard(
"Numbered pages",
"Page numbers windowed around the current page with ellipsis gaps, so a large set never renders hundreds of buttons.",
{ page: 5, pageSize: 10, total: 200, variant: "numbered", siblingCount: 1 },
),
advanced(
"Wider window",
"siblingCount widens how many pages sit either side of the current one.",
{ page: 8, pageSize: 25, total: 900, variant: "numbered", siblingCount: 2 },
),
],
},
DataTable: {
demos: [
standard(
"Sortable, searchable and paged",
"Click a header to sort, type to filter, and page through the results. Every derivation is a shared function, so the first page is server rendered and stays live after hydration.",
{
columns: DATATABLE_COLUMNS_PLAIN,
rows: DATATABLE_ROWS,
caption: "Accounts",
description: "15 records across four plans.",
pageSize: 5,
pageSizes: [5, 10, 25],
selectable: true,
actions: [],
},
),
advanced(
"Bulk actions on selection",
"An inbox pattern: Refresh is always available, while Mark as read, Archive and Delete appear only once something is ticked. Each handler receives the selected records, and an action output fires for every click.",
{
columns: DATATABLE_COLUMNS_INBOX,
rows: DATATABLE_ROWS,
actions: DATATABLE_ACTIONS,
selectable: true,
caption: "Inbox",
description: "Tick a row to reveal the selection-only actions.",
pageSize: 6,
pageSizes: [6, 12, 25],
searchPlaceholder: "Search mail",
},
),
standard(
"Numbered pagination",
"Page numbers instead of arrows, windowed around the current page so a large table never renders hundreds of buttons.",
{
columns: DATATABLE_COLUMNS_PLAIN,
rows: DATATABLE_ROWS,
actions: [],
paginationStyle: "numbered",
pageSize: 4,
pageSizes: [4, 8, 15],
caption: "Accounts",
description: "15 records, four per page.",
},
),
advanced(
"Full gridlines and custom cell markup",
'gridlines="grid" adds column rules as well as row rules. The Status column is rendered from markup rather than text, so a cell can hold a badge, a link or any other component output.',
{
columns: DATATABLE_COLUMNS,
rows: DATATABLE_ROWS,
actions: [],
gridlines: "grid",
striped: false,
pageSize: 5,
pageSizes: [5, 10, 25],
caption: "Accounts",
description: "Status is supplied as markup through a html column.",
},
),
compact(
"Fixed widths and alignment",
"Columns can set their own width and alignment: text left, counts right, short labels centred. Widths are plain CSS, so percentages, rem and ch all work.",
{
columns: DATATABLE_COLUMNS_NARROW,
rows: DATATABLE_ROWS,
actions: [],
searchable: false,
pageSize: 5,
pageSizes: [5, 10, 25],
density: "comfortable",
caption: "Column sizing",
},
),
advanced(
"Comparison layout",
'layout="comparison" transposes the table: fields run down the left and each record gets its own column. The label column stays put while the rest scrolls sideways.',
{
columns: DATATABLE_COLUMNS_COMPARE,
rows: DATATABLE_ROWS,
actions: [],
layout: "comparison",
searchable: false,
pageSize: 3,
pageSizes: [3, 5, 8],
caption: "Feature",
},
),
standard(
"Sticky first column",
"With many columns the table scrolls sideways; stickyFirstColumn keeps the record name in view so a row never loses its label.",
{
columns: DATATABLE_COLUMNS_PLAIN,
rows: DATATABLE_ROWS,
actions: [],
stickyFirstColumn: true,
pageSize: 5,
pageSizes: [5, 10, 25],
caption: "Accounts",
description: "Scroll the table horizontally on a narrow screen.",
},
),
compact("Compact density, no pagination", "Every row at once, tighter rows, no footer.", {
columns: DATATABLE_COLUMNS_PLAIN,
rows: DATATABLE_ROWS,
pageSizes: [5, 10, 25],
actions: [],
paginated: false,
density: "compact",
searchable: false,
striped: false,
caption: "All accounts",
}),
advanced("Empty state", "What a table shows before any records arrive.", {
columns: DATATABLE_COLUMNS_PLAIN,
rows: "[]",
pageSizes: [5, 10, 25],
actions: [],
caption: "Accounts",
emptyLabel: "No accounts match this filter yet",
}),
],
playground: {
columns: DATATABLE_COLUMNS,
rows: DATATABLE_ROWS,
caption: "Accounts",
pageSize: 5,
pageSizes: [5, 10, 25],
actions: DATATABLE_ACTIONS,
selectable: true,
},
options: {
density: ["compact", "default", "comfortable"],
paginationStyle: ["compact", "numbered"],
gridlines: ["rows", "grid"],
color: ["primary", "secondary", "success", "danger", "info"],
},
},
// A Toaster is a HOST, not a widget. The generic profile rendered five empty
// boxes -- and because every mounted host answers the same window event, one
// toast() call produced five toasts. One host plus buttons that actually
// raise notifications is the only demo that shows anything.
Toaster: {
demos: [
withBefore(TOASTER_DEMO_BUTTONS)(
"Raise notifications from anywhere",
"Mount one host, then call toast() from any client function. Each tone brings its own icon and colour, and hovering the stack holds a toast open while you read it. Actions here show label-only for brevity; attach onClick/onAction handlers from a functions{} block.",
{ position: "bottom-right", duration: 4500, max: 4 },
),
],
playground: { position: "bottom-right", duration: 4500, max: 4 },
options: {
position: [
"top-left",
"top-center",
"top-right",
"bottom-left",
"bottom-center",
"bottom-right",
],
size: ["sm", "default", "lg"],
},
},
PublicPageShell: {
demos: [
standard(
"Complete public page shell",
"Use the shell around a complete marketing or public-service page.",
{ maxWidth: "xl", background: "default" },
{ default: shellPreview },
),
compact(
"Constrained documentation shell",
"Keep long-form documentation readable with a compact content width.",
{ maxWidth: "compact", headerOffset: "sm", background: "soft" },
{ default: shellPreview },
),
advanced(
"Full-bleed landing page",
"Allow full-width sections while keeping overflow and minimum-height behavior consistent.",
{ maxWidth: "full", fullWidth: true, minHeight: "screen", overflow: "clip" },
{ default: shellPreview },
),
],
options: {
maxWidth: ["compact", "lg", "xl", "wide", "2xl", "full"],
headerOffset: ["none", "sm", "md", "lg"],
background: ["default", "soft", "raised", "transparent"],
overflow: ["visible", "hidden", "clip", "auto"],
minHeight: ["none", "screen", "full"],
},
},
AnnouncementBar: {
demos: [
standard(
"Soft product notice",
"Use a calm, dismissible notice inside a constrained content area.",
{
badge: "Public notice",
badgeIcon: "icon-[lucide--sparkles]",
message: "All composite components are now available",
description: "Review each component and its recommended use cases.",
icon: "icon-[lucide--megaphone]",
actionLabel: "View components",
actionHref: "#components",
actionIcon: "icon-[lucide--arrow-down]",
dismissible: true,
width: "default",
variant: "soft",
},
),
compact(
"Wide solid announcement",
"Use stronger contrast for important platform or service announcements.",
{
badge: "Release",
message: "WRNexusJS UI updates are ready",
description: "Explore the redesigned responsive components.",
icon: "icon-[lucide--rocket]",
actionLabel: "Read changes",
actionHref: "#release",
dismissible: true,
width: "wide",
compact: true,
variant: "solid",
},
),
advanced(
"Full-width critical alert",
"Use edge-to-edge width for time-sensitive information that applies to the complete page.",
{
badge: "Service alert",
message: "Scheduled maintenance tonight",
description: "Some services may be temporarily unavailable from 23:00 to 23:30.",
icon: "icon-[lucide--triangle-alert]",
actionLabel: "View status",
actionHref: "#status",
dismissible: true,
width: "full",
color: "warning",
variant: "solid",
},
),
],
playground: { width: "wide", dismissible: true, variant: "solid" },
options: {
width: ["default", "wide", "full"],
variant: ["default", "soft", "outline", "solid", "minimal"],
size: ["compact", "default", "spacious"],
color: ["primary", "secondary", "info", "success", "warning", "danger"],
role: ["status", "alert"],
live: ["off", "polite", "assertive"],
},
},
Breadcrumb: {
demos: [
standard("Minimal page trail", "Use a restrained breadcrumb above standard page content.", {
items: breadcrumbs,
size: "small",
variant: "minimal",
}),
compact(
"Soft navigation trail",
"Add a soft surface when the breadcrumb needs more separation from surrounding content.",
{ items: breadcrumbs, size: "medium", variant: "soft", showHome: true },
),
advanced(
"Large directory breadcrumb",
"Use a larger breadcrumb in directories, dashboards, and touch-first interfaces.",
{
items: breadcrumbs,
size: "large",
variant: "outline",
showHome: true,
separator: "slash",
},
),
],
options: {
size: ["small", "medium", "large"],
separator: ["chevron", "slash", "dot", "arrow"],
variant: ["minimal", "soft", "outline", "contrast"],
},
},
PageHeader: {
demos: [
standard(
"Page header with actions",
"Introduce a service or documentation page with breadcrumbs and clear actions.",
{
eyebrow: "Component showcase",
title: "Page headers with clear hierarchy",
description:
"Use PageHeader for services, directories, legal pages, guides, dashboards, and public information.",
icon: "icon-[lucide--panel-top]",
showBreadcrumbs: true,
breadcrumbs,
primaryLabel: "Primary action",
primaryHref: "#primary",
primaryIcon: "icon-[lucide--arrow-down]",
secondaryLabel: "Secondary action",
secondaryHref: "#secondary",
secondaryIcon: "icon-[lucide--house]",
maxWidth: "full",
},
),
compact(
"Compact service header",
"Use reduced spacing when a page already sits inside an application shell.",
{
eyebrow: "Citizen service",
title: "Track a complaint",
description: "Check the latest status using your complaint reference.",
icon: "icon-[lucide--scan-search]",
compact: true,
primaryLabel: "Track status",
primaryHref: "#track",
variant: "soft",
},
),
advanced(
"Centered campaign header",
"Use a centered header for campaigns, guides, and high-level public information.",
{
eyebrow: "Safety guide",
title: "Prepare your family for emergencies",
description:
"Practical guidance for creating a plan, preparing supplies, and staying informed.",
centered: true,
align: "center",
variant: "minimal",
maxWidth: "wide",
},
),
],
playground: { showBreadcrumbs: true, breadcrumbs, maxWidth: "full" },
options: {
align: ["left", "center", "right"],
size: ["small", "default", "large"],
maxWidth: ["compact", "lg", "xl", "wide", "2xl", "full"],
variant: ["default", "minimal", "soft", "raised", "tinted", "solid"],
color: ["primary", "secondary", "info", "success", "warning", "danger"],
},
},
Hero: {
demos: [
standard(
"Split hero with visual",
"Lead a landing page with clear content and a flexible visual slot.",
{
eyebrow: "Reusable public UI",
eyebrowIcon: "icon-[lucide--sparkles]",
title: "Build polished pages",
highlight: "with consistent hero layouts",
description:
"Create strong first impressions for public portals, product pages, and service overviews.",
layout: "split",
visualPosition: "right",
visualStyle: "card",
primaryLabel: "Explore components",
primaryHref: "#components",
primaryIcon: "icon-[lucide--arrow-right]",
secondaryLabel: "Read documentation",
secondaryHref: "#docs",
secondaryIcon: "icon-[lucide--book-open]",
maxWidth: "wide",
variant: "gradient",
},
{ visual: visualPanel },
),
compact(
"Centered campaign hero",
"Use a stacked, centered layout for announcements, campaigns, and simple conversion pages.",
{
eyebrow: "Public campaign",
title: "Safer communities start with trusted information",
description: "Find verified guidance, public notices, and citizen services in one place.",
align: "center",
layout: "stacked",
size: "default",
variant: "soft",
primaryLabel: "Browse services",
primaryHref: "#services",
},
),
advanced(
"Hero with badges and trust",
"Add product proof, audience badges, and supporting trust information.",
{
eyebrow: "Developer platform",
title: "Ship reliable interfaces faster",
highlight: "without duplicating design work",
description:
"Reusable components, server rendering, themes, accessibility, and responsive behavior.",
badges: ["SSR first", "Theme aware", "Accessible"],
trustItems: ["108 UI components", "Light and dark themes", "Mobile ready"],
layout: "split",
visualPosition: "left",
visualStyle: "soft",
variant: "raised",
},
{ visual: visualPanel },
),
],
playground: { layout: "split", visualPosition: "right", maxWidth: "wide" },
options: {
align: ["left", "center", "right"],
size: ["compact", "default", "lg", "xl"],
layout: ["split", "stacked", "content"],
visualPosition: ["left", "right"],
visualStyle: ["plain", "card", "soft"],
variant: ["default", "soft", "raised", "outline", "gradient", "solid", "minimal"],
maxWidth: ["compact", "lg", "xl", "wide", "2xl", "full"],
},
},
HeroActions: {
demos: [
standard(
"Primary and secondary actions",
"Group the most important hero actions with consistent spacing and hierarchy.",
{ actions: heroActions, align: "left", orientation: "horizontal" },
),
compact(
"Centered campaign actions",
"Center actions beneath a stacked hero or CTA message.",
{ actions: heroActions, align: "center", orientation: "horizontal", size: "sm" },
),
advanced(
"Vertical mobile-first actions",
"Use a vertical group for narrow panels, onboarding, or three-action flows.",
{
actions: [
...heroActions,
{
label: "Contact support",
href: "#support",
icon: "icon-[lucide--life-buoy]",
variant: "ghost",
},
],
orientation: "vertical",
fullWidthMobile: true,
size: "lg",
},
),
],
playground: { actions: heroActions },
options: {
align: ["left", "center", "right"],
orientation: ["horizontal", "vertical"],
size: ["sm", "default", "lg"],
},
},
SplitHero: {
demos: [
standard(
"Balanced content and visual",
"Explain a product, department, or service with a balanced two-column introduction.",
{
eyebrow: "Balanced layout",
title: "Combine detailed content",
highlight: "with a strong visual panel",
description:
"Use SplitHero for product explanations, department introductions, campaigns, and feature storytelling.",
primaryLabel: "View public services",
primaryHref: "#services",
primaryIcon: "icon-[lucide--arrow-right]",
secondaryLabel: "Contact department",
secondaryHref: "#contact",
secondaryIcon: "icon-[lucide--phone]",
visualPosition: "right",
ratio: "balanced",
maxWidth: "wide",
},
{ visual: visualPanel },
),
compact(
"Visual-first introduction",
"Reverse the layout when the screenshot, map, or media needs first visual priority.",
{
eyebrow: "Visual first",
title: "Show the interface before the explanation",
description: "Place the visual on the left and use a compact content column.",
visualPosition: "left",
reverse: true,
ratio: "visual",
variant: "soft",
},
{ visual: visualPanel },
),
advanced(
"Structured service overview",
"Use structured visual items for capabilities, facts, or proof points.",
{
eyebrow: "Department overview",
title: "One service, clearly explained",
description: "Pair narrative content with structured supporting information.",
visualTitle: "Service highlights",
visualDescription: "A consistent, responsive supporting panel.",
visualItems: [
{ label: "Online access", value: "24/7", icon: "icon-[lucide--globe-2]" },
{ label: "Response tracking", value: "Live", icon: "icon-[lucide--activity]" },
{ label: "Languages", value: "3", icon: "icon-[lucide--languages]" },
],
ratio: "content",
variant: "gradient",
},
),
],
options: {
visualPosition: ["left", "right"],
ratio: ["balanced", "content", "visual"],
align: ["left", "center", "right"],
variant: ["default", "soft", "raised", "gradient", "solid", "minimal"],
maxWidth: ["compact", "lg", "xl", "wide", "2xl", "full"],
},
},
Section: {
demos: [
standard(
"Standard content section",
"Create predictable vertical rhythm around a page section.",
{ id: "standard-section", spacing: "lg", maxWidth: "xl", variant: "grid" },
{ default: '
',
},
),
compact(
"Click-triggered compact menu",
"Use a button-triggered context menu when discoverability matters.",
{
items: menuItems,
title: "Quick actions",
trigger: "click",
size: "sm",
minWidth: "12rem",
},
{ trigger: '' },
),
advanced(
"Pointer and keyboard menu",
"Support right-click, click, and keyboard activation without forcing the menu open.",
{
items: menuItems,
title: "Accessible actions",
open: false,
defaultOpen: false,
trigger: "both",
variant: "soft",
placement: "bottom-start",
},
{
trigger:
'',
},
),
],
playground: { items: menuItems, open: false, defaultOpen: false, trigger: "contextmenu" },
options: {
trigger: ["contextmenu", "click", "both", "manual"],
placement: ["pointer", "top-start", "top-end", "bottom-start", "bottom-end"],
align: ["start", "center", "end"],
size: ["sm", "default", "lg"],
variant: ["default", "raised", "soft", "outline"],
},
},
Dropdown: {
demos: [
standard("Action dropdown", "Group related actions behind one compact trigger.", {
label: "Open actions",
icon: "icon-[lucide--menu]",
items: menuItems,
placement: "bottom-start",
width: "lg",
}),
compact(
"Compact overflow menu",
"Use an icon-led compact menu in tables, cards, and toolbars.",
{
label: "More actions",
icon: "icon-[lucide--ellipsis]",
items: menuItems,
size: "sm",
width: "sm",
showChevron: false,
variant: "soft",
},
),
advanced(
"Detailed action menu",
"Open the menu from its trigger to preview placement, descriptions, shortcuts, danger states, and event output.",
{
label: "Review detailed menu",
items: menuItems,
open: false,
defaultOpen: false,
placement: "bottom-end",
width: "xl",
variant: "raised",
},
),
],
playground: {
items: menuItems,
open: false,
defaultOpen: false,
label: "Open playground menu",
},
options: {
placement: ["top-start", "top-end", "bottom-start", "bottom-end"],
width: ["sm", "md", "lg", "xl", "full"],
size: ["sm", "default", "lg"],
variant: ["default", "raised", "soft", "outline"],
},
},
Drawer: {
demos: [
standard(
"Right-side detail drawer",
"Keep supporting record details or forms available without leaving the page.",
{
triggerLabel: "Open drawer",
triggerIcon: "icon-[lucide--panel-right-open]",
title: "Citizen service details",
description: "Review supporting information without leaving the current page.",
icon: "icon-[lucide--panel-right]",
placement: "right",
size: "md",
},
{
default:
'
Place forms, filters, navigation, or record details here.
',
footer:
'',
},
),
compact(
"Bottom mobile drawer",
"Use a bottom sheet for compact mobile workflows and contextual actions.",
{
triggerLabel: "Open mobile sheet",
title: "Choose an action",
placement: "bottom",
size: "sm",
variant: "soft",
},
{
default:
'
Mobile-friendly supporting actions.
',
},
),
advanced(
"Wide navigation drawer",
"Open a wide, scrollable drawer with custom header and footer content from an explicit trigger.",
{
open: false,
defaultOpen: false,
triggerLabel: "Open navigation drawer",
triggerIcon: "icon-[lucide--panel-left-open]",
title: "Navigation and filters",
description: "A wide drawer for complex supporting workflows.",
placement: "left",
size: "lg",
scrollable: true,
},
{
default:
'
Long scrollable content
Filters, navigation, details, and forms can be composed here.
',
},
),
compact(
"Top notice drawer",
"Slide a panel down from the top edge for announcements, search, or quick settings.",
{
open: false,
defaultOpen: false,
triggerLabel: "Open top drawer",
triggerIcon: "icon-[lucide--panel-top-open]",
title: "Scheduled maintenance",
description: "The workspace will be read-only on Sunday from 02:00 to 03:00 UTC.",
placement: "top",
size: "sm",
},
{
default:
'
Save your work before the window starts.
',
},
),
],
playground: {
open: false,
defaultOpen: false,
triggerLabel: "Open playground drawer",
title: "Drawer playground",
},
options: {
placement: ["left", "right", "top", "bottom"],
size: ["sm", "md", "lg", "xl", "full"],
variant: ["default", "soft", "outline", "solid"],
},
},
Modal: {
demos: [
standard(
"Confirmation modal",
"Focus the user on one clear decision with confirm and cancel actions.",
{
triggerLabel: "Open modal",
triggerIcon: "icon-[lucide--square-stack]",
title: "Confirm service request",
description: "Review the information before continuing.",
icon: "icon-[lucide--shield-check]",
confirmLabel: "Confirm request",
confirmIcon: "icon-[lucide--check]",
cancelLabel: "Go back",
size: "md",
},
{
default:
'
This request will be submitted for review.
',
},
),
compact("Destructive confirmation", "Use a danger treatment for irreversible operations.", {
triggerLabel: "Delete record",
title: "Delete this record?",
description: "This action cannot be undone.",
confirmLabel: "Delete record",
cancelLabel: "Keep record",
destructive: true,
size: "sm",
variant: "outline",
}),
advanced(
"Scrollable form modal",
"Open a larger modal for focused forms while keeping actions visible.",
{
open: false,
defaultOpen: false,
triggerLabel: "Open request form",
triggerIcon: "icon-[lucide--file-plus-2]",
title: "Create service request",
description: "Complete the required information.",
confirmLabel: "Submit request",
size: "lg",
scrollable: true,
variant: "soft",
},
{
default:
'',
},
),
],
playground: {
open: false,
defaultOpen: false,
triggerLabel: "Open playground modal",
title: "Modal playground",
},
options: {
size: ["sm", "md", "lg", "xl", "full"],
placement: ["center", "top"],
variant: ["default", "soft", "outline", "solid"],
},
},
Popover: {
demos: [
standard(
"Supporting information",
"Attach contextual information and actions to a nearby trigger.",
{
triggerLabel: "View details",
triggerIcon: "icon-[lucide--info]",
title: "Verified public information",
description: "This panel can contain text, actions, forms, or custom content.",
icon: "icon-[lucide--badge-check]",
actionLabel: "Open guide",
actionHref: "#guide",
width: "lg",
},
{
default:
"
Popover content remains attached to its trigger and becomes mobile-friendly on small screens.
",
},
),
compact(
"Compact action popover",
"Use a small popover for quick actions and concise explanations.",
{
triggerLabel: "Quick actions",
triggerIcon: "icon-[lucide--zap]",
title: "Quick actions",
placement: "top",
width: "sm",
size: "sm",
variant: "soft",
},
{
default:
'',
},
),
advanced(
"Rich status popover",
"Open a wide panel with close control, arrow, custom content, and footer action.",
{
open: false,
defaultOpen: false,
triggerLabel: "Open rich panel",
title: "Service status",
description: "Current operational information.",
placement: "bottom-end",
width: "xl",
showClose: true,
actionLabel: "Open status page",
actionHref: "#status",
variant: "raised",
},
{
default:
'
All systems operationalLast checked moments ago
',
},
),
],
playground: {
open: false,
defaultOpen: false,
triggerLabel: "Open playground popover",
title: "Popover playground",
},
options: {
placement: [
"top",
"top-start",
"top-end",
"bottom",
"bottom-start",
"bottom-end",
"left",
"right",
],
width: ["sm", "md", "lg", "xl"],
size: ["sm", "default", "lg"],
variant: ["default", "raised", "soft", "outline"],
},
},
Tooltip: {
demos: [
standard(
"Hover and focus tooltip",
"Explain an unfamiliar control without interrupting the workflow.",
{
id: "help-tooltip",
title: "Helpful information",
content: "Tooltips explain controls without interrupting the user.",
placement: "top",
},
{ trigger: '' },
),
compact(
"Click tooltip",
"Use click activation for touch-first or interactive help.",
{
id: "click-tooltip",
content: "Click again or press Escape to close.",
trigger: "click",
placement: "bottom",
size: "sm",
variant: "soft",
},
{ trigger: '' },
),
advanced(
"Interactive rich tooltip",
"Allow pointer interaction when the tooltip contains supporting links or controls.",
{
id: "interactive-tooltip",
title: "Keyboard shortcut",
description: "Open global search from anywhere.",
content: "Press Ctrl or Command plus K.",
trigger: "both",
placement: "right",
interactive: true,
maxWidth: "22rem",
variant: "dark",
},
{ trigger: '' },
),
],
playground: {
open: false,
defaultOpen: false,
trigger: "hover",
content: "Hover or focus the trigger to inspect the tooltip.",
},
options: {
trigger: ["hover", "focus", "click", "both"],
placement: [
"top",
"top-start",
"top-end",
"bottom",
"bottom-start",
"bottom-end",
"left",
"right",
],
size: ["sm", "default", "lg"],
variant: ["dark", "light", "soft", "solid"],
},
},
Container: {
demos: [
standard(
"Standard content container",
"Keep page content aligned to a predictable readable width.",
{ maxWidth: "xl", size: "default" },
{ default: '
Centered container content
' },
),
compact(
"Compact reading container",
"Use a smaller maximum width for forms, legal copy, and focused content.",
{ maxWidth: "compact", size: "compact" },
{ default: '
Compact readable content
' },
),
advanced(
"Full-width layout container",
"Allow dashboards and data-heavy pages to use the available width.",
{ maxWidth: "full", size: "spacious" },
{ default: '