🚧 VeloxKit is pre-release software. APIs may change before v1.0. Get started →
Documentation
Form Components
Radio

RadioGroup / Radio Stable WINMACLNX

A group of mutually exclusive radio buttons. RadioGroup manages shared state; Radio renders individual options.

Import

import { RadioGroup, Radio } from 'veloxkit'

Basic usage

const [theme, setTheme] = useState('system')
 
<RadioGroup value={theme} onValueChange={setTheme}>
  <Radio value="light"  label="Light"  />
  <Radio value="dark"   label="Dark"   />
  <Radio value="system" label="System" />
</RadioGroup>

Props

RadioGroup

PropTypeDefaultDescription
valuestringCurrently selected value (required)
onValueChange(value: string) => voidCalled when selection changes
styleViewStyleContainer style
childrenReactNode<Radio> elements

Radio

PropTypeDefaultDescription
valuestringThe value this option represents (required)
labelstringDisplay text
disabledbooleanfalsePrevents selection

Examples

Horizontal alignment

<RadioGroup
  value={size}
  onValueChange={setSize}
  style={{ flexDirection: 'row', gap: 24 }}
>
  <Radio value="sm" label="Small"  />
  <Radio value="md" label="Medium" />
  <Radio value="lg" label="Large"  />
</RadioGroup>

With form validation

const [plan, setPlan] = useState('')
const [error, setError] = useState('')
 
const handleSubmit = () => {
  if (!plan) {
    setError('Please select a plan.')
    return
  }
  // proceed
}
 
return (
  <View style={{ gap: 16 }}>
    <Text style={{ fontSize: 16, fontWeight: '600' }}>Choose a plan</Text>
 
    <RadioGroup value={plan} onValueChange={v => { setPlan(v); setError('') }}>
      <Radio value="free"  label="Free — 5 projects" />
      <Radio value="pro"   label="Pro — Unlimited projects" />
      <Radio value="team"  label="Team — Shared workspace" />
    </RadioGroup>
 
    {error ? <Text style={{ color: '#f87171', fontSize: 13 }}>{error}</Text> : null}
 
    <Pressable onPress={handleSubmit}
               style={{ padding: 12, backgroundColor: '#7aa2f7', borderRadius: 8 }}>
      <Text style={{ color: '#171923', fontWeight: '600' }}>Continue</Text>
    </Pressable>
  </View>
)

Cards instead of dots

If you want a more prominent selection UI, combine RadioGroup state with Pressable children:

const [selected, setSelected] = useState('monthly')
 
const plans = [
  { value: 'monthly', label: 'Monthly', price: '$9/mo' },
  { value: 'annual',  label: 'Annual',  price: '$79/yr  (save 27%)' },
]
 
<View style={{ gap: 8 }}>
  {plans.map(p => (
    <Pressable
      key={p.value}
      onPress={() => setSelected(p.value)}
      style={{
        padding: 16,
        borderRadius: 10,
        borderWidth: 2,
        borderColor: selected === p.value ? '#7aa2f7' : '#2a2a3e',
        backgroundColor: selected === p.value ? '#1e1e3a' : 'transparent',
      }}
    >
      <Text style={{ fontWeight: '600' }}>{p.label}</Text>
      <Text style={{ color: '#9999bb', fontSize: 13 }}>{p.price}</Text>
    </Pressable>
  ))}
</View>