A radio button component for single selection from a group. Supports four appearances: radio (default circular indicator), button (Panel-powered with full emphasis and feedback), tab-horizontal (bottom-border accent), and tab-vertical (left-border accent).
---
import Radio from "../Radio.astro";
import { stack } from "@pindoba/styled-system/patterns";
---
<div class={stack({ gap: "md", direction: "column" })}>
<Radio id="astro-def-1" name="astro-def" value="option1">Option 1</Radio>
<Radio id="astro-def-2" name="astro-def" value="option2" checked
>Option 2</Radio
>
<Radio id="astro-def-3" name="astro-def" value="option3" disabled
>Disabled</Radio
>
</div>All four appearance variants side by side.
---
import Radio from "../Radio.astro";
import { stack } from "@pindoba/styled-system/patterns";
---
<div class={stack({ gap: "xl", direction: "column" })}>
<div>
<h3>radio (default)</h3>
<div class={stack({ gap: "md", direction: "column" })}>
<Radio id="astro-app-r1" name="astro-app-radio" value="r1" checked
>Option 1</Radio
>
<Radio id="astro-app-r2" name="astro-app-radio" value="r2">Option 2</Radio
>
</div>
</div>
<div>
<h3>button</h3>
<div class={stack({ gap: "sm", direction: "row" })}>
<Radio
id="astro-app-b1"
name="astro-app-button"
value="b1"
appearance="button"
checked
>
Option 1
</Radio>
<Radio
id="astro-app-b2"
name="astro-app-button"
value="b2"
appearance="button"
>
Option 2
</Radio>
<Radio
id="astro-app-b3"
name="astro-app-button"
value="b3"
appearance="button"
>
Option 3
</Radio>
</div>
</div>
<div>
<h3>tab-horizontal</h3>
<div class={stack({ gap: "sm", direction: "row" })}>
<Radio
id="astro-app-th1"
name="astro-app-tabh"
value="th1"
appearance="tab-horizontal"
checked
>
Tab 1
</Radio>
<Radio
id="astro-app-th2"
name="astro-app-tabh"
value="th2"
appearance="tab-horizontal"
>
Tab 2
</Radio>
<Radio
id="astro-app-th3"
name="astro-app-tabh"
value="th3"
appearance="tab-horizontal"
>
Tab 3
</Radio>
</div>
</div>
<div>
<h3>tab-vertical</h3>
<div class={stack({ gap: "xs", direction: "column" })}>
<Radio
id="astro-app-tv1"
name="astro-app-tabv"
value="tv1"
appearance="tab-vertical"
checked
>
Dashboard
</Radio>
<Radio
id="astro-app-tv2"
name="astro-app-tabv"
value="tv2"
appearance="tab-vertical"
>
Settings
</Radio>
</div>
</div>
</div>Three sizes are available across all appearances.
---
import Radio from "../Radio.astro";
import { stack } from "@pindoba/styled-system/patterns";
---
<div class={stack({ gap: "xl", direction: "column" })}>
<div>
<h3>radio appearance</h3>
<div class={stack({ gap: "sm", direction: "row", align: "center" })}>
<Radio id="astro-size-sm" name="astro-size" value="sm" size="sm" checked
>Small</Radio
>
<Radio id="astro-size-md" name="astro-size" value="md" size="md"
>Medium</Radio
>
<Radio id="astro-size-lg" name="astro-size" value="lg" size="lg"
>Large</Radio
>
</div>
</div>
<div>
<h3>button appearance</h3>
<div class={stack({ gap: "sm", direction: "row", align: "center" })}>
<Radio
id="astro-sbtn-sm"
name="astro-sbtn"
value="sm"
appearance="button"
size="sm"
checked>Small</Radio
>
<Radio
id="astro-sbtn-md"
name="astro-sbtn"
value="md"
appearance="button"
size="md">Medium</Radio
>
<Radio
id="astro-sbtn-lg"
name="astro-sbtn"
value="lg"
appearance="button"
size="lg">Large</Radio
>
</div>
</div>
</div>appearance="button" composes with Panel — use emphasis (primary, secondary, ghost) and feedback (primary, success, danger, warning, neutral) to control the surface.
---
import Radio from "../Radio.astro";
import { stack } from "@pindoba/styled-system/patterns";
---
<div class={stack({ gap: "xl", direction: "column" })}>
<div>
<h3>Primary (default)</h3>
<div class={stack({ gap: "sm", direction: "row" })}>
<Radio
id="astro-btn-p1"
name="astro-btn-primary"
value="p1"
appearance="button"
checked
>
Option 1
</Radio>
<Radio
id="astro-btn-p2"
name="astro-btn-primary"
value="p2"
appearance="button"
>
Option 2
</Radio>
<Radio
id="astro-btn-p3"
name="astro-btn-primary"
value="p3"
appearance="button"
>
Option 3
</Radio>
</div>
</div>
<div>
<h3>Danger</h3>
<div class={stack({ gap: "sm", direction: "row" })}>
<Radio
id="astro-btn-d1"
name="astro-btn-danger"
value="d1"
appearance="button"
feedback="danger"
checked
>
Option 1
</Radio>
<Radio
id="astro-btn-d2"
name="astro-btn-danger"
value="d2"
appearance="button"
feedback="danger"
>
Option 2
</Radio>
</div>
</div>
<div>
<h3>Warning</h3>
<div class={stack({ gap: "sm", direction: "row" })}>
<Radio
id="astro-btn-w1"
name="astro-btn-warning"
value="w1"
appearance="button"
feedback="warning"
checked
>
Option 1
</Radio>
<Radio
id="astro-btn-w2"
name="astro-btn-warning"
value="w2"
appearance="button"
feedback="warning"
>
Option 2
</Radio>
</div>
</div>
<div>
<h3>Success</h3>
<div class={stack({ gap: "sm", direction: "row" })}>
<Radio
id="astro-btn-s1"
name="astro-btn-success"
value="s1"
appearance="button"
feedback="success"
checked
>
Option 1
</Radio>
<Radio
id="astro-btn-s2"
name="astro-btn-success"
value="s2"
appearance="button"
feedback="success"
>
Option 2
</Radio>
</div>
</div>
</div>tab-horizontal and tab-vertical render a minimal accent-border indicator. Use feedback to change the accent color.
---
import Radio from "../Radio.astro";
import { stack } from "@pindoba/styled-system/patterns";
---
<div class={stack({ gap: "xl", direction: "column" })}>
<div>
<h3>Tab Horizontal</h3>
<div class={stack({ gap: "sm", direction: "row" })}>
<Radio
id="astro-tab-h1"
name="astro-tab-horiz"
value="h1"
appearance="tab-horizontal"
checked
>
All
</Radio>
<Radio
id="astro-tab-h2"
name="astro-tab-horiz"
value="h2"
appearance="tab-horizontal"
>
Active
</Radio>
<Radio
id="astro-tab-h3"
name="astro-tab-horiz"
value="h3"
appearance="tab-horizontal"
>
Archived
</Radio>
</div>
</div>
<div>
<h3>Tab Vertical</h3>
<div class={stack({ gap: "xs", direction: "column" })}>
<Radio
id="astro-tab-v1"
name="astro-tab-vert"
value="v1"
appearance="tab-vertical"
checked
>
Dashboard
</Radio>
<Radio
id="astro-tab-v2"
name="astro-tab-vert"
value="v2"
appearance="tab-vertical"
>
Settings
</Radio>
<Radio
id="astro-tab-v3"
name="astro-tab-vert"
value="v3"
appearance="tab-vertical"
>
Profile
</Radio>
</div>
</div>
<div>
<h3>Tab Horizontal — Danger feedback</h3>
<div class={stack({ gap: "sm", direction: "row" })}>
<Radio
id="astro-tab-hd1"
name="astro-tab-danger"
value="hd1"
appearance="tab-horizontal"
feedback="danger"
checked
>
Errors
</Radio>
<Radio
id="astro-tab-hd2"
name="astro-tab-danger"
value="hd2"
appearance="tab-horizontal"
feedback="danger"
>
Warnings
</Radio>
</div>
</div>
</div>Badges inside radio components scale with the component’s size via fontSize: 1rem.
---
import Radio from "../Radio.astro";
import Badge from "@pindoba/astro-badge";
import { stack } from "@pindoba/styled-system/patterns";
---
<div class={stack({ gap: "xl", direction: "column" })}>
<div>
<h3>radio appearance</h3>
<div class={stack({ gap: "sm", direction: "row", align: "center" })}>
<Radio
id="astro-badge-radio-sm"
name="astro-badge-radio"
value="sm"
size="sm"
checked
>
Small <Badge feedback="primary" size="sm">3</Badge>
</Radio>
<Radio
id="astro-badge-radio-md"
name="astro-badge-radio"
value="md"
size="md"
>
Medium <Badge feedback="primary" size="sm">3</Badge>
</Radio>
<Radio
id="astro-badge-radio-lg"
name="astro-badge-radio"
value="lg"
size="lg"
>
Large <Badge feedback="primary" size="sm">3</Badge>
</Radio>
</div>
</div>
<div>
<h3>button appearance</h3>
<div class={stack({ gap: "sm", direction: "row", align: "center" })}>
<Radio
id="astro-badge-btn-sm"
name="astro-badge-btn"
value="sm"
appearance="button"
size="sm"
checked
>
Small <Badge feedback="primary" size="sm">3</Badge>
</Radio>
<Radio
id="astro-badge-btn-md"
name="astro-badge-btn"
value="md"
appearance="button"
size="md"
>
Medium <Badge feedback="primary" size="sm">3</Badge>
</Radio>
<Radio
id="astro-badge-btn-lg"
name="astro-badge-btn"
value="lg"
appearance="button"
size="lg"
>
Large <Badge feedback="primary" size="sm">3</Badge>
</Radio>
</div>
</div>
</div>The passThrough prop provides per-slot escape hatches: style accepts a Panda CSS SystemStyleObject merged with the base styles, and props forwards arbitrary HTML attributes onto the element.
---
import Radio from "../Radio.astro";
import { stack } from "@pindoba/styled-system/patterns";
---
<div class={stack({ gap: "xl", direction: "column" })}>
<div>
<h3>Custom root style via passThrough</h3>
<div class={stack({ gap: "md", direction: "column" })}>
<Radio
id="astro-cust-1"
name="astro-cust"
value="c1"
passThrough={{
root: {
style: { gap: "lg", padding: "sm" },
},
}}
>
Extra padding
</Radio>
</div>
</div>
<div>
<h3>Custom input style via passThrough</h3>
<div class={stack({ gap: "md", direction: "column" })}>
<Radio
id="astro-cust-2"
name="astro-cust"
value="c2"
passThrough={{
input: {
style: { width: "2em", height: "2em" },
},
}}
>
Larger indicator
</Radio>
</div>
</div>
<div>
<h3>Custom props via passThrough</h3>
<div class={stack({ gap: "md", direction: "column" })}>
<Radio
id="astro-cust-3"
name="astro-cust"
value="c3"
passThrough={{
root: {
props: { "data-testid": "my-radio" },
},
input: {
props: { "aria-label": "Custom radio button" },
},
}}
>
With data attributes
</Radio>
</div>
</div>
</div>| Prop | |
|---|---|
appearance | appearance Visual style of the radio. radio: Default circular indicator. button: Styled as a button using Panel composition. tab-horizontal: Bottom-border accent tab. tab-vertical: Left-border accent tab. Type Default Required |
emphasis | emphasis Emphasis level for button appearance. primary: Solid accent background. secondary: Surface background with border. ghost: Transparent background. Type Default Required |
feedback | feedback Color scheme applied via colorPalette. For radio and tab appearances this sets the indicator accent color. For button appearance this sets the Panel feedback color. Type Default Required |
size | size Size of the component. Type Default Required |
fullWidth | fullWidth Expand the radio to fill its container width. Type Default Required |
id | id Unique identifier for the radio input, used for label association. Type Default Required |
passThrough | passThrough Per-slot style and attribute overrides. Type Default Required |
children | children Label content rendered next to the radio indicator. Type Default Required |
...rest | ...rest Standard HTML input attributes (excluding type and size). Type Default Required |