Skip to main content
Glama
radio-usage.md13.3 kB
# Radio Group Component Usage ## Overview The radio group component provides accessible radio buttons for single selection from a list of options. It supports various layouts including vertical lists, horizontal groups, and card-style selections. Radio groups are built using native HTML radio inputs with enhanced styling. ## JavaScript Requirements ### Required Scripts ```html <!-- Include Basecoat CSS and JavaScript --> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/basecoat-css@latest/dist/basecoat.cdn.min.css"> <script src="https://cdn.jsdelivr.net/npm/basecoat-css@latest/dist/js/basecoat.min.js" defer></script> <script src="https://cdn.jsdelivr.net/npm/basecoat-css@latest/dist/js/radio-group.min.js" defer></script> ``` ## HTML Structure ### Basic Radio Group ```html <fieldset class="radio-group grid gap-3" role="radiogroup"> <legend class="label mb-2">Select an option</legend> <label class="label gap-3"> <input type="radio" name="option" value="option1" checked> Option 1 </label> <label class="label gap-3"> <input type="radio" name="option" value="option2"> Option 2 </label> <label class="label gap-3"> <input type="radio" name="option" value="option3"> Option 3 </label> </fieldset> ``` ### Radio with Description ```html <fieldset class="radio-group grid gap-4" role="radiogroup"> <legend class="label mb-2">Notification frequency</legend> <div class="flex items-start gap-3"> <input type="radio" id="instant" name="frequency" value="instant" class="mt-1"> <div class="grid gap-1"> <label for="instant" class="label">Instant</label> <p class="text-muted-foreground text-sm">Get notified immediately for all activity</p> </div> </div> <div class="flex items-start gap-3"> <input type="radio" id="daily" name="frequency" value="daily" class="mt-1"> <div class="grid gap-1"> <label for="daily" class="label">Daily Digest</label> <p class="text-muted-foreground text-sm">Receive a summary once per day</p> </div> </div> <div class="flex items-start gap-3"> <input type="radio" id="weekly" name="frequency" value="weekly" class="mt-1"> <div class="grid gap-1"> <label for="weekly" class="label">Weekly Digest</label> <p class="text-muted-foreground text-sm">Receive a summary once per week</p> </div> </div> </fieldset> ``` ## States ### Default State ```html <input type="radio" name="option" value="default"> ``` ### Selected State ```html <input type="radio" name="option" value="selected" checked> ``` ### Disabled State ```html <input type="radio" name="option" value="disabled" disabled> <input type="radio" name="option" value="disabled-checked" checked disabled> ``` ### Invalid State ```html <input type="radio" name="option" value="invalid" aria-invalid="true"> ``` ## Implementation Examples ### Plan Selection ```html <form class="form space-y-6"> <fieldset class="radio-group grid gap-4" role="radiogroup"> <legend class="text-lg font-medium mb-2">Choose a plan</legend> <label class="flex items-start gap-3 p-4 border rounded-lg cursor-pointer hover:bg-accent/50 has-[:checked]:border-primary has-[:checked]:bg-primary/5"> <input type="radio" name="plan" value="free" class="mt-1"> <div class="grid gap-1 flex-1"> <div class="flex items-center justify-between"> <span class="font-medium">Free</span> <span class="text-muted-foreground">$0/month</span> </div> <p class="text-muted-foreground text-sm">Perfect for trying out our service</p> </div> </label> <label class="flex items-start gap-3 p-4 border rounded-lg cursor-pointer hover:bg-accent/50 has-[:checked]:border-primary has-[:checked]:bg-primary/5"> <input type="radio" name="plan" value="pro" class="mt-1" checked> <div class="grid gap-1 flex-1"> <div class="flex items-center justify-between"> <span class="font-medium">Pro</span> <span class="text-muted-foreground">$29/month</span> </div> <p class="text-muted-foreground text-sm">Best for professionals and small teams</p> </div> </label> <label class="flex items-start gap-3 p-4 border rounded-lg cursor-pointer hover:bg-accent/50 has-[:checked]:border-primary has-[:checked]:bg-primary/5"> <input type="radio" name="plan" value="enterprise" class="mt-1"> <div class="grid gap-1 flex-1"> <div class="flex items-center justify-between"> <span class="font-medium">Enterprise</span> <span class="text-muted-foreground">Custom</span> </div> <p class="text-muted-foreground text-sm">For large organizations with custom needs</p> </div> </label> </fieldset> <button type="submit" class="btn">Continue</button> </form> ``` ### Shipping Options ```html <fieldset class="radio-group grid gap-3" role="radiogroup"> <legend class="label mb-2">Shipping Method</legend> <label class="flex items-center justify-between p-3 border rounded-lg cursor-pointer hover:bg-accent/50 has-[:checked]:border-primary"> <div class="flex items-center gap-3"> <input type="radio" name="shipping" value="standard"> <div> <span class="font-medium">Standard Shipping</span> <p class="text-muted-foreground text-sm">5-7 business days</p> </div> </div> <span class="font-medium">$4.99</span> </label> <label class="flex items-center justify-between p-3 border rounded-lg cursor-pointer hover:bg-accent/50 has-[:checked]:border-primary"> <div class="flex items-center gap-3"> <input type="radio" name="shipping" value="express" checked> <div> <span class="font-medium">Express Shipping</span> <p class="text-muted-foreground text-sm">2-3 business days</p> </div> </div> <span class="font-medium">$9.99</span> </label> <label class="flex items-center justify-between p-3 border rounded-lg cursor-pointer hover:bg-accent/50 has-[:checked]:border-primary"> <div class="flex items-center gap-3"> <input type="radio" name="shipping" value="overnight"> <div> <span class="font-medium">Overnight Shipping</span> <p class="text-muted-foreground text-sm">Next business day</p> </div> </div> <span class="font-medium">$19.99</span> </label> </fieldset> ``` ### Horizontal Radio Group ```html <fieldset class="radio-group" role="radiogroup"> <legend class="label mb-3">Size</legend> <div class="flex gap-3"> <label class="label gap-2"> <input type="radio" name="size" value="small"> Small </label> <label class="label gap-2"> <input type="radio" name="size" value="medium" checked> Medium </label> <label class="label gap-2"> <input type="radio" name="size" value="large"> Large </label> </div> </fieldset> ``` ### Rating Selection ```html <fieldset class="radio-group" role="radiogroup" aria-label="Rating"> <legend class="label mb-3">How would you rate your experience?</legend> <div class="flex gap-2"> <label class="flex flex-col items-center gap-1 cursor-pointer"> <input type="radio" name="rating" value="1" class="sr-only peer"> <span class="text-2xl peer-checked:scale-110 transition-transform">😞</span> <span class="text-xs text-muted-foreground">Poor</span> </label> <label class="flex flex-col items-center gap-1 cursor-pointer"> <input type="radio" name="rating" value="2" class="sr-only peer"> <span class="text-2xl peer-checked:scale-110 transition-transform">😐</span> <span class="text-xs text-muted-foreground">Fair</span> </label> <label class="flex flex-col items-center gap-1 cursor-pointer"> <input type="radio" name="rating" value="3" class="sr-only peer"> <span class="text-2xl peer-checked:scale-110 transition-transform">🙂</span> <span class="text-xs text-muted-foreground">Good</span> </label> <label class="flex flex-col items-center gap-1 cursor-pointer"> <input type="radio" name="rating" value="4" class="sr-only peer"> <span class="text-2xl peer-checked:scale-110 transition-transform">😊</span> <span class="text-xs text-muted-foreground">Great</span> </label> <label class="flex flex-col items-center gap-1 cursor-pointer"> <input type="radio" name="rating" value="5" class="sr-only peer"> <span class="text-2xl peer-checked:scale-110 transition-transform">🤩</span> <span class="text-xs text-muted-foreground">Excellent</span> </label> </div> </fieldset> ``` ## JavaScript Events ### Initialization Event ```javascript document.addEventListener('basecoat:initialized', function(e) { if (e.target.matches('.radio-group')) { console.log('Radio group initialized'); } }); ``` ### Change Event Handling ```javascript const radioGroup = document.querySelectorAll('input[name="plan"]'); radioGroup.forEach(radio => { radio.addEventListener('change', function() { if (this.checked) { console.log('Selected plan:', this.value); updatePriceDisplay(this.value); } }); }); function updatePriceDisplay(plan) { const prices = { free: 0, pro: 29, enterprise: 'Custom' }; document.getElementById('price-display').textContent = typeof prices[plan] === 'number' ? `$${prices[plan]}/month` : prices[plan]; } ``` ### Programmatic Selection ```javascript function selectRadio(name, value) { const radio = document.querySelector(`input[name="${name}"][value="${value}"]`); if (radio) { radio.checked = true; radio.dispatchEvent(new Event('change', { bubbles: true })); } } // Usage selectRadio('plan', 'pro'); ``` ## Accessibility Guidelines ### ARIA Requirements - Use `role="radiogroup"` on the container - Provide a `<legend>` or `aria-label` for the group - Each radio should have an associated label - Use `aria-describedby` for additional descriptions ### Example with Full Accessibility ```html <fieldset class="radio-group grid gap-3" role="radiogroup" aria-labelledby="payment-legend" aria-describedby="payment-desc" > <legend id="payment-legend" class="label mb-1">Payment Method</legend> <p id="payment-desc" class="text-muted-foreground text-sm mb-3"> Select your preferred payment method </p> <div class="flex items-start gap-3"> <input type="radio" id="credit-card" name="payment" value="credit-card" aria-describedby="credit-desc" class="mt-1" > <div class="grid gap-1"> <label for="credit-card" class="label">Credit Card</label> <p id="credit-desc" class="text-muted-foreground text-sm"> Visa, Mastercard, American Express </p> </div> </div> <div class="flex items-start gap-3"> <input type="radio" id="paypal" name="payment" value="paypal" aria-describedby="paypal-desc" class="mt-1" > <div class="grid gap-1"> <label for="paypal" class="label">PayPal</label> <p id="paypal-desc" class="text-muted-foreground text-sm"> Pay securely with your PayPal account </p> </div> </div> </fieldset> ``` ### Keyboard Navigation - **Arrow Up/Down**: Move between radio options (vertical layout) - **Arrow Left/Right**: Move between radio options (horizontal layout) - **Space**: Select the focused option - **Tab**: Move focus to/from the radio group ## Best Practices ### When to Use Radio Groups - Single selection from 2-7 options - When all options need to be visible - When comparison between options is important - Mutually exclusive choices ### When to Use Other Components - Many options (7+): Use Select/Combobox instead - On/Off binary: Use Switch instead - Multiple selections: Use Checkboxes instead ### Visual Guidelines - Display all options at once when possible - Use consistent spacing between options - Clearly indicate the selected state - Group related options logically ### Label Guidelines - Keep option labels concise - Use parallel grammatical structure - Order options logically (alphabetically, by frequency, etc.) - Include additional context with descriptions when needed ## Form Integration ### Using with Form Class ```html <form class="form grid gap-6"> <fieldset class="radio-group grid gap-3" role="radiogroup"> <legend class="label mb-2">Preferred contact method</legend> <label class="label gap-3"> <input type="radio" name="contact" value="email" required> Email </label> <label class="label gap-3"> <input type="radio" name="contact" value="phone"> Phone </label> <label class="label gap-3"> <input type="radio" name="contact" value="text"> Text Message </label> </fieldset> <button type="submit" class="btn">Submit</button> </form> ``` ### Validation ```javascript const form = document.querySelector('form'); form.addEventListener('submit', function(e) { const selected = document.querySelector('input[name="contact"]:checked'); if (!selected) { e.preventDefault(); // Show error const fieldset = document.querySelector('.radio-group'); fieldset.setAttribute('aria-invalid', 'true'); // Display error message } }); ```

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/GustavoGomezPG/basecoat-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server