[
  {
    "path": ".eslintignore",
    "content": "# Folders\ndist/\nassets/\npages/\ncomponents/\nstyles/\n\n# Files\nREADME.md"
  },
  {
    "path": ".eslintrc.json",
    "content": "{\n    \"root\": true,\n    \"env\": {\n        \"browser\": true,\n        \"es2021\": true,\n        \"node\": true\n    },\n    \"extends\": [\n        \"eslint:recommended\",\n        \"plugin:react/recommended\",\n        \"plugin:@typescript-eslint/recommended\",\n        \"plugin:prettier/recommended\",\n        \"plugin:react-hooks/recommended\",\n        \"next/core-web-vitals\"\n    ],\n    \"overrides\": [],\n    \"parser\": \"@typescript-eslint/parser\",\n    \"parserOptions\": {\n        \"ecmaVersion\": \"latest\",\n        \"ecmaFeatures\": {\n            \"jsx\": true\n        },\n        \"sourceType\": \"module\"\n    },\n    \"settings\": {\n        \"react\": {\n            \"version\": \"detect\"\n        }\n    },\n    \"plugins\": [\"react\", \"@typescript-eslint\", \"import\", \"prettier\", \"@next/eslint-plugin-next\"],\n    \"rules\": {\n        \"indent\": [\"error\", 4],\n        \"linebreak-style\": [\"error\", \"unix\"],\n        \"quotes\": [\"error\", \"double\"],\n        \"semi\": [\"error\", \"always\"],\n        \"import/order\": [\n            \"error\",\n            {\n                \"alphabetize\": {\n                    \"order\": \"asc\",\n                    \"caseInsensitive\": true\n                },\n                \"newlines-between\": \"always\"\n            }\n        ],\n        \"react/prop-types\": \"off\",\n        \"react/jsx-uses-react\": \"off\",\n        \"react/react-in-jsx-scope\": \"off\",\n        \"react-hooks/rules-of-hooks\": \"error\",\n        \"react-hooks/exhaustive-deps\": \"warn\",\n        \"@typescript-eslint/no-var-requires\": 0,\n        \"prettier/prettier\": [\"error\", { \"endOfLine\": \"auto\" }, { \"usePrettierrc\": true }]\n    }\n}\n"
  },
  {
    "path": ".gitignore",
    "content": "# See https://help.github.com/ignore-files/ for more about ignoring files.\n\n# dependencies\nnode_modules\n/.next/\n/.rollup.cache/\n\n# test coverage\ncoverage\n\n# builds\nbuild\ndist\n.rpt2_cache\n.eslintcache\ntsconfig.tsbuildinfo\n\n# misc\n.DS_Store\n.env\n.env.local\n.env.development.local\n.env.test.local\n.env.production.local\n.yarn\n.yarnrc.yml\n\nnpm-debug.log*\nyarn-debug.log*\nyarn-error.log*\n\n.vscode\n.idea"
  },
  {
    "path": ".npmignore",
    "content": "## Folders\nsrc\nnode_modules\n.vscode\n.idea\nassets\n.git\npages\npage-components\nstyles\n.next\n.rollup.cache\n## Files\nbabel.config.json\ntsconfig.json\nrollup.config.js\nnext.config.js\nnext-env.d.ts\n.gitignore\n.eslintignore\n.eslintrc.json\n.prettierrc\n.prettierignore\n.DS_Store\nnpm-debug.log\npackage-lock.json\nyarn.lock\ntailwind.config.js\npostcss.config.js\ntsconfig.tsbuildinfo\n"
  },
  {
    "path": ".prettierignore",
    "content": "# Folders\ndist/\nassets/\n.next/\n.rollup.cache/\n\n# Files\nREADME.md"
  },
  {
    "path": ".prettierrc",
    "content": "{\n    \"semi\": true,\n    \"tabWidth\": 4,\n    \"printWidth\": 100,\n    \"singleQuote\": false,\n    \"trailingComma\": \"none\",\n    \"quoteProps\": \"as-needed\",\n    \"jsxSingleQuote\": false,\n    \"bracketSpacing\": true,\n    \"arrowParens\": \"avoid\",\n    \"proseWrap\": \"always\"\n}\n"
  },
  {
    "path": "CONTRIBUTING.md",
    "content": "# Contributing\n\nThanks for your interest in contributing to `react-tailwindcss-select`! Please take a moment to\nreview this document **before submitting a pull request**.\n\n-   [Pull requests](#pull-requests)\n-   [Installation](#installation)\n-   [Coding standards](#coding-standards)\n-   [Running playground](#running-playgrounds)\n-   [Before you make a Pull Request](#before-you-make-a-pull-request)\n\n## Pull requests\n\n**Please ask first before starting work on any significant new features.**\n\nIt's never a fun experience to have your pull request declined after investing a lot of time and\neffort into a new feature. To avoid this from happening, we request that contributors create\n[an issue](https://github.com/onesine/react-tailwindcss-select/issues) to first discuss any\nsignificant new features.\n\n## Installation\n\nYou only require a `yarn install` in the root directory to install everything you need.\n\n```sh\nyarn install\n```\n\n## Coding standards\n\nWe use `prettier` for making sure that the codebase is formatted consistently. To automatically fix\nany style violations in your code, you can run:\n\n**Using yarn**\n\n```sh\nyarn pret:fix\n```\n\n**Using npm**\n\n```sh\nnpm pret:fix\n```\n\n## Running playground\n\nWe currently use `next.js` as server for live testing.\n\nYou can run the `dev` script and open your browser to `http://localhost:8888`.\n\nSee complete `props` usage in `pages/index.js` file.\n\n**Using yarn**\n\n```sh\nyarn dev\n```\n\n**Using npm**\n\n```sh\nnpm dev\n```\n\n## Before you make a Pull Request\n\nWe recommend to run these scripts in sequence before you make your commit message amd open a Pull\nRequest\n\n**Let's clean the code first**\n\n```sh\nyarn pret:fix\n```\n\n**Test a build of your changes**\n\n```sh\nyarn build\n\n```\n"
  },
  {
    "path": "LICENSE",
    "content": "MIT License\n\nCopyright (c) 2020 Onesine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE."
  },
  {
    "path": "README.md",
    "content": "<h1 align=\"center\" style=\"border-bottom: 0 white\">\n    📦 React tailwindcss select\n</h1>\n\n<p align=\"center\">\n    React-tailwindcss-select is a simple component ready to be inserted into your project <br> This component inspired by <a href=\"https://react-select.com\">React-select</a> is a select input made with <a href=\"https://tailwindcss.com/\">Tailwindcss</a> and <a href=\"https://reactjs.com\">React</a>.\n</p>\n\n<p align=\"center\">\n    <a href=\"https://github.com/onesine/react-tailwindcss-select/blob/master/LICENSE\">\n        <img src=\"https://img.shields.io/npm/l/react-tailwindcss-select.svg\" alt=\"MIT License\">\n    </a>\n    <a href=\"https://www.npmjs.com/package/react-tailwindcss-select\">\n        <img src=\"https://img.shields.io/npm/v/react-tailwindcss-select.svg\">\n    </a>\n    <a href=\"https://github.com/yarnpkg/berry\">\n        <img src=\"https://img.shields.io/badge/developed%20with-Yarn%202-blue\">\n    </a>\n</p>\n\n## Features\n\n-   ✅ Select field for a single item\n-   ✅ Selection field for multiple items\n-   ✅ Optional button to clear the field\n-   ✅ Optional search for an item\n-   ✅ Optional deactivation of an option\n-   ✅ TypeScript support\n-   ✅ Group options\n-   ✅ Customization of the select field style\n-   ⬜ Fixed Options (multiple items select)\n\n## Why ❔\n\nA select with the above features is above all indispensable in many projects. On a project using\ntailwindcss, when I install [react-select](https://react-select.com) or other such packages, the\nstyle of the latter is affected by that of [tailwind](https://tailwindcss.com/).\n\nRather than looking for a component that uses [tailwind](https://tailwindcss.com/), I preferred to\nmake my own based on react-select which I like (and also because I generally like to reinvent the\nwheel 😅).\n\n<p align=\"center\">\n    <img src=\"https://raw.githubusercontent.com/onesine/react-tailwindcss-select/master/assets/img/Screen_Shot_2022-08-04_at_17.04.09.png\" alt=\"preview react-tailwindcss-select\">\n</p>\n\n## Online Demo\n\nYou can find the online demo at [here](https://demo-react-tailwindcss-select.vercel.app/)\n\n## Install\n\nYou can use yarn\n\n```bash\nyarn add react-tailwindcss-select\n```\n\nOr via npm\n\n```bash\nnpm install react-tailwindcss-select\n```\n\nmake sure you have installed the peer dependencies as well with the below versions.\n\n```\n\"react\": \"^18.2.0\"\n```\n\n## Usage\n\nThis component also exports a tiny CSS file built by tailwind. All CSS classes used in designing and\ncustomizing the select component are all custom tailwind classes which ensures that an existing\ntailwind project would not need to include this CSS file again.\n\n### Tailwind Project\n\nA tailwind project would only have to import the react component using\n`import Select from 'react-tailwindcss-select'` and specify the component in the tailwind\nconfiguration to generate the styles of the classes used by react-tailwindcss-select.\n\nUse this code to add the component to the tailwind configuration\n\n```javascript\n// in your tailwind.config.js\nmodule.exports = {\n    // ...\n    content: [\n        \"./src/**/*.{js,jsx,ts,tsx}\",\n        \"./node_modules/react-tailwindcss-select/dist/index.esm.js\"\n    ]\n    // ...\n};\n```\n\n### None Tailwind Project\n\nOn a project that does not use tailwind, you need to import the component's CSS as well. To do this\nuse these two codes: `import Select from 'react-tailwindcss-select'` and\n`import 'react-tailwindcss-select/dist/index.css'`\n\n> **Warning**\n>\n> In this case when you don't use tailwind on your project, think about isolating the component and\n> its style so that tailwind doesn't affect the style of the elements in your project. For this, you\n> can use the\n> [shadow dom](https://developer.mozilla.org/en-US/docs/Web/Web_Components/Using_shadow_DOM).\n\nThen use react-tailwindcss-select in your app:\n\n#### With React Component\n\n```javascript\nimport React from \"react\";\nimport Select from \"react-tailwindcss-select\";\n\nconst options = [\n    { value: \"fox\", label: \"🦊 Fox\" },\n    { value: \"Butterfly\", label: \"🦋 Butterfly\" },\n    { value: \"Honeybee\", label: \"🐝 Honeybee\" }\n];\n\nclass App extends React.Component {\n    constructor(props) {\n        super(props);\n        this.state = { animal: null };\n\n        this.handleChange = this.handleChange.bind(this);\n    }\n\n    handleChange(value) {\n        console.log(\"value:\", value);\n        this.setState({ animal: value });\n    }\n\n    render() {\n        const { animal } = this.state;\n\n        return (\n            <Select\n                value={animal}\n                onChange={this.handleChange}\n                options={options}\n            />\n        );\n    }\n}\n```\n\n#### With React Hooks\n\n```javascript\nimport { useState } from \"react\";\nimport Select from \"react-tailwindcss-select\";\n\nconst options = [\n    { value: \"fox\", label: \"🦊 Fox\" },\n    { value: \"Butterfly\", label: \"🦋 Butterfly\" },\n    { value: \"Honeybee\", label: \"🐝 Honeybee\" }\n];\n\nconst App = () => {\n    const [animal, setAnimal] = useState(null);\n\n    const handleChange = value => {\n        console.log(\"value:\", value);\n        setAnimal(value);\n    };\n\n    return (\n        <Select\n            value={animal}\n            onChange={handleChange}\n            options={options}\n        />\n    );\n};\n\nexport default App;\n```\n\n## Theming options\n\n**Supported themes**\n![Theme supported](https://raw.githubusercontent.com/onesine/react-tailwindcss-datepicker/master/assets/img/Screen_Shot_2022-08-04_at_17.04.09_theme.png?raw=true)\n\nTo change the default theme, simply add the `primaryColor` props to your select field with the theme\nvalue. By default, the `primaryColor` is set to `blue`\n\n### Indigo example\n\n```javascript\nimport { useState } from \"react\";\nimport Select from \"react-tailwindcss-select\";\n\nconst options = [\n    { value: \"fox\", label: \"🦊 Fox\" },\n    { value: \"Butterfly\", label: \"🦋 Butterfly\" },\n    { value: \"Honeybee\", label: \"🐝 Honeybee\" }\n];\n\nconst App = () => {\n    const [animal, setAnimal] = useState(null);\n\n    const handleChange = value => {\n        console.log(\"value:\", value);\n        setAnimal(value);\n    };\n\n    return (\n        <Select\n            primaryColor={\"indigo\"}\n            value={animal}\n            onChange={handleChange}\n            options={options}\n        />\n    );\n};\n\nexport default App;\n```\n\n## Props\n\nThis table shows all the options available in react-tailwindcss-select.\n\n| Option                                        | Type       | Default            | Description                                                                            |\n|-----------------------------------------------|------------|--------------------|----------------------------------------------------------------------------------------|\n| [`classNames`](#classNames)                   | `Object`   | `undefined`        | This prop allows you to style most of the components used by this library.             |\n| `isClearable`                                 | `Boolean`  | `true`             | Indicates if you can empty the select field.                                           |\n| `isDisabled`                                  | `Boolean`  | `false`            | Indicates if you can disable the select field.                                         |\n| `isMultiple`                                  | `Boolean`  | `false`            | Indicates if you can do a multiple selection.                                          |\n| `isSearchable`                                | `Boolean`  | `false`            | Indicates if you can search the elements of the select field.                          |\n| [`formatGroupLabel`](#formatGroupLabel)       | `Function` | `null`             | Allows you to use a custom rendering template for each subgroup title                  |\n| [`formatOptionLabel`](#formatOptionLabel)     | `Function` | `null`             | Allows you to use a custom rendering template for each option in the list              |\n| `loading`                                     | `Boolean`  | `false`            | Indicates if you want a loader to appear in the field.                                 |\n| `menuIsOpen`                                  | `Boolean`  | `false`            | Indicates if you want the options menu to be displayed by default.                     |\n| `noOptionsMessage`                            | `String`   | `No results found` | Default message when there is no option in the select field.                           |\n| [`onChange`](#onChange)                       | `Function` |                    | This callback, if present, is triggered when the select field value is modified.       |\n| [`onSearchInputChange`](#onSearchInputChange) | `Function` |                    | This callback, if present, is triggered when the search input field value is modified. |\n| [`options`](#options)                         | `Array`    | `[]`               | All options or options groups available in the selection field.                        |\n| `placeholder`                                 | `String`   | `Select...`        | The placeholder shown for the select field.                                            |\n| `primaryColor`                                | `String`   | `blue`             | Default theme of the field.                                                            |\n| `searchInputPlaceholder`                      | `String`   | `Search...`        | The placeholder shown for the search input field.                                      |\n| [`value`](#value)                             | `Object`   | `null`             | Current value of select field.                                                         |\n\n### onChange\n\nThis callback, if present, is triggered when the select field value is modified. This callback takes\nas a parameter the current value(s) selected. These values respect the same structure as the\nelements of the options.\n\n```js\ncurrentValue => {\n    console.log(\"currentValue:\", currentValue);\n};\n```\n\n### onSearchInputChange\n\nThis callback, if present, is triggered when the search input field value is modified. This callback takes\nas parameter a `React.ChangeEvent<HTMLInputElement>`.\n\n```js\ne => {\n    console.log(\"value:\", e.target.value);\n};\n```\n\n### options\n\nAll options are available in the select field. Each option element must have a `value` property that\nserves as an identifier for the element, a `label` property that is the text that is displayed in\nthe options list, and an optional `disabled` property to specify whether the element is active.\n\n```js\n// default element\nconst options = [{ value: \"fox\", label: \"🦊 Fox\" }];\n// default element with `disabled`\nconst options = [{ value: \"fox\", label: \"🦊 Fox\", disabled: true }];\n```\n\n#### Group item\n\nIf you want to group options you can use the following code.\n\n```js\nconst options = [\n    {\n        label: \"Mammal\",\n        options: [\n            { value: \"Dolphin\", label: \"🐬 Dolphin\" },\n            { value: \"Giraffe\", label: \"🦒 Giraffe\" }\n        ]\n    },\n    {\n        label: \"Carnivore\",\n        options: [\n            { value: \"Tiger\", label: \"🐅 Tiger\" },\n            { value: \"Lion\", label: \"🦁 Lion\" }\n        ]\n    },\n    // 👉 You can put the grouped and ungrouped options together\n    { value: \"Zombie\", label: \"🧟 Zombie\" }\n];\n```\n\n> **Info**\n>\n> 👉 You can put the grouped and ungrouped options together.\n\n### value\n\nThe current value of the select field. These objects must follow the same structure as an `options`\nelement. Thus, the following would work:\n\n```js\n// default element Simple Select\nconst value = { value: \"fox\", label: \"🦊 Fox\" };\n// default element with `disabled` Simple Select\nconst value = { value: \"fox\", label: \"🦊 Fox\", disabled: true };\n// default element Multiple Select\nconst value = [{ value: \"fox\", label: \"🦊 Fox\" }];\n// default element with `disabled` Multiple Select\nconst value = [{ value: \"fox\", label: \"🦊 Fox\", disabled: true }];\n```\n\n### formatGroupLabel\n\n`formatGroupLabel` allows you to use a custom rendering template for each subgroup title <br />\n\n```jsx\nimport { useState } from \"react\";\nimport Select from \"react-tailwindcss-select\";\n\nconst options = [\n    {\n        label: \"Mammal\",\n        options: [\n            { value: \"Dolphin\", label: \"🐬 Dolphin\" },\n            { value: \"Giraffe\", label: \"🦒 Giraffe\" }\n        ]\n    },\n    {\n        label: \"Carnivore\",\n        options: [\n            { value: \"Tiger\", label: \"🐅 Tiger\" },\n            { value: \"Lion\", label: \"🦁 Lion\" }\n        ]\n    }\n];\n\nconst App = () => {\n    const [animal, setAnimal] = useState(null);\n\n    const handleChange = value => {\n        console.log(\"value:\", value);\n        setAnimal(value);\n    };\n\n    return (\n        <Select\n            value={animal}\n            onChange={handleChange}\n            options={options}\n            isMultiple={true}\n            formatGroupLabel={data => (\n                <div className={`py-2 text-xs flex items-center justify-between`}>\n                    // 👉 data represents each subgroup\n                    <span className=\"font-bold\">{data.label}</span>\n                    <span className=\"bg-gray-200 h-5 h-5 p-1.5 flex items-center justify-center rounded-full\">\n                        {data.options.length}\n                    </span>\n                </div>\n            )}\n        />\n    );\n};\n\nexport default App;\n```\n\n> **Info**\n>\n> 👉 data represents each subgroup.\n\n### formatOptionLabel\n\n`formatOptionLabel` allows you to use a custom rendering template for each option in the list.\n<br />\n\n```jsx\nimport { useState } from \"react\";\nimport Select from \"react-tailwindcss-select\";\n\nconst options = [\n    { value: \"fox\", label: \"🦊 Fox\" },\n    { value: \"Butterfly\", label: \"🦋 Butterfly\" },\n    { value: \"Honeybee\", label: \"🐝 Honeybee\" }\n];\n\nconst App = () => {\n    const [animal, setAnimal] = useState(null);\n\n    const handleChange = value => {\n        console.log(\"value:\", value);\n        setAnimal(value);\n    };\n\n    return (\n        <Select\n            value={animal}\n            onChange={handleChange}\n            options={options}\n            formatOptionLabel={data => (\n                <li\n                    className={`block transition duration-200 px-2 py-2 cursor-pointer select-none truncate rounded ${\n                        !data.isSelected\n                            ? `text-white bg-blue-500`\n                            : `bg-blue-100 text-blue-500`\n                    }`}\n                >\n                    // data represents each option in the list\n                    {data.label}\n                </li>\n            )}\n        />\n    );\n};\n\nexport default App;\n```\n\n> **Info**\n>\n> 👉 data represents each option in the list.\n\n### classNames\n\nAs of version 1.6.0 of `react-tailwindcss-select` you can now use the `classNames` prop for styling.\n\n> **Info**\n>\n> 👉 Note: this is not to be confused with the className prop, which will add a class to the component.\n\n`classNames` takes an object with keys to represent the various inner components that `react-tailwindcss-select` is made up of.\n\nEach key takes a callback function or a string. If a key is not filled in, the default classes of the component will be used.\n\n#### All keys\n\n```typescript\ninterface SelectProps {\n    // ....\n    classNames?: {\n        menuButton?: (value?: { isDisabled?: boolean }) => string;\n        menu?: string;\n        tagItem?: (value?: { item?: Option, isDisabled?: boolean }) => string;\n        tagItemText?: string;\n        tagItemIconContainer?: string;\n        tagItemIcon?: string;\n        list?: string;\n        listGroupLabel?: string;\n        listItem?: (value?: { isSelected?: boolean }) => string;\n        listDisabledItem?: string;\n        ChevronIcon?: (value?: { open?: boolean }) => string;\n        searchContainer?: string;\n        searchBox?: string;\n        searchIcon?: string;\n        closeIcon?: string;\n    };\n    // ...\n}\n```\n\n#### Example of a custom style\n\n```javascript\nimport { useState } from \"react\";\nimport Select from \"react-tailwindcss-select\";\n\nconst options = [\n    { value: \"fox\", label: \"🦊 Fox\" },\n    { value: \"Butterfly\", label: \"🦋 Butterfly\" },\n    { value: \"Honeybee\", label: \"🐝 Honeybee\" }\n];\n\nconst App = () => {\n    const[animal, setAnimal] =useState(null);\n\n    const handleChange = value => {\n        console.log(\"value:\", value);\n        setAnimal(value);\n    };\n\n    return(\n        <Select\n            value={animal}\n            onChange={handleChange}\n            options={options}\n            classNames={{\n                menuButton: ({ isDisabled }) => (\n                    `flex text-sm text-gray-500 border border-gray-300 rounded shadow-sm transition-all duration-300 focus:outline-none ${\n                        isDisabled\n                            ? \"bg-gray-200\"\n                            : \"bg-white hover:border-gray-400 focus:border-blue-500 focus:ring focus:ring-blue-500/20\"\n                    }`\n                ),\n                menu: \"absolute z-10 w-full bg-white shadow-lg border rounded py-1 mt-1.5 text-sm text-gray-700\",\n                listItem: ({ isSelected }) => (\n                    `block transition duration-200 px-2 py-2 cursor-pointer select-none truncate rounded ${\n                        isSelected\n                            ? `text-white bg-blue-500`\n                            : `text-gray-500 hover:bg-blue-100 hover:text-blue-500`\n                    }`\n                )\n            }}\n        />\n    );\n};\n\nexport default App;\n```\n\n## PlayGround\n\nClone the `master` branch and run commands:\n\n```sh\n# Using npm\nnpm install && npm dev\n\n# Using yarn\nyarn install && yarn dev\n\n```\n\nOpen a browser and navigate to `http://localhost:8888`\n\n## Contributing\n\nGot ideas on how to make this better? Open an issue!\n\nDon't forget to see [CONTRIBUTING.md](https://github.com/onesine/react-tailwindcss-select/blob/master/CONTRIBUTING.md)\n\n## Thanks\n\nThis component is inspired by the excellent [react-select](https://react-select.com/) library by Jed\nWatson.\n\nI thank you in advance for your contribution to this project.\n\n## License\n\nMIT Licensed. Copyright (c) Lewhe Onesine 2022.\n"
  },
  {
    "path": "next-env.d.ts",
    "content": "/// <reference types=\"next\" />\n/// <reference types=\"next/image-types/global\" />\n\n// NOTE: This file should not be edited\n// see https://nextjs.org/docs/basic-features/typescript for more information.\n"
  },
  {
    "path": "next.config.js",
    "content": "/** @type {import('next').NextConfig} */\nconst nextConfig = {\n    reactStrictMode: true\n};\n\nmodule.exports = nextConfig;\n"
  },
  {
    "path": "package.json",
    "content": "{\n    \"name\": \"react-tailwindcss-select\",\n    \"version\": \"1.8.5\",\n    \"description\": \"A select input made with React js and Tailwind CSS\",\n    \"main\": \"dist/index.cjs.js\",\n    \"module\": \"dist/index.esm.js\",\n    \"types\": \"dist/index.d.ts\",\n    \"author\": \"onesine\",\n    \"license\": \"MIT\",\n    \"scripts\": {\n        \"watch\": \"rollup -c -w\",\n        \"clean\": \"rm -rf dist\",\n        \"tailwind-build\": \"tailwindcss -i ./src/index.css -o ./dist/index.css --minify\",\n        \"lint\": \"eslint .\",\n        \"lint:fix\": \"eslint --fix .\",\n        \"pret\": \"prettier -c .\",\n        \"pret:fix\": \"prettier -w .\",\n        \"format\": \"prettier --write './**/*.{js,jsx,ts,tsx,css,md,json}' --config ./.prettierrc\",\n        \"build\": \"npm run pret && npm run lint && npm run clean && rollup -c && npm run tailwind-build\",\n        \"dev\": \"next dev -p 8888\"\n    },\n    \"repository\": {\n        \"type\": \"git\",\n        \"url\": \"https://github.com/onesine/react-tailwindcss-select\"\n    },\n    \"keywords\": [\n        \"combobox\",\n        \"form\",\n        \"input\",\n        \"multiselect\",\n        \"react\",\n        \"react-component\",\n        \"react-tailwind\",\n        \"select\",\n        \"tailwind\",\n        \"tailwindcss\",\n        \"ui\"\n    ],\n    \"peerDependencies\": {\n        \"react\": \"^18.2.0\"\n    },\n    \"devDependencies\": {\n        \"@rollup/plugin-commonjs\": \"^24.0.1\",\n        \"@rollup/plugin-node-resolve\": \"^15.0.1\",\n        \"@rollup/plugin-typescript\": \"^11.0.0\",\n        \"@tailwindcss/forms\": \"^0.5.2\",\n        \"@types/node\": \"18.14.6\",\n        \"@types/react\": \"^18.0.21\",\n        \"@typescript-eslint/eslint-plugin\": \"^5.45.0\",\n        \"@typescript-eslint/parser\": \"^5.45.0\",\n        \"autoprefixer\": \"^10.4.13\",\n        \"eslint\": \"^8.28.0\",\n        \"eslint-config-next\": \"^13.2.3\",\n        \"eslint-config-prettier\": \"^8.5.0\",\n        \"eslint-plugin-import\": \"^2.27.5\",\n        \"eslint-plugin-prettier\": \"^4.2.1\",\n        \"eslint-plugin-react\": \"^7.31.11\",\n        \"eslint-plugin-react-hooks\": \"^4.6.0\",\n        \"next\": \"^13.2.3\",\n        \"postcss\": \"^8.4.14\",\n        \"prettier\": \"^2.8.0\",\n        \"react\": \"^18.2.0\",\n        \"react-dom\": \"^18.2.0\",\n        \"rollup\": \"^2.77.2\",\n        \"tailwindcss\": \"^3.1.7\",\n        \"tslib\": \"^2.4.0\",\n        \"typescript\": \"^4.8.4\"\n    }\n}\n"
  },
  {
    "path": "page-components/Alert.jsx",
    "content": "const Alert = ({ children, title, type = \"info\" }) => {\n    return (\n        <div\n            className=\"bg-blue-100 border-t-4 border-blue-500 rounded-b text-blue-900 px-2 md:px-4 py-3 shadow-md\"\n            role=\"alert\"\n        >\n            <div className=\"flex\">\n                <div className=\"py-0.5 md:py-1\">\n                    {type === \"info\" && (\n                        <svg\n                            className=\"h-5 md:h-6 h-5 md:w-6 text-blue-500 mr-2 md:mr-4\"\n                            fill=\"none\"\n                            stroke=\"currentColor\"\n                            viewBox=\"0 0 24 24\"\n                            xmlns=\"http://www.w3.org/2000/svg\"\n                        >\n                            <path\n                                strokeLinecap=\"round\"\n                                strokeLinejoin=\"round\"\n                                strokeWidth={2}\n                                d=\"M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z\"\n                            />\n                        </svg>\n                    )}\n                </div>\n\n                <div>\n                    <p className=\"font-bold\">{title}</p>\n\n                    {children}\n                </div>\n            </div>\n        </div>\n    );\n};\n\nexport default Alert;\n"
  },
  {
    "path": "page-components/Button.jsx",
    "content": "const Button = ({ children, icon = null, active = false, onClick }) => {\n    return (\n        <button\n            onClick={onClick}\n            className={`transition duration-75 flex items-center space-x-2 ${\n                active ? \"shadow bg-white\" : \"\"\n            } py-1.5 lg:py-2 rounded-lg px-2 lg:px-3 text-xs lg:text-sm text-gray-600 font-bold`}\n        >\n            {icon !== null && icon === \"eyes\" && (\n                <svg\n                    className={`w-4 h4 lg:w-5 lg:h-5 ${active ? \"text-blue-500\" : \"\"}`}\n                    fill=\"none\"\n                    stroke=\"currentColor\"\n                    viewBox=\"0 0 24 24\"\n                    xmlns=\"http://www.w3.org/2000/svg\"\n                >\n                    <path\n                        strokeLinecap=\"round\"\n                        strokeLinejoin=\"round\"\n                        strokeWidth={2}\n                        d=\"M15 12a3 3 0 11-6 0 3 3 0 016 0z\"\n                    />\n                    <path\n                        strokeLinecap=\"round\"\n                        strokeLinejoin=\"round\"\n                        strokeWidth={2}\n                        d=\"M2.458 12C3.732 7.943 7.523 5 12 5c4.478 0 8.268 2.943 9.542 7-1.274 4.057-5.064 7-9.542 7-4.477 0-8.268-2.943-9.542-7z\"\n                    />\n                </svg>\n            )}\n\n            {icon !== null && icon === \"code\" && (\n                <svg\n                    className={`w-4 h4 lg:w-5 lg:h-5 ${active ? \"text-blue-500\" : \"\"}`}\n                    fill=\"none\"\n                    stroke=\"currentColor\"\n                    viewBox=\"0 0 24 24\"\n                    xmlns=\"http://www.w3.org/2000/svg\"\n                >\n                    <path\n                        strokeLinecap=\"round\"\n                        strokeLinejoin=\"round\"\n                        strokeWidth={2}\n                        d=\"M10 20l4-16m4 4l4 4-4 4M6 16l-4-4 4-4\"\n                    />\n                </svg>\n            )}\n\n            <span className={`${active ? \"text-gray-700\" : \"text-gray-500\"}`}>{children}</span>\n        </button>\n    );\n};\n\nexport default Button;\n"
  },
  {
    "path": "page-components/Checkbox.jsx",
    "content": "const Checkbox = ({ children, checked, onChange, id }) => {\n    return (\n        <label htmlFor={id} className=\"space-x-2 inline-block mr-2\">\n            <input\n                id={id}\n                checked={checked}\n                onChange={onChange}\n                className=\"rounded border-gray-300 text-blue-600 shadow-sm focus:border-blue-300 focus:ring focus:ring-offset-0 focus:ring-blue-200 focus:ring-opacity-50\"\n                type=\"checkbox\"\n            />\n            <span className=\"text-xs font-semibold cursor-pointer\">{children}</span>\n        </label>\n    );\n};\n\nexport default Checkbox;\n"
  },
  {
    "path": "page-components/Header.jsx",
    "content": "const Header = ({ children }) => {\n    return (\n        <div className=\"flex justify-end mb-4\">\n            <div className=\"bg-slate-100 p-0.5 rounded-lg flex items-center\">{children}</div>\n        </div>\n    );\n};\n\nexport default Header;\n"
  },
  {
    "path": "page-components/Link.jsx",
    "content": "export const DarkLink = ({ children, url }) => {\n    return (\n        <a\n            target=\"_blank\"\n            rel=\"noreferrer\"\n            className=\"text-slate-100 hover:underline active:text-blue-700 font-semibold\"\n            href={url}\n        >\n            {children}\n        </a>\n    );\n};\n\nexport const LightLink = ({ children, url }) => {\n    return (\n        <a\n            target=\"_blank\"\n            rel=\"noreferrer\"\n            className=\"hover:underline active:text-blue-700 font-semibold\"\n            href={url}\n        >\n            {children}\n        </a>\n    );\n};\n"
  },
  {
    "path": "page-components/SelectContainer.jsx",
    "content": "const SelectContainer = ({ children }) => {\n    return (\n        <div className=\"w-full mt-10 md:mt-14 flex items-center justify-center\">\n            <div className=\"w-full md:w-3/4 lg:w-4/6 xl:w-2/4\">{children}</div>\n        </div>\n    );\n};\n\nexport default SelectContainer;\n"
  },
  {
    "path": "page-components/TailwindColors.jsx",
    "content": "const TailwindColors = ({ changeColor }) => {\n    return (\n        <div className=\"w-full mt-3 grid grid-cols-2 md:grid-cols-4 lg:grid-cols-6 gap-5\">\n            <div\n                onClick={() => changeColor(\"blue\")}\n                className=\"h-7 px-2 text-xs font-semibold bg-blue-500 rounded-md flex items-center justify-center text-white cursor-pointer\"\n            >\n                blue\n            </div>\n            <div\n                onClick={() => changeColor(\"orange\")}\n                className=\"h-7 px-2 text-xs font-semibold bg-orange-500 rounded-md flex items-center justify-center text-white cursor-pointer\"\n            >\n                orange\n            </div>\n            <div\n                onClick={() => changeColor(\"yellow\")}\n                className=\"h-7 px-2 text-xs font-semibold bg-yellow-500 rounded-md flex items-center justify-center text-white cursor-pointer\"\n            >\n                yellow\n            </div>\n            <div\n                onClick={() => changeColor(\"red\")}\n                className=\"h-7 px-2 text-xs font-semibold bg-red-500 rounded-md flex items-center justify-center text-white cursor-pointer\"\n            >\n                red\n            </div>\n            <div\n                onClick={() => changeColor(\"purple\")}\n                className=\"h-7 px-2 text-xs font-semibold bg-purple-500 rounded-md flex items-center justify-center text-white cursor-pointer\"\n            >\n                purple\n            </div>\n            <div\n                onClick={() => changeColor(\"amber\")}\n                className=\"h-7 px-2 text-xs font-semibold bg-amber-500 rounded-md flex items-center justify-center text-white cursor-pointer\"\n            >\n                amber\n            </div>\n            <div\n                onClick={() => changeColor(\"lime\")}\n                className=\"h-7 px-2 text-xs font-semibold bg-lime-500 rounded-md flex items-center justify-center text-white cursor-pointer\"\n            >\n                lime\n            </div>\n            <div\n                onClick={() => changeColor(\"green\")}\n                className=\"h-7 px-2 text-xs font-semibold bg-green-500 rounded-md flex items-center justify-center text-white cursor-pointer\"\n            >\n                green\n            </div>\n            <div\n                onClick={() => changeColor(\"emerald\")}\n                className=\"h-7 px-2 text-xs font-semibold bg-emerald-500 rounded-md flex items-center justify-center text-white cursor-pointer\"\n            >\n                emerald\n            </div>\n            <div\n                onClick={() => changeColor(\"teal\")}\n                className=\"h-7 px-2 text-xs font-semibold bg-teal-500 rounded-md flex items-center justify-center text-white cursor-pointer\"\n            >\n                teal\n            </div>\n            <div\n                onClick={() => changeColor(\"cyan\")}\n                className=\"h-7 px-2 text-xs font-semibold bg-cyan-500 rounded-md flex items-center justify-center text-white cursor-pointer\"\n            >\n                cyan\n            </div>\n            <div\n                onClick={() => changeColor(\"sky\")}\n                className=\"h-7 px-2 text-xs font-semibold bg-sky-500 rounded-md flex items-center justify-center text-white cursor-pointer\"\n            >\n                sky\n            </div>\n            <div\n                onClick={() => changeColor(\"indigo\")}\n                className=\"h-7 px-2 text-xs font-semibold bg-indigo-500 rounded-md flex items-center justify-center text-white cursor-pointer\"\n            >\n                indigo\n            </div>\n            <div\n                onClick={() => changeColor(\"violet\")}\n                className=\"h-7 px-2 text-xs font-semibold bg-violet-500 rounded-md flex items-center justify-center text-white cursor-pointer\"\n            >\n                violet\n            </div>\n            <div\n                onClick={() => changeColor(\"purple\")}\n                className=\"h-7 px-2 text-xs font-semibold bg-purple-500 rounded-md flex items-center justify-center text-white cursor-pointer\"\n            >\n                purple\n            </div>\n            <div\n                onClick={() => changeColor(\"fuchsia\")}\n                className=\"h-7 px-2 text-xs font-semibold bg-fuchsia-500 rounded-md flex items-center justify-center text-white cursor-pointer\"\n            >\n                fuchsia\n            </div>\n            <div\n                onClick={() => changeColor(\"pink\")}\n                className=\"h-7 px-2 text-xs font-semibold bg-pink-500 rounded-md flex items-center justify-center text-white cursor-pointer\"\n            >\n                pink\n            </div>\n            <div\n                onClick={() => changeColor(\"rose\")}\n                className=\"h-7 px-2 text-xs font-semibold bg-rose-500 rounded-md flex items-center justify-center text-white cursor-pointer\"\n            >\n                rose\n            </div>\n        </div>\n    );\n};\n\nexport default TailwindColors;\n"
  },
  {
    "path": "pages/_app.js",
    "content": "import \"../src/index.css\";\n\nconst App = ({ Component, pageProps }) => {\n    return <Component {...pageProps} />;\n};\n\nexport default App;\n"
  },
  {
    "path": "pages/index.js",
    "content": "import Head from \"next/head\";\nimport Select from \"../src\";\nimport Header from \"../page-components/Header\";\nimport Button from \"../page-components/Button\";\nimport SelectContainer from \"../page-components/SelectContainer\";\nimport { useCallback, useEffect, useState } from \"react\";\nimport TailwindColors from \"../page-components/TailwindColors\";\nimport Checkbox from \"../page-components/Checkbox\";\nimport Alert from \"../page-components/Alert\";\nimport { DarkLink, LightLink } from \"../page-components/Link\";\n\nconst MANGAS = [\n    {\n        label: \"SHONEN\",\n        options: [\n            { value: \"One Piece\", label: \"🤩 One Piece\", disabled: false },\n            { value: \"Naruto Shippûden\", label: \"🤭 Naruto Shippûden\", disabled: false },\n            { value: \"Hunter x Hunter\", label: \"🥰 Hunter x Hunter\", disabled: false }\n        ]\n    },\n    {\n        label: \"SHOJO\",\n        options: [\n            { value: \"Orange\", label: \"🤩 Orange\", disabled: false },\n            { value: \"Nana\", label: \"🤭 Nana\", disabled: false },\n            { value: \"Tonari no Kaibutsu-kun\", label: \"🥰 Tonari no Kaibutsu-kun\", disabled: false }\n        ]\n    },\n    {\n        label: \"SEINEN\",\n        options: [\n            { value: \"Death Note\", label: \"🤩 Death Note\", disabled: false },\n            { value: \"Btooom!\", label: \"🤭 Btooom!\", disabled: false },\n            { value: \"Black Lagoon\", label: \"🥰 Black Lagoon\", disabled: false }\n        ]\n    },\n    {\n        label: \"JOSEI\",\n        options: [\n            { value: \"Nodame Cantabile\", label: \"🤩 Nodame Cantabile\", disabled: false },\n            { value: \"Chihayafuru\", label: \"🤭 Chihayafuru\", disabled: false },\n            { value: \"Blue\", label: \"🥰 Blue\", disabled: false }\n        ]\n    },\n    { value: \"Naruto Shippûden\", label: \"🤭 Naruto Shippûden\", disabled: false },\n    { value: \"One Piece\", label: \"🤩 One Piece\", disabled: false },\n    { value: \"Bleach\", label: \"🥹 Bleach\", disabled: false },\n    { value: \"Boruto\", label: \"😡 Boruto\", disabled: false },\n    { value: \"Hunter x Hunter\", label: \"🥰 Hunter x Hunter\", disabled: false },\n    { value: \"Dragon Ball Z\", label: \"🥵 Dragon Ball Z\", disabled: false },\n    { value: \"Fullmetal Alchemist\", label: \"🫡 Fullmetal Alchemist\", disabled: false },\n    { value: \"My Hero Academia\", label: \"🤯 My Hero Academia\", disabled: false },\n    { value: \"Black Clover\", label: \"😍 Black Clover\", disabled: false }\n];\n\nconst SELECT_OPTIONS = [\n    \"isClearable\",\n    \"isSearchable\",\n    \"isMultiple\",\n    \"isDisabled\",\n    \"loading\",\n    \"isGroupOption\"\n];\n\nconst printAlertContent = (element, value) => {\n    const printText = (text, value) =>\n        value ? <p className=\"text-xs md:text-sm transition duration-75\">{text}</p> : null;\n\n    switch (element) {\n        case \"isClearable\":\n            return printText(\"You can empty the field\", value);\n        case \"isSearchable\":\n            return printText(\"You can search for an item in the option list\", value);\n        case \"isMultiple\":\n            return printText(\"You can select several options\", value);\n        case \"isDisabled\":\n            return printText(\"The field is disabled\", value);\n        case \"loading\":\n            return printText(\"A loader appears on the field\", value);\n        case \"isGroupOption\":\n            return printText(\"The options of the select field are grouped\", value);\n        default:\n            return null;\n    }\n};\n\nconst Home = () => {\n    const [options, setOptions] = useState([]);\n    const [loading, setLoading] = useState(false);\n    const [showCode, setShowCode] = useState(false);\n    const [value, setValue] = useState(null);\n    const [isClearable, setIsClearable] = useState(false);\n    const [isMultiple, setIsMultiple] = useState(false);\n    const [isSearchable, setIsSearchable] = useState(false);\n    const [isDisabled, setIsDisabled] = useState(false);\n    const [isGroupOption, setIsGroupOption] = useState(false);\n    const [primaryColor, setPrimaryColor] = useState(\"purple\");\n\n    useEffect(() => {\n        setLoading(true);\n        const timer = setTimeout(() => {\n            setOptions(MANGAS);\n            setLoading(false);\n        }, 3000);\n\n        return () => {\n            clearTimeout(timer);\n        };\n    }, []);\n\n    const filterOptions = useCallback(\n        data => {\n            return data.filter(item => (isGroupOption ? \"options\" in item : !(\"options\" in item)));\n        },\n        [isGroupOption]\n    );\n\n    const toggleShowCode = useCallback(() => {\n        setShowCode(!showCode);\n    }, [showCode]);\n\n    const dispatch = useCallback(\n        (type = null, action, valueData = null) => {\n            switch (type) {\n                case \"isClearable\":\n                    if (action === \"set\") setIsClearable(valueData);\n                    if (action === \"get\") return isClearable;\n                    break;\n                case \"isSearchable\":\n                    if (action === \"set\") setIsSearchable(valueData);\n                    if (action === \"get\") return isSearchable;\n                    break;\n                case \"isMultiple\":\n                    if (action === \"set\") {\n                        if (value !== null) {\n                            setValue(null);\n                        }\n                        setIsMultiple(valueData);\n                    }\n                    if (action === \"get\") return isMultiple;\n                    break;\n                case \"isDisabled\":\n                    if (action === \"set\") setIsDisabled(valueData);\n                    if (action === \"get\") return isDisabled;\n                    break;\n                case \"loading\":\n                    if (action === \"set\") setLoading(valueData);\n                    if (action === \"get\") return loading;\n                    break;\n                case \"isGroupOption\":\n                    if (action === \"set\") {\n                        setIsGroupOption(valueData);\n                    }\n\n                    if (action === \"get\") return isGroupOption;\n                    break;\n                default:\n                    break;\n            }\n        },\n        [isClearable, isDisabled, isGroupOption, isMultiple, isSearchable, loading, value]\n    );\n\n    const handleCheck = useCallback(\n        (value, item) => {\n            dispatch(item, \"set\", value);\n        },\n        [dispatch]\n    );\n\n    return (\n        <>\n            <Head>\n                <title>react-tailwindcss-select PlayGround</title>\n            </Head>\n\n            <div className=\"w-full min-h-screen px-5 md:px-20 lg:px-36 md:flex md:flex-col md:justify-between\">\n                <h1 className=\"text-slate-600 mt-4 md:mt-8 lg:mt-20 mb-24 md:mb-8 md:text-xl lg:text-3xl text-center font-semibold\">\n                    Demo react-tailwindcss-select\n                </h1>\n\n                <div className=\"w-full\">\n                    <Header>\n                        <Button active={!showCode} icon={\"eyes\"} onClick={toggleShowCode}>\n                            Preview\n                        </Button>\n\n                        <Button active={showCode} icon={\"code\"} onClick={toggleShowCode}>\n                            Code\n                        </Button>\n                    </Header>\n\n                    <div\n                        className={`transition duration-75 ${\n                            showCode ? \"bg-slate-800\" : \"bg-gray-100\"\n                        } px-2 pb-6 md:p-8 min-h-[15rem] rounded-md border md:min-h-[20rem] lg:min-h-[25rem] w-full`}\n                    >\n                        {showCode ? (\n                            <div>\n                                <h2 className=\"text-white mt-8 font-semibold text-xl md:text-3xl lg:text-5xl xl:text-6xl\">\n                                    This part will be available soon.\n                                </h2>\n                                <p className=\"mt-3 md:mt-5 lg:mt-8 text-slate-400 text-xs md:text-sm lg:text-base\">\n                                    You can access the source code of the demo project{\" \"}\n                                    <DarkLink url=\"https://github.com/onesine/demo-react-tailwindcss-select\">\n                                        here\n                                    </DarkLink>\n                                    . <br />\n                                    Any contribution to the package will be welcome. You can access\n                                    the package source code{\" \"}\n                                    <DarkLink url=\"https://github.com/onesine/react-tailwindcss-select\">\n                                        here\n                                    </DarkLink>\n                                    <br />\n                                    Thanks for testing{\" \"}\n                                    <DarkLink url=\"https://www.npmjs.com/package/react-tailwindcss-select\">\n                                        react-tailwindcss-select\n                                    </DarkLink>{\" \"}\n                                    and have a nice 👋 day.\n                                </p>\n                            </div>\n                        ) : (\n                            <SelectContainer>\n                                <Select\n                                    /*classNames={{\n                                        menuButton: (state) => \"flex text-sm text-gray-500 border border-gray-300 rounded shadow-sm transition-all duration-300 focus:outline-none bg-white hover:border-gray-400 focus:border-blue-500 focus:ring focus:ring-blue-500/20\",\n                                        menu: \"absolute z-10 w-full bg-white shadow-lg border rounded py-1 mt-1.5 text-sm text-gray-700\",\n                                        listItem: ({isSelected}) => \"list-none py-1.5 px-2 hover:bg-blue-500 rounded-md hover:text-white cursor-pointer\",\n                                        tagItem: ({isDisabled, item}) => {\n                                            console.log(\"item:\", item)\n                                            return 'flex space-x-2 p-0.5 rounded bg-blue-500 text-white';\n                                        }\n                                    }}*/\n                                    primaryColor={primaryColor}\n                                    options={filterOptions(options)}\n                                    onChange={value => setValue(value)}\n                                    value={value}\n                                    loading={loading}\n                                    isClearable={isClearable}\n                                    isSearchable={isSearchable}\n                                    isMultiple={isMultiple}\n                                    /*formatGroupLabel={(data) => (\n                                        <div className={`py-2 text-xs flex items-center justify-between`}>\n                                            <span className=\"font-bold\">{data.label}</span>\n                                            <span className=\"bg-gray-200 h-5 h-5 p-1.5 flex items-center justify-center rounded-full\">{data.options.length}</span>\n                                        </div>\n                                    )}*/\n                                    isDisabled={isDisabled}\n                                />\n\n                                <div className=\"mt-2\">\n                                    {SELECT_OPTIONS.map((item, index) => (\n                                        <Checkbox\n                                            id={item}\n                                            key={index}\n                                            checked={dispatch(item, \"get\")}\n                                            onChange={e => handleCheck(e.target.checked, item)}\n                                        >\n                                            {item}\n                                        </Checkbox>\n                                    ))}\n                                </div>\n\n                                <TailwindColors changeColor={color => setPrimaryColor(color)} />\n\n                                <p className=\"mt-3 text-center text-xs text-gray-500 font-semibold\">\n                                    If you want to try a theme proposed by one of these colors. You\n                                    can click disappointed.\n                                </p>\n\n                                {(isClearable ||\n                                    isSearchable ||\n                                    isMultiple ||\n                                    isDisabled ||\n                                    loading ||\n                                    isGroupOption) && (\n                                    <div className=\"mt-10 transition duration-75\">\n                                        <Alert title={\"Information\"}>\n                                            {printAlertContent(\"isClearable\", isClearable)}\n                                            {printAlertContent(\"isSearchable\", isSearchable)}\n                                            {printAlertContent(\"isMultiple\", isMultiple)}\n                                            {printAlertContent(\"isDisabled\", isDisabled)}\n                                            {printAlertContent(\"loading\", loading)}\n                                            {printAlertContent(\"isGroupOption\", isGroupOption)}\n                                        </Alert>\n                                    </div>\n                                )}\n                            </SelectContainer>\n                        )}\n                    </div>\n                </div>\n\n                <p className=\"text-center py-10 text-slate-500 text-sm\">\n                    Made with ❤️ by <LightLink url=\"https://twitter.com/LewheO\">Onesine</LightLink>,\n                    powered by <LightLink url=\"https://reactjs.org/\">react</LightLink> and{\" \"}\n                    <LightLink url=\"https://tailwindcss.com/\">tailwindcss</LightLink>.\n                </p>\n            </div>\n        </>\n    );\n};\n\nexport default Home;\n"
  },
  {
    "path": "postcss.config.js",
    "content": "module.exports = {\n    plugins: {\n        tailwindcss: {},\n        autoprefixer: {},\n        ...(process.env.NODE_ENV === \"production\" ? { cssnano: {} } : {})\n    }\n};\n"
  },
  {
    "path": "rollup.config.js",
    "content": "import commonjs from \"@rollup/plugin-commonjs\";\nimport resolve from \"@rollup/plugin-node-resolve\";\nimport typescript from \"@rollup/plugin-typescript\";\n\nconst packageJson = require(\"./package.json\");\nconst options = require(\"./tsconfig.json\");\n\nmodule.exports = {\n    input: \"src/index.tsx\",\n    output: [\n        {\n            file: packageJson.main,\n            format: \"cjs\",\n            exports: \"auto\",\n            sourcemap: true\n        },\n        {\n            file: packageJson.module,\n            format: \"esm\",\n            exports: \"auto\",\n            sourcemap: true\n        }\n    ],\n    external: [\"react\"],\n    plugins: [resolve(), commonjs(), typescript({ ...options.compilerOptions, jsx: \"react\" })]\n};\n"
  },
  {
    "path": "src/components/DisabledItem.tsx",
    "content": "import React, { useContext } from \"react\";\n\nimport { SelectContext } from \"./SelectProvider\";\n\ninterface DisabledItemProps {\n    children: JSX.Element | string;\n}\n\nconst DisabledItem: React.FC<DisabledItemProps> = ({ children }) => {\n    const { classNames } = useContext(SelectContext);\n    return (\n        <div\n            className={\n                classNames && classNames.listDisabledItem\n                    ? classNames.listDisabledItem\n                    : \"px-2 py-2 cursor-not-allowed truncate text-gray-400 select-none\"\n            }\n        >\n            {children}\n        </div>\n    );\n};\n\nexport default DisabledItem;\n"
  },
  {
    "path": "src/components/GroupItem.tsx",
    "content": "import React from \"react\";\n\nimport Item from \"./Item\";\nimport { useSelectContext } from \"./SelectProvider\";\nimport { GroupOption } from \"./type\";\n\ninterface GroupItemProps {\n    item: GroupOption;\n    primaryColor: string;\n}\n\nconst GroupItem: React.FC<GroupItemProps> = ({ item, primaryColor }) => {\n    const { classNames, formatGroupLabel } = useSelectContext();\n\n    return (\n        <>\n            {item.options.length > 0 && (\n                <>\n                    {formatGroupLabel ? (\n                        <>{formatGroupLabel(item)}</>\n                    ) : (\n                        <div\n                            className={\n                                classNames?.listGroupLabel\n                                    ? classNames.listGroupLabel\n                                    : \"pr-2 py-2 cursor-default select-none truncate font-bold text-gray-700\"\n                            }\n                        >\n                            {item.label}\n                        </div>\n                    )}\n\n                    {item.options.map((item, index) => (\n                        <Item primaryColor={primaryColor} key={index} item={item} />\n                    ))}\n                </>\n            )}\n        </>\n    );\n};\n\nexport default GroupItem;\n"
  },
  {
    "path": "src/components/Icons.tsx",
    "content": "import React from \"react\";\n\ninterface Props {\n    className?: string;\n}\n\nexport const CloseIcon: React.FC<Props> = ({ className = \"\" }) => {\n    return (\n        <svg\n            className={className}\n            fill=\"currentColor\"\n            viewBox=\"0 0 20 20\"\n            xmlns=\"http://www.w3.org/2000/svg\"\n        >\n            <path\n                fillRule=\"evenodd\"\n                d=\"M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z\"\n                clipRule=\"evenodd\"\n            />\n        </svg>\n    );\n};\n\nexport const ChevronIcon: React.FC<Props> = ({ className = \"\" }) => {\n    return (\n        <svg\n            className={className}\n            fill=\"currentColor\"\n            viewBox=\"0 0 20 20\"\n            xmlns=\"http://www.w3.org/2000/svg\"\n        >\n            <path\n                fillRule=\"evenodd\"\n                d=\"M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z\"\n                clipRule=\"evenodd\"\n            />\n        </svg>\n    );\n};\n\nexport const SearchIcon: React.FC<Props> = ({ className = \"\" }) => {\n    return (\n        <svg\n            className={className}\n            fill=\"none\"\n            stroke=\"currentColor\"\n            viewBox=\"0 0 24 24\"\n            xmlns=\"http://www.w3.org/2000/svg\"\n        >\n            <path\n                strokeLinecap=\"round\"\n                strokeLinejoin=\"round\"\n                strokeWidth={2}\n                d=\"M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z\"\n            />\n        </svg>\n    );\n};\n"
  },
  {
    "path": "src/components/Item.tsx",
    "content": "import React, { useCallback, useMemo } from \"react\";\n\nimport { COLORS, DEFAULT_THEME, THEME_DATA } from \"../constants\";\n\nimport DisabledItem from \"./DisabledItem\";\nimport { useSelectContext } from \"./SelectProvider\";\nimport { Option } from \"./type\";\n\ninterface ItemProps {\n    item: Option;\n    primaryColor: string;\n}\n\nconst Item: React.FC<ItemProps> = ({ item, primaryColor }) => {\n    const { classNames, value, handleValueChange, formatOptionLabel } = useSelectContext();\n\n    const isSelected = useMemo(() => {\n        return value !== null && !Array.isArray(value) && value.value === item.value;\n    }, [item.value, value]);\n\n    const textHoverColor = useMemo(() => {\n        if (COLORS.includes(primaryColor)) {\n            return THEME_DATA.textHover[primaryColor as keyof typeof THEME_DATA.textHover];\n        }\n        return THEME_DATA.textHover[DEFAULT_THEME];\n    }, [primaryColor]);\n\n    const bgColor = useMemo(() => {\n        if (COLORS.includes(primaryColor)) {\n            return THEME_DATA.bg[primaryColor as keyof typeof THEME_DATA.bg];\n        }\n        return THEME_DATA.bg[DEFAULT_THEME];\n    }, [primaryColor]);\n\n    const bgHoverColor = useMemo(() => {\n        if (COLORS.includes(primaryColor)) {\n            return THEME_DATA.bgHover[primaryColor as keyof typeof THEME_DATA.bgHover];\n        }\n        return THEME_DATA.bgHover[DEFAULT_THEME];\n    }, [primaryColor]);\n\n    const getItemClass = useCallback(() => {\n        const baseClass =\n            \"block transition duration-200 px-2 py-2 cursor-pointer select-none truncate rounded\";\n        const selectedClass = isSelected\n            ? `text-white ${bgColor}`\n            : `text-gray-500 ${bgHoverColor} ${textHoverColor}`;\n\n        return classNames && classNames.listItem\n            ? classNames.listItem({ isSelected })\n            : `${baseClass} ${selectedClass}`;\n    }, [bgColor, bgHoverColor, classNames, isSelected, textHoverColor]);\n\n    return (\n        <>\n            {formatOptionLabel ? (\n                <div onClick={() => handleValueChange(item)}>\n                    {formatOptionLabel({ ...item, isSelected })}\n                </div>\n            ) : (\n                <>\n                    {item.disabled ? (\n                        <DisabledItem>{item.label}</DisabledItem>\n                    ) : (\n                        <li\n                            tabIndex={0}\n                            onKeyDown={(e: React.KeyboardEvent<HTMLLIElement>) => {\n                                if (e.key === ' ' || e.key === 'Enter') {\n                                    handleValueChange(item)\n                                }\n                            }}\n                            aria-selected={isSelected}\n                            role={\"option\"}\n                            onClick={() => handleValueChange(item)}\n                            className={getItemClass()}\n                        >\n                            {item.label}\n                        </li>\n                    )}\n                </>\n            )}\n        </>\n    );\n};\n\nexport default Item;\n"
  },
  {
    "path": "src/components/Options.tsx",
    "content": "import React, { useCallback, useContext, useMemo } from \"react\";\n\nimport { DEFAULT_THEME } from \"../constants\";\n\nimport DisabledItem from \"./DisabledItem\";\nimport GroupItem from \"./GroupItem\";\nimport Item from \"./Item\";\nimport { SelectContext } from \"./SelectProvider\";\nimport { Option, Options as ListOption } from \"./type\";\n\ninterface OptionsProps {\n    list: ListOption;\n    noOptionsMessage: string;\n    text: string;\n    isMultiple: boolean;\n    value: Option | Option[] | null;\n    primaryColor: string;\n}\n\nconst Options: React.FC<OptionsProps> = ({\n    list,\n    noOptionsMessage,\n    text,\n    isMultiple,\n    value,\n    primaryColor = DEFAULT_THEME\n}) => {\n    const { classNames } = useContext(SelectContext);\n    const filterByText = useCallback(() => {\n        const filterItem = (item: Option) => {\n            return item.label.toLowerCase().indexOf(text.toLowerCase()) > -1;\n        };\n\n        let result = list.map(item => {\n            if (\"options\" in item) {\n                return {\n                    label: item.label,\n                    options: item.options.filter(filterItem)\n                };\n            }\n            return item;\n        });\n\n        result = result.filter(item => {\n            if (\"options\" in item) {\n                return item.options.length > 0;\n            }\n            return filterItem(item);\n        });\n\n        return result;\n    }, [text, list]);\n\n    const removeValues = useCallback(\n        (array: ListOption) => {\n            if (!isMultiple) {\n                return array;\n            }\n\n            if (Array.isArray(value)) {\n                const valueId = value.map(item => item.value);\n\n                const filterItem = (item: Option) => !valueId.includes(item.value);\n\n                let newArray = array.map(item => {\n                    if (\"options\" in item) {\n                        return {\n                            label: item.label,\n                            options: item.options.filter(filterItem)\n                        };\n                    }\n                    return item;\n                });\n\n                newArray = newArray.filter(item => {\n                    if (\"options\" in item) {\n                        return item.options.length > 0;\n                    } else {\n                        return filterItem(item);\n                    }\n                });\n\n                return newArray;\n            }\n            return array;\n        },\n        [isMultiple, value]\n    );\n\n    const filterResult = useMemo(() => {\n        return removeValues(filterByText());\n    }, [filterByText, removeValues]);\n\n    return (\n        <div\n            role=\"options\"\n            className={classNames && classNames.list ? classNames.list : \"max-h-72 overflow-y-auto\"}\n        >\n            {filterResult.map((item, index) => (\n                <React.Fragment key={index}>\n                    {\"options\" in item ? (\n                        <>\n                            <div className=\"px-2.5\">\n                                <GroupItem\n                                    primaryColor={primaryColor || DEFAULT_THEME}\n                                    item={item}\n                                />\n                            </div>\n\n                            {index + 1 < filterResult.length && <hr className=\"my-1\" />}\n                        </>\n                    ) : (\n                        <div className=\"px-2.5\">\n                            <Item primaryColor={primaryColor || DEFAULT_THEME} item={item} />\n                        </div>\n                    )}\n                </React.Fragment>\n            ))}\n\n            {filterResult.length === 0 && <DisabledItem>{noOptionsMessage}</DisabledItem>}\n        </div>\n    );\n};\n\nexport default Options;\n"
  },
  {
    "path": "src/components/SearchInput.tsx",
    "content": "import React, { forwardRef, useContext } from \"react\";\n\nimport { SearchIcon } from \"./Icons\";\nimport { SelectContext } from \"./SelectProvider\";\n\ninterface SearchInputProps {\n    placeholder?: string;\n    value: string;\n    onChange: (e: React.ChangeEvent<HTMLInputElement>) => void;\n    name?: string;\n}\n\nconst SearchInput = forwardRef<HTMLInputElement, SearchInputProps>(function SearchInput(\n    { placeholder = \"\", value = \"\", onChange, name = \"\" },\n    ref\n) {\n    const { classNames } = useContext(SelectContext);\n    return (\n        <div\n            className={\n                classNames && classNames.searchContainer\n                    ? classNames.searchContainer\n                    : \"relative py-1 px-2.5\"\n            }\n        >\n            <SearchIcon\n                className={\n                    classNames && classNames.searchIcon\n                        ? classNames.searchIcon\n                        : \"absolute w-5 h-5 mt-2.5 pb-0.5 ml-2 text-gray-500\"\n                }\n            />\n            <input\n                ref={ref}\n                className={\n                    classNames && classNames.searchBox\n                        ? classNames.searchBox\n                        : \"w-full py-2 pl-8 text-sm text-gray-500 bg-gray-100 border border-gray-200 rounded focus:border-gray-200 focus:ring-0 focus:outline-none\"\n                }\n                type=\"text\"\n                placeholder={placeholder}\n                value={value}\n                onChange={onChange}\n                name={name}\n            />\n        </div>\n    );\n});\n\nexport default SearchInput;\n"
  },
  {
    "path": "src/components/Select.tsx",
    "content": "import React, { useCallback, useEffect, useRef, useState } from \"react\";\n\nimport { COLORS, DEFAULT_THEME, THEME_DATA } from \"../constants\";\nimport useOnClickOutside from \"../hooks/use-onclick-outside\";\n\nimport { ChevronIcon, CloseIcon } from \"./Icons\";\nimport Options from \"./Options\";\nimport SearchInput from \"./SearchInput\";\nimport SelectProvider from \"./SelectProvider\";\nimport Spinner from \"./Spinner\";\nimport { Option, Options as ListOption, SelectProps } from \"./type\";\n\nconst Select: React.FC<SelectProps> = ({\n    options = [],\n    value = null,\n    onChange,\n    onSearchInputChange,\n    placeholder = \"Select...\",\n    searchInputPlaceholder = \"Search...\",\n    isMultiple = false,\n    isClearable = false,\n    isSearchable = false,\n    isDisabled = false,\n    loading = false,\n    menuIsOpen = false,\n    noOptionsMessage = \"No options found\",\n    primaryColor = DEFAULT_THEME,\n    formatGroupLabel = null,\n    formatOptionLabel = null,\n    classNames\n}) => {\n    const [open, setOpen] = useState<boolean>(menuIsOpen);\n    const [list, setList] = useState<ListOption>(options);\n    const [inputValue, setInputValue] = useState<string>(\"\");\n    const ref = useRef<HTMLDivElement>(null);\n    const searchBoxRef = useRef<HTMLInputElement>(null);\n\n    useEffect(() => {\n        const formatItem = (item: Option) => {\n            if (\"disabled\" in item) return item;\n            return {\n                ...item,\n                disabled: false\n            };\n        };\n\n        setList(\n            options.map(item => {\n                if (\"options\" in item) {\n                    return {\n                        label: item.label,\n                        options: item.options.map(formatItem)\n                    };\n                } else {\n                    return formatItem(item);\n                }\n            })\n        );\n    }, [options]);\n\n    useEffect(() => {\n        if (isSearchable) {\n            if (open) {\n                searchBoxRef.current?.select();\n            } else {\n                setInputValue(\"\");\n            }\n        }\n    }, [open, isSearchable]);\n\n    const toggle = useCallback(() => {\n        if (!isDisabled) {\n            setOpen(!open);\n        }\n    }, [isDisabled, open]);\n\n    const closeDropDown = useCallback(() => {\n        if (open) setOpen(false);\n    }, [open]);\n\n    useOnClickOutside(ref, () => {\n        closeDropDown();\n    });\n\n    const onPressEnterOrSpace = useCallback(\n        (e: React.KeyboardEvent<HTMLDivElement>) => {\n            e.preventDefault();\n            if ((e.code === \"Enter\" || e.code === \"Space\") && !isDisabled) {\n                toggle();\n            }\n        },\n        [isDisabled, toggle]\n    );\n\n    const handleValueChange = useCallback(\n        (selected: Option) => {\n            function update() {\n                if (!isMultiple && !Array.isArray(value)) {\n                    closeDropDown();\n                    onChange(selected);\n                }\n\n                if (isMultiple && (Array.isArray(value) || value === null)) {\n                    onChange(value === null ? [selected] : [...value, selected]);\n                }\n            }\n\n            if (selected !== value) {\n                update();\n            }\n        },\n        [closeDropDown, isMultiple, onChange, value]\n    );\n\n    const clearValue = useCallback(\n        (e: React.MouseEvent<HTMLDivElement>) => {\n            e.stopPropagation();\n            onChange(null);\n        },\n        [onChange]\n    );\n\n    const removeItem = useCallback(\n        (e: React.MouseEvent<HTMLDivElement>, item: Option) => {\n            if (isMultiple && Array.isArray(value) && value.length) {\n                e.stopPropagation();\n                const result = value.filter(current => item.value !== current.value);\n                onChange(result.length ? result : null);\n            }\n        },\n        [isMultiple, onChange, value]\n    );\n\n    const getSelectClass = useCallback(() => {\n        let ringColor = THEME_DATA.ring[DEFAULT_THEME];\n        if (COLORS.includes(primaryColor)) {\n            ringColor = THEME_DATA.ring[primaryColor as keyof typeof THEME_DATA.ring];\n        }\n\n        let borderFocus = THEME_DATA.borderFocus[DEFAULT_THEME];\n        if (COLORS.includes(primaryColor)) {\n            borderFocus =\n                THEME_DATA.borderFocus[primaryColor as keyof typeof THEME_DATA.borderFocus];\n        }\n        const baseClass =\n            \"flex text-sm text-gray-500 border border-gray-300 rounded shadow-sm transition-all duration-300 focus:outline-none\";\n        const defaultClass = `${baseClass} ${\n            isDisabled\n                ? \"bg-gray-200\"\n                : `bg-white hover:border-gray-400 ${borderFocus} focus:ring ${ringColor}`\n        }`;\n\n        return classNames && classNames.menuButton\n            ? classNames.menuButton({ isDisabled })\n            : defaultClass;\n    }, [classNames, isDisabled, primaryColor]);\n\n    const getTagItemClass = useCallback(\n        (item: Option) => {\n            const baseClasse = \"bg-gray-200 border rounded-sm flex space-x-1\";\n            const disabledClass = isDisabled ? \"border-gray-500 px-1\" : \"pl-1\";\n            return classNames?.tagItem\n                ? classNames.tagItem({ item, isDisabled })\n                : `${baseClasse} ${disabledClass}`;\n        },\n        [classNames, isDisabled]\n    );\n\n    return (\n        <SelectProvider\n            otherData={{\n                formatGroupLabel,\n                formatOptionLabel,\n                classNames\n            }}\n            value={value}\n            handleValueChange={handleValueChange}\n        >\n            <div className=\"relative w-full\" ref={ref}>\n                <div\n                    aria-expanded={open}\n                    onKeyDown={onPressEnterOrSpace}\n                    onClick={toggle}\n                    className={getSelectClass()}\n                >\n                    <div className=\"grow pl-2.5 py-2 pr-2 flex flex-wrap gap-1\">\n                        {!isMultiple ? (\n                            <p className=\"truncate cursor-default select-none\">\n                                {value && !Array.isArray(value) ? value.label : placeholder}\n                            </p>\n                        ) : (\n                            <>\n                                {value === null && placeholder}\n\n                                {Array.isArray(value) &&\n                                    value.map((item, index) => (\n                                        <div className={getTagItemClass(item)} key={index}>\n                                            <p\n                                                className={\n                                                    classNames?.tagItemText\n                                                        ? classNames.tagItemText\n                                                        : \"text-gray-600 truncate cursor-default select-none\"\n                                                }\n                                            >\n                                                {item.label}\n                                            </p>\n                                            {!isDisabled && (\n                                                <div\n                                                    role=\"button\"\n                                                    tabIndex={0}\n                                                    onClick={e => removeItem(e, item)}\n                                                    className={\n                                                        classNames?.tagItemIconContainer\n                                                            ? classNames.tagItemIconContainer\n                                                            : \"flex items-center px-1 cursor-pointer rounded-r-sm hover:bg-red-200 hover:text-red-600\"\n                                                    }\n                                                >\n                                                    <CloseIcon\n                                                        className={\n                                                            classNames?.tagItemIcon\n                                                                ? classNames.tagItemIcon\n                                                                : \"w-3 h-3 mt-0.5\"\n                                                        }\n                                                    />\n                                                </div>\n                                            )}\n                                        </div>\n                                    ))}\n                            </>\n                        )}\n                    </div>\n\n                    <div className=\"flex flex-none items-center py-1.5\">\n                        {loading && (\n                            <div className=\"px-1.5\">\n                                <Spinner primaryColor={primaryColor} />\n                            </div>\n                        )}\n\n                        {isClearable && !isDisabled && value !== null && (\n                            <div className=\"px-1.5 cursor-pointer\" onClick={clearValue}>\n                                <CloseIcon\n                                    className={\n                                        classNames?.closeIcon\n                                            ? classNames.closeIcon\n                                            : \"w-5 h-5 p-0.5\"\n                                    }\n                                />\n                            </div>\n                        )}\n\n                        <div className=\"h-full\">\n                            <span className=\"w-px h-full inline-block text-white bg-gray-300 text-opacity-0\" />\n                        </div>\n\n                        <div className=\"px-1.5\">\n                            <ChevronIcon\n                                className={`transition duration-300 w-6 h-6 p-0.5${\n                                    open ? \" transform rotate-90 text-gray-500\" : \" text-gray-300\"\n                                }`}\n                            />\n                        </div>\n                    </div>\n                </div>\n\n                {open && !isDisabled && (\n                    <div\n                        className={\n                            classNames?.menu\n                                ? classNames.menu\n                                : \"absolute z-10 w-full bg-white shadow-lg border rounded py-1 mt-1.5 text-sm text-gray-700\"\n                        }\n                    >\n                        {isSearchable && (\n                            <SearchInput\n                                ref={searchBoxRef}\n                                value={inputValue}\n                                placeholder={searchInputPlaceholder}\n                                onChange={e => {\n                                    if (\n                                        onSearchInputChange &&\n                                        typeof onSearchInputChange === \"function\"\n                                    )\n                                        onSearchInputChange(e);\n                                    setInputValue(e.target.value);\n                                }}\n                            />\n                        )}\n\n                        <Options\n                            list={list}\n                            noOptionsMessage={noOptionsMessage}\n                            text={inputValue}\n                            isMultiple={isMultiple}\n                            value={value}\n                            primaryColor={primaryColor || DEFAULT_THEME}\n                        />\n                    </div>\n                )}\n            </div>\n        </SelectProvider>\n    );\n};\n\nexport default Select;\n"
  },
  {
    "path": "src/components/SelectProvider.tsx",
    "content": "import React, { createContext, useContext, useMemo } from \"react\";\n\nimport { ClassNames, GroupOption, Option } from \"./type\";\n\ninterface Store {\n    value: Option | Option[] | null;\n    handleValueChange: (selected: Option) => void;\n    formatGroupLabel: ((data: GroupOption) => JSX.Element) | null;\n    formatOptionLabel: ((data: Option) => JSX.Element) | null;\n    classNames?: ClassNames;\n}\n\ninterface Props {\n    value: Option | Option[] | null;\n    handleValueChange: (selected: Option) => void;\n    children: JSX.Element;\n    otherData: {\n        formatGroupLabel: ((data: GroupOption) => JSX.Element) | null;\n        formatOptionLabel: ((data: Option) => JSX.Element) | null;\n        classNames?: ClassNames;\n    };\n}\n\nexport const SelectContext = createContext<Store>({\n    value: null,\n    handleValueChange: selected => {\n        console.log(\"selected:\", selected);\n    },\n    formatGroupLabel: null,\n    formatOptionLabel: null,\n    classNames: undefined\n});\n\nexport const useSelectContext = (): Store => {\n    return useContext(SelectContext);\n};\n\nconst SelectProvider: React.FC<Props> = ({ value, handleValueChange, otherData, children }) => {\n    const store = useMemo(() => {\n        return {\n            value,\n            handleValueChange,\n            formatGroupLabel:\n                otherData && typeof otherData.formatGroupLabel === \"function\"\n                    ? otherData.formatGroupLabel\n                    : null,\n            formatOptionLabel:\n                otherData && typeof otherData.formatOptionLabel === \"function\"\n                    ? otherData.formatOptionLabel\n                    : null,\n            classNames: otherData?.classNames || undefined\n        };\n    }, [handleValueChange, otherData, value]);\n\n    return <SelectContext.Provider value={store}>{children}</SelectContext.Provider>;\n};\n\nexport default SelectProvider;\n"
  },
  {
    "path": "src/components/Spinner.tsx",
    "content": "import React, { useMemo } from \"react\";\n\nimport { COLORS, DEFAULT_THEME, THEME_DATA } from \"../constants\";\n\ninterface Props {\n    primaryColor?: string;\n}\n\nconst Spinner: React.FC<Props> = ({ primaryColor = DEFAULT_THEME }) => {\n    const spinnerColor = useMemo(() => {\n        if (COLORS.includes(primaryColor)) {\n            return THEME_DATA.text[primaryColor as keyof typeof THEME_DATA.text];\n        }\n        return THEME_DATA.text[DEFAULT_THEME];\n    }, [primaryColor]);\n\n    return (\n        <svg\n            className={`animate-spin mr-0.5 h-5 w-5 ${spinnerColor}`}\n            xmlns=\"http://www.w3.org/2000/svg\"\n            fill=\"none\"\n            viewBox=\"0 0 24 24\"\n        >\n            <circle\n                className=\"opacity-25\"\n                cx=\"12\"\n                cy=\"12\"\n                r=\"10\"\n                stroke=\"currentColor\"\n                strokeWidth=\"4\"\n            />\n            <path\n                className=\"opacity-75\"\n                fill=\"currentColor\"\n                d=\"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z\"\n            />\n        </svg>\n    );\n};\n\nexport default Spinner;\n"
  },
  {
    "path": "src/components/type.ts",
    "content": "import React from \"react\";\n\nexport interface Option {\n    value: string;\n    label: string;\n    disabled?: boolean;\n    isSelected?: boolean;\n}\n\nexport interface GroupOption {\n    label: string;\n    options: Option[];\n}\n\nexport type Options = Array<Option | GroupOption>;\n\nexport interface ClassNames {\n    menuButton?: (value?: { isDisabled?: boolean }) => string;\n    menu?: string;\n    tagItem?: (value?: { item?: Option; isDisabled?: boolean }) => string;\n    tagItemText?: string;\n    tagItemIconContainer?: string;\n    tagItemIcon?: string;\n    list?: string;\n    listGroupLabel?: string;\n    listItem?: (value?: { isSelected?: boolean }) => string;\n    listDisabledItem?: string;\n    ChevronIcon?: (value?: { open?: boolean }) => string;\n    searchContainer?: string;\n    searchBox?: string;\n    searchIcon?: string;\n    closeIcon?: string;\n}\n\nexport type SelectValue = Option | Option[] | null;\n\nexport interface SelectProps {\n    options: Options;\n    value: SelectValue;\n    onChange: (value: SelectValue) => void;\n    onSearchInputChange?: (e: React.ChangeEvent<HTMLInputElement>) => void;\n    placeholder?: string;\n    isMultiple?: boolean;\n    isClearable?: boolean;\n    isSearchable?: boolean;\n    isDisabled?: boolean;\n    loading?: boolean;\n    menuIsOpen?: boolean;\n    searchInputPlaceholder?: string;\n    noOptionsMessage?: string;\n    primaryColor: string;\n    formatGroupLabel?: ((data: GroupOption) => JSX.Element) | null;\n    formatOptionLabel?: ((data: Option) => JSX.Element) | null;\n    classNames?: ClassNames;\n}\n"
  },
  {
    "path": "src/constants/index.ts",
    "content": "export const COLORS = [\n    \"blue\",\n    \"orange\",\n    \"yellow\",\n    \"red\",\n    \"purple\",\n    \"amber\",\n    \"lime\",\n    \"green\",\n    \"emerald\",\n    \"teal\",\n    \"cyan\",\n    \"sky\",\n    \"violet\",\n    \"indigo\",\n    \"purple\",\n    \"fuchsia\",\n    \"pink\",\n    \"rose\"\n];\n\nexport const DEFAULT_THEME = \"blue\";\n\nexport const THEME_DATA = {\n    bg: {\n        blue: \"bg-blue-500\",\n        orange: \"bg-orange-500\",\n        yellow: \"bg-yellow-500\",\n        red: \"bg-red-500\",\n        purple: \"bg-purple-500\",\n        amber: \"bg-amber-500\",\n        lime: \"bg-lime-500\",\n        green: \"bg-green-500\",\n        emerald: \"bg-emerald-500\",\n        teal: \"bg-teal-500\",\n        cyan: \"bg-cyan-500\",\n        sky: \"bg-sky-500\",\n        indigo: \"bg-indigo-500\",\n        violet: \"bg-violet-500\",\n        fuchsia: \"bg-fuchsia-500\",\n        pink: \"bg-pink-500\",\n        rose: \"bg-rose-500\"\n    },\n    bgHover: {\n        blue: \"hover:bg-blue-100\",\n        orange: \"hover:bg-orange-100\",\n        yellow: \"hover:bg-yellow-100\",\n        red: \"hover:bg-red-100\",\n        purple: \"hover:bg-purple-100\",\n        amber: \"hover:bg-amber-100\",\n        lime: \"hover:bg-lime-100\",\n        green: \"hover:bg-green-100\",\n        emerald: \"hover:bg-emerald-100\",\n        teal: \"hover:bg-teal-100\",\n        cyan: \"hover:bg-cyan-100\",\n        sky: \"hover:bg-sky-100\",\n        indigo: \"hover:bg-indigo-100\",\n        violet: \"hover:bg-violet-100\",\n        fuchsia: \"hover:bg-fuchsia-100\",\n        pink: \"hover:bg-pink-100\",\n        rose: \"hover:bg-rose-100\"\n    },\n    ring: {\n        blue: \"focus:ring-blue-500/20\",\n        orange: \"focus:ring-orange-500/20\",\n        yellow: \"focus:ring-yellow-500/20\",\n        red: \"focus:ring-red-500/20\",\n        purple: \"focus:ring-purple-500/20\",\n        amber: \"focus:ring-amber-500/20\",\n        lime: \"focus:ring-lime-500/20\",\n        green: \"focus:ring-green-500/20\",\n        emerald: \"focus:ring-emerald-500/20\",\n        teal: \"focus:ring-teal-500/20\",\n        cyan: \"focus:ring-cyan-500/20\",\n        sky: \"focus:ring-sky-500/20\",\n        indigo: \"focus:ring-indigo-500/20\",\n        violet: \"focus:ring-violet-500/20\",\n        fuchsia: \"focus:ring-fuchsia-500/20\",\n        pink: \"focus:ring-pink-500/20\",\n        rose: \"focus:ring-rose-500/20\"\n    },\n    borderFocus: {\n        blue: \"focus:border-blue-500\",\n        orange: \"focus:border-orange-500\",\n        yellow: \"focus:border-yellow-500\",\n        red: \"focus:border-red-500\",\n        purple: \"focus:border-purple-500\",\n        amber: \"focus:border-amber-500\",\n        lime: \"focus:border-lime-500\",\n        green: \"focus:border-green-500\",\n        emerald: \"focus:border-emerald-500\",\n        teal: \"focus:border-teal-500\",\n        cyan: \"focus:border-cyan-500\",\n        sky: \"focus:border-sky-500\",\n        indigo: \"focus:border-indigo-500\",\n        violet: \"focus:border-violet-500\",\n        fuchsia: \"focus:border-fuchsia-500\",\n        pink: \"focus:border-pink-500\",\n        rose: \"focus:border-rose-500\"\n    },\n    text: {\n        blue: \"text-blue-500\",\n        orange: \"text-orange-500\",\n        yellow: \"text-yellow-500\",\n        red: \"text-red-500\",\n        purple: \"text-purple-500\",\n        amber: \"text-amber-500\",\n        lime: \"text-lime-500\",\n        green: \"text-green-500\",\n        emerald: \"text-emerald-500\",\n        teal: \"text-teal-500\",\n        cyan: \"text-cyan-500\",\n        sky: \"text-sky-500\",\n        indigo: \"text-indigo-500\",\n        violet: \"text-violet-500\",\n        fuchsia: \"text-fuchsia-500\",\n        pink: \"text-pink-500\",\n        rose: \"text-rose-500\"\n    },\n    textHover: {\n        blue: \"hover:text-blue-500\",\n        orange: \"hover:text-orange-500\",\n        yellow: \"hover:text-yellow-500\",\n        red: \"hover:text-red-500\",\n        purple: \"hover:text-purple-500\",\n        amber: \"hover:text-amber-500\",\n        lime: \"hover:text-lime-500\",\n        green: \"hover:text-green-500\",\n        emerald: \"hover:text-emerald-500\",\n        teal: \"hover:text-teal-500\",\n        cyan: \"hover:text-cyan-500\",\n        sky: \"hover:text-sky-500\",\n        indigo: \"hover:text-indigo-500\",\n        violet: \"hover:text-violet-500\",\n        fuchsia: \"hover:text-fuchsia-500\",\n        pink: \"hover:text-pink-500\",\n        rose: \"hover:text-rose-500\"\n    }\n};\n"
  },
  {
    "path": "src/hooks/use-onclick-outside.ts",
    "content": "import React, { useEffect } from \"react\";\n\nexport default function useOnClickOutside(\n    ref: React.RefObject<HTMLDivElement>,\n    handler: (e?: MouseEvent | TouchEvent) => void\n) {\n    useEffect(() => {\n        const listener = (event: MouseEvent | TouchEvent) => {\n            if (!ref.current || ref.current.contains(event.target as Node)) {\n                return;\n            }\n\n            handler(event);\n        };\n\n        document.addEventListener(\"mousedown\", listener);\n        document.addEventListener(\"touchstart\", listener);\n\n        return () => {\n            document.removeEventListener(\"mousedown\", listener);\n            document.removeEventListener(\"touchstart\", listener);\n        };\n    }, [ref, handler]);\n}\n"
  },
  {
    "path": "src/index.css",
    "content": "@tailwind base;\n@tailwind components;\n@tailwind utilities;\n"
  },
  {
    "path": "src/index.tsx",
    "content": "import Select from \"./components/Select\";\n\nexport default Select;\n"
  },
  {
    "path": "tailwind.config.js",
    "content": "/** @type {import('tailwindcss').Config} */\nmodule.exports = {\n    content: [\n        \"./pages/**/*.{js,ts,jsx,tsx}\",\n        \"./page-components/**/*.{js,ts,jsx,tsx}\",\n        \"./src/**/*.{js,ts,jsx,tsx}\"\n    ],\n    theme: {\n        extend: {}\n    },\n    plugins: [require(\"@tailwindcss/forms\")]\n};\n"
  },
  {
    "path": "tsconfig.json",
    "content": "{\n    \"compilerOptions\": {\n        \"target\": \"esnext\",\n        \"lib\": [\"dom\", \"esnext\"],\n        \"module\": \"esnext\",\n        \"jsx\": \"preserve\",\n        \"moduleResolution\": \"node\",\n        \"forceConsistentCasingInFileNames\": true,\n        \"strict\": true,\n        \"noImplicitReturns\": true,\n        \"allowSyntheticDefaultImports\": true,\n        \"esModuleInterop\": true,\n        \"baseUrl\": \"src/\",\n        \"declaration\": true,\n        \"outDir\": \"./dist\",\n        \"inlineSources\": true,\n        \"sourceMap\": true,\n        \"rootDir\": \"src\",\n        \"allowJs\": true,\n        \"skipLibCheck\": true,\n        \"noEmit\": true,\n        \"incremental\": true,\n        \"resolveJsonModule\": true,\n        \"isolatedModules\": true\n    },\n    \"include\": [\"src/**/*\"],\n    \"exclude\": [\"node_modules\"]\n}\n"
  }
]