RadioGroup

The RadioGroup component is a fundamental building block for displaying text in your React Native applications. It is designed to render styled text with various customization options, making it versatile for a wide range of use cases.

Expo component example
Airplane
Train or bus

Installation

To use the RadioGroup component, make sure first that you have initiated the library.

CLI

This command will add the RadioGroup component file to your project and install any necessary dependencies.

npx mallaui@latest add RadioGroup

Manual

Copy and paste the following code into your project. Make sure to install the necessary dependencies first and update path to match your project setup.

RadioGroup.tsx

import {Pressable, StyleSheet, View, ViewStyle} from 'react-native';
import {useStyles} from '../../styles/useStyles';
import {AppTheme} from '../../styles/theme';
import {FC, createContext, useContext, useState} from 'react';
import {Text} from './Text';
import {DescriptionText} from './DescriptionText';

type RadioGroupContextType = {
  value: string | undefined;
  onChange: (value: string) => void;
  isDisabled?: boolean;
};

const RadioGroupContext = createContext<RadioGroupContextType>({
  value: undefined,
  onChange: () => null,
  isDisabled: false
});

const defaultButtonStyles = (theme: AppTheme) => {
  return StyleSheet.create({
    wrapper: {
      flexDirection: 'row',
      alignItems: 'center',
      justifyContent: 'space-between',
      marginVertical: 10
    },
    wrapperWithDescription: {
      flexDirection: 'row',
      alignItems: 'flex-start',
      justifyContent: 'space-between'
    },
    textWrapper: {
      flexDirection: 'column'
    },
    radio: {
      height: 20,
      width: 20,
      borderRadius: 10,
      borderWidth: 1.5,
      borderColor: theme.colors.app.primary,
      backgroundColor: theme.colors.app.background,
      alignItems: 'center',
      justifyContent: 'center'
    },
    dot: {
      height: 10,
      width: 10,
      borderRadius: 5,
      backgroundColor: theme.colors.app.primary
    },
    disabled: {
      opacity: 0.5
    }
  });
};

interface IButtonProps {
  /**
   * The description of the radio.
   */
  description?: string;

  /**
   * The label of the radio.
   */
  label: string;

  /**
   * The value of the radio.
   */
  value: string;

  /**
   * The style to apply to the radio.
   */
  style?: ViewStyle;
}

const Button: FC<IButtonProps> = ({style, value, label, description}) => {
  const styles = useStyles(defaultButtonStyles);
  const {value: selectedValue, onChange, isDisabled} = useContext(RadioGroupContext);

  const isSelected = selectedValue === value;

  return (
    <View style={[styles.wrapper, !!description && styles.wrapperWithDescription]}>
      <View style={styles.textWrapper}>
        {label ? (
          <Text color='primary' size='md' fontWeight='medium'>
            {label}
          </Text>
        ) : null}
        {description ? <DescriptionText>{description}</DescriptionText> : null}
      </View>
      <Pressable
        disabled={isDisabled}
        accessibilityRole='radio'
        hitSlop={10}
        accessibilityState={{disabled: isDisabled, selected: isSelected}}
        style={[style, styles.radio, isDisabled && styles.disabled]}
        onPress={() => onChange(value)}
      >
        {isSelected ? <View style={styles.dot} /> : null}
      </Pressable>
    </View>
  );
};

Button.displayName = 'RadioGroup.Button';

interface IRadioGroupProps {
  /**
   * The default value of the radio group.
   */
  defaultValue?: string;

  /**
   * The radio group children.
   */
  children: React.ReactNode;

  /**
   * If the radio group is disabled, it becomes opaque and uncheckable.
   */
  isDisabled?: boolean;

  /**
   * Function to call when the radio group value changes.
   */
  onValueChange: (value: string) => void;

  [x: string]: any;
}

const RadioGroup = ({
  defaultValue,
  isDisabled,
  children,
  onValueChange
}: IRadioGroupProps) => {
  const [value, setValue] = useState(defaultValue);

  const onChange = (value: string) => {
    setValue(value);
    onValueChange(value);
  };

  return (
    <RadioGroupContext.Provider value={{value, onChange, isDisabled}}>
      <View accessibilityRole='radiogroup'>{children}</View>
    </RadioGroupContext.Provider>
  );
};

RadioGroup.displayName = 'RadioGroup';

RadioGroup.Button = Button;

export {RadioGroup};

Usage

import { RadioGroup } from './components/ui/RadioGroup'
import {useState} from 'react';
import {RadioGroup} from './components/ui/RadioGroup';

export function ExampleRadioGroup() {
  const [value, setValue] = useState('air');

  return (
      <RadioGroup defaultValue={value} onValueChange={setValue}>
        <RadioGroup.Button value={'air'} label={'Airplane'} />
        <RadioGroup.Button value={'ground'} label={'Train or bus'} />
      </RadioGroup>
  );
}

Properties

RadioGroup

  • Name
    defaultValue
    Type
    string
    Description

    Default value of the radio group.

  • Name
    onValueChange
    Type
    function
    Description

    Function to call when the radio group value changes.

  • Name
    isDisabled
    Type
    boolean
    Description

    Boolean if the radio group is disabled.

RadioGroup.Button

  • Name
    label
    Type
    string
    Description

    Label for the radio.

  • Name
    description
    Type
    string
    Description

    Description that will be displayed under the label.


Description

Expo component example
Bicycle
Enjoy a leisurely ride, connecting with nature.
Car
Opt for the convenience of a car.
Public Transit
Contribute to a sustainable environment.

State

Expo component example
Dogs are great
Cats are awersome

Was this page helpful?