Primitives
The presentational building blocks compositions and custom components are made of: layout, content, data display, charts, feedback, navigation, media, inputs, motion and decor. Each has a closed prop contract, generated here from the manifest.
On this page
- Layout
- Stack
- Row
- Grid
- Box
- Center
- Spacer
- Split
- Card
- Section
- Separator
- AspectRatio
- ScrollArea
- Collapsible
- Accordion
- Tabs
- Container
- Resizable
- Content
- Heading
- Text
- Display
- Lead
- Eyebrow
- Meta
- Value
- Code
- Kbd
- Badge
- Marker
- FieldLabel
- Quote
- BulletList
- Message
- ChatBubble
- Markdown
- Data display
- Stat
- StatGroup
- MetricCard
- Progress
- ProgressRing
- AnimatedNumber
- Avatar
- AvatarGroup
- Persona
- DataTable
- KeyValueList
- Timeline
- ActivityFeed
- MilestonePath
- Steps
- Rating
- PriceTag
- ListItem
- ItemList
- StructuredList
- Attachment
- EmptyState
- Skeleton
- Spinner
- QrCode
- IconBadge
- Charts
- AreaChart
- BarChart
- LineChart
- PieChart
- RadarChart
- RadialChart
- CalendarHeatmap
- ActivityHeatmap
- Sparkline
- BarStrip
- BarList
- Feedback
- Alert
- Banner
- Tooltip
- HoverCard
- Popover
- Dialog
- Sheet
- Drawer
- Navigation
- Button
- IconButton
- HeroButton
- TextLink
- Breadcrumb
- ButtonGroup
- DropdownMenu
- Dock
- Pagination
- Media and maps
- MapView
- Embed
- Image
- Icon
- IconDisk
- Carousel
- ImageMask
- BeforeAfter
- LogoStrip
- VideoPlayer
- SeedArt
- ShapeMark
- Inputs
- TextInput
- TextArea
- SearchInput
- PasswordInput
- NumberInput
- QuantityStepper
- Checkbox
- Switch
- Slider
- RadioGroup
- Select
- NativeSelect
- Combobox
- MultiSelect
- TagsInput
- Toggle
- ToggleGroup
- OptionWheel
- DatePicker
- Calendar
- OtpInput
- ColorPicker
- FileDrop
- Field
- RichTextEditor
- Motion
- TextReveal
- Marquee
- FadeIn
- Typewriter
- GradientHeading
- WordRelay
- WarpText
- ZoomWords
- WordStream
- FallingText
- ParticleText
- TextRibbon
- TypographyVortex
- VariableProximity
- ScrollReveal
- CaretSwap
- WritingCaret
- ScrollExpand
- FloatLayer
- Parallax
- ImageSwap
- Decor
- DotsBackground
- GridBackground
- PatternBackground
- ContoursBackground
- FoldsBackground
- PebblesBackground
- SproutsBackground
- SunwashBackground
- WeaveBackground
- AmbientBackground
- DepthBackground
- ContourField
- PigmentField
- PortalField
- ElasticMesh
- MetaBalls
- MagicRings
- Strands
- RippleDistortion
- ClickSpark
- GhostCursor
- SwarmCursor
- TargetCursor
- ImageTrail
- ShapeArtwork
- InfiniteSpiral
- OrbitImages
- DotMatrix
- GradientWash
- NoiseTexture
- AnimatedGradient
- ShaderGlow
Primitives receive values; they never fetch. In a JSON composition you bind props with $field, $agg, $each and $route; in a code component you import them from @app/kit/primitives and pass values from app.query or app.rows.
An invalid prop in a composition is dropped by the normalizer (with a note in the check report's fixes) rather than failing the build. Primitives marked leaf-only (stateful inputs) work only inside code components.
Code components may also import recharts, motion/react and qrcode.react directly, next to react, lucide-react and @app/kit/primitives.
Embed frames only these hosts: https://www.youtube-nocookie.comhttps://player.vimeo.comhttps://www.google.comhttps://www.loom.comhttps://www.figma.comhttps://calendly.comhttps://open.spotify.comhttps://form.typeform.comhttps://docs.google.comhttps://codepen.io
Layout
Stackapplandingauthleaf
Vertical flow of children.
| Prop | Type | Description |
|---|---|---|
gapoptional | "none" | "xs" | "sm" | "md" | "lg" | "xl" | Space between children (default md). |
alignoptional | "stretch" | "start" | "center" | "end" |
Slots: children
import { Stack } from "@app/kit/primitives";
<Stack gap="sm" children={["One","Two"]} />{
"Stack": {
"gap": "sm",
"children": [
"One",
"Two"
]
}
}Wraps kit
Rowapplandingauthleaf
Horizontal flow of children; wraps on small screens when wrap is true.
| Prop | Type | Description |
|---|---|---|
gapoptional | "none" | "xs" | "sm" | "md" | "lg" | "xl" | Space between children (default md). |
alignoptional | "start" | "center" | "end" | "baseline" | "stretch" | |
justifyoptional | "start" | "center" | "end" | "between" | |
wrapoptional | boolean |
Slots: children
import { Row } from "@app/kit/primitives";
<Row gap="sm" justify="between" children={["Left","Right"]} />{
"Row": {
"gap": "sm",
"justify": "between",
"children": [
"Left",
"Right"
]
}
}Wraps kit
Gridapplandingauthleaf
Responsive grid: `columns` at full width, clamped to the space it has (1 on phones, ≤2 in narrow panes).
| Prop | Type | Description |
|---|---|---|
columnsoptional | number (1 to 12) | Columns at full width (default 3). |
gapoptional | "none" | "xs" | "sm" | "md" | "lg" | "xl" | Space between children (default md). |
Slots: children
import { Grid } from "@app/kit/primitives";
<Grid columns={2} children={["A","B","C"]} />{
"Grid": {
"columns": 2,
"children": [
"A",
"B",
"C"
]
}
}Wraps kit
Boxapplandingauthleaf
A padded region, optionally tinted/bordered — groups related content without a card's weight.
| Prop | Type | Description |
|---|---|---|
paddingoptional | "none" | "sm" | "md" | "lg" | |
toneoptional | "none" | "muted" | "accent" | "info" | "positive" | "warning" | "danger" | |
borderoptional | boolean |
Slots: children
import { Box } from "@app/kit/primitives";
<Box padding="md" tone="muted" children={["Inside a box"]} />{
"Box": {
"padding": "md",
"tone": "muted",
"children": [
"Inside a box"
]
}
}Wraps kit
Centerapplandingauthleaf
Centers its children both ways (hero moments, empty panels).
| Prop | Type | Description |
|---|---|---|
minHeightoptional | number (0 to 1200) | Minimum height in px. |
Slots: children
import { Center } from "@app/kit/primitives";
<Center minHeight={120} children={["Centered"]} />{
"Center": {
"minHeight": 120,
"children": [
"Centered"
]
}
}Wraps kit
Spacerapplandingauthleaf
Fixed vertical breathing room.
| Prop | Type | Description |
|---|---|---|
sizeoptional | "sm" | "md" | "lg" | "xl" |
import { Spacer } from "@app/kit/primitives";
<Spacer size="md" />{
"Spacer": {
"size": "md"
}
}Wraps kit
Splitapplandingauthleaf
Two columns side by side from lg up (main + aside).
| Prop | Type | Description |
|---|---|---|
ratiooptional | "1:1" | "2:1" | "1:2" | "3:1" | |
gapoptional | "none" | "xs" | "sm" | "md" | "lg" | "xl" | Space between children (default md). |
Slots: children
import { Split } from "@app/kit/primitives";
<Split ratio="2:1" children={["Main","Aside"]} />{
"Split": {
"ratio": "2:1",
"children": [
"Main",
"Aside"
]
}
}Wraps kit
Cardapplandingauthleaf
The standard content surface: optional title/description header, body children, footer text.
| Prop | Type | Description |
|---|---|---|
titleoptional | string | |
descriptionoptional | string | |
footeroptional | string | |
variantoptional | "default" | "featured" | "panel" | "tinted" | "ink" | |
toneoptional | "neutral" | "pink" | "yellow" | "olive" | "blue" | Paint for variant tinted. |
sizeoptional | "default" | "sm" | |
tooptional | app route | Makes the whole card a link. |
Slots: children
import { Card } from "@app/kit/primitives";
<Card title="Morning flow" description="Mon · 7:00" children={["Body copy"]} />{
"Card": {
"title": "Morning flow",
"description": "Mon · 7:00",
"children": [
"Body copy"
]
}
}Wraps o00h:card
Sectionapplandingauthleaf
A titled page section: eyebrow + section title + optional lead, then children.
| Prop | Type | Description |
|---|---|---|
titlerequired | string | |
eyebrowoptional | string | |
descriptionoptional | string |
Slots: children
import { Section } from "@app/kit/primitives";
<Section title="This week" eyebrow="Schedule" children={["…"]} />{
"Section": {
"title": "This week",
"eyebrow": "Schedule",
"children": [
"…"
]
}
}Wraps o00h:typography, kit
Separatorapplandingauthleaf
A hairline divider.
| Prop | Type | Description |
|---|---|---|
orientationoptional | "horizontal" | "vertical" |
import { Separator } from "@app/kit/primitives";
<Separator />{
"Separator": {}
}Wraps o00h:separator
AspectRatioapplandingauthleaf
Holds children at a fixed ratio (media frames).
| Prop | Type | Description |
|---|---|---|
ratiooptional | "1:1" | "4:3" | "3:2" | "16:9" | "21:9" | "3:4" |
Slots: children
import { AspectRatio } from "@app/kit/primitives";
<AspectRatio ratio="16:9" children={["media"]} />{
"AspectRatio": {
"ratio": "16:9",
"children": [
"media"
]
}
}Wraps o00h:aspect-ratio
ScrollAreaapplandingauthleaf
A bounded scroll region with the kit's organic scrollbar.
| Prop | Type | Description |
|---|---|---|
maxHeightoptional | number (80 to 1200) | Max height in px (default 320). |
Slots: children
import { ScrollArea } from "@app/kit/primitives";
<ScrollArea maxHeight={120} children={["Row 1","Row 2"]} />{
"ScrollArea": {
"maxHeight": 120,
"children": [
"Row 1",
"Row 2"
]
}
}Wraps o00h:scroll-area
Collapsibleapplandingauthleaf
A titled section the viewer can fold away.
| Prop | Type | Description |
|---|---|---|
titlerequired | string | |
defaultOpenoptional | boolean |
Slots: children
import { Collapsible } from "@app/kit/primitives";
<Collapsible title="Details" defaultOpen={true} children={["Hidden detail"]} />{
"Collapsible": {
"title": "Details",
"defaultOpen": true,
"children": [
"Hidden detail"
]
}
}Wraps o00h:collapsible
Accordionapplandingauthleaf
Question/answer style disclosure list (FAQ, care notes).
| Prop | Type | Description |
|---|---|---|
itemsrequired | Array<{ title: string; body: string }> | |
multipleoptional | boolean | Allow several open at once. |
import { Accordion } from "@app/kit/primitives";
<Accordion
items={[{"title":"How often?","body":"Weekly."},{"title":"Where?","body":"Studio B."}]}
/>{
"Accordion": {
"items": [
{
"title": "How often?",
"body": "Weekly."
},
{
"title": "Where?",
"body": "Studio B."
}
]
}
}Wraps o00h:accordion
Tabsapplandingauthleaf
Switch between child panels; one label per child, in order.
| Prop | Type | Description |
|---|---|---|
labelsrequired | string[] | |
variantoptional | "default" | "pills" | "underline" | "lenses" | "notebook" |
Slots: children
import { Tabs } from "@app/kit/primitives";
<Tabs labels={["Today","Week"]} children={["Today panel","Week panel"]} />{
"Tabs": {
"labels": [
"Today",
"Week"
],
"children": [
"Today panel",
"Week panel"
]
}
}Wraps o00h:tabs
Containerapplandingauthleaf
Caps content width and centers it (landing sections, reading pages).
| Prop | Type | Description |
|---|---|---|
sizeoptional | "sm" | "md" | "lg" | "xl" |
Slots: children
import { Container } from "@app/kit/primitives";
<Container size="md" children={["Narrow column"]} />{
"Container": {
"size": "md",
"children": [
"Narrow column"
]
}
}Wraps otf:layouts/container
Resizableappleaf
Two panes with a draggable divider (editors, compare views).
| Prop | Type | Description |
|---|---|---|
directionoptional | "horizontal" | "vertical" |
Slots: children
import { Resizable } from "@app/kit/primitives";
<Resizable children={["Left pane","Right pane"]} />{
"Resizable": {
"children": [
"Left pane",
"Right pane"
]
}
}Wraps o00h:resizable
Content
Headingapplandingauthleaf
A heading at level 1-4 (1 = display, 2 = section, 3 = title, 4 = small).
| Prop | Type | Description |
|---|---|---|
textrequired | string | |
leveloptional | number (1 to 4) | |
alignoptional | "start" | "center" |
import { Heading } from "@app/kit/primitives";
<Heading text="Your plants today" level={2} />{
"Heading": {
"text": "Your plants today",
"level": 2
}
}Wraps o00h:typography
Textapplandingauthleaf
Body copy. tone=muted for secondary text; size sm/md/lg.
| Prop | Type | Description |
|---|---|---|
textrequired | string | |
toneoptional | "default" | "muted" | "accent" | "positive" | "warning" | "danger" | |
sizeoptional | "xs" | "sm" | "md" | "lg" | |
weightoptional | "regular" | "medium" | "semibold" | "bold" | |
alignoptional | "start" | "center" | "end" | |
truncateoptional | boolean |
import { Text } from "@app/kit/primitives";
<Text text="Water when the top inch is dry." tone="muted" />{
"Text": {
"text": "Water when the top inch is dry.",
"tone": "muted"
}
}Wraps o00h:typography
Displaylandingauthleafapp
Oversized display headline (landing heroes).
| Prop | Type | Description |
|---|---|---|
textrequired | string | |
alignoptional | "start" | "center" |
import { Display } from "@app/kit/primitives";
<Display text="Grow on schedule." />{
"Display": {
"text": "Grow on schedule."
}
}Wraps o00h:typography
Leadapplandingauthleaf
An intro paragraph under a heading.
| Prop | Type | Description |
|---|---|---|
textrequired | string | |
alignoptional | "start" | "center" |
import { Lead } from "@app/kit/primitives";
<Lead text="Every class this week, at a glance." />{
"Lead": {
"text": "Every class this week, at a glance."
}
}Wraps o00h:typography
Eyebrowapplandingauthleaf
Small uppercase kicker above a heading.
| Prop | Type | Description |
|---|---|---|
textrequired | string |
import { Eyebrow } from "@app/kit/primitives";
<Eyebrow text="This week" />{
"Eyebrow": {
"text": "This week"
}
}Wraps o00h:typography
Metaapplandingauthleaf
Tiny secondary metadata (timestamps, counts).
| Prop | Type | Description |
|---|---|---|
textrequired | string | |
iconoptional | icon name |
import { Meta } from "@app/kit/primitives";
<Meta text="Updated 5 min ago" icon="Clock" />{
"Meta": {
"text": "Updated 5 min ago",
"icon": "Clock"
}
}Wraps o00h:typography
Valueapplandingauthleaf
A tabular-number value inline (prices, measurements).
| Prop | Type | Description |
|---|---|---|
textrequired | string | |
sizeoptional | "sm" | "md" | "lg" | "xl" |
import { Value } from "@app/kit/primitives";
<Value text="$1,240" size="lg" />{
"Value": {
"text": "$1,240",
"size": "lg"
}
}Wraps o00h:typography
Codeapplandingauthleaf
An inline identifier or code token.
| Prop | Type | Description |
|---|---|---|
textrequired | string |
import { Code } from "@app/kit/primitives";
<Code text="INV-2041" />{
"Code": {
"text": "INV-2041"
}
}Wraps o00h:typography
Kbdapplandingauthleaf
A keyboard key hint.
| Prop | Type | Description |
|---|---|---|
textrequired | string |
import { Kbd } from "@app/kit/primitives";
<Kbd text="⌘K" />{
"Kbd": {
"text": "⌘K"
}
}Wraps o00h:kbd
Badgeapplandingauthleaf
A small status/label pill. Bind text to an enum field for status.
| Prop | Type | Description |
|---|---|---|
textrequired | string | |
toneoptional | "neutral" | "accent" | "info" | "positive" | "warning" | "danger" | |
appearanceoptional | "pill" | "stamp" | "tag" | "counter" | |
iconoptional | icon name |
import { Badge } from "@app/kit/primitives";
<Badge text="Operational" tone="positive" />{
"Badge": {
"text": "Operational",
"tone": "positive"
}
}Wraps o00h:badge
Markerapplandingauthleaf
A dot + label status marker (ok / danger / neutral).
| Prop | Type | Description |
|---|---|---|
textrequired | string | |
toneoptional | "neutral" | "positive" | "danger" |
import { Marker } from "@app/kit/primitives";
<Marker text="Live" tone="positive" />{
"Marker": {
"text": "Live",
"tone": "positive"
}
}Wraps o00h:marker
FieldLabelapplandingauthleaf
A small label paired with a value (key: value rows).
| Prop | Type | Description |
|---|---|---|
textrequired | string |
import { FieldLabel } from "@app/kit/primitives";
<FieldLabel text="Next watering" />{
"FieldLabel": {
"text": "Next watering"
}
}Wraps o00h:label
Quoteapplandingauthleaf
A pull quote / testimonial line with attribution.
| Prop | Type | Description |
|---|---|---|
textrequired | string | |
citeoptional | string |
import { Quote } from "@app/kit/primitives";
<Quote text="Best class schedule in town." cite="Maya, member" />{
"Quote": {
"text": "Best class schedule in town.",
"cite": "Maya, member"
}
}Wraps kit
BulletListapplandingauthleaf
A short bulleted or checked list of strings.
| Prop | Type | Description |
|---|---|---|
itemsrequired | string[] | |
markeroptional | "dot" | "check" | "number" |
import { BulletList } from "@app/kit/primitives";
<BulletList items={["Bright, indirect light","Water weekly"]} marker="check" />{
"BulletList": {
"items": [
"Bright, indirect light",
"Water weekly"
],
"marker": "check"
}
}Wraps kit
Messageapplandingauthleaf
A notice-style message row with title and description.
| Prop | Type | Description |
|---|---|---|
titlerequired | string | |
textoptional | string | |
mineoptional | boolean |
import { Message } from "@app/kit/primitives";
<Message title="Coach Dana" text="Bring a mat tomorrow." />{
"Message": {
"title": "Coach Dana",
"text": "Bring a mat tomorrow."
}
}Wraps o00h:message
ChatBubbleapplandingauthleaf
A chat bubble; mine=true aligns right in the accent colour.
| Prop | Type | Description |
|---|---|---|
textrequired | string | |
mineoptional | boolean | |
timeoptional | string |
import { ChatBubble } from "@app/kit/primitives";
<ChatBubble text="See you at 7!" mine={true} time="6:42" />{
"ChatBubble": {
"text": "See you at 7!",
"mine": true,
"time": "6:42"
}
}Wraps o00h:bubble
Markdownapplandingauthleaf
Renders markdown text safely (headings, bold/italic, lists, task lists, quotes, code, links, https images) — raw HTML shows as text, unsafe link schemes are dropped. Pair with RichTextEditor; store the markdown as a text field.
| Prop | Type | Description |
|---|---|---|
textrequired | string | Markdown source. |
sizeoptional | "sm" | "md" |
import { Markdown } from "@app/kit/primitives";
<Markdown
text="## Care notes\n\nWater **weekly**; mist in *summer*.\n\n- Bright, indirect light\n- [x] Repotted\n\n[Guide](https://example.com/monstera)"
/>{
"Markdown": {
"text": "## Care notes\n\nWater **weekly**; mist in *summer*.\n\n- Bright, indirect light\n- [x] Repotted\n\n[Guide](https://example.com/monstera)"
}
}Wraps kit
Data display
Statapplandingauthleaf
One labelled number (bind value to a $field or $agg; set format there).
| Prop | Type | Description |
|---|---|---|
labelrequired | string | |
valuerequired | string | Already formatted — use the binding's format. |
hintoptional | string | Small line under the value. |
iconoptional | icon name | |
trendoptional | "none" | "up" | "down" | |
emphasisoptional | "default" | "underline" |
import { Stat } from "@app/kit/primitives";
<Stat label="Classes this week" value="42" hint="+6 vs last week" trend="up" />{
"Stat": {
"label": "Classes this week",
"value": "42",
"hint": "+6 vs last week",
"trend": "up"
}
}Wraps o00h:label
StatGroupapplandingauthleaf
A wrapping row of Stat children.
No props.
Slots: children
import { StatGroup } from "@app/kit/primitives";
<StatGroup children={["stat A","stat B"]} />{
"StatGroup": {
"children": [
"stat A",
"stat B"
]
}
}Wraps o00h:label
MetricCardapplandingauthleaf
A KPI card: label, big value, change chip, optional icon.
| Prop | Type | Description |
|---|---|---|
labelrequired | string | |
valuerequired | string | |
changeoptional | string | |
trendoptional | "up" | "down" | |
iconoptional | icon name |
import { MetricCard } from "@app/kit/primitives";
<MetricCard
label="Uptime (30d)"
value="99.98%"
change="+0.02%"
trend="up"
icon="Activity"
/>{
"MetricCard": {
"label": "Uptime (30d)",
"value": "99.98%",
"change": "+0.02%",
"trend": "up",
"icon": "Activity"
}
}Wraps otf:blocks/metric-card
Progressapplandingauthleaf
A progress bar (value of max).
| Prop | Type | Description |
|---|---|---|
valuerequired | number | |
maxoptional | number | |
labeloptional | string | |
appearanceoptional | "organic" | "line" | "segmented" | "orbit" | |
sizeoptional | "sm" | "default" | "lg" |
import { Progress } from "@app/kit/primitives";
<Progress value={7} max={10} label="7 of 10 plants watered" />{
"Progress": {
"value": 7,
"max": 10,
"label": "7 of 10 plants watered"
}
}Wraps o00h:progress
ProgressRingapplandingauthleaf
A circular progress ring with a centre label — streaks, goals, completion.
| Prop | Type | Description |
|---|---|---|
valuerequired | number | |
maxoptional | number | |
labeloptional | string | Centre text (defaults to the percentage). |
captionoptional | string | Line under the ring. |
sizeoptional | "sm" | "md" | "lg" | |
toneoptional | "neutral" | "accent" | "info" | "positive" | "warning" | "danger" |
import { ProgressRing } from "@app/kit/primitives";
<ProgressRing value={5} max={7} label="5d" caption="Watering streak" tone="positive" />{
"ProgressRing": {
"value": 5,
"max": 7,
"label": "5d",
"caption": "Watering streak",
"tone": "positive"
}
}Wraps kit
AnimatedNumberapplandingauthleaf
A number that counts up to its value (hero stats).
| Prop | Type | Description |
|---|---|---|
valuerequired | number | |
formatoptional | "number" | "currency" | "percent" | |
treatmentoptional | "count" | "roll" | "steps" |
import { AnimatedNumber } from "@app/kit/primitives";
<AnimatedNumber value={1287} format="number" />{
"AnimatedNumber": {
"value": 1287,
"format": "number"
}
}Wraps o00h:animated-number
Avatarapplandingauthleaf
A person's picture, or their initials when there is no image.
| Prop | Type | Description |
|---|---|---|
namerequired | string | |
imageoptional | string (image URL) | |
sizeoptional | "sm" | "default" | "lg" | |
shapeoptional | "circle" | "rounded" | "pebble" |
import { Avatar } from "@app/kit/primitives";
<Avatar name="Dana Ruiz" size="default" />{
"Avatar": {
"name": "Dana Ruiz",
"size": "default"
}
}Wraps o00h:avatar
AvatarGroupapplandingauthleaf
Overlapping initials for a few people, with +N overflow.
| Prop | Type | Description |
|---|---|---|
namesrequired | string[] | |
maxoptional | number (1 to 8) |
import { AvatarGroup } from "@app/kit/primitives";
<AvatarGroup names={["Ana Li","Bo Kim","Cy Ng","Di Ho"]} max={3} />{
"AvatarGroup": {
"names": [
"Ana Li",
"Bo Kim",
"Cy Ng",
"Di Ho"
],
"max": 3
}
}Wraps o00h:avatar
Personaapplandingauthleaf
Avatar + name + subtitle (who owns / who did it).
| Prop | Type | Description |
|---|---|---|
namerequired | string | |
subtitleoptional | string | |
imageoptional | string (image URL) | |
sizeoptional | "sm" | "md" | "lg" |
import { Persona } from "@app/kit/primitives";
<Persona name="Coach Dana" subtitle="Yoga · Studio B" />{
"Persona": {
"name": "Coach Dana",
"subtitle": "Yoga · Studio B"
}
}Wraps otf:components/persona
DataTableapplandingauthleaf
A plain read-only table over rows (use an EntityList BLOCK for real record lists).
| Prop | Type | Description |
|---|---|---|
columnsrequired | string[] | Row keys to show, in order. |
headersoptional | string[] | Header copy per column (defaults to the key). |
rowsrequired | Array<{ *: string }> | |
appearanceoptional | "ledger" | "rich" | "comparison" |
import { DataTable } from "@app/kit/primitives";
<DataTable
columns={["name","status"]}
headers={["Service","Status"]}
rows={[{"name":"API","status":"Up"},{"name":"Web","status":"Up"}]}
/>{
"DataTable": {
"columns": [
"name",
"status"
],
"headers": [
"Service",
"Status"
],
"rows": [
{
"name": "API",
"status": "Up"
},
{
"name": "Web",
"status": "Up"
}
]
}
}Wraps o00h:table
KeyValueListapplandingauthleaf
Label/value pairs (a record's facts).
| Prop | Type | Description |
|---|---|---|
itemsrequired | Array<{ label: string; value: string }> | |
orientationoptional | "horizontal" | "vertical" |
import { KeyValueList } from "@app/kit/primitives";
<KeyValueList
items={[{"label":"Light","value":"Bright, indirect"},{"label":"Water","value":"Weekly"}]}
/>{
"KeyValueList": {
"items": [
{
"label": "Light",
"value": "Bright, indirect"
},
{
"label": "Water",
"value": "Weekly"
}
]
}
}Wraps otf:components/property-list
Timelineapplandingauthleaf
A vertical sequence of dated events.
| Prop | Type | Description |
|---|---|---|
itemsrequired | Array<{ title: string; description: string; time: string; tone: string }> |
import { Timeline } from "@app/kit/primitives";
<Timeline
items={[{"title":"Repotted","time":"Mar 2"},{"title":"Fertilised","time":"Mar 9"}]}
/>{
"Timeline": {
"items": [
{
"title": "Repotted",
"time": "Mar 2"
},
{
"title": "Fertilised",
"time": "Mar 9"
}
]
}
}Wraps otf:components/timeline
ActivityFeedapplandingauthleaf
Who-did-what feed with actors and timestamps.
| Prop | Type | Description |
|---|---|---|
titleoptional | string | |
entriesrequired | Array<{ title: string; description: string; actor: string; time: string; badge: string }> | |
emptyoptional | string |
import { ActivityFeed } from "@app/kit/primitives";
<ActivityFeed
title="Recent"
entries={[{"title":"Booked Spin 7am","actor":"Maya","time":"2h ago"}]}
/>{
"ActivityFeed": {
"title": "Recent",
"entries": [
{
"title": "Booked Spin 7am",
"actor": "Maya",
"time": "2h ago"
}
]
}
}Wraps o00h:activity-feed
MilestonePathapplandingauthleaf
An ordered journey with complete / current / upcoming milestones.
| Prop | Type | Description |
|---|---|---|
titleoptional | string | |
itemsrequired | Array<{ title: string; description: string; state: string; meta: string }> | |
presentationoptional | "journey" | "sequence" | "review" |
import { MilestonePath } from "@app/kit/primitives";
<MilestonePath
items={[{"title":"Sprout","state":"complete"},{"title":"First leaf","state":"current"},{"title":"Bloom","state":"upcoming"}]}
/>{
"MilestonePath": {
"items": [
{
"title": "Sprout",
"state": "complete"
},
{
"title": "First leaf",
"state": "current"
},
{
"title": "Bloom",
"state": "upcoming"
}
]
}
}Wraps o00h:milestone-path
Stepsapplandingauthleaf
A numbered step indicator (where the viewer is in a process).
| Prop | Type | Description |
|---|---|---|
labelsrequired | string[] | |
currentoptional | number (1 to …) | |
presentationoptional | "rail" | "ledger" | "compact" |
import { Steps } from "@app/kit/primitives";
<Steps labels={["Pick class","Confirm","Done"]} current={2} />{
"Steps": {
"labels": [
"Pick class",
"Confirm",
"Done"
],
"current": 2
}
}Wraps o00h:stepper
Ratingapplandingauthleaf
Read-only star rating.
| Prop | Type | Description |
|---|---|---|
valuerequired | number | |
maxoptional | number (1 to 10) | |
sizeoptional | "sm" | "md" | "lg" |
import { Rating } from "@app/kit/primitives";
<Rating value={4.5} max={5} />{
"Rating": {
"value": 4.5,
"max": 5
}
}Wraps otf:primitives/rating
PriceTagapplandingauthleaf
A price, optionally with a struck compare-at price and discount chip.
| Prop | Type | Description |
|---|---|---|
amountrequired | number | |
compareAtoptional | number | |
sizeoptional | "sm" | "md" | "lg" |
import { PriceTag } from "@app/kit/primitives";
<PriceTag amount={24} compareAt={30} />{
"PriceTag": {
"amount": 24,
"compareAt": 30
}
}Wraps otf:primitives/price-tag
ListItemapplandingauthleaf
A list row: icon, title, description, trailing meta; links when `to` is set.
| Prop | Type | Description |
|---|---|---|
titlerequired | string | |
descriptionoptional | string | |
metaoptional | string | |
iconoptional | icon name | |
imageoptional | string (image URL) | |
tooptional | app route |
import { ListItem } from "@app/kit/primitives";
<ListItem
title="Fiddle-leaf fig"
description="Living room"
meta="in 2d"
icon="Sparkles"
/>{
"ListItem": {
"title": "Fiddle-leaf fig",
"description": "Living room",
"meta": "in 2d",
"icon": "Sparkles"
}
}Wraps o00h:item
ItemListapplandingauthleaf
Groups ListItem children into one bordered list.
No props.
Slots: children
import { ItemList } from "@app/kit/primitives";
<ItemList children={["row 1","row 2"]} />{
"ItemList": {
"children": [
"row 1",
"row 2"
]
}
}Wraps o00h:item
StructuredListapplandingauthleaf
A titled settings-style list of rows with description and right-hand value.
| Prop | Type | Description |
|---|---|---|
titleoptional | string | |
itemsrequired | Array<{ title: string; description: string; value: string }> |
import { StructuredList } from "@app/kit/primitives";
<StructuredList
title="Care"
items={[{"title":"Light","value":"Indirect"},{"title":"Humidity","value":"60%"}]}
/>{
"StructuredList": {
"title": "Care",
"items": [
{
"title": "Light",
"value": "Indirect"
},
{
"title": "Humidity",
"value": "60%"
}
]
}
}Wraps otf:components/structured-list
Attachmentapplandingauthleaf
A file chip: type, name, meta.
| Prop | Type | Description |
|---|---|---|
namerequired | string | |
typeoptional | string | |
metaoptional | string |
import { Attachment } from "@app/kit/primitives";
<Attachment name="invoice-0412.pdf" type="PDF" meta="120 KB" />{
"Attachment": {
"name": "invoice-0412.pdf",
"type": "PDF",
"meta": "120 KB"
}
}Wraps o00h:attachment
EmptyStateapplandingauthleaf
Nothing-here-yet panel with authored copy.
| Prop | Type | Description |
|---|---|---|
titlerequired | string | |
descriptionoptional | string | |
variantoptional | "default" | "partial" | "error" | "filtered" | |
iconoptional | icon name |
import { EmptyState } from "@app/kit/primitives";
<EmptyState title="No classes today" description="The studio is resting." />{
"EmptyState": {
"title": "No classes today",
"description": "The studio is resting."
}
}Wraps o00h:empty
Skeletonapplandingauthleaf
Loading placeholder lines.
| Prop | Type | Description |
|---|---|---|
linesoptional | number (1 to 8) | |
variantoptional | "default" | "pill" | "card" | "disk" | "line" |
import { Skeleton } from "@app/kit/primitives";
<Skeleton lines={2} />{
"Skeleton": {
"lines": 2
}
}Wraps o00h:skeleton
Spinnerapplandingauthleaf
Busy indicator with optional label.
| Prop | Type | Description |
|---|---|---|
labeloptional | string |
import { Spinner } from "@app/kit/primitives";
<Spinner label="Loading" />{
"Spinner": {
"label": "Loading"
}
}Wraps o00h:spinner
QrCodeapplandingauthleaf
A QR code for a value (ticket codes, links).
| Prop | Type | Description |
|---|---|---|
valuerequired | string | |
sizeoptional | number (64 to 320) |
import { QrCode } from "@app/kit/primitives";
<QrCode value="TICKET-8812" size={96} />{
"QrCode": {
"value": "TICKET-8812",
"size": 96
}
}Wraps otf:primitives/qr-code
IconBadgeapplandingauthleaf
An icon in a tinted square (feature/stat adornment).
| Prop | Type | Description |
|---|---|---|
iconrequired | icon name | |
toneoptional | "neutral" | "accent" | "positive" | "warning" | "danger" | |
sizeoptional | "sm" | "md" | "lg" |
import { IconBadge } from "@app/kit/primitives";
<IconBadge icon="Dumbbell" tone="accent" />{
"IconBadge": {
"icon": "Dumbbell",
"tone": "accent"
}
}Wraps otf:components/icon-badge
Charts
AreaChartapplandingauthleaf
Trend over an ordered axis, filled.
| Prop | Type | Description |
|---|---|---|
datarequired | Array<{ label: string; value: number }> | [{label, value}] points (value2 optional for a second series). Trends: {$agg: {entity, metric, groupBy: <date field>, bucket: day|week|month, range?: this_month|this_quarter|this_year…}} — grouped server-side over the whole table. |
captionrequired | string | Accessible chart title. |
seriesLabeloptional | string | Legend name of `value`. |
series2Labeloptional | string | Legend name of `value2` when points carry one. |
formatoptional | "number" | "currency" | "percent" | |
variantoptional | "linear" | "step" | "stacked" |
import { AreaChart } from "@app/kit/primitives";
<AreaChart
caption="Bookings by day"
data={[{"label":"Mon","value":12},{"label":"Tue","value":18},{"label":"Wed","value":9}]}
/>{
"AreaChart": {
"caption": "Bookings by day",
"data": [
{
"label": "Mon",
"value": 12
},
{
"label": "Tue",
"value": 18
},
{
"label": "Wed",
"value": 9
}
]
}
}Wraps o00h:area-chart
BarChartapplandingauthleaf
Compare values across categories.
| Prop | Type | Description |
|---|---|---|
datarequired | Array<{ label: string; value: number }> | [{label, value}] points (value2 optional for a second series). Trends: {$agg: {entity, metric, groupBy: <date field>, bucket: day|week|month, range?: this_month|this_quarter|this_year…}} — grouped server-side over the whole table. |
captionrequired | string | Accessible chart title. |
seriesLabeloptional | string | Legend name of `value`. |
series2Labeloptional | string | Legend name of `value2` when points carry one. |
formatoptional | "number" | "currency" | "percent" | |
variantoptional | "grouped" | "stacked" | "horizontal" |
import { BarChart } from "@app/kit/primitives";
<BarChart
caption="Bookings by day"
data={[{"label":"Mon","value":12},{"label":"Tue","value":18},{"label":"Wed","value":9}]}
/>{
"BarChart": {
"caption": "Bookings by day",
"data": [
{
"label": "Mon",
"value": 12
},
{
"label": "Tue",
"value": 18
},
{
"label": "Wed",
"value": 9
}
]
}
}Wraps o00h:bar-chart
LineChartapplandingauthleaf
Trend line(s) over time.
| Prop | Type | Description |
|---|---|---|
datarequired | Array<{ label: string; value: number }> | [{label, value}] points (value2 optional for a second series). Trends: {$agg: {entity, metric, groupBy: <date field>, bucket: day|week|month, range?: this_month|this_quarter|this_year…}} — grouped server-side over the whole table. |
captionrequired | string | Accessible chart title. |
seriesLabeloptional | string | Legend name of `value`. |
series2Labeloptional | string | Legend name of `value2` when points carry one. |
formatoptional | "number" | "currency" | "percent" | |
variantoptional | "linear" | "smooth" | "step" |
import { LineChart } from "@app/kit/primitives";
<LineChart
caption="Bookings by day"
data={[{"label":"Mon","value":12},{"label":"Tue","value":18},{"label":"Wed","value":9}]}
/>{
"LineChart": {
"caption": "Bookings by day",
"data": [
{
"label": "Mon",
"value": 12
},
{
"label": "Tue",
"value": 18
},
{
"label": "Wed",
"value": 9
}
]
}
}Wraps o00h:line-chart
PieChartapplandingauthleaf
Share of a whole (≤6 slices).
| Prop | Type | Description |
|---|---|---|
datarequired | Array<{ label: string; value: number }> | [{label, value}] points (value2 optional for a second series). Trends: {$agg: {entity, metric, groupBy: <date field>, bucket: day|week|month, range?: this_month|this_quarter|this_year…}} — grouped server-side over the whole table. |
captionrequired | string | Accessible chart title. |
variantoptional | "pie" | "donut" | |
formatoptional | "number" | "currency" | "percent" |
import { PieChart } from "@app/kit/primitives";
<PieChart
caption="Plants by room"
data={[{"label":"Kitchen","value":3},{"label":"Bedroom","value":5}]}
/>{
"PieChart": {
"caption": "Plants by room",
"data": [
{
"label": "Kitchen",
"value": 3
},
{
"label": "Bedroom",
"value": 5
}
]
}
}Wraps o00h:pie-chart
RadarChartapplandingauthleaf
Profile across 3-8 dimensions.
| Prop | Type | Description |
|---|---|---|
datarequired | Array<{ label: string; value: number }> | [{label, value}] points (value2 optional for a second series). Trends: {$agg: {entity, metric, groupBy: <date field>, bucket: day|week|month, range?: this_month|this_quarter|this_year…}} — grouped server-side over the whole table. |
captionrequired | string | Accessible chart title. |
seriesLabeloptional | string | Legend name of `value`. |
maxoptional | number | |
variantoptional | "polygon" | "rounded" | "grid" |
import { RadarChart } from "@app/kit/primitives";
<RadarChart
caption="Fitness profile"
data={[{"label":"Cardio","value":7},{"label":"Strength","value":5},{"label":"Mobility","value":8}]}
/>{
"RadarChart": {
"caption": "Fitness profile",
"data": [
{
"label": "Cardio",
"value": 7
},
{
"label": "Strength",
"value": 5
},
{
"label": "Mobility",
"value": 8
}
]
}
}Wraps o00h:radar-chart
RadialChartapplandingauthleaf
Progress rings against a max (goal completion per item).
| Prop | Type | Description |
|---|---|---|
datarequired | Array<{ label: string; value: number }> | [{label, value}] points (value2 optional for a second series). Trends: {$agg: {entity, metric, groupBy: <date field>, bucket: day|week|month, range?: this_month|this_quarter|this_year…}} — grouped server-side over the whole table. |
captionrequired | string | Accessible chart title. |
maxoptional | number | |
variantoptional | "full" | "semicircle" |
import { RadialChart } from "@app/kit/primitives";
<RadialChart
caption="Weekly goals"
max={100}
data={[{"label":"Water","value":80},{"label":"Feed","value":40}]}
/>{
"RadialChart": {
"caption": "Weekly goals",
"max": 100,
"data": [
{
"label": "Water",
"value": 80
},
{
"label": "Feed",
"value": 40
}
]
}
}Wraps o00h:radial-chart
CalendarHeatmapapplandingauthleaf
GitHub-style day grid over recent weeks (activity per date).
| Prop | Type | Description |
|---|---|---|
datarequired | Array<{ date: string; value: number }> | [{date: YYYY-MM-DD, value}] |
weeksoptional | number (4 to 53) | |
showLegendoptional | boolean |
import { CalendarHeatmap } from "@app/kit/primitives";
<CalendarHeatmap
weeks={8}
data={[{"date":"2026-09-01","value":2},{"date":"2026-09-02","value":5}]}
/>{
"CalendarHeatmap": {
"weeks": 8,
"data": [
{
"date": "2026-09-01",
"value": 2
},
{
"date": "2026-09-02",
"value": 5
}
]
}
}Wraps otf:charts/heatmap
ActivityHeatmapapplandingauthleaf
A captioned calendar heatmap card with a headline total.
| Prop | Type | Description |
|---|---|---|
totalrequired | string | |
captionoptional | string | |
datarequired | Array<{ date: string; value: number }> | |
weeksoptional | number (4 to 53) |
import { ActivityHeatmap } from "@app/kit/primitives";
<ActivityHeatmap
total="128"
caption="check-ins this season"
weeks={8}
data={[{"date":"2026-09-01","value":3}]}
/>{
"ActivityHeatmap": {
"total": "128",
"caption": "check-ins this season",
"weeks": 8,
"data": [
{
"date": "2026-09-01",
"value": 3
}
]
}
}Wraps otf:blocks/activity-heatmap
Sparklineapplandingauthleaf
A tiny inline trend (inside stats and list rows).
| Prop | Type | Description |
|---|---|---|
datarequired | Array<{ label: string; value: number }> | [{label, value}] points (value2 optional for a second series). Trends: {$agg: {entity, metric, groupBy: <date field>, bucket: day|week|month, range?: this_month|this_quarter|this_year…}} — grouped server-side over the whole table. |
typeoptional | "line" | "area" | |
heightoptional | number (16 to 120) |
import { Sparkline } from "@app/kit/primitives";
<Sparkline
data={[{"label":"1","value":3},{"label":"2","value":6},{"label":"3","value":4}]}
/>{
"Sparkline": {
"data": [
{
"label": "1",
"value": 3
},
{
"label": "2",
"value": 6
},
{
"label": "3",
"value": 4
}
]
}
}Wraps otf:charts/sparkline
BarStripapplandingauthleaf
A strip of N small colored cells, oldest → newest: uptime history, daily check-ins, one heatmap row. Values are numbers (colored by thresholds or intensity) or tone words (up/degraded/down, done/missed, positive/warning/danger).
| Prop | Type | Description |
|---|---|---|
datarequired | Array<{ label: string; value: string }> | [{label, value}] one cell per point — bind with $each + map (value: {$field, map: {down: "danger"}}) or $agg groupBy with bucket. |
captionrequired | string | What the strip shows (accessible name, shown above). |
cellsoptional | number (1 to 120) | Show the LAST n points (default 90). |
goodAboveoptional | number | Numeric values ≥ this are positive (e.g. 99.9 for uptime %). |
warnAboveoptional | number | Numeric values ≥ this (and < goodAbove) are warning; lower is danger. |
summaryoptional | string | Right-aligned headline ("99.95% uptime"). |
showRangeoptional | boolean | First/last labels under the strip (default true). |
import { BarStrip } from "@app/kit/primitives";
<BarStrip
caption="API uptime"
summary="99.9% uptime"
goodAbove={99.9}
warnAbove={99}
data={[{"label":"Sep 1","value":100},{"label":"Sep 2","value":99.95},{"label":"Sep 3","value":98.2},{"label":"Sep 4","value":"degraded"},{"label":"Sep 5","value":"up"}]}
/>{
"BarStrip": {
"caption": "API uptime",
"summary": "99.9% uptime",
"goodAbove": 99.9,
"warnAbove": 99,
"data": [
{
"label": "Sep 1",
"value": 100
},
{
"label": "Sep 2",
"value": 99.95
},
{
"label": "Sep 3",
"value": 98.2
},
{
"label": "Sep 4",
"value": "degraded"
},
{
"label": "Sep 5",
"value": "up"
}
]
}
}Wraps kit
BarListapplandingauthleaf
Ranked horizontal bars with labels (top-N lists).
| Prop | Type | Description |
|---|---|---|
datarequired | Array<{ label: string; value: number }> | [{label, value}] points (value2 optional for a second series). Trends: {$agg: {entity, metric, groupBy: <date field>, bucket: day|week|month, range?: this_month|this_quarter|this_year…}} — grouped server-side over the whole table. |
formatoptional | "number" | "currency" | "percent" | |
emptyMessageoptional | string |
import { BarList } from "@app/kit/primitives";
<BarList data={[{"label":"Spin","value":32},{"label":"Yoga","value":21}]} />{
"BarList": {
"data": [
{
"label": "Spin",
"value": 32
},
{
"label": "Yoga",
"value": 21
}
]
}
}Wraps otf:blocks/bar-list
Feedback
Alertapplandingauthleaf
An inline notice with title + description in a status tone.
| Prop | Type | Description |
|---|---|---|
titlerequired | string | |
descriptionoptional | string | |
toneoptional | "neutral" | "info" | "positive" | "warning" | "danger" | "accent" | |
presentationoptional | "note" | "banner" | "dispatch" | |
iconoptional | icon name |
import { Alert } from "@app/kit/primitives";
<Alert
title="Degraded performance"
description="API latency is elevated."
tone="warning"
/>{
"Alert": {
"title": "Degraded performance",
"description": "API latency is elevated.",
"tone": "warning"
}
}Wraps o00h:alert
Bannerapplandingauthleaf
A full-width announcement strip.
| Prop | Type | Description |
|---|---|---|
titlerequired | string | |
descriptionoptional | string | |
toneoptional | "info" | "positive" | "warning" | "danger" | "neutral" |
import { Banner } from "@app/kit/primitives";
<Banner
title="Holiday hours"
description="The studio closes at 4pm Friday."
tone="info"
/>{
"Banner": {
"title": "Holiday hours",
"description": "The studio closes at 4pm Friday.",
"tone": "info"
}
}Wraps otf:components/banner
Tooltipapplandingauthleaf
Hover hint on its children.
| Prop | Type | Description |
|---|---|---|
textrequired | string |
Slots: children
import { Tooltip } from "@app/kit/primitives";
<Tooltip text="Last checked 2 min ago" children={["hover me"]} />{
"Tooltip": {
"text": "Last checked 2 min ago",
"children": [
"hover me"
]
}
}Wraps o00h:tooltip
HoverCardapplandingauthleaf
Richer hover preview (title + text) on its children.
| Prop | Type | Description |
|---|---|---|
titlerequired | string | |
textoptional | string |
Slots: children
import { HoverCard } from "@app/kit/primitives";
<HoverCard title="Studio B" text="Heated floor, 20 mats." children={["Studio B"]} />{
"HoverCard": {
"title": "Studio B",
"text": "Heated floor, 20 mats.",
"children": [
"Studio B"
]
}
}Wraps o00h:hover-card
Popoverapplandingauthleaf
A click-to-open floating panel holding its children.
| Prop | Type | Description |
|---|---|---|
triggerrequired | string | Label of the button that opens it. |
Slots: children
import { Popover } from "@app/kit/primitives";
<Popover trigger="Details" children={["More detail"]} />{
"Popover": {
"trigger": "Details",
"children": [
"More detail"
]
}
}Wraps o00h:popover
Dialogapplandingauthleaf
A modal opened from a button; children are its body.
| Prop | Type | Description |
|---|---|---|
triggerrequired | string | Label of the button that opens it. |
titlerequired | string | |
descriptionoptional | string |
Slots: children
import { Dialog } from "@app/kit/primitives";
<Dialog
trigger="View policy"
title="Cancellation policy"
children={["Cancel up to 2h before class."]}
/>{
"Dialog": {
"trigger": "View policy",
"title": "Cancellation policy",
"children": [
"Cancel up to 2h before class."
]
}
}Wraps o00h:dialog
Sheetapplandingauthleaf
A side panel opened from a button.
| Prop | Type | Description |
|---|---|---|
triggerrequired | string | Label of the button that opens it. |
titlerequired | string | |
sideoptional | "start" | "end" |
Slots: children
import { Sheet } from "@app/kit/primitives";
<Sheet trigger="Filters" title="Filters" children={["…"]} />{
"Sheet": {
"trigger": "Filters",
"title": "Filters",
"children": [
"…"
]
}
}Wraps o00h:sheet
Drawerapplandingauthleaf
A bottom drawer opened from a button (mobile-friendly detail).
| Prop | Type | Description |
|---|---|---|
triggerrequired | string | Label of the button that opens it. |
titlerequired | string |
Slots: children
import { Drawer } from "@app/kit/primitives";
<Drawer trigger="Open" title="Care guide" children={["Water weekly."]} />{
"Drawer": {
"trigger": "Open",
"title": "Care guide",
"children": [
"Water weekly."
]
}
}Wraps o00h:drawer
Navigation
Buttonapplandingauthleaf
A button that navigates to a route (in a code leaf: calls onClick).
| Prop | Type | Description |
|---|---|---|
labelrequired | string | |
tooptional | app route | |
variantoptional | "default" | "accent" | "secondary" | "outline" | "ghost" | "danger" | |
sizeoptional | "sm" | "default" | "lg" | |
iconoptional | icon name | |
fullWidthoptional | boolean | |
onClickoptional | function (leaf only) |
import { Button } from "@app/kit/primitives";
<Button label="Book this class" variant="default" icon="Calendar" />{
"Button": {
"label": "Book this class",
"variant": "default",
"icon": "Calendar"
}
}Wraps o00h:button
IconButtonapplandingauthleaf
A round icon-only button (label is its accessible name).
| Prop | Type | Description |
|---|---|---|
iconrequired | icon name | |
labelrequired | string | |
tooptional | app route | |
onClickoptional | function (leaf only) |
import { IconButton } from "@app/kit/primitives";
<IconButton icon="Settings" label="Settings" />{
"IconButton": {
"icon": "Settings",
"label": "Settings"
}
}Wraps o00h:icon
HeroButtonlandingauthleafapp
The big organic call-to-action for landing heroes.
| Prop | Type | Description |
|---|---|---|
labelrequired | string | |
tooptional | app route | |
showArrowoptional | boolean |
import { HeroButton } from "@app/kit/primitives";
<HeroButton label="Start free" showArrow={true} />{
"HeroButton": {
"label": "Start free",
"showArrow": true
}
}Wraps o00h:hero-button
TextLinkapplandingauthleaf
An inline animated text link to a route.
| Prop | Type | Description |
|---|---|---|
labelrequired | string | |
torequired | app route | |
treatmentoptional | "underline-start" | "underline-center" | "wash-up" | "contour" |
import { TextLink } from "@app/kit/primitives";
<TextLink label="See all plants" to="/" />{
"TextLink": {
"label": "See all plants",
"to": "/"
}
}Wraps o00h:living-link
Breadcrumbapplandingauthleaf
Where-am-I trail; the last item is the current page.
| Prop | Type | Description |
|---|---|---|
itemsrequired | Array<{ label: string; to: string }> |
import { Breadcrumb } from "@app/kit/primitives";
<Breadcrumb items={[{"label":"Plants","to":"/"},{"label":"Monstera"}]} />{
"Breadcrumb": {
"items": [
{
"label": "Plants",
"to": "/"
},
{
"label": "Monstera"
}
]
}
}Wraps o00h:breadcrumb
ButtonGroupapplandingauthleaf
A segmented row of route buttons (views of the same thing).
| Prop | Type | Description |
|---|---|---|
itemsrequired | Array<{ label: string; to: string }> | |
activeoptional | string | Label of the selected item. |
import { ButtonGroup } from "@app/kit/primitives";
<ButtonGroup items={[{"label":"Day","to":"/"},{"label":"Week","to":"/"}]} active="Day" />{
"ButtonGroup": {
"items": [
{
"label": "Day",
"to": "/"
},
{
"label": "Week",
"to": "/"
}
],
"active": "Day"
}
}Wraps o00h:button-group
Docklandingauthleafapp
A magnifying icon dock of shortcuts (landing/showcase flourish).
| Prop | Type | Description |
|---|---|---|
itemsrequired | Array<{ label: string; icon: string; to: string }> | |
variantoptional | "glass" | "shelf" | "rail" |
import { Dock } from "@app/kit/primitives";
<Dock
items={[{"label":"Home","icon":"Home","to":"/"},{"label":"Plants","icon":"Sparkles","to":"/"}]}
/>{
"Dock": {
"items": [
{
"label": "Home",
"icon": "Home",
"to": "/"
},
{
"label": "Plants",
"icon": "Sparkles",
"to": "/"
}
]
}
}Wraps o00h:dock
Paginationleaf
Page switcher — leaf-only (a leaf owns the page state).
| Prop | Type | Description |
|---|---|---|
pagerequired | number | |
totalPagesrequired | number | |
onPageChangeoptional | function (leaf only) |
import { Pagination } from "@app/kit/primitives";
<Pagination page={2} totalPages={5} />Wraps o00h:pagination
Media and maps
MapViewapplandingauthleaf
An interactive map (OpenStreetMap tiles, lazy-loaded) with one marker per record that has coordinates; popups open the record; > 50 markers cluster. Bind markers with $each over an entity with lat/lng fields.
| Prop | Type | Description |
|---|---|---|
markersrequired | Array<{ lat: number; lng: number; label: string; href: string }> | [{lat, lng, label, href}] — {"$each": {"entity": "place", "limit": 400}, "map": {"lat": {"$field": "lat"}, "lng": {"$field": "lng"}, "label": {"$field": "name"}, "href": {"$route": "/places/:id"}}} |
heightoptional | "sm" | "md" | "lg" | |
captionoptional | string | |
zoomoptional | number (1 to 18) | Fixed zoom; omit to fit every marker. |
import { MapView } from "@app/kit/primitives";
<MapView
caption="Our three shops"
markers={[{"lat":52.5208,"lng":13.4095,"label":"Mitte"},{"lat":52.4996,"lng":13.418,"label":"Kreuzberg"},{"lat":52.539,"lng":13.424,"label":"Prenzlauer Berg"}]}
/>{
"MapView": {
"caption": "Our three shops",
"markers": [
{
"lat": 52.5208,
"lng": 13.4095,
"label": "Mitte"
},
{
"lat": 52.4996,
"lng": 13.418,
"label": "Kreuzberg"
},
{
"lat": 52.539,
"lng": 13.424,
"label": "Prenzlauer Berg"
}
]
}
}Wraps kit
Embedapplandingauthleaf
Embeds a video, map, design, booking page, playlist, form or pen in a sandboxed frame — YouTube, Vimeo, Google Maps, Loom, Figma, Calendly, Spotify, Typeform, Google Forms, CodePen (paste the normal share URL; it is normalized to the official embed URL). Any other URL renders a link card.
| Prop | Type | Description |
|---|---|---|
urlrequired | string | Share URL, e.g. https://youtu.be/<id>, https://open.spotify.com/playlist/<id>, https://calendly.com/<user>/<event>. |
titlerequired | string | Accessible title of the frame (and the link card). |
aspectoptional | "16:9" | "4:3" | "1:1" | "9:16" | "3:4" | "tall" | "compact" | Frame shape; omit for the provider's natural shape. |
captionoptional | string |
import { Embed } from "@app/kit/primitives";
<Embed url="https://www.youtube.com/watch?v=dQw4w9WgXcQ" title="Studio tour" />{
"Embed": {
"url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
"title": "Studio tour"
}
}Wraps kit
Imageapplandingauthleaf
A framed image at a fixed ratio; falls back to generated art when empty.
| Prop | Type | Description |
|---|---|---|
srcoptional | string (image URL) | |
altrequired | string | |
ratiooptional | "1:1" | "4:3" | "3:2" | "16:9" | "3:4" | "auto" | |
fitoptional | "cover" | "contain" | |
roundedoptional | "none" | "md" | "lg" | "full" |
import { Image } from "@app/kit/primitives";
<Image alt="Monstera deliciosa" ratio="4:3" />{
"Image": {
"alt": "Monstera deliciosa",
"ratio": "4:3"
}
}Wraps kit
Iconapplandingauthleaf
A lucide icon from the closed icon set.
| Prop | Type | Description |
|---|---|---|
namerequired | icon name | |
sizeoptional | "sm" | "md" | "lg" | "xl" | |
toneoptional | "default" | "muted" | "accent" | "positive" | "warning" | "danger" |
import { Icon } from "@app/kit/primitives";
<Icon name="Sparkles" size="lg" tone="accent" />{
"Icon": {
"name": "Sparkles",
"size": "lg",
"tone": "accent"
}
}Wraps kit
IconDiskapplandingauthleaf
An icon on a soft coloured disk (feature bullets).
| Prop | Type | Description |
|---|---|---|
iconrequired | icon name | |
toneoptional | "default" | "pink" | "yellow" | "olive" | "blue" | "ink" | "cream" | |
sizeoptional | "sm" | "default" | "lg" |
import { IconDisk } from "@app/kit/primitives";
<IconDisk icon="Heart" tone="pink" />{
"IconDisk": {
"icon": "Heart",
"tone": "pink"
}
}Wraps o00h:icon
Carouselapplandingauthleaf
Horizontally swipeable slides — one per child.
| Prop | Type | Description |
|---|---|---|
presentationoptional | "shelf" | "story" | "index" |
Slots: children
import { Carousel } from "@app/kit/primitives";
<Carousel children={["Slide 1","Slide 2","Slide 3"]} />{
"Carousel": {
"children": [
"Slide 1",
"Slide 2",
"Slide 3"
]
}
}Wraps o00h:carousel
ImageMaskapplandingauthleaf
An image clipped to an organic signature shape.
| Prop | Type | Description |
|---|---|---|
srcrequired | string (image URL) | |
altrequired | string | |
shapeoptional | "daisy-12" | "petal-7" | "aster-9" | "sunburst-24" | "clover-soft" | "cloud-3" | "pebble-soft" | "pebble-tall" | "ribbon-soft" | "scalloped-square" | "cushion" | "seed-wing" | |
captionoptional | string |
import { ImageMask } from "@app/kit/primitives";
<ImageMask src="" alt="Studio" shape="clover-soft" />{
"ImageMask": {
"src": "",
"alt": "Studio",
"shape": "clover-soft"
}
}Wraps o00h:image-masking
BeforeAfterapplandingauthleaf
Drag-to-compare two images (before / after).
| Prop | Type | Description |
|---|---|---|
beforerequired | string (image URL) | |
afterrequired | string (image URL) | |
beforeLabeloptional | string | |
afterLabeloptional | string |
import { BeforeAfter } from "@app/kit/primitives";
<BeforeAfter before="" after="" beforeLabel="Before" afterLabel="After" />{
"BeforeAfter": {
"before": "",
"after": "",
"beforeLabel": "Before",
"afterLabel": "After"
}
}Wraps otf:primitives/comparison
LogoStriplandingauthleafapp
A scrolling strip of partner/customer names (landing social proof).
| Prop | Type | Description |
|---|---|---|
namesrequired | string[] |
import { LogoStrip } from "@app/kit/primitives";
<LogoStrip names={["Acme","Globex","Initech"]} />{
"LogoStrip": {
"names": [
"Acme",
"Globex",
"Initech"
]
}
}Wraps otf:primitives/logo-carousel
VideoPlayerapplandingauthleaf
An HTML5 video with the kit's controls.
| Prop | Type | Description |
|---|---|---|
srcrequired | string (image URL) | Video URL. |
posteroptional | string (image URL) |
import { VideoPlayer } from "@app/kit/primitives";
<VideoPlayer src="data:video/mp4;base64," poster="" />{
"VideoPlayer": {
"src": "data:video/mp4;base64,",
"poster": ""
}
}Wraps otf:data/VideoPlayer
SeedArtapplandingauthleaf
Deterministic generated artwork from a seed string (no-image placeholder).
| Prop | Type | Description |
|---|---|---|
seedrequired | string | |
labelrequired | string |
import { SeedArt } from "@app/kit/primitives";
<SeedArt seed="monstera" label="Monstera" />{
"SeedArt": {
"seed": "monstera",
"label": "Monstera"
}
}Wraps shadcn:seed-art
ShapeMarkapplandingauthleaf
A signature organic shape as an ornament.
| Prop | Type | Description |
|---|---|---|
shapeoptional | "daisy-12" | "petal-7" | "aster-9" | "sunburst-24" | "clover-soft" | "cloud-3" | "pebble-soft" | "pebble-tall" | "ribbon-soft" | "scalloped-square" | "cushion" | "seed-wing" | |
variantoptional | "fill" | "outline" | |
sizeoptional | number (16 to 320) |
import { ShapeMark } from "@app/kit/primitives";
<ShapeMark shape="daisy-12" size={48} />{
"ShapeMark": {
"shape": "daisy-12",
"size": 48
}
}Wraps o00h:shape
Inputs
TextInputleaf
Single-line text.
| Prop | Type | Description |
|---|---|---|
labeloptional | string | Visible label. |
valueoptional | string | |
placeholderoptional | string | |
typeoptional | "text" | "email" | "url" | "tel" | |
onChangeoptional | function (leaf only) | (value) => void |
import { TextInput } from "@app/kit/primitives";
<TextInput label="Name" value="Monstera" />Wraps o00h:input
TextArealeaf
Multi-line text.
| Prop | Type | Description |
|---|---|---|
labeloptional | string | Visible label. |
valueoptional | string | |
placeholderoptional | string | |
rowsoptional | number (2 to 20) | |
onChangeoptional | function (leaf only) | (value) => void |
import { TextArea } from "@app/kit/primitives";
<TextArea label="Notes" value="Likes humidity" />Wraps o00h:textarea
SearchInputleaf
Search box with clear + shortcut hint.
| Prop | Type | Description |
|---|---|---|
valueoptional | string | |
placeholderoptional | string | |
onChangeoptional | function (leaf only) | (value) => void |
import { SearchInput } from "@app/kit/primitives";
<SearchInput placeholder="Search plants" />Wraps otf:forms/search-input
PasswordInputleaf
Password with reveal + strength meter.
| Prop | Type | Description |
|---|---|---|
labeloptional | string | Visible label. |
valueoptional | string | |
strengthoptional | boolean | |
onChangeoptional | function (leaf only) | (value) => void |
import { PasswordInput } from "@app/kit/primitives";
<PasswordInput label="Password" strength={true} />Wraps otf:forms/password-input
NumberInputleaf
Number with steppers.
| Prop | Type | Description |
|---|---|---|
labeloptional | string | Visible label. |
valueoptional | number | |
minoptional | number | |
maxoptional | number | |
stepoptional | number | |
onChangeoptional | function (leaf only) | (value) => void |
import { NumberInput } from "@app/kit/primitives";
<NumberInput label="Reps" value={12} min={0} max={50} />Wraps o00h:number-input
QuantityStepperleaf
Compact −/+ quantity control.
| Prop | Type | Description |
|---|---|---|
valueoptional | number | |
minoptional | number | |
maxoptional | number | |
onChangeoptional | function (leaf only) | (value) => void |
import { QuantityStepper } from "@app/kit/primitives";
<QuantityStepper value={2} min={1} max={9} />Wraps otf:primitives/quantity-stepper
Checkboxleaf
A labelled checkbox.
| Prop | Type | Description |
|---|---|---|
labelrequired | string | |
checkedoptional | boolean | |
onChangeoptional | function (leaf only) | (value) => void |
import { Checkbox } from "@app/kit/primitives";
<Checkbox label="Watered" checked={true} />Wraps o00h:checkbox
Switchleaf
An on/off setting.
| Prop | Type | Description |
|---|---|---|
labelrequired | string | |
checkedoptional | boolean | |
onChangeoptional | function (leaf only) | (value) => void |
import { Switch } from "@app/kit/primitives";
<Switch label="Reminders" checked={true} />Wraps o00h:switch
Sliderleaf
Pick a number on a range.
| Prop | Type | Description |
|---|---|---|
labeloptional | string | Visible label. |
valueoptional | number | |
minoptional | number | |
maxoptional | number | |
stepoptional | number | |
onChangeoptional | function (leaf only) | (value) => void |
import { Slider } from "@app/kit/primitives";
<Slider label="Intensity" value={40} min={0} max={100} />Wraps o00h:slider
RadioGroupleaf
Choose one of a few options.
| Prop | Type | Description |
|---|---|---|
labeloptional | string | Visible label. |
optionsrequired | string[] | Option labels (also their values). |
valueoptional | string | |
appearanceoptional | "row" | "card" | "chip" | |
onChangeoptional | function (leaf only) | (value) => void |
import { RadioGroup } from "@app/kit/primitives";
<RadioGroup label="Level" options={["Easy","Medium","Hard"]} value="Medium" />Wraps o00h:radio-group
Selectleaf
Choose one from a dropdown.
| Prop | Type | Description |
|---|---|---|
labeloptional | string | Visible label. |
optionsrequired | string[] | Option labels (also their values). |
valueoptional | string | |
placeholderoptional | string | |
onChangeoptional | function (leaf only) | (value) => void |
import { Select } from "@app/kit/primitives";
<Select label="Room" options={["Kitchen","Bedroom"]} value="Kitchen" />Wraps o00h:select
NativeSelectleaf
A plain native dropdown (long option lists, mobile).
| Prop | Type | Description |
|---|---|---|
labeloptional | string | Visible label. |
optionsrequired | string[] | Option labels (also their values). |
valueoptional | string | |
onChangeoptional | function (leaf only) | (value) => void |
import { NativeSelect } from "@app/kit/primitives";
<NativeSelect label="Month" options={["Jan","Feb"]} value="Jan" />Wraps o00h:native-select
Comboboxleaf
Type-to-filter single choice.
| Prop | Type | Description |
|---|---|---|
optionsrequired | string[] | Option labels (also their values). |
valueoptional | string | |
placeholderoptional | string | |
onChangeoptional | function (leaf only) | (value) => void |
import { Combobox } from "@app/kit/primitives";
<Combobox options={["Aloe","Basil","Cactus"]} placeholder="Pick a plant" />Wraps o00h:combobox
MultiSelectleaf
Choose several (tokens).
| Prop | Type | Description |
|---|---|---|
labelrequired | string | |
optionsrequired | string[] | Option labels (also their values). |
valueoptional | string[] | |
onChangeoptional | function (leaf only) | (value) => void |
import { MultiSelect } from "@app/kit/primitives";
<MultiSelect label="Days" options={["Mon","Wed","Fri"]} value={["Mon"]} />Wraps o00h:multi-select
TagsInputleaf
Free-form tag entry.
| Prop | Type | Description |
|---|---|---|
valueoptional | string[] | |
placeholderoptional | string | |
onChangeoptional | function (leaf only) | (value) => void |
import { TagsInput } from "@app/kit/primitives";
<TagsInput value={["indoor","low-light"]} />Wraps otf:forms/tags
Toggleleaf
A pressed/unpressed tool button.
| Prop | Type | Description |
|---|---|---|
labelrequired | string | |
pressedoptional | boolean | |
iconoptional | icon name | |
onChangeoptional | function (leaf only) | (value) => void |
import { Toggle } from "@app/kit/primitives";
<Toggle label="Favourite" pressed={true} icon="Star" />Wraps o00h:toggle
ToggleGroupleaf
Segmented single choice.
| Prop | Type | Description |
|---|---|---|
optionsrequired | string[] | Option labels (also their values). |
valueoptional | string | |
onChangeoptional | function (leaf only) | (value) => void |
import { ToggleGroup } from "@app/kit/primitives";
<ToggleGroup options={["Day","Week","Month"]} value="Week" />Wraps o00h:toggle-group
OptionWheelleaf
A rotary picker for a short list.
| Prop | Type | Description |
|---|---|---|
optionsrequired | string[] | Option labels (also their values). |
indexoptional | number | |
presentationoptional | "arc" | "reel" | "compact" | |
onChangeoptional | function (leaf only) | (value) => void |
import { OptionWheel } from "@app/kit/primitives";
<OptionWheel options={["S","M","L"]} index={1} />Wraps o00h:option-wheel
DatePickerleaf
Pick a date from a popover calendar.
| Prop | Type | Description |
|---|---|---|
valueoptional | string | YYYY-MM-DD |
placeholderoptional | string | |
onChangeoptional | function (leaf only) | (value) => void |
import { DatePicker } from "@app/kit/primitives";
<DatePicker value="2026-10-01" />Wraps o00h:date-picker
Calendarleafapp
An inline month calendar with a selected day.
| Prop | Type | Description |
|---|---|---|
valueoptional | string | YYYY-MM-DD |
onChangeoptional | function (leaf only) | (value) => void |
import { Calendar } from "@app/kit/primitives";
<Calendar value="2026-10-01" />{
"Calendar": {
"value": "2026-10-01"
}
}Wraps o00h:calendar
OtpInputleaf
One-time code entry.
| Prop | Type | Description |
|---|---|---|
lengthoptional | number (4 to 8) | |
valueoptional | string | |
onChangeoptional | function (leaf only) | (value) => void |
import { OtpInput } from "@app/kit/primitives";
<OtpInput length={6} />Wraps o00h:input-otp
ColorPickerleaf
Pick a colour.
| Prop | Type | Description |
|---|---|---|
valueoptional | string | |
onChangeoptional | function (leaf only) | (value) => void |
import { ColorPicker } from "@app/kit/primitives";
<ColorPicker value="#3b82f6" />Wraps otf:forms/color-picker
FileDropleaf
Drag-and-drop file picker (files go to onChange).
| Prop | Type | Description |
|---|---|---|
labeloptional | string | Visible label. |
acceptoptional | string | |
multipleoptional | boolean | |
onChangeoptional | function (leaf only) | (value) => void |
import { FileDrop } from "@app/kit/primitives";
<FileDrop label="Drop a photo" accept="image/*" />Wraps o00h:dropzone
Fieldleaf
Label + description + error around one input child.
| Prop | Type | Description |
|---|---|---|
labelrequired | string | |
descriptionoptional | string | |
erroroptional | string |
Slots: children
import { Field } from "@app/kit/primitives";
<Field label="Nickname" description="Shown on the leaderboard" children={["input"]} />Wraps o00h:field
RichTextEditorleaf
Rich text as markdown: a textarea with a formatting toolbar (bold, italic, heading, lists, quote, code, link; ⌘B/⌘I/⌘K) and a Write/Preview toggle. onChange gets the markdown string — store it in a text field, show it with Markdown.
| Prop | Type | Description |
|---|---|---|
labeloptional | string | Visible label. |
valueoptional | string | Markdown. |
placeholderoptional | string | |
rowsoptional | number (3 to 30) | |
onChangeoptional | function (leaf only) | (value) => void |
import { RichTextEditor } from "@app/kit/primitives";
<RichTextEditor label="Description" value="**Bright** light, water *weekly*." />Wraps kit
Motion
TextRevealapplandingauthleaf
Headline that reveals word by word on mount.
| Prop | Type | Description |
|---|---|---|
textrequired | string | |
asoptional | "h1" | "h2" | "h3" | "p" | |
variantoptional | "rise" | "fade" | "soften" | "fold" | "bloom" | "scale" | "settle" |
import { TextReveal } from "@app/kit/primitives";
<TextReveal text="Every class, one glance." as="h2" />{
"TextReveal": {
"text": "Every class, one glance.",
"as": "h2"
}
}Wraps o00h:text-reveal, otf:text
Marqueeapplandingauthleaf
A slow endless ticker of its children (announcements, logos).
| Prop | Type | Description |
|---|---|---|
directionoptional | "left" | "right" | |
speedoptional | "slow" | "normal" | "fast" | |
labeloptional | string | Accessible name. |
Slots: children
import { Marquee } from "@app/kit/primitives";
<Marquee label="News" children={["Open late Thursday","New spin bikes"]} />{
"Marquee": {
"label": "News",
"children": [
"Open late Thursday",
"New spin bikes"
]
}
}Wraps o00h:marquee, otf:primitives/marquee
FadeInapplandingauthleaf
Fades/slides its children in on mount.
| Prop | Type | Description |
|---|---|---|
directionoptional | "none" | "up" | "down" | "left" | "right" | |
delayoptional | number (0 to 2) |
Slots: children
import { FadeIn } from "@app/kit/primitives";
<FadeIn direction="up" children={["Hello"]} />{
"FadeIn": {
"direction": "up",
"children": [
"Hello"
]
}
}Wraps otf:motion, o00h:presence
Typewriterlandingauthleaf
Types then deletes each word in turn (hero rotating noun).
| Prop | Type | Description |
|---|---|---|
wordsrequired | string[] |
import { Typewriter } from "@app/kit/primitives";
<Typewriter words={["yoga","spin","pilates"]} />{
"Typewriter": {
"words": [
"yoga",
"spin",
"pilates"
]
}
}Wraps otf:text
GradientHeadinglandingauthleaf
A heading filled with a (optionally animated) gradient.
| Prop | Type | Description |
|---|---|---|
textrequired | string | |
presetoptional | "primary" | "warm" | "cosmic" | "aurora" | "sunset" | |
animateoptional | boolean |
import { GradientHeading } from "@app/kit/primitives";
<GradientHeading text="Grow something" preset="primary" />{
"GradientHeading": {
"text": "Grow something",
"preset": "primary"
}
}Wraps otf:text
WordRelaylandingauthleaf
Cycles through words in place.
| Prop | Type | Description |
|---|---|---|
wordsrequired | string[] |
import { WordRelay } from "@app/kit/primitives";
<WordRelay words={["Plan","Track","Grow"]} />{
"WordRelay": {
"words": [
"Plan",
"Track",
"Grow"
]
}
}Wraps o00h:word-relay
WarpTextlandingauthleaf
Text that warps under the pointer.
| Prop | Type | Description |
|---|---|---|
textrequired | string | |
sizeoptional | "sm" | "default" | "lg" |
import { WarpText } from "@app/kit/primitives";
<WarpText text="Warp" />{
"WarpText": {
"text": "Warp"
}
}Wraps o00h:warp-text
ZoomWordslandingauthleaf
Words zoom in one after another.
| Prop | Type | Description |
|---|---|---|
textrequired | string | |
sizeoptional | "sm" | "default" | "lg" |
import { ZoomWords } from "@app/kit/primitives";
<ZoomWords text="Big bold words" />{
"ZoomWords": {
"text": "Big bold words"
}
}Wraps o00h:zoom-words
WordStreamlandingauthleaf
Words drift past in a stream.
| Prop | Type | Description |
|---|---|---|
textrequired | string | |
sizeoptional | "sm" | "default" | "lg" |
import { WordStream } from "@app/kit/primitives";
<WordStream text="Stream of words" />{
"WordStream": {
"text": "Stream of words"
}
}Wraps o00h:word-stream
FallingTextlandingauthleaf
Letters fall and pile up with gravity.
| Prop | Type | Description |
|---|---|---|
textrequired | string | |
sizeoptional | "sm" | "default" | "lg" |
import { FallingText } from "@app/kit/primitives";
<FallingText text="Gravity" />{
"FallingText": {
"text": "Gravity"
}
}Wraps o00h:falling-text
ParticleTextlandingauthleaf
Text made of particles that scatter from the pointer.
| Prop | Type | Description |
|---|---|---|
textrequired | string | |
sizeoptional | "sm" | "default" | "lg" |
import { ParticleText } from "@app/kit/primitives";
<ParticleText text="Particles" />{
"ParticleText": {
"text": "Particles"
}
}Wraps o00h:particle-text
TextRibbonlandingauthleaf
Text flowing along a wavy ribbon.
| Prop | Type | Description |
|---|---|---|
textrequired | string |
import { TextRibbon } from "@app/kit/primitives";
<TextRibbon text="Along the ribbon" />{
"TextRibbon": {
"text": "Along the ribbon"
}
}Wraps o00h:text-ribbon
TypographyVortexlandingauthleaf
Text rings spiralling into a vortex.
| Prop | Type | Description |
|---|---|---|
textrequired | string | |
sizeoptional | "sm" | "default" | "lg" |
import { TypographyVortex } from "@app/kit/primitives";
<TypographyVortex text="Vortex" />{
"TypographyVortex": {
"text": "Vortex"
}
}Wraps o00h:typography-vortex
VariableProximitylandingauthleaf
Font weight swells near the pointer.
| Prop | Type | Description |
|---|---|---|
textrequired | string | |
sizeoptional | "sm" | "default" | "lg" |
import { VariableProximity } from "@app/kit/primitives";
<VariableProximity text="Hover me" />{
"VariableProximity": {
"text": "Hover me"
}
}Wraps o00h:variable-proximity
ScrollReveallandingauthleaf
A statement that sharpens as it scrolls into view.
| Prop | Type | Description |
|---|---|---|
textrequired | string | |
sizeoptional | "sm" | "default" | "lg" |
import { ScrollReveal } from "@app/kit/primitives";
<ScrollReveal text="Scroll to read" />{
"ScrollReveal": {
"text": "Scroll to read"
}
}Wraps o00h:scroll-reveal
CaretSwaplandingauthleaf
Retypes one phrase into another.
| Prop | Type | Description |
|---|---|---|
fromrequired | string | |
torequired | string | |
sizeoptional | "sm" | "default" | "lg" |
import { CaretSwap } from "@app/kit/primitives";
<CaretSwap from="Chaos" to="Calm" />{
"CaretSwap": {
"from": "Chaos",
"to": "Calm"
}
}Wraps o00h:caret-swap
WritingCaretlandingauthleaf
A blinking writing caret after a line of text.
| Prop | Type | Description |
|---|---|---|
textrequired | string |
import { WritingCaret } from "@app/kit/primitives";
<WritingCaret text="Start typing" />{
"WritingCaret": {
"text": "Start typing"
}
}Wraps o00h:writing-caret
ScrollExpandlandingauthleaf
Children grow to full width as they scroll in.
No props.
Slots: children
import { ScrollExpand } from "@app/kit/primitives";
<ScrollExpand children={["Expanding"]} />{
"ScrollExpand": {
"children": [
"Expanding"
]
}
}Wraps o00h:scroll-expand
FloatLayerlandingauthleaf
Children float gently with depth parallax.
| Prop | Type | Description |
|---|---|---|
depthoptional | number (0 to 80) |
Slots: children
import { FloatLayer } from "@app/kit/primitives";
<FloatLayer children={["Floating"]} />{
"FloatLayer": {
"children": [
"Floating"
]
}
}Wraps o00h:float-layer
Parallaxlandingauthleaf
Children move at a parallax offset while scrolling.
| Prop | Type | Description |
|---|---|---|
offsetoptional | number (-200 to 200) |
Slots: children
import { Parallax } from "@app/kit/primitives";
<Parallax children={["Parallax"]} />{
"Parallax": {
"children": [
"Parallax"
]
}
}Wraps otf:motion
ImageSwaplandingauthleaf
Two images; hovering transitions to the second (pixel / wave / grain / dither).
| Prop | Type | Description |
|---|---|---|
firstrequired | string (image URL) | |
secondrequired | string (image URL) | |
altrequired | string | |
effectoptional | "pixel" | "wave" | "grain" | "dither" |
import { ImageSwap } from "@app/kit/primitives";
<ImageSwap first="" second="" alt="Before and after" effect="wave" />{
"ImageSwap": {
"first": "",
"second": "",
"alt": "Before and after",
"effect": "wave"
}
}Wraps o00h:pixel-swap, o00h:wave-wipe, o00h:grain-dissolve, o00h:dither-dissolve
Decor
DotsBackgroundlandingauthleaf
Quiet dot-grid paper.
| Prop | Type | Description |
|---|---|---|
heightoptional | number (120 to 900) | Region height in px (default 320). |
Slots: children
import { DotsBackground } from "@app/kit/primitives";
<DotsBackground height={160} children={["Headline on decor"]} />{
"DotsBackground": {
"height": 160,
"children": [
"Headline on decor"
]
}
}Wraps o00h:dots-background
GridBackgroundlandingauthleaf
Blueprint grid lines.
| Prop | Type | Description |
|---|---|---|
heightoptional | number (120 to 900) | Region height in px (default 320). |
Slots: children
import { GridBackground } from "@app/kit/primitives";
<GridBackground height={160} children={["Headline on decor"]} />{
"GridBackground": {
"height": 160,
"children": [
"Headline on decor"
]
}
}Wraps o00h:grid-background
PatternBackgroundlandingauthleaf
One of the subtle vector patterns.
| Prop | Type | Description |
|---|---|---|
heightoptional | number (120 to 900) | Region height in px (default 320). |
variantoptional | "dots" | "grid" | "contours" | "weave" | "pebbles" | "sunwash" | "folds" | "sprouts" |
Slots: children
import { PatternBackground } from "@app/kit/primitives";
<PatternBackground height={160} children={["Headline on decor"]} />{
"PatternBackground": {
"height": 160,
"children": [
"Headline on decor"
]
}
}Wraps o00h:pattern-background
ContoursBackgroundlandingauthleaf
Topographic contour lines.
| Prop | Type | Description |
|---|---|---|
heightoptional | number (120 to 900) | Region height in px (default 320). |
Slots: children
import { ContoursBackground } from "@app/kit/primitives";
<ContoursBackground height={160} children={["Headline on decor"]} />{
"ContoursBackground": {
"height": 160,
"children": [
"Headline on decor"
]
}
}Wraps o00h:contours-background
FoldsBackgroundlandingauthleaf
Folded-paper creases.
| Prop | Type | Description |
|---|---|---|
heightoptional | number (120 to 900) | Region height in px (default 320). |
Slots: children
import { FoldsBackground } from "@app/kit/primitives";
<FoldsBackground height={160} children={["Headline on decor"]} />{
"FoldsBackground": {
"height": 160,
"children": [
"Headline on decor"
]
}
}Wraps o00h:folds-background
PebblesBackgroundlandingauthleaf
Scattered soft pebbles.
| Prop | Type | Description |
|---|---|---|
heightoptional | number (120 to 900) | Region height in px (default 320). |
Slots: children
import { PebblesBackground } from "@app/kit/primitives";
<PebblesBackground height={160} children={["Headline on decor"]} />{
"PebblesBackground": {
"height": 160,
"children": [
"Headline on decor"
]
}
}Wraps o00h:pebbles-background
SproutsBackgroundlandingauthleaf
Tiny sprouting marks (garden, growth).
| Prop | Type | Description |
|---|---|---|
heightoptional | number (120 to 900) | Region height in px (default 320). |
Slots: children
import { SproutsBackground } from "@app/kit/primitives";
<SproutsBackground height={160} children={["Headline on decor"]} />{
"SproutsBackground": {
"height": 160,
"children": [
"Headline on decor"
]
}
}Wraps o00h:sprouts-background
SunwashBackgroundlandingauthleaf
Warm sun-wash light.
| Prop | Type | Description |
|---|---|---|
heightoptional | number (120 to 900) | Region height in px (default 320). |
Slots: children
import { SunwashBackground } from "@app/kit/primitives";
<SunwashBackground height={160} children={["Headline on decor"]} />{
"SunwashBackground": {
"height": 160,
"children": [
"Headline on decor"
]
}
}Wraps o00h:sunwash-background
WeaveBackgroundlandingauthleaf
Woven textile texture.
| Prop | Type | Description |
|---|---|---|
heightoptional | number (120 to 900) | Region height in px (default 320). |
Slots: children
import { WeaveBackground } from "@app/kit/primitives";
<WeaveBackground height={160} children={["Headline on decor"]} />{
"WeaveBackground": {
"height": 160,
"children": [
"Headline on decor"
]
}
}Wraps o00h:weave-background
AmbientBackgroundlandingauthleaf
Drifting ambient edge decoration.
| Prop | Type | Description |
|---|---|---|
heightoptional | number (120 to 900) | Region height in px (default 320). |
variantoptional | "drift" | "orbit" | "contour" |
Slots: children
import { AmbientBackground } from "@app/kit/primitives";
<AmbientBackground height={160} children={["Headline on decor"]} />{
"AmbientBackground": {
"height": 160,
"children": [
"Headline on decor"
]
}
}Wraps o00h:ambient-background
DepthBackgroundlandingauthleaf
Layered depth particles.
| Prop | Type | Description |
|---|---|---|
heightoptional | number (120 to 900) | Region height in px (default 320). |
variantoptional | "pollen" | "contour" | "orbital" |
Slots: children
import { DepthBackground } from "@app/kit/primitives";
<DepthBackground height={160} children={["Headline on decor"]} />{
"DepthBackground": {
"height": 160,
"children": [
"Headline on decor"
]
}
}Wraps o00h:depth-background
ContourFieldlandingauthleaf
Living WebGL contour shader.
| Prop | Type | Description |
|---|---|---|
heightoptional | number (120 to 900) | Region height in px (default 320). |
toneoptional | "balanced" | "warm" | "cool" |
Slots: children
import { ContourField } from "@app/kit/primitives";
<ContourField height={160} children={["Headline on decor"]} />{
"ContourField": {
"height": 160,
"children": [
"Headline on decor"
]
}
}Wraps o00h:contour-field
PigmentFieldlandingauthleaf
Living pigment wash shader.
| Prop | Type | Description |
|---|---|---|
heightoptional | number (120 to 900) | Region height in px (default 320). |
toneoptional | "balanced" | "warm" | "cool" |
Slots: children
import { PigmentField } from "@app/kit/primitives";
<PigmentField height={160} children={["Headline on decor"]} />{
"PigmentField": {
"height": 160,
"children": [
"Headline on decor"
]
}
}Wraps o00h:pigment-field
PortalFieldlandingauthleaf
Interactive portal glow.
| Prop | Type | Description |
|---|---|---|
heightoptional | number (120 to 900) | Region height in px (default 320). |
toneoptional | "balanced" | "warm" | "cool" |
Slots: children
import { PortalField } from "@app/kit/primitives";
<PortalField height={160} children={["Headline on decor"]} />{
"PortalField": {
"height": 160,
"children": [
"Headline on decor"
]
}
}Wraps o00h:portal-field
ElasticMeshlandingauthleaf
Elastic sheet that bends under the pointer.
| Prop | Type | Description |
|---|---|---|
heightoptional | number (120 to 900) | Region height in px (default 320). |
toneoptional | "pink" | "olive" | "blue" | "yellow" |
Slots: children
import { ElasticMesh } from "@app/kit/primitives";
<ElasticMesh height={160} children={["Headline on decor"]} />{
"ElasticMesh": {
"height": 160,
"children": [
"Headline on decor"
]
}
}Wraps o00h:elastic-mesh
MetaBallslandingauthleaf
Merging liquid blobs.
| Prop | Type | Description |
|---|---|---|
heightoptional | number (120 to 900) | Region height in px (default 320). |
toneoptional | "pink" | "olive" | "blue" | "yellow" |
Slots: children
import { MetaBalls } from "@app/kit/primitives";
<MetaBalls height={160} children={["Headline on decor"]} />{
"MetaBalls": {
"height": 160,
"children": [
"Headline on decor"
]
}
}Wraps o00h:meta-balls
MagicRingslandingauthleaf
Concentric rings that follow the pointer.
| Prop | Type | Description |
|---|---|---|
heightoptional | number (120 to 900) | Region height in px (default 320). |
toneoptional | "pink" | "olive" | "blue" | "yellow" |
Slots: children
import { MagicRings } from "@app/kit/primitives";
<MagicRings height={160} children={["Headline on decor"]} />{
"MagicRings": {
"height": 160,
"children": [
"Headline on decor"
]
}
}Wraps o00h:magic-rings
Strandslandingauthleaf
Swaying fibre strands.
| Prop | Type | Description |
|---|---|---|
heightoptional | number (120 to 900) | Region height in px (default 320). |
toneoptional | "pink" | "olive" | "blue" | "yellow" |
Slots: children
import { Strands } from "@app/kit/primitives";
<Strands height={160} children={["Headline on decor"]} />{
"Strands": {
"height": 160,
"children": [
"Headline on decor"
]
}
}Wraps o00h:strands
RippleDistortionlandingauthleaf
Water-ripple distortion.
| Prop | Type | Description |
|---|---|---|
heightoptional | number (120 to 900) | Region height in px (default 320). |
toneoptional | "pink" | "olive" | "blue" | "yellow" |
Slots: children
import { RippleDistortion } from "@app/kit/primitives";
<RippleDistortion height={160} children={["Headline on decor"]} />{
"RippleDistortion": {
"height": 160,
"children": [
"Headline on decor"
]
}
}Wraps o00h:ripple-distortion
ClickSparklandingauthleaf
Sparks where the visitor clicks.
| Prop | Type | Description |
|---|---|---|
heightoptional | number (120 to 900) | Region height in px (default 320). |
toneoptional | "pink" | "olive" | "blue" | "yellow" |
Slots: children
import { ClickSpark } from "@app/kit/primitives";
<ClickSpark height={160} children={["Headline on decor"]} />{
"ClickSpark": {
"height": 160,
"children": [
"Headline on decor"
]
}
}Wraps o00h:click-spark
GhostCursorlandingauthleaf
A trailing ghost cursor.
| Prop | Type | Description |
|---|---|---|
heightoptional | number (120 to 900) | Region height in px (default 320). |
toneoptional | "pink" | "olive" | "blue" | "yellow" |
Slots: children
import { GhostCursor } from "@app/kit/primitives";
<GhostCursor height={160} children={["Headline on decor"]} />{
"GhostCursor": {
"height": 160,
"children": [
"Headline on decor"
]
}
}Wraps o00h:ghost-cursor
SwarmCursorlandingauthleaf
A swarm that follows the pointer.
| Prop | Type | Description |
|---|---|---|
heightoptional | number (120 to 900) | Region height in px (default 320). |
toneoptional | "pink" | "olive" | "blue" | "yellow" |
Slots: children
import { SwarmCursor } from "@app/kit/primitives";
<SwarmCursor height={160} children={["Headline on decor"]} />{
"SwarmCursor": {
"height": 160,
"children": [
"Headline on decor"
]
}
}Wraps o00h:swarm-cursor
TargetCursorlandingauthleaf
A targeting reticle cursor.
| Prop | Type | Description |
|---|---|---|
heightoptional | number (120 to 900) | Region height in px (default 320). |
Slots: children
import { TargetCursor } from "@app/kit/primitives";
<TargetCursor height={160} children={["Headline on decor"]} />{
"TargetCursor": {
"height": 160,
"children": [
"Headline on decor"
]
}
}Wraps o00h:target-cursor
ImageTraillandingauthleaf
Images trail the pointer.
| Prop | Type | Description |
|---|---|---|
heightoptional | number (120 to 900) | Region height in px (default 320). |
toneoptional | "pink" | "olive" | "blue" | "yellow" |
Slots: children
import { ImageTrail } from "@app/kit/primitives";
<ImageTrail height={160} children={["Headline on decor"]} />{
"ImageTrail": {
"height": 160,
"children": [
"Headline on decor"
]
}
}Wraps o00h:image-trail
ShapeArtworklandingauthleaf
One large signature shape with a cast shadow.
| Prop | Type | Description |
|---|---|---|
heightoptional | number (120 to 900) | Region height in px (default 320). |
toneoptional | "pink" | "olive" | "blue" | "yellow" |
Slots: children
import { ShapeArtwork } from "@app/kit/primitives";
<ShapeArtwork height={160} children={["Headline on decor"]} />{
"ShapeArtwork": {
"height": 160,
"children": [
"Headline on decor"
]
}
}Wraps o00h:shape-artwork
InfiniteSpirallandingauthleaf
An endless spiral of images.
| Prop | Type | Description |
|---|---|---|
heightoptional | number (120 to 900) | Region height in px (default 320). |
imagesoptional | string[] | Image URLs. |
Slots: children
import { InfiniteSpiral } from "@app/kit/primitives";
<InfiniteSpiral height={160} children={["Headline on decor"]} />{
"InfiniteSpiral": {
"height": 160,
"children": [
"Headline on decor"
]
}
}Wraps o00h:infinite-spiral
OrbitImageslandingauthleaf
Images orbiting the content.
| Prop | Type | Description |
|---|---|---|
heightoptional | number (120 to 900) | Region height in px (default 320). |
imagesoptional | string[] | Image URLs. |
Slots: children
import { OrbitImages } from "@app/kit/primitives";
<OrbitImages height={160} children={["Headline on decor"]} />{
"OrbitImages": {
"height": 160,
"children": [
"Headline on decor"
]
}
}Wraps o00h:orbit-images
DotMatrixlandingauthleaf
Dotted matrix with vignette.
| Prop | Type | Description |
|---|---|---|
heightoptional | number (120 to 900) | Region height in px (default 320). |
Slots: children
import { DotMatrix } from "@app/kit/primitives";
<DotMatrix height={160} children={["Headline on decor"]} />{
"DotMatrix": {
"height": 160,
"children": [
"Headline on decor"
]
}
}Wraps otf:backgrounds
GradientWashlandingauthleaf
Soft radial gradient wash.
| Prop | Type | Description |
|---|---|---|
heightoptional | number (120 to 900) | Region height in px (default 320). |
presetoptional | "slate" | "warm" | "cosmic" | "aurora" | "subtle" |
Slots: children
import { GradientWash } from "@app/kit/primitives";
<GradientWash height={160} children={["Headline on decor"]} />{
"GradientWash": {
"height": 160,
"children": [
"Headline on decor"
]
}
}Wraps otf:backgrounds
NoiseTexturelandingauthleaf
Film-grain noise texture.
| Prop | Type | Description |
|---|---|---|
heightoptional | number (120 to 900) | Region height in px (default 320). |
Slots: children
import { NoiseTexture } from "@app/kit/primitives";
<NoiseTexture height={160} children={["Headline on decor"]} />{
"NoiseTexture": {
"height": 160,
"children": [
"Headline on decor"
]
}
}Wraps otf:backgrounds
AnimatedGradientlandingauthleaf
Slowly shifting mesh gradient.
| Prop | Type | Description |
|---|---|---|
heightoptional | number (120 to 900) | Region height in px (default 320). |
variantoptional | "mesh" | "shift" | "pulse" |
Slots: children
import { AnimatedGradient } from "@app/kit/primitives";
<AnimatedGradient height={160} children={["Headline on decor"]} />{
"AnimatedGradient": {
"height": 160,
"children": [
"Headline on decor"
]
}
}Wraps otf:backgrounds
ShaderGlowlandingauthleaf
Hero shader glow (WebGL).
| Prop | Type | Description |
|---|---|---|
heightoptional | number (120 to 900) | Region height in px (default 320). |
Slots: children
import { ShaderGlow } from "@app/kit/primitives";
<ShaderGlow height={160} children={["Headline on decor"]} />{
"ShaderGlow": {
"height": 160,
"children": [
"Headline on decor"
]
}
}Wraps otf:backgrounds