Zum Hauptinhalt springen

Radio

Die Radio-Komponente ermöglicht Benutzern, eine Option aus einer Gruppe auszuwählen. Sie unterstützt verschiedene Größen, Varianten und Zustände und kann als Button oder Karte dargestellt werden.

Import

import { Radio, RadioGroup } from '@smolitux/core';

Verwendung

Einfache Radio-Buttons

<RadioGroup name="fruit" label="Wählen Sie eine Frucht:">
<Radio value="apple" label="Apfel" />
<Radio value="banana" label="Banane" />
<Radio value="orange" label="Orange" />
</RadioGroup>

Radio-Gruppe mit Standardwert

const [value, setValue] = useState('female');

<RadioGroup
name="gender"
label="Geschlecht"
value={value}
onChange={(e) => setValue(e.target.value)}
>
<Radio value="male" label="Männlich" />
<Radio value="female" label="Weiblich" />
<Radio value="other" label="Divers" />
</RadioGroup>

Radio-Gruppe mit Hilfetext

<RadioGroup 
name="payment"
label="Zahlungsmethode"
helperText="Wählen Sie Ihre bevorzugte Zahlungsmethode."
>
<Radio value="credit" label="Kreditkarte" />
<Radio value="paypal" label="PayPal" />
<Radio value="bank" label="Banküberweisung" />
</RadioGroup>

Deaktivierte Radio-Buttons

<RadioGroup name="subscription" label="Abonnement">
<Radio value="free" label="Kostenlos" />
<Radio value="basic" label="Basic" />
<Radio value="premium" label="Premium" disabled />
</RadioGroup>

Radio-Gruppe mit Fehlermeldung

<RadioGroup 
name="terms"
label="Nutzungsbedingungen"
error="Bitte wählen Sie eine Option aus"
isInvalid
>
<Radio value="accept" label="Ich akzeptiere die Nutzungsbedingungen" />
<Radio value="decline" label="Ich lehne die Nutzungsbedingungen ab" />
</RadioGroup>

Verschiedene Größen

<RadioGroup name="size-xs" label="Extra klein" size="xs">
<Radio value="option1" label="Option 1" />
<Radio value="option2" label="Option 2" />
</RadioGroup>

<RadioGroup name="size-sm" label="Klein" size="sm">
<Radio value="option1" label="Option 1" />
<Radio value="option2" label="Option 2" />
</RadioGroup>

<RadioGroup name="size-md" label="Mittel" size="md">
<Radio value="option1" label="Option 1" />
<Radio value="option2" label="Option 2" />
</RadioGroup>

<RadioGroup name="size-lg" label="Groß" size="lg">
<Radio value="option1" label="Option 1" />
<Radio value="option2" label="Option 2" />
</RadioGroup>

<RadioGroup name="size-xl" label="Extra groß" size="xl">
<Radio value="option1" label="Option 1" />
<Radio value="option2" label="Option 2" />
</RadioGroup>

Verschiedene Varianten

<RadioGroup name="variant-solid" label="Solid">
<Radio value="option1" label="Option 1" variant="solid" />
<Radio value="option2" label="Option 2" variant="solid" />
</RadioGroup>

<RadioGroup name="variant-outline" label="Outline">
<Radio value="option1" label="Option 1" variant="outline" />
<Radio value="option2" label="Option 2" variant="outline" />
</RadioGroup>

<RadioGroup name="variant-filled" label="Filled">
<Radio value="option1" label="Option 1" variant="filled" />
<Radio value="option2" label="Option 2" variant="filled" />
</RadioGroup>

<RadioGroup name="variant-minimal" label="Minimal">
<Radio value="option1" label="Option 1" variant="minimal" />
<Radio value="option2" label="Option 2" variant="minimal" />
</RadioGroup>

Verschiedene Farbschemata

<RadioGroup name="color-primary" label="Primär">
<Radio value="option1" label="Option 1" colorScheme="primary" />
<Radio value="option2" label="Option 2" colorScheme="primary" />
</RadioGroup>

<RadioGroup name="color-secondary" label="Sekundär">
<Radio value="option1" label="Option 1" colorScheme="secondary" />
<Radio value="option2" label="Option 2" colorScheme="secondary" />
</RadioGroup>

<RadioGroup name="color-success" label="Erfolg">
<Radio value="option1" label="Option 1" colorScheme="success" />
<Radio value="option2" label="Option 2" colorScheme="success" />
</RadioGroup>

<RadioGroup name="color-danger" label="Gefahr">
<Radio value="option1" label="Option 1" colorScheme="danger" />
<Radio value="option2" label="Option 2" colorScheme="danger" />
</RadioGroup>

Label-Positionen

<RadioGroup name="label-right" label="Label rechts">
<Radio value="option1" label="Option 1" labelPosition="right" />
<Radio value="option2" label="Option 2" labelPosition="right" />
</RadioGroup>

