Filter button in React Native

Viewed 1805

I tried to make this work like in YouTube filter button. Which one button pressed other button disable in React Native via reusable component. How could I achieve something like this?
PS: Please correct me if I use wrong technical term, if it isn't call filter button.Sample

or similar to this, I want it to function like Radio button which mean one button click other button is disable, but look like chip button using React native.
enter image description here

2 Answers

You can make a toggle button like below and toggle the styles, Basically we set the background color and text color using the variable, and i have added a callback which you can use in your main component.

const Filters = ({ data, onValueChange }) => {
  const [selectedIndex, setSelectedIndex] = useState(-1);

  return (
    <View style={{ flexDirection: 'row' }}>
      {data.map((x, i) => (
        <FilterButton
          text={x.title}
          id={i}
          selectedIndex={selectedIndex}
          callback={(id) => {
            setSelectedIndex(id);
            if (onValueChange) {
              onValueChange(id);
            }
          }}
        />
      ))}
    </View>
  );
};

const FilterButton = ({ callback, text, id, selectedIndex }) => {
  const clicked = selectedIndex === id;
  return (
    <TouchableOpacity
      style={[
        { borderRadius: 20, borderColor: 'black', borderWidth: 2, padding: 10 },
        { backgroundColor: clicked ? 'black' : 'white' },
      ]}
      onPress={() => {
        callback(id);
      }}>
      <Text style={{ color: clicked ? 'white' : 'black' }}>
        {text}
      </Text>
    </TouchableOpacity>
  );
};

Usage

  <Filters data={[{ title: 'Test' }, { title: 'test2' }]} onValueChange={(id)=>alert(id)}/>

You need to create a button bar and then we need to create a reusable button for this button bar. Here is an example

export default function App() {
  const [text, setText] = React.useState('');
  const [filters, setFilters] = React.useState([
    { label: 'ALL' },
    { label: 'A' },
    { label: 'B' },
    { label: 'C' },
  ]);
  const [selected, setSelected] = React.useState(filters[0]);

  const callback = (data) => {
    if (selected === data) return setSelected(filters[0]);
    setSelected(data);
  };

  return (
    <View style={styles.container}>
      {filters.map((filter) => (
        <FilterButton
          selected={filter === selected}
          disabled={filter !== selected && selected !== filters[0] && filter !== filters[0]}
          data={filter}
          callback={callback}
        />
      ))}
    </View>
  );
}

const FilterButton = ({ callback, selected, disabled, data }) => {
  return (
    <TouchableOpacity
      style={[
        styles.filterButton,
        { backgroundColor: disabled? 'lightgrey':(selected ? 'black' : 'white') },
      ]}
      onPress={() => {
        if (callback && !disabled) {
          callback(data);
        }
      }}>
      <Text style={{ color: selected ? 'white' : 'black' }}>
        {data.label}
      </Text>
    </TouchableOpacity>
  );
};

const styles = StyleSheet.create({
  container: {
    flexDirection:'row',
    backgroundColor: '#ecf0f1',
    padding: 8,
  },
  filterButton: {
    borderRadius: 15, padding: 8, paddingLeft:24, paddingRight:24,
    marginRight:8
  },
});

Here is expo link https://snack.expo.io/@saachitech/89f0cd

Related