# mt-react-components

[![Supported by Mettle Tech](https://img.shields.io/badge/Supported%20by-Mettle%20Tech-00797b)](https://mettletech.co)

**mt-react-components** is a collection of lightweight, reusable React components.

mt-react-components is supported by <a href="https://mettletech.co" target="_blank">Mettle Tech</a>. Perfect for dashboards, ag-grid, tables, grouped UI elements and modern React applications.

Features include: 

- 🔍 **MTSearchComponent**: A debounce-enabled search input with clear functionality.
- 🔘 **MTSwitchButton**: A customizable toggle switch.
- 📋 **MTPopoverMenu**: A flexible action menu using popovers.
- 🪪 **MTCustomLegend**: A customizable React legend component designed to display a titled fieldset with consistent styles and flexible props. Ideal for dashboards, charts, and grouped UI elements.
- ✅ **MTCheckbox**: A customizable React checkbox component that supports both single and multiple checkbox modes with optional image/logo rendering. Ideal for forms with flexible input requirements.
- 🔘 **MTRadioButton**: A customizable and reusable radio button component for React applications. Supports both single radio mode and grouped radio button mode with flexible styling options.
- 📋 **MTAutosuggestComponentWithCount**: A customizable React multi-select dropdown component built on top of `react-select`, offering a compact and user-friendly UI with a **“Select All”** option and a **selected item count summary**. Ideal for filters, batch selectors, and compact UI use cases.

<!-- ---

### 📁 Repository  
[![Repo Icon](https://img.icons8.com/ios-filled/16/000000/github.png)](https://github.com/your-org/mt-react-components)  
[**github.com/your-org/mt-react-components**](https://github.com/your-org/mt-react-components)

### 🌐 Homepage  
[![Link Icon](https://img.icons8.com/ios-filled/16/000000/link.png)](https://your-org.github.io/mt-react-components)  
[**your-org.github.io/mt-react-components**](https://your-org.github.io/mt-react-components)

--- -->

## ✨ Features

### MTSearchComponent
- Debounced input using `react-debounce-input`
- Clear button to reset search
- Customizable placeholder, width, debounce timeout
- Simple styling included

### 🛠 MTSearchComponent Props

| Prop             | Type     | Default    | Description                               |
|------------------|----------|------------|-------------------------------------------|
| `value`          | string   | –          | Controlled input value                    |
| `onChange`       | func     | –          | Callback for input change                 |
| `clearValue`     | func     | –          | Callback to clear input                   |
| `placeholder`    | string   | "Search"   | Placeholder text                          |
| `minLength`      | number   | 2          | Minimum length to trigger debounce        |
| `debounceTimeout`| number   | 500        | Delay before calling `onChange` (ms)      |
| `autoComplete`   | string   | "off"      | Input autoComplete attribute              |
| `width`          | string   | "200px"    | Component width                           |

### 📘 Usage – MTSearchComponent

```jsx
import { MTSearchComponent } from 'mt-react-components';

const MyComponent = () => {
  const [value, setValue] = useState('');

  const handleChange = (val) => {
    setValue(val);
  };

  const handleClear = () => {
    setValue('');
  };

  return (
    <MTSearchComponent
      value={value}
      onChange={handleChange}
      clearValue={handleClear}
      placeholder="Search here"
    />
  );
};

```
### 🖼️ How it looks

![MT-Search-Component](./images/seachIcon.png)

### MTSwitchButton
- A simple toggle switch for enabling or disabling a setting
- Customizable colors and sizes
- Supports both controlled and uncontrolled modes
- Lightweight and easy to use

### 🛠 MTSwitchButton Props

| Prop             | Type     | Default    | Description                               |
|------------------|----------|------------|-------------------------------------------|
| `checked`        | bool     | false      | Determines whether the switch is on or off|
| `onChange`       | func     | –          | Callback function when the switch is toggled|
| `disabled`       | bool     | false      | Disables the switch if true               |
| `colorOn`        | string   | "#4CAF50"  | Color of the switch when it’s turned on   |
| `colorOff`       | string   | "#ccc"     | Color of the switch when it’s turned off  |
| `size`           | string   | "medium"   | Size of the switch ("small", "medium", "large")|
| `onLabel`        | string   | "On"       | Label displayed when switch is on         |
| `offLabel`       | string   | "Off"      | Label displayed when switch is off        |

### 📘 Usage –  MTSwitchButton

```jsx
import { MTSwitchButton } from 'mt-react-components';

const MyComponent = () => {
  const [isOn, setIsOn] = useState(false);

  const handleSwitch = (checked) => {
    setIsOn(checked);
  };

  return (
    <MTSwitchButton
      checked={isOn}
      onChange={handleSwitch}
      onLabel="On"
      offLabel="Off"
    />
  );
};

```
### 🖼️ How it looks

![MT-Switch-Button](./images/switch.png)

### MTPopoverMenu
- A simple customizable React popover menu component
- Ideal for grid/table actions
- Easily configurable and reusable
- Lightweight and easy to use

### 🛠 MTPopoverMenu Props

| Prop               | Type     | Default         | Description                                           |
|--------------------|----------|---------------- |------------------------------------------------------ |
| `placement`        | string   | right           | Position of the popover (top, right, bottom, left)    |
| `actions`          | array    | []              | List of action objects (see structure below)          |
| `children`         | ReactNode| required        | Element that triggers the popover on click            |
| `gridData`         | any      | undefined       | Data passed to the onClick of each action             |
| `wrapperClassName` | string   | 'popup-wrapper' | Class name applied to the popover wrapper for styling |

### 🛠 MTPopoverMenu Action Object Structure
| Property      | Type     | Required   | Description                           |
|---------------|----------|------------|-------------------------------------- |
| `label`       | `string` | ✅        | The text label of the action          |
| `icon`        | `string` | ✅        | Font Awesome class for the icon       |
| `onClick`     | `func`   | ✅        | Callback invoked with `gridData`      |
| `shouldShow`  | `bool`   | ✅        | Whether this action should be shown   |

### 📘 Usage –  MTPopoverMenu

```jsx
import { MTPopoverMenu } from 'mt-react-components';

const MyComponent = () => {
  return (
    <MTPopoverMenu
    placement="left"
    gridData={params}
    actions={[
        {
            label: 'Edit',
            icon: 'fa-pencil',
            onClick: edit,
            shouldShow: true,
        },
        {
            label: 'Delete',
            icon: 'fa-trash',
            onClick: delete,
            shouldShow: true,
        }
    ]}
    >
        <button className="ellipsisIcon"><i className="fa fa-ellipsis-v"></i></button>
    </MTPopoverMenu>
  );
};

```
### 🖼️ How it looks

![MT-Popover-Menu](./images/popover.png)

### MTCustomLegend
- Customizable title, font size, and colors
- Adjustable border and background
- Easily composable with any JSX content
- Lightweight and framework-agnostic (just needs React)

### 🛠 MTCustomLegend Props

| Prop              | Type        | Default     | Description                                   |
| ----------------- | ----------- | ----------- | --------------------------------------------- |
| `title`           | `string`    | `""`        | The title displayed at the top of the legend. |
| `body`            | `ReactNode` | `null`      | The JSX content to display inside the legend. |
| `className`       | `string`    | `""`        | Additional CSS classes for custom styling.    |
| `backgroundColor` | `string`    | `"#ffffff"` | Background color of the fieldset container.   |
| `borderColor`     | `string`    | `"#EEF0F5"` | Color of the fieldset border.                 |
| `borderRadius`    | `string`    | `"6"`       | Border radius of the fieldset, in pixels.     |
| `titleFontSize`   | `string`    | `"15"`      | Font size of the title, in pixels.            |
| `titleColor`      | `string`    | `"#5f646d"` | Color of the title text.                      |

### 📘 Usage –  MTCustomLegend

```jsx
import { MTCustomLegend } from 'mt-react-components';

const MyComponent = () => {
  return (
    <MTCustomLegend
      title="Your title"
      className="You can add your own class name"
      backgroundColor="#ffffff"
      borderColor="#EEF0F5"
      borderRadius="6"
      titleFontSize="15"
      titleColor="#5f646d"
      body={<>Your content</>}
    >
  );
};

```
### 🖼️ How it looks

![MT-Custom-Legend](./images/legend.png)

### MTCheckbox
- Single checkbox mode for boolean fields
- Multiple checkbox support with dynamic options
- Optional image/logo display beside options
- Custom styling via className
- Fully accessible and keyboard-friendly
- Support for disabled state

### 🛠 Single Checkbox Mode

| Prop        | Type       | Default | Description                          |
| ----------- | ---------- | ------- | ------------------------------------ |
| `label`     | `string`   | —       | Label displayed next to the checkbox |
| `name`      | `string`   | —       | Name of the input field              |
| `checked`   | `boolean`  | `false` | Checked state of the checkbox        |
| `onChange`  | `function` | —       | Callback when checkbox state changes |
| `className` | `string`   | `""`    | Custom class for styling             |
| `disabled`  | `boolean`  | `false` | Disable the checkbox                 |

### 🛠 Multiple Checkbox Mode (options provided)

| Prop        | Type       | Default | Description                                                                 |
| ----------- | ---------- | ------- | --------------------------------------------------------------------------- |
| `options`   | `array`    | —       | Array of checkbox items with `label`, `checked`, `logo_url`, and `disabled` |
| `onChange`  | `function` | —       | Callback when any option is toggled                                         |
| `showImage` | `boolean`  | `false` | Show image/logo for each checkbox if available                              |
| `className` | `string`   | `""`    | Custom class for wrapper                                                    |
| `disabled`  | `boolean`  | `false` | Disable all checkboxes                                                      |

### 📘 Usage –  MTCheckbox

```jsx
import { MTCheckbox } from 'mt-react-components';

const MyComponent = () => {
  const [checked, setChecked] = React.useState(false);
  const [options, setOptions] = React.useState([
    { label: "Wi-Fi", checked: false, logo_url: "", disabled: false },
    { label: "AC", checked: true, logo_url: "", disabled: false }
  ]);

  const handleSingleChange = (e, name) => {
    setChecked(e.target.checked);
  };

  const handleMultiChange = (index) => {
    const updated = [...options];
    updated[index].checked = !updated[index].checked;
    setOptions(updated);
  };

  return (
    <>
      {/* Single Checkbox */}
      <MTCheckbox
        name="name"
        label="Your label"
        checked={checked}
        onChange={handleSingleChange}
      />

      {/* Multiple Checkbox */}
      <MTCheckbox
        options={options}
        onChange={handleMultiChange}
        showImage={true}
      />
    </>
  );
};

```
### 🖼️ How it looks

![MT-Checkbox](./images/checkbox.png)

### MTRadioButton
- Supports single and multiple radio button modes
- Custom styling with included CSS
- Controlled component with `checked` and `onChange` support
- Works well with forms and dynamic data
- Lightweight and React 17+/18+ compatible

### 🛠 MTRadioButton Props

| Prop        | Type            | Default     | Description                                                               |
| ----------- | --------------- | ----------- | ------------------------------------------------------------------------- |
| `label`     | `string`        | `""`        | Label for the single radio mode                                           |
| `name`      | `string`        | `""`        | Name attribute for the radio input                                        |
| `checked`   | `boolean`       | `false`     | Controls the checked state for single radio mode                          |
| `onChange`  | `function`      | `undefined` | Callback for handling change. In multi mode, receives the selected index. |
| `options`   | `Array<object>` | `undefined` | Array of `{ label, checked, disabled? }` for grouped radio buttons        |
| `className` | `string`        | `""`        | Additional class names for styling the wrapper                            |
| `disabled`  | `boolean`       | `false`     | Disables the entire radio button(s)                                       |

### 📘 Usage –  MTRadioButton

```jsx
import { MTRadioButton } from 'mt-react-components';

const MyComponent = () => {
  const [gender, setGender] = useState({
        male: true,
        female: false,
    });

    const [options, setOptions] = useState([
        { label: 'WiFi', checked: true },
        { label: 'Parking', checked: false },
    ]);

    const handleSingleChange = (event, type) => {
      let genderTemp = Object.assign({}, gender);
      const { checked, value } = event.target;
      
        if (type == "male") {
            if (checked) {
                genderTemp = { ...genderTemp, "male": true, "female": false}
                setGender(genderTemp);
            } else {
                genderTemp = { ...genderTemp, "male": false, "female": false}
                setGender(genderTemp);
            }
        }
        if (type == "female") {
            if (checked) {
                genderTemp = { ...genderTemp, "female": true, "male": false}
                setGender(genderTemp);
            } else {
                genderTemp = { ...genderTemp, "female": false, "male": false}
                setGender(genderTemp);
            }
        }
    }

    const handleMultiChange = (selectedIndex) => {
        const updatedOptions = options.map((item, index) => ({
            ...item,
            checked: index === selectedIndex,
        }));
        setOptions(updatedOptions);
    };

    return (
        <div>
            {/* Single Radio Button Group (Gender) */}
            <MTRadioButton
                name="gender"
                label="Male"
                checked={gender.male}
                onChange={(e) => handleSingleChange(e, "male")}
            />
            <MTRadioButton
                name="gender"
                label="Female"
                checked={gender.female}
                onChange={(e) => handleSingleChange(e, "female")}
            />

            {/* Multiple Radio Buttons (Facilities) */}
            <MTRadioButton
                name="facilities"
                options={options}
                onChange={handleMultiChange}
            />
        </div>
    );
};

export default MyComponent;

```
### 🖼️ How it looks

![MT-Radio-Button](./images/RadioButton.png)

### MTAutosuggestComponentWithCount
- Multi-select with "Select All" functionality
- Displays `+ N more` count instead of all selected chips
- Custom dropdown header with close button
- Controlled component with external state support
- Easily stylable with CSS
- Custom width and placeholder support

### 🛠 MTAutosuggestComponentWithCount

| Prop              | Type       | Default             | Description                                                                 |
|-------------------|------------|---------------------|-----------------------------------------------------------------------------|
| `options`         | `Array`    | `[]`                | The dropdown list of selectable options. Each option is an object `{ label, value }`. |
| `selectedOptions` | `Array`    | `[]`                | Currently selected options (controlled input).                              |
| `onChange`        | `Function` | `undefined`         | Callback triggered when the selected options change.                        |
| `placeholder`     | `String`   | `"Select Options"`  | Placeholder shown when no option is selected.                               |
| `menuHeader`      | `String`   | `"Options"`         | Header text displayed at the top of the dropdown.                           |
| `classNamePrefix` | `String`   | `"multi-dropdown-box"` | Prefix for class names to help with styling customization.               |
| `selectAll`       | `Boolean`  | `true`              | Enables or disables the "Select All" option.                                |
| `width`           | `Number`   | `200`               | Sets the width of the dropdown in pixels.                                   |

### 📘 Usage –  MTAutosuggestComponentWithCount

```jsx
import { MTAutosuggestComponentWithCount } from 'mt-react-components';

const MyComponent = () => {
  const [selectedOptions, setSelectedOptions] = useState([]);
  
  const options = [
    { label: 'Option 1', value: 'option1' },
    { label: 'Option 2', value: 'option2' },
    { label: 'Option 3', value: 'option3' }
  ];

  const handleChange = (selected) => {
    setSelectedOptions(selected);
  };

  return (
    <MTAutosuggestComponentWithCount
      options={options}
      selectedOptions={selectedOptions}
      onChange={handleChange}
      placeholder="Select Options"
      menuHeader="Choose Options"
      selectAll={true}
    />
  );
};

```
### 🖼️ How it looks

![MT-Checkbox](./images/multi-select.png)

### 📦 Installation

```bash
npm install mt-search-component