<RadioGroup name="label-left" label="Label links">
<Radio value="option1" label="Option 1" labelPosition="left" />
<Radio value="option2" label="Option 2" labelPosition="left" />
</RadioGroup>

Verschiedene Anzeigetypen

<RadioGroup name="display-radio" label="Standard-Radio">
<Radio value="option1" label="Option 1" displayType="radio" />
<Radio value="option2" label="Option 2" displayType="radio" />
</RadioGroup>

<RadioGroup name="display-button" label="Button-Radio">
<Radio value="option1" label="Option 1" displayType="button" />
<Radio value="option2" label="Option 2" displayType="button" />
</RadioGroup>

<RadioGroup name="display-card" label="Karten-Radio">
<Radio value="option1" label="Option 1" displayType="card" />
<Radio value="option2" label="Option 2" displayType="card" />
</RadioGroup>

Horizontales Layout

<RadioGroup name="layout-horizontal" label="Horizontales Layout" layout="horizontal">
<Radio value="option1" label="Option 1" />
<Radio value="option2" label="Option 2" />
<Radio value="option3" label="Option 3" />
</RadioGroup>

Props

Radio Props

PropTypStandardBeschreibung
labelReactNode-Text-Label für den Radio-Button
helperTextReactNode-Hilfetext unter dem Radio-Button
errorReactNode-Fehlermeldung unter dem Radio-Button
successMessageReactNode-Erfolgsmeldung unter dem Radio-Button
size'xs' | 'sm' | 'md' | 'lg' | 'xl''md'Größe des Radio-Buttons
variant'solid' | 'outline' | 'filled' | 'minimal''solid'Visuelle Variante des Radio-Buttons
colorScheme'primary' | 'secondary' | 'success' | 'danger' | 'warning' | 'info' | 'neutral''primary'Farbschema des Radio-Buttons
borderedbooleanfalseOb der Radio-Button einen Rahmen haben soll
roundedbooleantrueOb der Radio-Button abgerundete Ecken haben soll
shadowbooleanfalseOb der Radio-Button einen Schatten haben soll
hoverablebooleantrueOb der Radio-Button einen Hover-Effekt haben soll
focusablebooleantrueOb der Radio-Button einen Fokus-Effekt haben soll
transitionbooleantrueOb der Radio-Button einen Übergangseffekt haben soll
transparentbooleanfalseOb der Radio-Button einen transparenten Hintergrund haben soll
tooltipstring-Tooltip-Text für den Radio-Button
isLoadingbooleanfalseOb der Radio-Button im Ladezustand ist
isValidbooleanfalseOb der Radio-Button gültig ist
isInvalidbooleanfalseOb der Radio-Button ungültig ist
isSuccessbooleanfalseOb der Radio-Button erfolgreich validiert ist
isDisabledbooleanfalseOb der Radio-Button deaktiviert ist
isRequiredbooleanfalseOb der Radio-Button erforderlich ist
labelPosition'left' | 'right''right'Position des Labels relativ zum Radio-Button
displayType'radio' | 'button' | 'card''radio'Anzeigetyp des Radio-Buttons
valuestring-Wert des Radio-Buttons
checkedboolean-Ob der Radio-Button ausgewählt ist (kontrollierter Modus)
defaultCheckedboolean-Ob der Radio-Button standardmäßig ausgewählt ist (unkontrollierter Modus)
onChange(event: React.ChangeEvent<HTMLInputElement>) => void-Callback-Funktion, die aufgerufen wird, wenn sich der Wert ändert
namestring-Name des Radio-Buttons für Formulare
idstring-ID des Radio-Buttons
classNamestring-Zusätzliche CSS-Klassen für den Radio-Button
labelClassNamestring-Zusätzliche CSS-Klassen für das Label
helperTextClassNamestring-Zusätzliche CSS-Klassen für den Hilfetext
errorClassNamestring-Zusätzliche CSS-Klassen für die Fehlermeldung

RadioGroup Props

PropTypStandardBeschreibung
namestring-Name für alle Radio-Buttons in der Gruppe
valuestring-Aktuell ausgewählter Wert (kontrollierter Modus)
onChange(event: React.ChangeEvent<HTMLInputElement>) => void-Callback bei Änderung der Auswahl
disabledbooleanfalseOb die Gruppe deaktiviert ist
requiredbooleanfalseOb die Gruppe erforderlich ist
errorReactNode-Fehlermeldung für die Gruppe
helperTextReactNode-Hilfetext für die Gruppe
successMessageReactNode-Erfolgsmeldung für die Gruppe
labelReactNode-Label für die Gruppe
size'xs' | 'sm' | 'md' | 'lg' | 'xl''md'Größe der Radio-Buttons in der Gruppe
layout'vertical' | 'horizontal''vertical'Layout der Gruppe
classNamestring-Zusätzliche CSS-Klassen für die Gruppe
isValidbooleanfalseOb die Gruppe gültig ist
isInvalidbooleanfalseOb die Gruppe ungültig ist
isSuccessbooleanfalseOb die Gruppe erfolgreich validiert ist
isLoadingbooleanfalseOb die Gruppe im Ladezustand ist
childrenReactNode-Die Radio-Buttons in der Gruppe

