How To Create Custom Listbox In React Js

In this article, we learn how to create a custom Listbox in react app.

First, we need to install all the MUI dependencies in our react app and also import clsx in react app.

Now need to import Paper, List, ListItem, and ListItemText from the MUI dependency.

Then give some default style to the Listbox.

let defaultStyle = {
    width: '200px',
    height: '250px',
    overflow: 'auto',
    padding: '10px',
    border: '1px solid black',
};
let selectStyle = {
    backgroundColor: 'rgb(184 184 240) !important'
}

Now pass these styles into the element and also map data from the props.

Also add className, checked and onclick event from the props.

So, the Listbox component looks like this,

import React from 'react';
import { makeStyles } from "@material-ui/core/styles";
import clsx from 'clsx';
import List from '@mui/material/List';
import ListItem from '@mui/material/ListItem';
import ListItemText from '@mui/material/ListItemText';
import Paper from '@mui/material/Paper';

const Listbox = (props) => {
    let defaultStyle = {
        width: '200px',
        height: '250px',
        overflow: 'auto',
        padding: '10px',
        border: '1px solid black',
    };
    let selectStyle = {
        backgroundColor: 'rgb(184 184 240) !important'
    }

    const useStyles = makeStyles({
        mainDivstyle: defaultStyle,
        selectedStyle: selectStyle
    });
    const customClasses = useStyles();

    return (
        <Paper className={clsx(customClasses.mainDivstyle)}
            {...props}
        >
            <List dense component="div" role="list">
                {props.data.map((value) => {
                    return (
                        <ListItem
                            key={value.id}
                            role="listitem"
                            button
                            sx={{ margin: '5px 0' }}
                            className={props.checked.includes(value.title) && (props.selecedCSS ? props.selecedCSS : clsx(customClasses.selectedStyle))}
                            onClick={() => props.onclick(value.title)}
                        >
                            <ListItemText id={value.id} primary={value.title} />
                        </ListItem>
                    );
                })}
                <ListItem />
            </List>
        </Paper >
    )
}

export default Listbox

Now need to call this component in App.js and also pass the attributes like data, checked,  onclick. These three attributes are compulsory passes as props.

We need to pass the data in below format,

const Data = [
    { id: 1, title: 'Item 1' },
    { id: 2, title: 'Item 2' },
    ...
]

In the Listbox component, we can also pass className, for a selected style we can pass selectedCSS, and also we can pass inline style as props.

So, my App.js looks like this,

import { useState } from 'react';
import './App.css';
import Listbox from './Listbox';

function App() {
  const Data = [
    { id: 1, title: 'Item 1' },
    { id: 2, title: 'Item 2' },
    { id: 3, title: 'Item 3' },
    { id: 4, title: 'Item 4' },
    { id: 5, title: 'Item 5' },
  ]

  const [checked, setChecked] = useState([]);

  const SelectItem = (value) => {
    const currentIndex = checked.indexOf(value);
    const newChecked = [...checked];
    if (currentIndex === -1) {
      newChecked.push(value);
    } else {
      newChecked.splice(currentIndex, 1);
    }
    setChecked(newChecked);
  };

  return (
    <>
      <Listbox
        data={Data}
        className="listboxes"
        selecedCSS="selectcolor"
        onclick={SelectItem}
        checked={checked}
      />
    </>
  );
}

export default App;

Output:-

Submit a Comment

Your email address will not be published.

Subscribe

Select Categories