10.1k

Radio Stack

PreviousNext

A stacked radio group with collapsible content panels, perfect for selection flows with additional details like shipping options or payment methods.

<script setup lang="ts">
import {
  RadioStack,
  RadioStackContent,
  RadioStackItem,
  RadioStackTrigger,
} from '@/components/ui/radio-stack'
import { ref } from 'vue'

const selected = ref('standard')
</script>

<template>
  <RadioStack v-model="selected" class="w-full max-w-md">
    <RadioStackItem value="standard">
      <RadioStackTrigger value="standard">
        <div class="flex flex-col">
          <span>Standard Shipping</span>
          <span class="text-sm font-normal text-muted-foreground">Free</span>
        </div>
      </RadioStackTrigger>
      <RadioStackContent value="standard">
        <p class="text-sm text-muted-foreground">
          Delivery in 5-7 business days. Available for all orders.
        </p>
      </RadioStackContent>
    </RadioStackItem>

    <RadioStackItem value="express">
      <RadioStackTrigger value="express">
        <div class="flex flex-col">
          <span>Express Shipping</span>
          <span class="text-sm font-normal text-muted-foreground">$9.99</span>
        </div>
      </RadioStackTrigger>
      <RadioStackContent value="express">
        <p class="text-sm text-muted-foreground">
          Delivery in 2-3 business days. Orders placed before 2pm ship same day.
        </p>
      </RadioStackContent>
    </RadioStackItem>

    <RadioStackItem value="overnight">
      <RadioStackTrigger value="overnight">
        <div class="flex flex-col">
          <span>Overnight Shipping</span>
          <span class="text-sm font-normal text-muted-foreground">$24.99</span>
        </div>
      </RadioStackTrigger>
      <RadioStackContent value="overnight">
        <p class="text-sm text-muted-foreground">
          Next business day delivery. Orders placed before 12pm ship same day.
        </p>
      </RadioStackContent>
    </RadioStackItem>
  </RadioStack>
</template>

Installation

pnpm dlx @frontic/ui add radio-stack

Usage

<script setup lang="ts">
import {
  RadioStack,
  RadioStackContent,
  RadioStackItem,
  RadioStackTrigger,
} from '@/components/ui/radio-stack'

const selected = ref('standard')
</script>

<template>
  <RadioStack v-model="selected">
    <RadioStackItem value="standard">
      <RadioStackTrigger value="standard">
        Standard Shipping
      </RadioStackTrigger>
      <RadioStackContent value="standard">
        Delivery in 5-7 business days
      </RadioStackContent>
    </RadioStackItem>

    <RadioStackItem value="express">
      <RadioStackTrigger value="express">
        Express Shipping
      </RadioStackTrigger>
      <RadioStackContent value="express">
        Delivery in 2-3 business days
      </RadioStackContent>
    </RadioStackItem>
  </RadioStack>
</template>

Components

The Radio Stack is composed of several sub-components:

ComponentDescription
RadioStackThe root container that manages state and provides context
RadioStackItemWrapper for each radio option
RadioStackTriggerThe clickable area with the radio indicator
RadioStackContentCollapsible content that expands when the option is selected
RadioStackIndicatorThe visual radio button indicator (used internally by RadioStackTrigger)

Examples

Default

<script setup lang="ts">
import {
  RadioStack,
  RadioStackContent,
  RadioStackItem,
  RadioStackTrigger,
} from '@/components/ui/radio-stack'
import { ref } from 'vue'

const selected = ref('standard')
</script>

<template>
  <RadioStack v-model="selected" class="w-full max-w-md">
    <RadioStackItem value="standard">
      <RadioStackTrigger value="standard">
        <div class="flex flex-col">
          <span>Standard Shipping</span>
          <span class="text-sm font-normal text-muted-foreground">Free</span>
        </div>
      </RadioStackTrigger>
      <RadioStackContent value="standard">
        <p class="text-sm text-muted-foreground">
          Delivery in 5-7 business days. Available for all orders.
        </p>
      </RadioStackContent>
    </RadioStackItem>

    <RadioStackItem value="express">
      <RadioStackTrigger value="express">
        <div class="flex flex-col">
          <span>Express Shipping</span>
          <span class="text-sm font-normal text-muted-foreground">$9.99</span>
        </div>
      </RadioStackTrigger>
      <RadioStackContent value="express">
        <p class="text-sm text-muted-foreground">
          Delivery in 2-3 business days. Orders placed before 2pm ship same day.
        </p>
      </RadioStackContent>
    </RadioStackItem>

    <RadioStackItem value="overnight">
      <RadioStackTrigger value="overnight">
        <div class="flex flex-col">
          <span>Overnight Shipping</span>
          <span class="text-sm font-normal text-muted-foreground">$24.99</span>
        </div>
      </RadioStackTrigger>
      <RadioStackContent value="overnight">
        <p class="text-sm text-muted-foreground">
          Next business day delivery. Orders placed before 12pm ship same day.
        </p>
      </RadioStackContent>
    </RadioStackItem>
  </RadioStack>
</template>

With Outline Variant

<script setup lang="ts">
import {
  RadioStack,
  RadioStackContent,
  RadioStackItem,
  RadioStackTrigger,
} from '@/components/ui/radio-stack'
import { ref } from 'vue'

const selected = ref('card')
</script>

<template>
  <RadioStack v-model="selected" variant="outline" class="w-full max-w-md">
    <RadioStackItem value="card">
      <RadioStackTrigger value="card">
        <div class="flex flex-col">
          <span>Credit Card</span>
          <span class="text-sm font-normal text-muted-foreground">Visa, Mastercard, Amex</span>
        </div>
      </RadioStackTrigger>
      <RadioStackContent value="card">
        <p class="text-sm text-muted-foreground">
          Pay securely with your credit or debit card. We accept all major cards.
        </p>
      </RadioStackContent>
    </RadioStackItem>

    <RadioStackItem value="paypal">
      <RadioStackTrigger value="paypal">
        <div class="flex flex-col">
          <span>PayPal</span>
          <span class="text-sm font-normal text-muted-foreground">Pay with your PayPal account</span>
        </div>
      </RadioStackTrigger>
      <RadioStackContent value="paypal">
        <p class="text-sm text-muted-foreground">
          You will be redirected to PayPal to complete your purchase securely.
        </p>
      </RadioStackContent>
    </RadioStackItem>

    <RadioStackItem value="bank">
      <RadioStackTrigger value="bank">
        <div class="flex flex-col">
          <span>Bank Transfer</span>
          <span class="text-sm font-normal text-muted-foreground">Direct bank transfer</span>
        </div>
      </RadioStackTrigger>
      <RadioStackContent value="bank">
        <p class="text-sm text-muted-foreground">
          Make payment directly from your bank account. Order ships after payment confirmation.
        </p>
      </RadioStackContent>
    </RadioStackItem>
  </RadioStack>
</template>