A layout wrapper that combines inputs, buttons, checkboxes, radios, and other controls into a single cohesive unit. The group owns the border and focus outline — inner components surrender their own borders and rings so the group presents as one unified element.
Group buttons, checkbox buttons, or radio buttons into a single connected control. All variants suppress their own borders and focus rings so the group presents as one cohesive element.
---
import Group from "../Group.astro";
import Input from "@pindoba/astro-input";
import Button from "@pindoba/astro-button";
import Checkbox from "@pindoba/astro-checkbox";
import Radio from "@pindoba/astro-radio";
import { stack } from "@pindoba/styled-system/patterns";
---
<div class={stack({ gap: "xl", direction: "column", width: "full" })}>
<div>
<h3>Full width — search bar</h3>
<Group fullWidth>
<Input fullWidth placeholder="Search..." />
<Button>Search</Button>
</Group>
</div>
<div>
<h3>Full width — segmented control</h3>
<Group fullWidth>
<Radio
id="group-fw-env-dev"
appearance="button"
name="group-fw-env"
value="dev"
fullWidth
checked>Dev</Radio
>
<Radio
id="group-fw-env-staging"
appearance="button"
name="group-fw-env"
value="staging"
fullWidth>Staging</Radio
>
<Radio
id="group-fw-env-prod"
appearance="button"
name="group-fw-env"
value="prod"
fullWidth>Prod</Radio
>
</Group>
</div>
<div>
<h3>Input with button</h3>
<Group>
<Input placeholder="Search..." />
<Button>Search</Button>
</Group>
</div>
<div>
<h3>Button on both sides</h3>
<Group>
<Button emphasis="secondary">-</Button>
<Input placeholder="Enter value" />
<Button emphasis="secondary">+</Button>
</Group>
</div>
<div>
<h3>Multiple inputs</h3>
<Group>
<Input placeholder="First name" />
<Input placeholder="Last name" />
</Group>
</div>
<div>
<h3>Button group</h3>
<Group>
<Button emphasis="secondary">Cut</Button>
<Button emphasis="secondary">Copy</Button>
<Button emphasis="secondary">Paste</Button>
</Group>
</div>
<div>
<h3>Mixed feedback buttons</h3>
<Group>
<Button feedback="success">Save</Button>
<Button feedback="warning" emphasis="secondary">Draft</Button>
<Button feedback="danger" emphasis="secondary">Delete</Button>
</Group>
</div>
<div>
<h3>Tab horizontal</h3>
<Group>
<Radio
id="group-tab-h-all"
appearance="tab-horizontal"
name="group-tab-h"
value="all"
checked>All</Radio
>
<Radio
id="group-tab-h-active"
appearance="tab-horizontal"
name="group-tab-h"
value="active">Active</Radio
>
<Radio
id="group-tab-h-archived"
appearance="tab-horizontal"
name="group-tab-h"
value="archived">Archived</Radio
>
</Group>
</div>
<div>
<h3>Tab vertical</h3>
<Group orientation="vertical">
<Radio
id="group-tab-v-dashboard"
appearance="tab-vertical"
name="group-tab-v"
value="dashboard"
checked>Dashboard</Radio
>
<Radio
id="group-tab-v-settings"
appearance="tab-vertical"
name="group-tab-v"
value="settings">Settings</Radio
>
<Radio
id="group-tab-v-profile"
appearance="tab-vertical"
name="group-tab-v"
value="profile">Profile</Radio
>
</Group>
</div>
<div>
<h3>Vertical button group</h3>
<Group orientation="vertical">
<Button emphasis="secondary">Cut</Button>
<Button emphasis="secondary">Copy</Button>
<Button emphasis="secondary">Paste</Button>
</Group>
</div>
<div>
<h3>Vertical checkbox group</h3>
<Group orientation="vertical">
<Checkbox appearance="button" size="md">Bold</Checkbox>
<Checkbox appearance="button" size="md">Italic</Checkbox>
<Checkbox appearance="button" size="md">Underline</Checkbox>
</Group>
</div>
<div>
<h3>Vertical radio button group</h3>
<Group orientation="vertical">
<Radio
id="group-view-v-list"
appearance="button"
size="md"
name="view-v"
value="list">List</Radio
>
<Radio
id="group-view-v-grid"
appearance="button"
size="md"
name="view-v"
value="grid">Grid</Radio
>
<Radio
id="group-view-v-table"
appearance="button"
size="md"
name="view-v"
value="table">Table</Radio
>
</Group>
</div>
<div>
<h3>Checkbox button group</h3>
<Group>
<Checkbox appearance="button" size="md">Bold</Checkbox>
<Checkbox appearance="button" size="md">Italic</Checkbox>
<Checkbox appearance="button" size="md">Underline</Checkbox>
</Group>
</div>
<div>
<h3>Radio button group</h3>
<Group>
<Radio
id="group-view-list"
appearance="button"
size="md"
name="view"
value="list">List</Radio
>
<Radio
id="group-view-grid"
appearance="button"
size="md"
name="view"
value="grid">Grid</Radio
>
<Radio
id="group-view-table"
appearance="button"
size="md"
name="view"
value="table">Table</Radio
>
</Group>
</div>
</div>Apply a semantic color to the group outline and pass matching feedback to the inner components.
---
import Group from "../Group.astro";
import Input from "@pindoba/astro-input";
import Button from "@pindoba/astro-button";
import { stack } from "@pindoba/styled-system/patterns";
---
<div class={stack({ gap: "md", direction: "column", width: "full" })}>
<Group feedback="neutral">
<Input placeholder="Neutral" />
<Button>Go</Button>
</Group>
<Group feedback="primary">
<Input feedback="primary" placeholder="Primary" />
<Button>Go</Button>
</Group>
<Group feedback="success">
<Input feedback="success" placeholder="Success" />
<Button feedback="success">Go</Button>
</Group>
<Group feedback="danger">
<Input feedback="danger" placeholder="Danger" />
<Button feedback="danger">Go</Button>
</Group>
<Group feedback="warning">
<Input feedback="warning" placeholder="Warning" />
<Button feedback="warning">Go</Button>
</Group>
</div>Use size to control the group’s border radius. Match it to the size of the inner controls so the rounding is proportional.
---
import Group from "../Group.astro";
import Input from "@pindoba/astro-input";
import Button from "@pindoba/astro-button";
import { stack } from "@pindoba/styled-system/patterns";
---
<div class={stack({ gap: "md", direction: "column", width: "full" })}>
<Group size="xs">
<Input size="xs" placeholder="Extra small" />
<Button size="xs">Go</Button>
</Group>
<Group size="sm">
<Input size="sm" placeholder="Small" />
<Button size="sm">Go</Button>
</Group>
<Group size="md">
<Input size="md" placeholder="Medium" />
<Button size="md">Go</Button>
</Group>
<Group size="lg">
<Input size="lg" placeholder="Large" />
<Button size="lg">Go</Button>
</Group>
</div>The passThrough prop provides an escape hatch for the root element: style accepts a Panda CSS SystemStyleObject and props forwards arbitrary HTML attributes.
---
import Group from "../Group.astro";
import Input from "@pindoba/astro-input";
import Button from "@pindoba/astro-button";
import { stack } from "@pindoba/styled-system/patterns";
---
<div class={stack({ gap: "xl", direction: "column" })}>
<div>
<h3>Custom style via passThrough</h3>
<Group passThrough={{ root: { style: { borderRadius: "full" } } }}>
<Input
placeholder="Search..."
passThrough={{ root: { style: { borderRadius: "full" } } }}
/>
<Button shape="pill">Go</Button>
</Group>
</div>
<div>
<h3>Custom props via passThrough</h3>
<Group
passThrough={{
root: {
props: { "data-testid": "search-group" },
},
}}
>
<Input placeholder="Search..." />
<Button>Search</Button>
</Group>
</div>
</div>| prop | type | default | req | description |
|---|---|---|---|---|
| feedback | "neutral""primary""success""danger""warning" | "neutral" | Semantic feedback color scheme applied to the group outline. neutral: Default. primary: Primary color. success: Green. danger: Red. warning: Orange. | |
| size | "xs""sm""md""lg" | "md" | Border radius matching the size of the inner controls. xs: Extra small. sm: Small. md: Default. lg: Large. | |
| passThrough | { root?: { style?: SystemStyleObject; props?: Record<string, unknown> } } | undefined | Custom styling and props for the group root element. | |
| ...rest | HTMLAttributes<HTMLDivElement> | - | Standard HTML div attributes passed to the group wrapper element. |