Barrierefreiheit

Die Radio-Komponente ist für Barrierefreiheit optimiert:

  • Korrekte Verknüpfung von Label und Radio-Button über IDs
  • Unterstützung für aria-invalid bei Fehlern
  • Unterstützung für aria-describedby für Hilfetexte und Fehlermeldungen
  • Tastaturnavigation mit Leertaste und Pfeiltasten

Beispiele

Radio-Buttons mit Icons

import { HomeIcon, BriefcaseIcon, CogIcon } from '@heroicons/react/outline';

<RadioGroup name="navigation" label="Navigation">
<Radio
value="home"
label={
<div className="flex items-center">
<HomeIcon className="w-5 h-5 mr-2" />
<span>Home</span>
</div>
}
/>
<Radio
value="work"
label={
<div className="flex items-center">
<BriefcaseIcon className="w-5 h-5 mr-2" />
<span>Arbeit</span>
</div>
}
/>
<Radio
value="settings"
label={
<div className="flex items-center">
<CogIcon className="w-5 h-5 mr-2" />
<span>Einstellungen</span>
</div>
}
/>
</RadioGroup>

Radio-Karten

function RadioCards() {
const [plan, setPlan] = useState('basic');

const plans = [
{
value: 'basic',
name: 'Basic',
price: '€9.99',
features: ['10 GB Speicher', '1 Benutzer', 'E-Mail-Support']
},
{
value: 'pro',
name: 'Professional',
price: '€19.99',
features: ['100 GB Speicher', '5 Benutzer', 'Prioritäts-Support']
},
{
value: 'enterprise',
name: 'Enterprise',
price: '€49.99',
features: ['Unbegrenzter Speicher', 'Unbegrenzte Benutzer', '24/7 Support']
}
];

return (
<RadioGroup
name="plan"
label="Wählen Sie einen Plan"
value={plan}
onChange={(e) => setPlan(e.target.value)}
layout="horizontal"
>
<div className="grid grid-cols-1 md:grid-cols-3 gap-4">
{plans.map(planOption => (
<Radio
key={planOption.value}
value={planOption.value}
displayType="card"
className="h-full"
label={
<div className="p-4">
<h3 className="text-lg font-bold">{planOption.name}</h3>
<div className="text-2xl font-bold my-2">{planOption.price}</div>
<ul className="mt-4 space-y-2">
{planOption.features.map((feature, index) => (
<li key={index} className="flex items-center">
<svg className="w-4 h-4 mr-2 text-green-500" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M5 13l4 4L19 7" />
</svg>
{feature}
</li>
))}
</ul>
</div>
}
/>
))}
</div>
</RadioGroup>
);
}

Radio-Buttons als Segmented Control

function SegmentedControl() {
const [view, setView] = useState('day');

return (
<RadioGroup
name="view"
value={view}
onChange={(e) => setView(e.target.value)}
layout="horizontal"
className="inline-flex bg-gray-100 p-1 rounded-lg"
>
<Radio
value="day"
label="Tag"
displayType="button"
className={`px-4 py-2 rounded-md ${view === 'day' ? 'bg-white shadow' : ''}`}
/>
<Radio
value="week"
label="Woche"
displayType="button"
className={`px-4 py-2 rounded-md ${view === 'week' ? 'bg-white shadow' : ''}`}
/>
<Radio
value="month"
label="Monat"
displayType="button"
className={`px-4 py-2 rounded-md ${view === 'month' ? 'bg-white shadow' : ''}`}
/>
</RadioGroup>
);
}

Radio-Gruppe mit Validierung

function ValidatedRadioGroup() {
const [value, setValue] = useState('');
const [error, setError] = useState('');

const handleChange = (e) => {
setValue(e.target.value);
setError('');
};

const handleSubmit = (e) => {
e.preventDefault();

if (!value) {
setError('Bitte wählen Sie eine Option aus.');
return;
}

alert(`Sie haben "${value}" ausgewählt.`);
};

return (
<form onSubmit={handleSubmit}>
<RadioGroup
name="options"
label="Wählen Sie eine Option"
value={value}
onChange={handleChange}
error={error}
isInvalid={!!error}
required
>
<Radio value="option1" label="Option 1" />
<Radio value="option2" label="Option 2" />
<Radio value="option3" label="Option 3" />
</RadioGroup>

<button
type="submit"
className="mt-4 px-4 py-2 bg-primary-600 text-white rounded hover:bg-primary-700"
>
Absenden
</button>
</form>
);
}