├── .browserslistrc ├── .changeset ├── README.md ├── config.json └── getChangelogEntry.js ├── .circleci └── config.yml ├── .codesandbox └── ci.json ├── .coveralls.yml ├── .editorconfig ├── .eslintignore ├── .eslintrc.js ├── .github ├── CONTRIBUTING.md ├── ISSUE_TEMPLATE │ ├── bug_report.md │ └── config.yml ├── dependabot.yml └── workflows │ └── release.yml ├── .gitignore ├── .nvmrc ├── .prettierignore ├── .prettierrc.js ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── babel.config.js ├── cypress.json ├── cypress ├── fixtures │ └── selectors.json ├── integration │ ├── multi-select.spec.ts │ └── single-select.spec.ts └── tsconfig.json ├── docs ├── App │ ├── Footer.tsx │ ├── GitHubButton.tsx │ ├── Header.tsx │ ├── PageNav.tsx │ ├── ScrollSpy.tsx │ ├── Section.tsx │ ├── Sticky.tsx │ ├── TwitterButton.tsx │ ├── components.tsx │ ├── index.tsx │ └── routes.ts ├── CHANGELOG.md ├── ExampleWrapper.tsx ├── NoMatch.tsx ├── PropTypes │ ├── Async.ts │ ├── Creatable.ts │ ├── Select.ts │ ├── components │ │ ├── ClearIndicator.ts │ │ ├── Control.ts │ │ ├── DropdownIndicator.ts │ │ ├── Group.ts │ │ ├── IndicatorsContainer.ts │ │ ├── IndicatorsSeparator.ts │ │ ├── Input.ts │ │ ├── LoadingIndicator.ts │ │ ├── LoadingMessage.ts │ │ ├── Menu.ts │ │ ├── MenuList.ts │ │ ├── MultiValue.ts │ │ ├── MultiValueContainer.ts │ │ ├── MultiValueLabel.ts │ │ ├── MultiValueRemove.ts │ │ ├── NoOptionsMessage.ts │ │ ├── Option.ts │ │ ├── Placeholder.ts │ │ ├── SelectContainer.ts │ │ ├── SingleValue.ts │ │ └── ValueContainer.ts │ └── stateManager.ts ├── Svg.tsx ├── Table.tsx ├── Tests.tsx ├── _redirects ├── data.ts ├── examples │ ├── AccessingInternals.tsx │ ├── AnimatedMulti.tsx │ ├── AsyncCallbacks.tsx │ ├── AsyncCreatable.tsx │ ├── AsyncMulti.tsx │ ├── AsyncPromises.tsx │ ├── BasicGrouped.tsx │ ├── BasicMulti.tsx │ ├── BasicSingle.tsx │ ├── ControlledMenu.tsx │ ├── CreatableAdvanced.tsx │ ├── CreatableInputOnly.tsx │ ├── CreatableMulti.tsx │ ├── CreatableSingle.tsx │ ├── CreateFilter.tsx │ ├── CustomAriaLive.tsx │ ├── CustomClearIndicator.tsx │ ├── CustomControl.tsx │ ├── CustomDropdownIndicator.tsx │ ├── CustomFilterOptions.tsx │ ├── CustomGetOptionLabel.tsx │ ├── CustomGetOptionValue.tsx │ ├── CustomGroup.tsx │ ├── CustomGroupHeading.tsx │ ├── CustomIndicatorSeparator.tsx │ ├── CustomIndicatorsContainer.tsx │ ├── CustomInput.tsx │ ├── CustomIsOptionDisabled.tsx │ ├── CustomLoadingIndicator.tsx │ ├── CustomLoadingMessage.tsx │ ├── CustomMenu.tsx │ ├── CustomMenuList.tsx │ ├── CustomMultiValueContainer.tsx │ ├── CustomMultiValueLabel.tsx │ ├── CustomMultiValueRemove.tsx │ ├── CustomNoOptionsMessage.tsx │ ├── CustomOption.tsx │ ├── CustomPlaceholder.tsx │ ├── CustomSelectContainer.tsx │ ├── CustomSelectProps.tsx │ ├── CustomSingleValue.tsx │ ├── CustomValueContainer.tsx │ ├── DefaultOptions.tsx │ ├── Experimental.tsx │ ├── FixedOptions.tsx │ ├── MenuBuffer.tsx │ ├── MenuPortal.tsx │ ├── MultiSelectSort.tsx │ ├── OnSelectResetsInput.tsx │ ├── Popout.tsx │ ├── StyleCompositionExample.tsx │ ├── StyledMulti.tsx │ ├── StyledSingle.tsx │ ├── Theme.tsx │ └── index.tsx ├── favicon.ico ├── generate-magical-types │ ├── generate │ │ └── package.json │ ├── package.json │ ├── serialize │ │ └── package.json │ └── src │ │ ├── generate.ts │ │ ├── serialize.ts │ │ └── types.ts ├── index.css ├── index.html ├── index.tsx ├── isArray.ts ├── markdown │ ├── renderer.tsx │ └── store.ts ├── package.json ├── pages │ ├── advanced │ │ └── index.tsx │ ├── async │ │ └── index.tsx │ ├── components │ │ └── index.tsx │ ├── creatable │ │ └── index.tsx │ ├── home │ │ └── index.tsx │ ├── props │ │ └── index.tsx │ ├── styles │ │ └── index.tsx │ ├── typescript │ │ └── index.tsx │ ├── upgrade-to-v2 │ │ ├── index.tsx │ │ └── props.tsx │ └── upgrade │ │ └── index.tsx ├── styled-components.tsx ├── tsconfig.json ├── utils.ts └── webpack.config.ts ├── netlify.toml ├── package.json ├── packages └── react-select │ ├── CHANGELOG.md │ ├── LICENSE │ ├── README.md │ ├── animated │ └── package.json │ ├── async-creatable │ └── package.json │ ├── async │ └── package.json │ ├── base │ └── package.json │ ├── creatable │ └── package.json │ ├── package.json │ ├── src │ ├── Async.tsx │ ├── AsyncCreatable.tsx │ ├── Creatable.tsx │ ├── NonceProvider.tsx │ ├── Select.tsx │ ├── __tests__ │ │ ├── Async.test.tsx │ │ ├── AsyncCreatable.test.tsx │ │ ├── Creatable.test.tsx │ │ ├── Select.test.tsx │ │ ├── StateManaged.test.tsx │ │ ├── __snapshots__ │ │ │ ├── Async.test.tsx.snap │ │ │ ├── AsyncCreatable.test.tsx.snap │ │ │ ├── Creatable.test.tsx.snap │ │ │ ├── Select.test.tsx.snap │ │ │ └── StateManaged.test.tsx.snap │ │ ├── constants.ts │ │ └── tsconfig.json │ ├── accessibility │ │ ├── helpers.ts │ │ └── index.ts │ ├── animated │ │ ├── Input.tsx │ │ ├── MultiValue.tsx │ │ ├── Placeholder.tsx │ │ ├── SingleValue.tsx │ │ ├── ValueContainer.tsx │ │ ├── index.ts │ │ └── transitions.tsx │ ├── async-creatable │ │ └── index.ts │ ├── async │ │ └── index.ts │ ├── base │ │ └── index.ts │ ├── builtins.ts │ ├── components │ │ ├── Control.tsx │ │ ├── Group.tsx │ │ ├── Input.tsx │ │ ├── LiveRegion.tsx │ │ ├── Menu.tsx │ │ ├── MultiValue.tsx │ │ ├── Option.tsx │ │ ├── Placeholder.tsx │ │ ├── SingleValue.tsx │ │ ├── containers.tsx │ │ ├── index.ts │ │ └── indicators.tsx │ ├── creatable │ │ └── index.ts │ ├── diacritics.ts │ ├── filters.ts │ ├── index.ts │ ├── internal │ │ ├── A11yText.tsx │ │ ├── DummyInput.tsx │ │ ├── RequiredInput.tsx │ │ ├── ScrollManager.tsx │ │ ├── index.ts │ │ ├── useScrollCapture.ts │ │ └── useScrollLock.ts │ ├── stateManager.tsx │ ├── styles.ts │ ├── theme.ts │ ├── types.ts │ ├── useAsync.ts │ ├── useCreatable.ts │ ├── useStateManager.ts │ └── utils.ts │ └── tsconfig.json ├── storybook ├── .gitignore ├── .storybook │ ├── .babelrc │ ├── main.ts │ └── preview.tsx ├── components │ ├── field.tsx │ ├── index.ts │ ├── inline.tsx │ ├── stack.tsx │ └── svg.tsx ├── data.ts ├── package.json ├── postcss.config.js ├── stories │ ├── AccessingInternalsViaRef.stories.tsx │ ├── AnimatedMulti.stories.tsx │ ├── AsyncCallbacks.stories.tsx │ ├── AsyncCreatable.stories.tsx │ ├── AsyncMulti.stories.tsx │ ├── AsyncPromises.stories.tsx │ ├── AsyncSelectWithDefaultOptions.stories.tsx │ ├── BasicGrouped.stories.tsx │ ├── BasicMulti.stories.tsx │ ├── BasicSingle.stories.tsx │ ├── ClassNamesWithTailwind.stories.tsx │ ├── ControlledMenu.stories.tsx │ ├── Creatable.stories.tsx │ ├── CreatableAdvanced.stories.tsx │ ├── CreatableInputOnly.stories.tsx │ ├── CreateFilter.stories.tsx │ ├── CustomAriaLive.stories.tsx │ ├── CustomClearIndicator.stories.tsx │ ├── CustomControl.stories.tsx │ ├── CustomDropdownIndicator.stories.tsx │ ├── CustomFilterOptions.stories.tsx │ ├── CustomFormatOptionLabel.stories.tsx │ ├── CustomGetOptionLabel.stories.tsx │ ├── CustomGetOptionValue.stories.tsx │ ├── CustomGroup.stories.tsx │ ├── CustomGroupHeading.stories.tsx │ ├── CustomIndicatorSeparator.stories.tsx │ ├── CustomIndicatorsContainer.stories.tsx │ ├── CustomInput.stories.tsx │ ├── CustomIsOptionDisabled.stories.tsx │ ├── CustomLoadingIndicator.stories.tsx │ ├── CustomLoadingMessage.stories.tsx │ ├── CustomMenu.stories.tsx │ ├── CustomMenuList.stories.tsx │ ├── CustomMultiValueContainer.stories.tsx │ ├── CustomMultiValueLabel.stories.tsx │ ├── CustomMultiValueRemove.stories.tsx │ ├── CustomNoOptionsMessage.stories.tsx │ ├── CustomOption.stories.tsx │ ├── CustomPlaceholder.stories.tsx │ ├── CustomSelectContainer.stories.tsx │ ├── CustomSelectProps.stories.tsx │ ├── CustomSingleValue.stories.tsx │ ├── CustomValueContainer.stories.tsx │ ├── ExperimentalDatePicker.stories.tsx │ ├── FixedOptions.stories.tsx │ ├── Grouped.stories.tsx │ ├── MenuBuffer.stories.tsx │ ├── MenuPortal.stories.tsx │ ├── MultiSelectSort.stories.tsx │ ├── OnSelectKeepsInput.stories.tsx │ ├── Popout.stories.tsx │ ├── StyleCompositionExample.stories.tsx │ ├── StyledMulti.stories.tsx │ ├── StyledSingle.stories.tsx │ ├── Tailwind.stories.tsx │ ├── Theme.stories.tsx │ └── UnstyledWithTailwind.stories.tsx ├── styles │ └── tailwind.css └── tailwind.config.js ├── test-setup.js ├── tsconfig.json └── yarn.lock /.browserslistrc: -------------------------------------------------------------------------------- 1 | > 0.25% 2 | ie 11 3 | not op_mini all 4 | -------------------------------------------------------------------------------- /.changeset/README.md: -------------------------------------------------------------------------------- 1 | # Changesets 2 | 3 | Hello and welcome! This folder has been automatically generated by `@changesets/cli`, a build tool that works with `bolt` to help you release components from a mono-repository. You can find the full documentation for it [here](https://www.npmjs.com/package/@changesets/cli) 4 | 5 | To help you get started though, here are some things you should know about this folder: 6 | 7 | ## Changesets are automatically generated 8 | 9 | Changesets are generated by the `yarn changeset` or `npx changeset` command. As long as you are following a changeset release flow, you shouldn't have any problems. 10 | 11 | ## Each changeset is its own folder 12 | 13 | We use hashes by default for these folder names to avoid collisions when generating them, but there's no harm that will come from renaming them. 14 | 15 | ## Changesets are automatically removed 16 | 17 | When `changeset bump` or equivalent command is run, all the changeset folders are removed. This is so we only ever use a changeset once. This makes this a very bad place to store any other information. 18 | 19 | ## Changesets come in two parts 20 | 21 | You should treat these parts quite differently: 22 | 23 | - `changes.md` is a file you should feel free to edit as much as you want. It will be prepended to your changelog when you next run your version command. 24 | - `changes.json` is a file that includes information about releases, what should be versioned by the version command. We strongly recommend against editing this directly, as you may make a new changeset that puts your bolt repository into an invalid state. 25 | 26 | ## I want to edit the information in a `changes.json` - how do I do it safely? 27 | 28 | The best option is to make a new changeset using the changeset command, copy over the `changes.md`, then delete the old changeset. 29 | 30 | ## Can I rename the folder for my changeset? 31 | 32 | Absolutely! We need unique hashes to make changesets play nicely with git, but changing your folder from our hash to your own name isn't going to cause any problems. 33 | 34 | ## Can I manually delete changesets? 35 | 36 | You can, but you should be aware this will remove the intent to release communicated by the changeset, and should be done with caution. 37 | -------------------------------------------------------------------------------- /.changeset/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://unpkg.com/@changesets/config@0.2.1/schema.json", 3 | "changelog": "./getChangelogEntry", 4 | "commit": false, 5 | "linked": [], 6 | "access": "public" 7 | } 8 | -------------------------------------------------------------------------------- /.changeset/getChangelogEntry.js: -------------------------------------------------------------------------------- 1 | require('dotenv').config(); 2 | const { getInfo } = require('@changesets/get-github-info'); 3 | 4 | const getReleaseLine = async (changeset, type) => { 5 | const [firstLine, ...futureLines] = changeset.summary 6 | .split('\n') 7 | .map((l) => l.trimRight()); 8 | let { links } = await getInfo({ 9 | repo: 'JedWatson/react-select', 10 | commit: changeset.commit, 11 | }); 12 | return `- ${links.commit}${links.pull === null ? '' : ` ${links.pull}`}${ 13 | links.user === null ? '' : ` Thanks ${links.user}!` 14 | } - ${firstLine}\n${futureLines.map((l) => ` ${l}`).join('\n')}`; 15 | }; 16 | 17 | const getDependencyReleaseLine = async (changesets, dependenciesUpdated) => { 18 | if (dependenciesUpdated.length === 0) return ''; 19 | 20 | const changesetLinks = changesets.map( 21 | (changeset) => `- Updated dependencies [${changeset.commit}]:` 22 | ); 23 | 24 | const updatedDepenenciesList = dependenciesUpdated.map( 25 | (dependency) => ` - ${dependency.name}@${dependency.version}` 26 | ); 27 | 28 | return [...changesetLinks, ...updatedDepenenciesList].join('\n'); 29 | }; 30 | 31 | module.exports = { 32 | getReleaseLine, 33 | getDependencyReleaseLine, 34 | }; 35 | -------------------------------------------------------------------------------- /.codesandbox/ci.json: -------------------------------------------------------------------------------- 1 | { 2 | "buildCommand": "build", 3 | "packages": ["packages/*"], 4 | "sandboxes": ["nfmxw"], 5 | "node": "20" 6 | } 7 | -------------------------------------------------------------------------------- /.coveralls.yml: -------------------------------------------------------------------------------- 1 | service-name: travis-ci 2 | repo_token: itdMRdBNgDK8Gb5nIA63zVMEryaxTQxkR 3 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # This file is for unifying the coding style for different editors and IDEs 2 | # editorconfig.org 3 | root = true 4 | 5 | [*] 6 | end_of_line = lf 7 | charset = utf-8 8 | trim_trailing_whitespace = true 9 | insert_final_newline = true 10 | indent_style = space 11 | indent_size = 2 12 | 13 | [*.md] 14 | trim_trailing_whitespace = false 15 | 16 | [.circleci/config.yml] 17 | indent_size = 4 18 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | coverage/* 2 | cypress/plugins/* 3 | cypress/support/* 4 | **/dist/* 5 | lib/* 6 | node_modules/* 7 | **/node_modules/* 8 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | extends: ['plugin:react-hooks/recommended', 'plugin:@typescript-eslint/base'], 3 | parser: '@typescript-eslint/parser', 4 | env: { 5 | browser: true, 6 | es6: true, 7 | node: true, 8 | }, 9 | plugins: ['react', '@typescript-eslint'], 10 | rules: { 11 | '@typescript-eslint/no-unused-vars': [ 12 | 'error', 13 | { 14 | args: 'after-used', 15 | argsIgnorePattern: '^event$', 16 | ignoreRestSiblings: true, 17 | vars: 'all', 18 | varsIgnorePattern: 'jsx|emotionJSX', 19 | }, 20 | ], 21 | curly: [2, 'multi-line'], 22 | 'jsx-quotes': 1, 23 | 'no-shadow': 0, 24 | '@typescript-eslint/no-shadow': 2, 25 | 'no-trailing-spaces': 1, 26 | 'no-underscore-dangle': 1, 27 | '@typescript-eslint/no-unused-expressions': 1, 28 | 'object-curly-spacing': [1, 'always'], 29 | '@typescript-eslint/quotes': [2, 'single', 'avoid-escape'], 30 | 'react/jsx-boolean-value': 1, 31 | 'react/jsx-no-undef': 1, 32 | 'react/jsx-uses-react': 1, 33 | 'react/jsx-uses-vars': 1, 34 | 'react/jsx-wrap-multilines': 1, 35 | 'react/no-did-mount-set-state': 1, 36 | 'react/no-did-update-set-state': 1, 37 | 'react/no-unknown-property': 1, 38 | 'react/react-in-jsx-scope': 1, 39 | 'react/self-closing-comp': 1, 40 | 'react/sort-prop-types': 1, 41 | '@typescript-eslint/semi': 2, 42 | '@typescript-eslint/no-inferrable-types': 2, 43 | strict: 0, 44 | }, 45 | settings: { 46 | react: { 47 | version: 'detect', 48 | }, 49 | }, 50 | }; 51 | -------------------------------------------------------------------------------- /.github/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | Thanks for your interest in React-Select. All forms of contribution are 4 | welcome, from issue reports to PRs and documentation / write-ups. 5 | 6 | Before you open a PR: 7 | 8 | - In development, run `yarn start` to build (+watch) the project source, and run 9 | the [development server](http://localhost:8000). 10 | - Please ensure all the examples work correctly after your change. If you're 11 | adding a major new use-case, add a new example demonstrating its use. 12 | - Be careful to follow the code style of the project. Run `yarn lint` after 13 | your changes and ensure you do not introduce any new errors or warnings. 14 | - This repository uses TypeScript, please run `yarn type-check` after your changes to ensure 15 | that you do not introduce any new type errors. 16 | 17 | - Ensure that your effort is aligned with the project's roadmap by talking to 18 | the maintainers, especially if you are going to spend a lot of time on it. 19 | - Make sure there's an issue open for any work you take on and intend to submit 20 | as a pull request - it helps core members review your concept and direction 21 | early and is a good way to discuss what you're planning to do. 22 | - If you open an issue and are interested in working on a fix, please let us 23 | know. We'll help you get started, rather than adding it to the queue. 24 | - Make sure you do not add regressions by running `yarn test`. 25 | - Where possible, include tests with your changes, either that demonstrates the 26 | bug, or tests the new functionality. If you're not sure how to test your 27 | changes, feel free to ping @gwyneplaine or @JedWatson 28 | - Run `yarn coveralls` to check that the coverage hasn't dropped, and look at the 29 | report (under the generated `coverage` directory) to check that your changes are 30 | covered 31 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: File a bug report 4 | title: '' 5 | labels: [issue/bug-unconfirmed] 6 | assignees: '' 7 | --- 8 | 9 | **Thanks for using react-select!** 10 | 11 | If you are going to ask a question or want to propose a change or a new feature, then please don't file an issue for this. 12 | Questions and feature requests have their own place in our discussions section. 13 | 14 | ## Are you reporting a bug or runtime error? 15 | 16 | Please include a test case that demonstrates the issue you're reporting! 17 | 18 | This is very helpful to maintainers in order to help us see the issue you're seeing. 19 | 20 | Please note we are currently only directing our efforts towards the current major (v5) version and beyond. 21 | 22 | We understand this might be inconvenient but it is in the best interest of supporting the broader community and to sustain the `react-select` project going forward. 23 | 24 | To report bugs against react-select v5 please fork the following code-sandbox: 25 | https://codesandbox.io/s/react-select-v5-sandbox-y5jtm 26 | 27 | You may also find the [online Babel tool](https://babeljs.io/repl/) quite helpful if you wish to use ES6/ES7 syntax not yet supported by the browser you are using. 28 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: false 2 | contact_links: 3 | - name: Feature request 4 | url: https://github.com/JedWatson/react-select/discussions/categories/ideas 5 | about: Got an idea for a feature or want to propose a change? Then this is the place for you. 6 | - name: Question on usage 7 | url: https://github.com/JedWatson/react-select/discussions/categories/q-a 8 | about: If you have a question regarding the usage of the library. 9 | - name: StackOverflow 10 | url: https://stackoverflow.com/questions/tagged/react-select 11 | about: Alternatively you can visit StackOverflow with the `[react-select]` tag 12 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: 'npm' 4 | directory: '/' 5 | schedule: 6 | interval: 'weekly' 7 | ignore: 8 | - dependency-name: '*' 9 | update-types: 10 | ['version-update:semver-minor', 'version-update:semver-patch'] 11 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: Release 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | 8 | permissions: 9 | contents: read 10 | 11 | jobs: 12 | release: 13 | permissions: 14 | # for changesets/action 15 | contents: write 16 | pull-requests: write 17 | name: Release 18 | runs-on: ubuntu-latest 19 | steps: 20 | - name: Checkout Repo 21 | uses: actions/checkout@v3 22 | with: 23 | # This makes Actions fetch all Git history so that Changesets can generate changelogs with the correct commits 24 | fetch-depth: 0 25 | 26 | - name: Setup Node.js 22.x 27 | uses: actions/setup-node@v4 28 | with: 29 | node-version: 22.x 30 | 31 | - name: Install Dependencies 32 | run: yarn 33 | 34 | - name: Create Release Pull Request or Publish to npm 35 | uses: changesets/action@v1 36 | with: 37 | publish: yarn release 38 | env: 39 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 40 | NPM_TOKEN: ${{ secrets.NPM_TOKEN }} 41 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Build 2 | lib 3 | dist 4 | docs/dist 5 | .env 6 | 7 | # Logs 8 | logs 9 | *.log 10 | 11 | # Runtime data 12 | pids 13 | *.pid 14 | *.seed 15 | 16 | # Coverage tools 17 | lib-cov 18 | coverage 19 | .nyc_output 20 | 21 | # Cypress 22 | cypress/videos 23 | cypress/screenshots 24 | cypress/support 25 | cypress/plugins 26 | 27 | # Dependency directory 28 | node_modules 29 | bower_components 30 | 31 | # Publish directory 32 | .publish 33 | 34 | # Editor artefacts 35 | .idea 36 | 37 | # Other 38 | .DS_Store 39 | .env 40 | package-lock.json 41 | 42 | # Notes 43 | .NOTES.md 44 | 45 | magical-types 46 | -------------------------------------------------------------------------------- /.nvmrc: -------------------------------------------------------------------------------- 1 | 22 2 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | coverage/* 2 | cypress/plugins/* 3 | cypress/support/* 4 | **/dist/* 5 | lib/* 6 | node_modules/* 7 | **/node_modules/* 8 | **/magical-types/* 9 | -------------------------------------------------------------------------------- /.prettierrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | singleQuote: true, 3 | trailingComma: 'es5', 4 | overrides: [ 5 | { 6 | files: '.changeset/pre.json', 7 | options: { parser: 'json-stringify' }, 8 | }, 9 | ], 10 | }; 11 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | Thanks for your interest in React-Select. All forms of contribution are 4 | welcome, from issue reports to PRs and documentation / write-ups. 5 | 6 | Before you open a PR: 7 | 8 | - In development, run `yarn start` to build (and watch) the project source, and run 9 | the [development server](http://localhost:8000). 10 | - Please ensure all the examples work correctly after your change. If you're 11 | adding a major new use-case, add a new example `/docs/examples` and subsequent documentation demonstrating its use `/docs/pages`. 12 | - Ensure that your effort is aligned with the project's roadmap by talking to 13 | the maintainers, especially if you are going to spend a lot of time on it. 14 | - Make sure there's an issue open for any work you take on and intend to submit 15 | as a pull request - it helps core members review your concept and direction 16 | early and is a good way to discuss what you're planning to do. 17 | - If you open an issue and are interested in working on a fix, please let us 18 | know. We'll help you get started, rather than inadvertently doubling up on your hard work. 19 | - Make sure you do not add regressions by running `yarn test`. 20 | - Where possible, include tests with your changes, either that demonstrates the 21 | bug, or tests the new functionality. 22 | - All new features and changes need documentation. 23 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2022 Jed Watson 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: [ 3 | '@emotion/babel-plugin', 4 | ['@babel/plugin-proposal-class-properties', { loose: true }], 5 | ['@babel/plugin-proposal-private-methods', { loose: true }], 6 | '@babel/plugin-transform-runtime', 7 | ], 8 | presets: [ 9 | '@babel/preset-env', 10 | '@babel/preset-react', 11 | '@babel/preset-typescript', 12 | ], 13 | }; 14 | -------------------------------------------------------------------------------- /cypress.json: -------------------------------------------------------------------------------- 1 | { 2 | "baseUrl": "http://localhost:8000/cypress-tests", 3 | "video": false 4 | } 5 | -------------------------------------------------------------------------------- /cypress/fixtures/selectors.json: -------------------------------------------------------------------------------- 1 | { 2 | "singleBasic": "#cypress-single", 3 | "singleBasicSelect": "#basic-select-single", 4 | "singleClearable": "#cypress-single-clearable", 5 | "singleClearableSelect": "#clearable-select-single", 6 | "singleGroupedSelect": "#grouped-options-single", 7 | "checkboxDisable": ".disable-checkbox", 8 | "checkboxEscapeClearsValue": ".escape-clears-value-checkbox", 9 | "groupHeading": ".react-select__group-heading", 10 | "indicatorClear": ".react-select__clear-indicator", 11 | "indicatorDropdown": ".react-select__dropdown-indicator", 12 | "menu": ".react-select__menu", 13 | "control": ".react-select__control", 14 | "menuOption": ".react-select__option", 15 | "noOptionsValue": ".react-select__menu-notice--no-options", 16 | "placeholder": ".react-select__placeholder", 17 | "singleValue": ".react-select__single-value", 18 | "menuSingle": "#basic-select-single .react-select__menu", 19 | "singleSelectSingleInput": "#react-select-basic-select-single-input", 20 | "toggleMenuSingle": "#basic-select-single .react-select__dropdown-indicator", 21 | "firstMultiValueRemove": "#multi-select .react-select__multi-value__remove:first", 22 | "menuMulti": "#multi-select .react-select__menu", 23 | "multiSelectDefaultValues": "#multi-select .react-select__multi-value", 24 | "multiSelectInput": "#react-select-multi-select-input", 25 | "placeHolderMulti": "#multi-select .react-select__placeholder", 26 | "toggleMenuMulti": "#multi-select .react-select__dropdown-indicator", 27 | "focusedOption": ".react-select__option--is-focused" 28 | } 29 | -------------------------------------------------------------------------------- /cypress/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es6", 4 | "module": "commonjs", 5 | "noEmit": true, 6 | "strict": true, 7 | "types": ["cypress"], 8 | "esModuleInterop": true, 9 | "resolveJsonModule": true 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /docs/App/Footer.tsx: -------------------------------------------------------------------------------- 1 | /** @jsx jsx */ 2 | import { jsx } from '@emotion/react'; 3 | 4 | // const smallDevice = '@media (max-width: 769px)'; 5 | const largeDevice = '@media (min-width: 770px)'; 6 | 7 | const Wrapper = (props: JSX.IntrinsicElements['div']) => ( 8 | <div 9 | css={{ 10 | backgroundColor: '#FAFBFC', 11 | borderTop: '1px solid #EBECF0', 12 | color: '#7A869A', 13 | fontSize: '0.85em', 14 | zIndex: 1, 15 | }} 16 | {...props} 17 | /> 18 | ); 19 | const Container = (props: JSX.IntrinsicElements['div']) => ( 20 | <div 21 | css={{ 22 | boxSizing: 'border-box', 23 | maxWidth: 800, 24 | marginLeft: 'auto', 25 | marginRight: 'auto', 26 | paddingLeft: 20, 27 | paddingRight: 20, 28 | 29 | [largeDevice]: { 30 | alignItems: 'center', 31 | display: 'flex', 32 | justifyContent: 'space-between', 33 | paddingBottom: 20, 34 | paddingTop: 20, 35 | }, 36 | }} 37 | {...props} 38 | /> 39 | ); 40 | const A = (props: JSX.IntrinsicElements['a']) => ( 41 | <a 42 | {...props} 43 | css={{ 44 | color: '#505F79', 45 | textDecoration: 'none', 46 | 47 | ':visited': { 48 | color: '#505F79', 49 | }, 50 | ':hover': { 51 | textDecoration: 'underline', 52 | }, 53 | }} 54 | target="_blank" 55 | /> 56 | ); 57 | 58 | export default function Footer() { 59 | return ( 60 | <Wrapper> 61 | <Container> 62 | <p> 63 | Copyright © <A href="https://twitter.com/JedWatson">Jed Watson</A>, 64 | 2022. MIT Licensed. 65 | </p> 66 | <p> 67 | Thanks to <A href="https://www.thinkmill.com.au">Thinkmill</A> and{' '} 68 | <A href="https://www.atlassian.com">Atlassian</A> for supporting this 69 | project. 70 | </p> 71 | </Container> 72 | </Wrapper> 73 | ); 74 | } 75 | -------------------------------------------------------------------------------- /docs/App/Section.tsx: -------------------------------------------------------------------------------- 1 | import React, { FunctionComponent } from 'react'; 2 | import { Redirect, Route, RouteComponentProps, Switch } from 'react-router-dom'; 3 | 4 | import routes from './routes'; 5 | 6 | const Section: FunctionComponent<RouteComponentProps> = () => { 7 | const routeKeys = Object.keys(routes); 8 | return ( 9 | <Switch> 10 | {routeKeys.map((r) => ( 11 | <Route key={r} path={r} render={(p) => <Content {...p} />} /> 12 | ))} 13 | <Redirect from="/" to="/home" /> 14 | </Switch> 15 | ); 16 | }; 17 | 18 | const Content = ({ location, match }: RouteComponentProps) => { 19 | const page = routes[match.path]; 20 | 21 | return ( 22 | <Route 23 | path={match.path} 24 | render={() => ( 25 | <Switch> 26 | <Route exact key={location.key} path={match.path} component={page} /> 27 | </Switch> 28 | )} 29 | /> 30 | ); 31 | }; 32 | 33 | export default Section; 34 | -------------------------------------------------------------------------------- /docs/App/TwitterButton.tsx: -------------------------------------------------------------------------------- 1 | /** @jsx jsx */ 2 | import { jsx } from '@emotion/react'; 3 | 4 | const TwitterButton = () => ( 5 | <div css={{ alignItems: 'center', display: 'inline-flex' }}> 6 | <a 7 | aria-label="Follow @JedWatson on Twitter" 8 | css={{ 9 | alignItems: 'center', 10 | display: 'flex', 11 | borderRadius: 2, 12 | color: 'white', 13 | border: '1px solid rgba(255, 255, 255, 0.3)', 14 | background: 'rgba(255, 255, 255, 0.1)', 15 | cursor: 'pointer', 16 | fontSize: 13, 17 | fontWeight: 'bold', 18 | padding: '5px 12px 5px 8px', 19 | marginLeft: '16px', 20 | position: 'relative', 21 | textDecoration: 'none', 22 | 23 | ':hover': { 24 | border: '1px solid rgba(255, 255, 255, 0.4)', 25 | background: 'rgba(255, 255, 255, 0.15)', 26 | }, 27 | }} 28 | href="https://twitter.com/JedWatson" 29 | target="_blank" 30 | > 31 | <svg 32 | version="1.1" 33 | width="16" 34 | height="16" 35 | viewBox="0 0 2000 1625.36" 36 | fill="currentColor" 37 | aria-hidden="true" 38 | > 39 | <path d="m 1999.9999,192.4 c -73.58,32.64 -152.67,54.69 -235.66,64.61 84.7,-50.78 149.77,-131.19 180.41,-227.01 -79.29,47.03 -167.1,81.17 -260.57,99.57 C 1609.3399,49.82 1502.6999,0 1384.6799,0 c -226.6,0 -410.328,183.71 -410.328,410.31 0,32.16 3.628,63.48 10.625,93.51 -341.016,-17.11 -643.368,-180.47 -845.739,-428.72 -35.324,60.6 -55.5583,131.09 -55.5583,206.29 0,142.36 72.4373,267.95 182.5433,341.53 -67.262,-2.13 -130.535,-20.59 -185.8519,-51.32 -0.039,1.71 -0.039,3.42 -0.039,5.16 0,198.803 141.441,364.635 329.145,402.342 -34.426,9.375 -70.676,14.395 -108.098,14.395 -26.441,0 -52.145,-2.578 -77.203,-7.364 52.215,163.008 203.75,281.649 383.304,284.946 -140.429,110.062 -317.351,175.66 -509.5972,175.66 -33.1211,0 -65.7851,-1.949 -97.8828,-5.738 181.586,116.4176 397.27,184.359 628.988,184.359 754.732,0 1167.462,-625.238 1167.462,-1167.47 0,-17.79 -0.41,-35.48 -1.2,-53.08 80.1799,-57.86 149.7399,-130.12 204.7499,-212.41" /> 40 | </svg> 41 | <span css={{ paddingLeft: 8 }}>Follow</span> 42 | </a> 43 | </div> 44 | ); 45 | 46 | export default TwitterButton; 47 | -------------------------------------------------------------------------------- /docs/App/routes.ts: -------------------------------------------------------------------------------- 1 | import { ComponentType } from 'react'; 2 | import Home from '../pages/home'; 3 | import Props from '../pages/props'; 4 | import Styles from '../pages/styles'; 5 | import Components from '../pages/components'; 6 | import Async from '../pages/async'; 7 | import Creatable from '../pages/creatable'; 8 | import Advanced from '../pages/advanced'; 9 | import TypeScript from '../pages/typescript'; 10 | import Upgrade from '../pages/upgrade'; 11 | import UpgradeToV2 from '../pages/upgrade-to-v2'; 12 | 13 | const routes: { readonly [key: string]: ComponentType } = { 14 | '/home': Home, 15 | '/props': Props, 16 | '/styles': Styles, 17 | '/components': Components, 18 | '/async': Async, 19 | '/creatable': Creatable, 20 | '/advanced': Advanced, 21 | '/typescript': TypeScript, 22 | '/upgrade': Upgrade, 23 | '/upgrade-to-v2': UpgradeToV2, 24 | }; 25 | 26 | export default routes; 27 | -------------------------------------------------------------------------------- /docs/NoMatch.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Link } from 'react-router-dom'; 3 | import { H1 } from './styled-components'; 4 | 5 | export default function NoMatch() { 6 | return ( 7 | <div> 8 | <H1>Oops!</H1> 9 | <p>Couldn't find this page.</p> 10 | <Link to="/">Back home</Link> 11 | </div> 12 | ); 13 | } 14 | -------------------------------------------------------------------------------- /docs/PropTypes/Async.ts: -------------------------------------------------------------------------------- 1 | export { AsyncAdditionalProps } from 'react-select/src/useAsync'; 2 | -------------------------------------------------------------------------------- /docs/PropTypes/Creatable.ts: -------------------------------------------------------------------------------- 1 | export { CreatableAdditionalProps } from 'react-select/src/useCreatable'; 2 | -------------------------------------------------------------------------------- /docs/PropTypes/Select.ts: -------------------------------------------------------------------------------- 1 | import { Component } from 'react'; 2 | 3 | import { Props, defaultProps } from 'react-select/src/Select'; 4 | import { GroupBase } from 'react-select'; 5 | 6 | export default class Select extends Component< 7 | Props<unknown, boolean, GroupBase<unknown>> 8 | > { 9 | defaultProps = defaultProps; 10 | } 11 | -------------------------------------------------------------------------------- /docs/PropTypes/components/ClearIndicator.ts: -------------------------------------------------------------------------------- 1 | import { Component } from 'react'; 2 | import { GroupBase, ClearIndicatorProps } from 'react-select'; 3 | 4 | export default class ClearIndicator< 5 | Option, 6 | IsMulti extends boolean, 7 | Group extends GroupBase<Option> 8 | > extends Component<ClearIndicatorProps<Option, IsMulti, Group>> {} 9 | -------------------------------------------------------------------------------- /docs/PropTypes/components/Control.ts: -------------------------------------------------------------------------------- 1 | import { Component } from 'react'; 2 | import { ControlProps, GroupBase } from 'react-select'; 3 | 4 | export default class Control< 5 | Option, 6 | IsMulti extends boolean, 7 | Group extends GroupBase<Option> 8 | > extends Component<ControlProps<Option, IsMulti, Group>> {} 9 | -------------------------------------------------------------------------------- /docs/PropTypes/components/DropdownIndicator.ts: -------------------------------------------------------------------------------- 1 | import { Component } from 'react'; 2 | import { GroupBase, DropdownIndicatorProps } from 'react-select'; 3 | 4 | export default class DropdownIndicator< 5 | Option, 6 | IsMulti extends boolean, 7 | Group extends GroupBase<Option> 8 | > extends Component<DropdownIndicatorProps<Option, IsMulti, Group>> {} 9 | -------------------------------------------------------------------------------- /docs/PropTypes/components/Group.ts: -------------------------------------------------------------------------------- 1 | import { Component } from 'react'; 2 | import { GroupBase, GroupProps } from 'react-select'; 3 | 4 | export default class Group< 5 | Option, 6 | IsMulti extends boolean, 7 | Group extends GroupBase<Option> 8 | > extends Component<GroupProps<Option, IsMulti, Group>> {} 9 | -------------------------------------------------------------------------------- /docs/PropTypes/components/IndicatorsContainer.ts: -------------------------------------------------------------------------------- 1 | import { Component } from 'react'; 2 | import { GroupBase, IndicatorsContainerProps } from 'react-select'; 3 | 4 | export default class IndicatorsContainer< 5 | Option, 6 | IsMulti extends boolean, 7 | Group extends GroupBase<Option> 8 | > extends Component<IndicatorsContainerProps<Option, IsMulti, Group>> {} 9 | -------------------------------------------------------------------------------- /docs/PropTypes/components/IndicatorsSeparator.ts: -------------------------------------------------------------------------------- 1 | import { Component } from 'react'; 2 | import { DropdownIndicatorProps, GroupBase } from 'react-select'; 3 | 4 | export default class DropdownIndicator< 5 | Option, 6 | IsMulti extends boolean, 7 | Group extends GroupBase<Option> 8 | > extends Component<DropdownIndicatorProps<Option, IsMulti, Group>> {} 9 | -------------------------------------------------------------------------------- /docs/PropTypes/components/Input.ts: -------------------------------------------------------------------------------- 1 | import { Component } from 'react'; 2 | import { GroupBase, InputProps } from 'react-select'; 3 | 4 | export default class Input< 5 | Option, 6 | IsMulti extends boolean, 7 | Group extends GroupBase<Option> 8 | > extends Component<InputProps<Option, IsMulti, Group>> {} 9 | -------------------------------------------------------------------------------- /docs/PropTypes/components/LoadingIndicator.ts: -------------------------------------------------------------------------------- 1 | import { Component } from 'react'; 2 | import { GroupBase, LoadingIndicatorProps } from 'react-select'; 3 | 4 | export default class LoadingIndicator< 5 | Option, 6 | IsMulti extends boolean, 7 | Group extends GroupBase<Option> 8 | > extends Component<LoadingIndicatorProps<Option, IsMulti, Group>> {} 9 | -------------------------------------------------------------------------------- /docs/PropTypes/components/LoadingMessage.ts: -------------------------------------------------------------------------------- 1 | import { Component } from 'react'; 2 | import { GroupBase, NoticeProps } from 'react-select'; 3 | 4 | export default class LoadingMessage< 5 | Option, 6 | IsMulti extends boolean, 7 | Group extends GroupBase<Option> 8 | > extends Component<NoticeProps<Option, IsMulti, Group>> {} 9 | -------------------------------------------------------------------------------- /docs/PropTypes/components/Menu.ts: -------------------------------------------------------------------------------- 1 | import { Component } from 'react'; 2 | import { GroupBase, MenuProps } from 'react-select'; 3 | 4 | export default class Menu< 5 | Option, 6 | IsMulti extends boolean, 7 | Group extends GroupBase<Option> 8 | > extends Component<MenuProps<Option, IsMulti, Group>> {} 9 | -------------------------------------------------------------------------------- /docs/PropTypes/components/MenuList.ts: -------------------------------------------------------------------------------- 1 | import { Component } from 'react'; 2 | import { GroupBase, MenuListProps } from 'react-select'; 3 | 4 | export default class MenuList< 5 | Option, 6 | IsMulti extends boolean, 7 | Group extends GroupBase<Option> 8 | > extends Component<MenuListProps<Option, IsMulti, Group>> {} 9 | -------------------------------------------------------------------------------- /docs/PropTypes/components/MultiValue.ts: -------------------------------------------------------------------------------- 1 | import { Component } from 'react'; 2 | import { GroupBase, MultiValueProps } from 'react-select'; 3 | 4 | export default class MultiValue< 5 | Option, 6 | IsMulti extends boolean, 7 | Group extends GroupBase<Option> 8 | > extends Component<MultiValueProps<Option, IsMulti, Group>> {} 9 | -------------------------------------------------------------------------------- /docs/PropTypes/components/MultiValueContainer.ts: -------------------------------------------------------------------------------- 1 | import { Component } from 'react'; 2 | import { GroupBase, MultiValueGenericProps } from 'react-select'; 3 | 4 | export default class MultiValueContainer< 5 | Option, 6 | IsMulti extends boolean, 7 | Group extends GroupBase<Option> 8 | > extends Component<MultiValueGenericProps<Option, IsMulti, Group>> {} 9 | -------------------------------------------------------------------------------- /docs/PropTypes/components/MultiValueLabel.ts: -------------------------------------------------------------------------------- 1 | import { Component } from 'react'; 2 | import { GroupBase, MultiValueGenericProps } from 'react-select'; 3 | 4 | export default class MultiValueLabel< 5 | Option, 6 | IsMulti extends boolean, 7 | Group extends GroupBase<Option> 8 | > extends Component<MultiValueGenericProps<Option, IsMulti, Group>> {} 9 | -------------------------------------------------------------------------------- /docs/PropTypes/components/MultiValueRemove.ts: -------------------------------------------------------------------------------- 1 | import { Component } from 'react'; 2 | import { GroupBase, MultiValueGenericProps } from 'react-select'; 3 | 4 | export default class MultiValueRemove< 5 | Option, 6 | IsMulti extends boolean, 7 | Group extends GroupBase<Option> 8 | > extends Component<MultiValueGenericProps<Option, IsMulti, Group>> {} 9 | -------------------------------------------------------------------------------- /docs/PropTypes/components/NoOptionsMessage.ts: -------------------------------------------------------------------------------- 1 | import { Component } from 'react'; 2 | import { GroupBase, NoticeProps } from 'react-select'; 3 | 4 | export default class NoOptionsMessage< 5 | Option, 6 | IsMulti extends boolean, 7 | Group extends GroupBase<Option> 8 | > extends Component<NoticeProps<Option, IsMulti, Group>> {} 9 | -------------------------------------------------------------------------------- /docs/PropTypes/components/Option.ts: -------------------------------------------------------------------------------- 1 | import { Component } from 'react'; 2 | import { GroupBase, OptionProps } from 'react-select'; 3 | 4 | export default class Option< 5 | Option, 6 | IsMulti extends boolean, 7 | Group extends GroupBase<Option> 8 | > extends Component<OptionProps<Option, IsMulti, Group>> {} 9 | -------------------------------------------------------------------------------- /docs/PropTypes/components/Placeholder.ts: -------------------------------------------------------------------------------- 1 | import { Component } from 'react'; 2 | import { GroupBase, PlaceholderProps } from 'react-select'; 3 | 4 | export default class Placeholder< 5 | Option, 6 | IsMulti extends boolean, 7 | Group extends GroupBase<Option> 8 | > extends Component<PlaceholderProps<Option, IsMulti, Group>> {} 9 | -------------------------------------------------------------------------------- /docs/PropTypes/components/SelectContainer.ts: -------------------------------------------------------------------------------- 1 | import { Component } from 'react'; 2 | import { ContainerProps, GroupBase } from 'react-select'; 3 | 4 | export default class SelectContainer< 5 | Option, 6 | IsMulti extends boolean, 7 | Group extends GroupBase<Option> 8 | > extends Component<ContainerProps<Option, IsMulti, Group>> {} 9 | -------------------------------------------------------------------------------- /docs/PropTypes/components/SingleValue.ts: -------------------------------------------------------------------------------- 1 | import { Component } from 'react'; 2 | import { GroupBase, SingleValueProps } from 'react-select'; 3 | 4 | export default class SingleValue< 5 | Option, 6 | IsMulti extends boolean, 7 | Group extends GroupBase<Option> 8 | > extends Component<SingleValueProps<Option, IsMulti, Group>> {} 9 | -------------------------------------------------------------------------------- /docs/PropTypes/components/ValueContainer.ts: -------------------------------------------------------------------------------- 1 | import { Component } from 'react'; 2 | import { GroupBase, ValueContainerProps } from 'react-select'; 3 | 4 | export default class ValueContainer< 5 | Option, 6 | IsMulti extends boolean, 7 | Group extends GroupBase<Option> 8 | > extends Component<ValueContainerProps<Option, IsMulti, Group>> {} 9 | -------------------------------------------------------------------------------- /docs/PropTypes/stateManager.ts: -------------------------------------------------------------------------------- 1 | export { StateManagerAdditionalProps } from 'react-select/src/useStateManager'; 2 | -------------------------------------------------------------------------------- /docs/Svg.tsx: -------------------------------------------------------------------------------- 1 | /** @jsx jsx */ 2 | import { jsx } from '@emotion/react'; 3 | 4 | export type SvgProps = { readonly size: number } & JSX.IntrinsicElements['svg']; 5 | 6 | const Svg = ({ size, ...props }: SvgProps) => ( 7 | <svg 8 | focusable="false" 9 | height={size} 10 | role="image" 11 | viewBox="0 0 20 20" 12 | width={size} 13 | css={{ 14 | display: 'inline-block', 15 | fill: 'currentColor', 16 | flexShrink: 0, 17 | lineHeight: 1, 18 | stroke: 'currentColor', 19 | strokeWidth: 0, 20 | }} 21 | {...props} 22 | /> 23 | ); 24 | 25 | export default Svg; 26 | -------------------------------------------------------------------------------- /docs/Table.tsx: -------------------------------------------------------------------------------- 1 | /** @jsx jsx */ 2 | import { FunctionComponent } from 'react'; 3 | import { jsx } from '@emotion/react'; 4 | 5 | export const Table: FunctionComponent = ({ children }) => ( 6 | <table 7 | css={{ 8 | width: '100%', 9 | marginTop: '30px', 10 | borderCollapse: 'collapse', 11 | }} 12 | > 13 | {children} 14 | </table> 15 | ); 16 | 17 | export const Header: FunctionComponent = ({ children }) => ( 18 | <td 19 | css={{ 20 | fontWeight: 'bold', 21 | padding: '4px 8px 4px 0', 22 | borderBottom: '3px solid #eee', 23 | }} 24 | > 25 | {children} 26 | </td> 27 | ); 28 | 29 | export const Cell: FunctionComponent = ({ children }) => ( 30 | <td 31 | css={{ 32 | fontSize: '90%', 33 | padding: '4px 8px 4px 0', 34 | borderBottom: '1px solid #eee', 35 | verticalAlign: 'top', 36 | }} 37 | > 38 | {children} 39 | </td> 40 | ); 41 | -------------------------------------------------------------------------------- /docs/_redirects: -------------------------------------------------------------------------------- 1 | /* /index.html 200 2 | -------------------------------------------------------------------------------- /docs/examples/AnimatedMulti.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | import Select from 'react-select'; 4 | import makeAnimated from 'react-select/animated'; 5 | import { colourOptions } from '../data'; 6 | 7 | const animatedComponents = makeAnimated(); 8 | 9 | export default function AnimatedMulti() { 10 | return ( 11 | <Select 12 | closeMenuOnSelect={false} 13 | components={animatedComponents} 14 | defaultValue={[colourOptions[4], colourOptions[5]]} 15 | isMulti 16 | options={colourOptions} 17 | /> 18 | ); 19 | } 20 | -------------------------------------------------------------------------------- /docs/examples/AsyncCallbacks.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | import AsyncSelect from 'react-select/async'; 4 | import { ColourOption, colourOptions } from '../data'; 5 | 6 | const filterColors = (inputValue: string) => { 7 | return colourOptions.filter((i) => 8 | i.label.toLowerCase().includes(inputValue.toLowerCase()) 9 | ); 10 | }; 11 | 12 | const loadOptions = ( 13 | inputValue: string, 14 | callback: (options: ColourOption[]) => void 15 | ) => { 16 | setTimeout(() => { 17 | callback(filterColors(inputValue)); 18 | }, 1000); 19 | }; 20 | 21 | export default () => ( 22 | <AsyncSelect cacheOptions loadOptions={loadOptions} defaultOptions /> 23 | ); 24 | -------------------------------------------------------------------------------- /docs/examples/AsyncCreatable.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | import AsyncCreatableSelect from 'react-select/async-creatable'; 4 | import { ColourOption, colourOptions } from '../data'; 5 | 6 | const filterColors = (inputValue: string) => { 7 | return colourOptions.filter((i) => 8 | i.label.toLowerCase().includes(inputValue.toLowerCase()) 9 | ); 10 | }; 11 | 12 | const promiseOptions = (inputValue: string) => 13 | new Promise<ColourOption[]>((resolve) => { 14 | setTimeout(() => { 15 | resolve(filterColors(inputValue)); 16 | }, 1000); 17 | }); 18 | 19 | export default () => ( 20 | <AsyncCreatableSelect 21 | cacheOptions 22 | defaultOptions 23 | loadOptions={promiseOptions} 24 | /> 25 | ); 26 | -------------------------------------------------------------------------------- /docs/examples/AsyncMulti.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | import AsyncSelect from 'react-select/async'; 4 | import { ColourOption, colourOptions } from '../data'; 5 | 6 | const filterColors = (inputValue: string) => { 7 | return colourOptions.filter((i) => 8 | i.label.toLowerCase().includes(inputValue.toLowerCase()) 9 | ); 10 | }; 11 | 12 | const promiseOptions = (inputValue: string) => 13 | new Promise<ColourOption[]>((resolve) => { 14 | setTimeout(() => { 15 | resolve(filterColors(inputValue)); 16 | }, 1000); 17 | }); 18 | 19 | export default () => ( 20 | <AsyncSelect 21 | isMulti 22 | cacheOptions 23 | defaultOptions 24 | loadOptions={promiseOptions} 25 | /> 26 | ); 27 | -------------------------------------------------------------------------------- /docs/examples/AsyncPromises.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | import AsyncSelect from 'react-select/async'; 4 | import { ColourOption, colourOptions } from '../data'; 5 | 6 | const filterColors = (inputValue: string) => { 7 | return colourOptions.filter((i) => 8 | i.label.toLowerCase().includes(inputValue.toLowerCase()) 9 | ); 10 | }; 11 | 12 | const promiseOptions = (inputValue: string) => 13 | new Promise<ColourOption[]>((resolve) => { 14 | setTimeout(() => { 15 | resolve(filterColors(inputValue)); 16 | }, 1000); 17 | }); 18 | 19 | export default () => ( 20 | <AsyncSelect cacheOptions defaultOptions loadOptions={promiseOptions} /> 21 | ); 22 | -------------------------------------------------------------------------------- /docs/examples/BasicGrouped.tsx: -------------------------------------------------------------------------------- 1 | import React, { CSSProperties } from 'react'; 2 | 3 | import Select from 'react-select'; 4 | import { 5 | ColourOption, 6 | colourOptions, 7 | FlavourOption, 8 | GroupedOption, 9 | groupedOptions, 10 | } from '../data'; 11 | 12 | const groupStyles = { 13 | display: 'flex', 14 | alignItems: 'center', 15 | justifyContent: 'space-between', 16 | }; 17 | const groupBadgeStyles: CSSProperties = { 18 | backgroundColor: '#EBECF0', 19 | borderRadius: '2em', 20 | color: '#172B4D', 21 | display: 'inline-block', 22 | fontSize: 12, 23 | fontWeight: 'normal', 24 | lineHeight: '1', 25 | minWidth: 1, 26 | padding: '0.16666666666667em 0.5em', 27 | textAlign: 'center', 28 | }; 29 | 30 | const formatGroupLabel = (data: GroupedOption) => ( 31 | <div style={groupStyles}> 32 | <span>{data.label}</span> 33 | <span style={groupBadgeStyles}>{data.options.length}</span> 34 | </div> 35 | ); 36 | 37 | export default () => ( 38 | <Select<ColourOption | FlavourOption, false, GroupedOption> 39 | defaultValue={colourOptions[1]} 40 | options={groupedOptions} 41 | formatGroupLabel={formatGroupLabel} 42 | /> 43 | ); 44 | -------------------------------------------------------------------------------- /docs/examples/BasicMulti.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | import Select from 'react-select'; 4 | import { colourOptions } from '../data'; 5 | 6 | export default () => ( 7 | <Select 8 | defaultValue={[colourOptions[2], colourOptions[3]]} 9 | isMulti 10 | name="colors" 11 | options={colourOptions} 12 | className="basic-multi-select" 13 | classNamePrefix="select" 14 | /> 15 | ); 16 | -------------------------------------------------------------------------------- /docs/examples/BasicSingle.tsx: -------------------------------------------------------------------------------- 1 | import React, { useState } from 'react'; 2 | 3 | import Select from 'react-select'; 4 | import { colourOptions } from '../data'; 5 | 6 | const Checkbox = ({ children, ...props }: JSX.IntrinsicElements['input']) => ( 7 | <label style={{ marginRight: '1em' }}> 8 | <input type="checkbox" {...props} /> 9 | {children} 10 | </label> 11 | ); 12 | 13 | export default () => { 14 | const [isClearable, setIsClearable] = useState(true); 15 | const [isSearchable, setIsSearchable] = useState(true); 16 | const [isDisabled, setIsDisabled] = useState(false); 17 | const [isLoading, setIsLoading] = useState(false); 18 | const [isRtl, setIsRtl] = useState(false); 19 | 20 | return ( 21 | <> 22 | <Select 23 | className="basic-single" 24 | classNamePrefix="select" 25 | defaultValue={colourOptions[0]} 26 | isDisabled={isDisabled} 27 | isLoading={isLoading} 28 | isClearable={isClearable} 29 | isRtl={isRtl} 30 | isSearchable={isSearchable} 31 | name="color" 32 | options={colourOptions} 33 | /> 34 | 35 | <div 36 | style={{ 37 | color: 'hsl(0, 0%, 40%)', 38 | display: 'inline-block', 39 | fontSize: 12, 40 | fontStyle: 'italic', 41 | marginTop: '1em', 42 | }} 43 | > 44 | <Checkbox 45 | checked={isClearable} 46 | onChange={() => setIsClearable((state) => !state)} 47 | > 48 | Clearable 49 | </Checkbox> 50 | <Checkbox 51 | checked={isSearchable} 52 | onChange={() => setIsSearchable((state) => !state)} 53 | > 54 | Searchable 55 | </Checkbox> 56 | <Checkbox 57 | checked={isDisabled} 58 | onChange={() => setIsDisabled((state) => !state)} 59 | > 60 | Disabled 61 | </Checkbox> 62 | <Checkbox 63 | checked={isLoading} 64 | onChange={() => setIsLoading((state) => !state)} 65 | > 66 | Loading 67 | </Checkbox> 68 | <Checkbox checked={isRtl} onChange={() => setIsRtl((state) => !state)}> 69 | RTL 70 | </Checkbox> 71 | </div> 72 | </> 73 | ); 74 | }; 75 | -------------------------------------------------------------------------------- /docs/examples/ControlledMenu.tsx: -------------------------------------------------------------------------------- 1 | import React, { useRef, useState } from 'react'; 2 | 3 | import Select, { SelectInstance } from 'react-select'; 4 | import { colourOptions } from '../data'; 5 | import { Note } from '../styled-components'; 6 | 7 | const Checkbox = (props: JSX.IntrinsicElements['input']) => ( 8 | <input type="checkbox" {...props} /> 9 | ); 10 | 11 | export default () => { 12 | const ref = useRef<SelectInstance>(null); 13 | const [menuIsOpen, setMenuIsOpen] = useState<boolean>(false); 14 | 15 | const toggleMenuIsOpen = () => { 16 | setMenuIsOpen((value) => !value); 17 | const selectEl = ref.current; 18 | if (!selectEl) return; 19 | if (menuIsOpen) selectEl.blur(); 20 | else selectEl.focus(); 21 | }; 22 | 23 | return ( 24 | <> 25 | <Select 26 | ref={ref} 27 | defaultValue={colourOptions[0]} 28 | isClearable 29 | menuIsOpen={menuIsOpen} 30 | styles={{ menu: (base) => ({ ...base, position: 'relative' }) }} 31 | name="color" 32 | options={colourOptions} 33 | /> 34 | <Note Tag="label"> 35 | <Checkbox 36 | checked={menuIsOpen} 37 | onChange={toggleMenuIsOpen} 38 | id="cypress-single__clearable-checkbox" 39 | /> 40 | menuIsOpen 41 | </Note> 42 | </> 43 | ); 44 | }; 45 | -------------------------------------------------------------------------------- /docs/examples/CreatableAdvanced.tsx: -------------------------------------------------------------------------------- 1 | import React, { useState } from 'react'; 2 | 3 | import CreatableSelect from 'react-select/creatable'; 4 | 5 | interface Option { 6 | readonly label: string; 7 | readonly value: string; 8 | } 9 | 10 | const createOption = (label: string) => ({ 11 | label, 12 | value: label.toLowerCase().replace(/\W/g, ''), 13 | }); 14 | 15 | const defaultOptions = [ 16 | createOption('One'), 17 | createOption('Two'), 18 | createOption('Three'), 19 | ]; 20 | 21 | export default () => { 22 | const [isLoading, setIsLoading] = useState(false); 23 | const [options, setOptions] = useState(defaultOptions); 24 | const [value, setValue] = useState<Option | null>(); 25 | 26 | const handleCreate = (inputValue: string) => { 27 | setIsLoading(true); 28 | setTimeout(() => { 29 | const newOption = createOption(inputValue); 30 | setIsLoading(false); 31 | setOptions((prev) => [...prev, newOption]); 32 | setValue(newOption); 33 | }, 1000); 34 | }; 35 | 36 | return ( 37 | <CreatableSelect 38 | isClearable 39 | isDisabled={isLoading} 40 | isLoading={isLoading} 41 | onChange={(newValue) => setValue(newValue)} 42 | onCreateOption={handleCreate} 43 | options={options} 44 | value={value} 45 | /> 46 | ); 47 | }; 48 | -------------------------------------------------------------------------------- /docs/examples/CreatableInputOnly.tsx: -------------------------------------------------------------------------------- 1 | import React, { KeyboardEventHandler } from 'react'; 2 | 3 | import CreatableSelect from 'react-select/creatable'; 4 | 5 | const components = { 6 | DropdownIndicator: null, 7 | }; 8 | 9 | interface Option { 10 | readonly label: string; 11 | readonly value: string; 12 | } 13 | 14 | const createOption = (label: string) => ({ 15 | label, 16 | value: label, 17 | }); 18 | 19 | export default () => { 20 | const [inputValue, setInputValue] = React.useState(''); 21 | const [value, setValue] = React.useState<readonly Option[]>([]); 22 | 23 | const handleKeyDown: KeyboardEventHandler = (event) => { 24 | if (!inputValue) return; 25 | switch (event.key) { 26 | case 'Enter': 27 | case 'Tab': 28 | setValue((prev) => [...prev, createOption(inputValue)]); 29 | setInputValue(''); 30 | event.preventDefault(); 31 | } 32 | }; 33 | 34 | return ( 35 | <CreatableSelect 36 | components={components} 37 | inputValue={inputValue} 38 | isClearable 39 | isMulti 40 | menuIsOpen={false} 41 | onChange={(newValue) => setValue(newValue)} 42 | onInputChange={(newValue) => setInputValue(newValue)} 43 | onKeyDown={handleKeyDown} 44 | placeholder="Type something and press enter..." 45 | value={value} 46 | /> 47 | ); 48 | }; 49 | -------------------------------------------------------------------------------- /docs/examples/CreatableMulti.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | import CreatableSelect from 'react-select/creatable'; 4 | import { colourOptions } from '../data'; 5 | 6 | export default () => <CreatableSelect isMulti options={colourOptions} />; 7 | -------------------------------------------------------------------------------- /docs/examples/CreatableSingle.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | import CreatableSelect from 'react-select/creatable'; 4 | import { colourOptions } from '../data'; 5 | 6 | export default () => <CreatableSelect isClearable options={colourOptions} />; 7 | -------------------------------------------------------------------------------- /docs/examples/CreateFilter.tsx: -------------------------------------------------------------------------------- 1 | import React, { useState } from 'react'; 2 | import Select, { createFilter } from 'react-select'; 3 | import { colourOptions } from '../data'; 4 | import { Note } from '../styled-components'; 5 | 6 | const Checkbox = (props: JSX.IntrinsicElements['input']) => ( 7 | <input type="checkbox" {...props} /> 8 | ); 9 | 10 | export default () => { 11 | const [ignoreCase, setIgnoreCase] = useState(false); 12 | const [ignoreAccents, setIgnoreAccents] = useState(false); 13 | const [trim, setTrim] = useState(false); 14 | const [matchFromStart, setMatchFromStart] = useState(false); 15 | 16 | const filterConfig = { 17 | ignoreCase, 18 | ignoreAccents, 19 | trim, 20 | matchFrom: matchFromStart ? ('start' as const) : ('any' as const), 21 | }; 22 | 23 | return ( 24 | <> 25 | <Select 26 | defaultValue={colourOptions[0]} 27 | isClearable 28 | isSearchable 29 | name="color" 30 | options={colourOptions} 31 | filterOption={createFilter(filterConfig)} 32 | /> 33 | <Note Tag="label"> 34 | <Checkbox 35 | checked={ignoreCase} 36 | onChange={() => setIgnoreCase((prev) => !prev)} 37 | id="cypress-single__clearable-checkbox" 38 | /> 39 | Ignore Case 40 | </Note> 41 | <Note Tag="label"> 42 | <Checkbox 43 | checked={ignoreAccents} 44 | onChange={() => setIgnoreAccents((prev) => !prev)} 45 | id="cypress-single__clearable-checkbox" 46 | /> 47 | Ignore Accents 48 | </Note> 49 | <Note Tag="label"> 50 | <Checkbox 51 | checked={trim} 52 | onChange={() => setTrim((prev) => !prev)} 53 | id="cypress-single__clearable-checkbox" 54 | /> 55 | Trim 56 | </Note> 57 | <Note Tag="label"> 58 | <Checkbox 59 | checked={matchFromStart} 60 | onChange={() => setMatchFromStart((prev) => !prev)} 61 | id="cypress-single__clearable-checkbox" 62 | /> 63 | Match from the start 64 | </Note> 65 | </> 66 | ); 67 | }; 68 | -------------------------------------------------------------------------------- /docs/examples/CustomAriaLive.tsx: -------------------------------------------------------------------------------- 1 | import React, { CSSProperties, useState } from 'react'; 2 | 3 | import Select, { AriaOnFocus } from 'react-select'; 4 | import { ColourOption, colourOptions } from '../data'; 5 | 6 | export default function CustomAriaLive() { 7 | const [ariaFocusMessage, setAriaFocusMessage] = useState(''); 8 | const [isMenuOpen, setIsMenuOpen] = useState(false); 9 | 10 | const style: { [key: string]: CSSProperties } = { 11 | blockquote: { 12 | fontStyle: 'italic', 13 | fontSize: '.75rem', 14 | margin: '1rem 0', 15 | }, 16 | label: { 17 | fontSize: '.75rem', 18 | fontWeight: 'bold', 19 | lineHeight: 2, 20 | }, 21 | }; 22 | 23 | const onFocus: AriaOnFocus<ColourOption> = ({ focused, isDisabled }) => { 24 | const msg = `You are currently focused on option ${focused.label}${ 25 | isDisabled ? ', disabled' : '' 26 | }`; 27 | setAriaFocusMessage(msg); 28 | return msg; 29 | }; 30 | 31 | const onMenuOpen = () => setIsMenuOpen(true); 32 | const onMenuClose = () => setIsMenuOpen(false); 33 | 34 | return ( 35 | <form> 36 | <label style={style.label} id="aria-label" htmlFor="aria-example-input"> 37 | Select a color 38 | </label> 39 | 40 | {!!ariaFocusMessage && !!isMenuOpen && ( 41 | <blockquote style={style.blockquote}>"{ariaFocusMessage}"</blockquote> 42 | )} 43 | 44 | <Select 45 | aria-labelledby="aria-label" 46 | ariaLiveMessages={{ 47 | onFocus, 48 | }} 49 | inputId="aria-example-input" 50 | name="aria-live-color" 51 | onMenuOpen={onMenuOpen} 52 | onMenuClose={onMenuClose} 53 | options={colourOptions} 54 | /> 55 | </form> 56 | ); 57 | } 58 | -------------------------------------------------------------------------------- /docs/examples/CustomClearIndicator.tsx: -------------------------------------------------------------------------------- 1 | import React, { CSSProperties, FunctionComponent } from 'react'; 2 | 3 | import Select, { ClearIndicatorProps } from 'react-select'; 4 | import { CSSObject } from '@emotion/serialize'; 5 | import { ColourOption, colourOptions } from '../data'; 6 | 7 | const CustomClearText: FunctionComponent = () => <>clear all</>; 8 | const ClearIndicator = (props: ClearIndicatorProps<ColourOption, true>) => { 9 | const { 10 | children = <CustomClearText />, 11 | getStyles, 12 | innerProps: { ref, ...restInnerProps }, 13 | } = props; 14 | return ( 15 | <div 16 | {...restInnerProps} 17 | ref={ref} 18 | style={getStyles('clearIndicator', props) as CSSProperties} 19 | > 20 | <div style={{ padding: '0px 5px' }}>{children}</div> 21 | </div> 22 | ); 23 | }; 24 | 25 | const ClearIndicatorStyles = ( 26 | base: CSSObject, 27 | state: ClearIndicatorProps<ColourOption> 28 | ): CSSObject => ({ 29 | ...base, 30 | cursor: 'pointer', 31 | color: state.isFocused ? 'blue' : 'black', 32 | }); 33 | 34 | export default function CustomClearIndicator() { 35 | return ( 36 | <Select 37 | closeMenuOnSelect={false} 38 | components={{ ClearIndicator }} 39 | styles={{ clearIndicator: ClearIndicatorStyles }} 40 | defaultValue={[colourOptions[4], colourOptions[5]]} 41 | isMulti 42 | options={colourOptions} 43 | /> 44 | ); 45 | } 46 | -------------------------------------------------------------------------------- /docs/examples/CustomControl.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | import Select, { components, ControlProps } from 'react-select'; 4 | import { ColourOption, colourOptions } from '../data'; 5 | const controlStyles = { 6 | border: '1px solid black', 7 | padding: '5px', 8 | background: colourOptions[2].color, 9 | color: 'white', 10 | }; 11 | 12 | const ControlComponent = (props: ControlProps<ColourOption, false>) => ( 13 | <div style={controlStyles}> 14 | <p>Custom Control</p> 15 | <components.Control {...props} /> 16 | </div> 17 | ); 18 | 19 | export default () => ( 20 | <Select 21 | defaultValue={colourOptions[0]} 22 | isClearable 23 | components={{ Control: ControlComponent }} 24 | isSearchable 25 | name="color" 26 | options={colourOptions} 27 | /> 28 | ); 29 | -------------------------------------------------------------------------------- /docs/examples/CustomDropdownIndicator.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import EmojiIcon from '@atlaskit/icon/glyph/emoji'; 3 | import Select, { components, DropdownIndicatorProps } from 'react-select'; 4 | import { ColourOption, colourOptions } from '../data'; 5 | 6 | const DropdownIndicator = ( 7 | props: DropdownIndicatorProps<ColourOption, true> 8 | ) => { 9 | return ( 10 | <components.DropdownIndicator {...props}> 11 | <EmojiIcon label="Emoji" primaryColor={colourOptions[2].color} /> 12 | </components.DropdownIndicator> 13 | ); 14 | }; 15 | 16 | export default () => ( 17 | <Select 18 | closeMenuOnSelect={false} 19 | components={{ DropdownIndicator }} 20 | defaultValue={[colourOptions[4], colourOptions[5]]} 21 | isMulti 22 | options={colourOptions} 23 | /> 24 | ); 25 | -------------------------------------------------------------------------------- /docs/examples/CustomFilterOptions.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import Select from 'react-select'; 3 | import { colourOptions } from '../data'; 4 | 5 | const filterOptions = ( 6 | candidate: { label: string; value: string; data: any }, 7 | input: string 8 | ) => { 9 | if (input) { 10 | return candidate.value === customOptions[0].value; 11 | } 12 | return true; 13 | }; 14 | 15 | const customOptions = [ 16 | { 17 | value: 'custom', 18 | label: 'Using a custom filter to always display this option on search', 19 | }, 20 | ...colourOptions, 21 | ]; 22 | 23 | export default () => ( 24 | <Select 25 | defaultValue={customOptions[0]} 26 | isClearable 27 | isSearchable 28 | name="color" 29 | options={customOptions} 30 | filterOption={filterOptions} 31 | /> 32 | ); 33 | -------------------------------------------------------------------------------- /docs/examples/CustomGetOptionLabel.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import Select from 'react-select'; 3 | import { flavourOptions } from '../data'; 4 | 5 | export default () => ( 6 | <> 7 | <p> 8 | Composing a display label from the label property and rating property in 9 | the options object 10 | </p> 11 | <Select 12 | defaultValue={flavourOptions[0]} 13 | isClearable 14 | isSearchable 15 | name="color" 16 | options={flavourOptions} 17 | getOptionLabel={(option) => `${option.label}: ${option.rating}`} 18 | /> 19 | </> 20 | ); 21 | -------------------------------------------------------------------------------- /docs/examples/CustomGetOptionValue.tsx: -------------------------------------------------------------------------------- 1 | import React, { Fragment } from 'react'; 2 | import Select from 'react-select'; 3 | import { dogOptions } from '../data'; 4 | 5 | export default function CustomGetOptionValue() { 6 | return ( 7 | <Fragment> 8 | <p>Using id property, instead of value property.</p> 9 | <Select 10 | defaultValue={dogOptions[0]} 11 | isClearable 12 | isSearchable 13 | name="dog" 14 | options={dogOptions} 15 | getOptionValue={(option) => `${option['id']}`} 16 | /> 17 | </Fragment> 18 | ); 19 | } 20 | -------------------------------------------------------------------------------- /docs/examples/CustomGroup.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | import Select, { components, GroupProps } from 'react-select'; 4 | import { 5 | ColourOption, 6 | colourOptions, 7 | FlavourOption, 8 | groupedOptions, 9 | } from '../data'; 10 | 11 | const groupStyles = { 12 | border: `2px dotted ${colourOptions[2].color}`, 13 | borderRadius: '5px', 14 | background: '#f2fcff', 15 | }; 16 | 17 | const Group = (props: GroupProps<ColourOption | FlavourOption, false>) => ( 18 | <div style={groupStyles}> 19 | <components.Group {...props} /> 20 | </div> 21 | ); 22 | 23 | export default () => ( 24 | <Select<ColourOption | FlavourOption> 25 | defaultValue={colourOptions[1]} 26 | options={groupedOptions} 27 | components={{ Group }} 28 | /> 29 | ); 30 | -------------------------------------------------------------------------------- /docs/examples/CustomGroupHeading.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | import Select, { components, GroupHeadingProps } from 'react-select'; 4 | import { 5 | ColourOption, 6 | colourOptions, 7 | FlavourOption, 8 | groupedOptions, 9 | } from '../data'; 10 | import EditorPanelIcon from '@atlaskit/icon/glyph/editor/panel'; 11 | import Tooltip from '@atlaskit/tooltip'; 12 | 13 | const groupStyles = { 14 | border: `2px dotted ${colourOptions[2].color}`, 15 | color: 'white', 16 | background: colourOptions[2].color, 17 | padding: '5px 0px', 18 | display: 'flex', 19 | }; 20 | 21 | const GroupHeading = ( 22 | props: GroupHeadingProps<ColourOption | FlavourOption> 23 | ) => ( 24 | <div style={groupStyles}> 25 | <components.GroupHeading {...props} /> 26 | <Tooltip content="Custom GroupHeading Component"> 27 | <EditorPanelIcon label="Editor Panel" /> 28 | </Tooltip> 29 | </div> 30 | ); 31 | 32 | export default () => ( 33 | <Select<ColourOption | FlavourOption> 34 | defaultValue={colourOptions[1]} 35 | options={groupedOptions} 36 | components={{ GroupHeading }} 37 | styles={{ 38 | groupHeading: (base) => ({ 39 | ...base, 40 | flex: '1 1', 41 | color: 'white', 42 | margin: 0, 43 | }), 44 | }} 45 | /> 46 | ); 47 | -------------------------------------------------------------------------------- /docs/examples/CustomIndicatorSeparator.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import Select, { IndicatorSeparatorProps } from 'react-select'; 3 | import { ColourOption, colourOptions } from '../data'; 4 | 5 | const indicatorSeparatorStyle = { 6 | alignSelf: 'stretch', 7 | backgroundColor: colourOptions[2].color, 8 | marginBottom: 8, 9 | marginTop: 8, 10 | width: 1, 11 | }; 12 | 13 | const IndicatorSeparator = ({ 14 | innerProps, 15 | }: IndicatorSeparatorProps<ColourOption, true>) => { 16 | return <span style={indicatorSeparatorStyle} {...innerProps} />; 17 | }; 18 | 19 | export default () => ( 20 | <Select 21 | closeMenuOnSelect={false} 22 | components={{ IndicatorSeparator }} 23 | defaultValue={[colourOptions[4], colourOptions[5]]} 24 | isMulti 25 | options={colourOptions} 26 | /> 27 | ); 28 | -------------------------------------------------------------------------------- /docs/examples/CustomIndicatorsContainer.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import Select, { components, IndicatorsContainerProps } from 'react-select'; 3 | import { ColourOption, colourOptions } from '../data'; 4 | 5 | const IndicatorsContainer = ( 6 | props: IndicatorsContainerProps<ColourOption, true> 7 | ) => { 8 | return ( 9 | <div style={{ background: colourOptions[2].color }}> 10 | <components.IndicatorsContainer {...props} /> 11 | </div> 12 | ); 13 | }; 14 | 15 | export default () => ( 16 | <Select 17 | closeMenuOnSelect={false} 18 | components={{ IndicatorsContainer }} 19 | defaultValue={[colourOptions[4], colourOptions[5]]} 20 | isMulti 21 | options={colourOptions} 22 | /> 23 | ); 24 | -------------------------------------------------------------------------------- /docs/examples/CustomInput.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import Tooltip from '@atlaskit/tooltip'; 3 | import Select, { components, InputProps } from 'react-select'; 4 | import { ColourOption, colourOptions } from '../data'; 5 | 6 | const Input = (props: InputProps<ColourOption, true>) => { 7 | if (props.isHidden) { 8 | return <components.Input {...props} />; 9 | } 10 | return ( 11 | <div style={{ border: `1px dotted ${colourOptions[2].color}` }}> 12 | <Tooltip content={'Custom Input'}> 13 | <components.Input {...props} /> 14 | </Tooltip> 15 | </div> 16 | ); 17 | }; 18 | 19 | export default () => ( 20 | <Select 21 | closeMenuOnSelect={false} 22 | components={{ Input }} 23 | defaultValue={[colourOptions[4], colourOptions[5]]} 24 | isMulti 25 | options={colourOptions} 26 | /> 27 | ); 28 | -------------------------------------------------------------------------------- /docs/examples/CustomIsOptionDisabled.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import Select from 'react-select'; 3 | import { flavourOptions } from '../data'; 4 | 5 | export default () => ( 6 | <> 7 | <p> 8 | Disable all options that do not have a 'safe' rating, via the 9 | isOptionsDisabled fn prop 10 | </p> 11 | <Select 12 | defaultValue={flavourOptions[0]} 13 | isClearable 14 | isSearchable 15 | name="color" 16 | options={flavourOptions} 17 | isOptionDisabled={(option) => option.rating !== 'safe'} 18 | /> 19 | </> 20 | ); 21 | -------------------------------------------------------------------------------- /docs/examples/CustomLoadingIndicator.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import Spinner from '@atlaskit/spinner'; 3 | import Tooltip from '@atlaskit/tooltip'; 4 | import AsyncSelect from 'react-select/async'; 5 | import { LoadingIndicatorProps } from 'react-select'; 6 | import { ColourOption, colourOptions } from '../data'; 7 | 8 | const LoadingIndicator = (props: LoadingIndicatorProps<ColourOption>) => { 9 | return ( 10 | <Tooltip content={'Custom Loader'}> 11 | <Spinner {...props} delay={0} /> 12 | </Tooltip> 13 | ); 14 | }; 15 | 16 | const filterColors = (inputValue: string) => 17 | colourOptions.filter((i) => 18 | i.label.toLowerCase().includes(inputValue.toLowerCase()) 19 | ); 20 | 21 | const promiseOptions = (inputValue: string) => 22 | new Promise<ColourOption[]>((resolve) => { 23 | setTimeout(() => { 24 | resolve(filterColors(inputValue)); 25 | }, 1000); 26 | }); 27 | 28 | const CustomLoadingIndicator = () => { 29 | return ( 30 | <AsyncSelect 31 | cacheOptions 32 | defaultOptions 33 | loadOptions={promiseOptions} 34 | components={{ LoadingIndicator }} 35 | /> 36 | ); 37 | }; 38 | 39 | export default CustomLoadingIndicator; 40 | -------------------------------------------------------------------------------- /docs/examples/CustomLoadingMessage.tsx: -------------------------------------------------------------------------------- 1 | import React, { CSSProperties } from 'react'; 2 | import Tooltip from '@atlaskit/tooltip'; 3 | import AsyncSelect from 'react-select/async'; 4 | import { NoticeProps } from 'react-select'; 5 | import { ColourOption, colourOptions } from '../data'; 6 | 7 | const LoadingMessage = (props: NoticeProps<ColourOption, false>) => { 8 | return ( 9 | <Tooltip content={'Custom Loading Message'}> 10 | <div 11 | {...props.innerProps} 12 | style={props.getStyles('loadingMessage', props) as CSSProperties} 13 | > 14 | {props.children} 15 | </div> 16 | </Tooltip> 17 | ); 18 | }; 19 | 20 | const filterColors = (inputValue: string) => 21 | colourOptions.filter((i) => 22 | i.label.toLowerCase().includes(inputValue.toLowerCase()) 23 | ); 24 | 25 | const promiseOptions = (inputValue: string) => 26 | new Promise<ColourOption[]>((resolve) => { 27 | setTimeout(() => { 28 | resolve(filterColors(inputValue)); 29 | }, 1000); 30 | }); 31 | 32 | const CustomLoadingMessage = () => { 33 | return ( 34 | <AsyncSelect 35 | cacheOptions 36 | defaultOptions 37 | loadOptions={promiseOptions} 38 | styles={{ 39 | loadingMessage: (base) => ({ 40 | ...base, 41 | backgroundColor: colourOptions[2].color, 42 | color: 'white', 43 | }), 44 | }} 45 | components={{ LoadingMessage }} 46 | /> 47 | ); 48 | }; 49 | 50 | export default CustomLoadingMessage; 51 | -------------------------------------------------------------------------------- /docs/examples/CustomMenu.tsx: -------------------------------------------------------------------------------- 1 | import React, { Fragment } from 'react'; 2 | 3 | import Select, { components, MenuProps } from 'react-select'; 4 | import { 5 | ColourOption, 6 | colourOptions, 7 | FlavourOption, 8 | GroupedOption, 9 | groupedOptions, 10 | } from '../data'; 11 | 12 | function getLength( 13 | options: readonly (GroupedOption | ColourOption | FlavourOption)[] 14 | ): number { 15 | return options.reduce((acc, curr) => { 16 | if ('options' in curr) return acc + getLength(curr.options); 17 | return acc + 1; 18 | }, 0); 19 | } 20 | 21 | const menuHeaderStyle = { 22 | padding: '8px 12px', 23 | }; 24 | 25 | const Menu = ( 26 | props: MenuProps<ColourOption | FlavourOption, false, GroupedOption> 27 | ) => { 28 | const optionsLength = getLength(props.options); 29 | return ( 30 | <Fragment> 31 | <div style={menuHeaderStyle}> 32 | Custom Menu with {optionsLength} options 33 | </div> 34 | <components.Menu<ColourOption | FlavourOption, false, GroupedOption> 35 | {...props} 36 | > 37 | {props.children} 38 | </components.Menu> 39 | </Fragment> 40 | ); 41 | }; 42 | 43 | export default () => ( 44 | <Select<ColourOption | FlavourOption, false, GroupedOption> 45 | defaultValue={colourOptions[1]} 46 | options={groupedOptions} 47 | components={{ Menu }} 48 | /> 49 | ); 50 | -------------------------------------------------------------------------------- /docs/examples/CustomMenuList.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | import Select, { components, MenuListProps } from 'react-select'; 4 | import { 5 | ColourOption, 6 | colourOptions, 7 | FlavourOption, 8 | GroupedOption, 9 | groupedOptions, 10 | } from '../data'; 11 | 12 | const menuHeaderStyle = { 13 | padding: '8px 12px', 14 | background: colourOptions[2].color, 15 | color: 'white', 16 | }; 17 | 18 | const MenuList = ( 19 | props: MenuListProps<ColourOption | FlavourOption, false, GroupedOption> 20 | ) => { 21 | return ( 22 | <components.MenuList {...props}> 23 | <div style={menuHeaderStyle}>Custom Menu List</div> 24 | {props.children} 25 | </components.MenuList> 26 | ); 27 | }; 28 | 29 | export default () => ( 30 | <Select<ColourOption | FlavourOption, false, GroupedOption> 31 | defaultValue={colourOptions[1]} 32 | options={groupedOptions} 33 | components={{ MenuList }} 34 | /> 35 | ); 36 | -------------------------------------------------------------------------------- /docs/examples/CustomMultiValueContainer.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import Tooltip from '@atlaskit/tooltip'; 3 | import Select, { components, MultiValueGenericProps } from 'react-select'; 4 | import { ColourOption, colourOptions } from '../data'; 5 | 6 | const MultiValueContainer = (props: MultiValueGenericProps<ColourOption>) => { 7 | return ( 8 | <Tooltip content={'Customise your multi-value container!'}> 9 | <components.MultiValueContainer {...props} /> 10 | </Tooltip> 11 | ); 12 | }; 13 | 14 | export default () => ( 15 | <Select 16 | closeMenuOnSelect={false} 17 | components={{ MultiValueContainer }} 18 | styles={{ 19 | multiValue: (base) => ({ 20 | ...base, 21 | border: `2px dotted ${colourOptions[2].color}`, 22 | }), 23 | }} 24 | defaultValue={[colourOptions[4], colourOptions[5]]} 25 | isMulti 26 | options={colourOptions} 27 | /> 28 | ); 29 | -------------------------------------------------------------------------------- /docs/examples/CustomMultiValueLabel.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import Tooltip from '@atlaskit/tooltip'; 3 | import Select, { components, MultiValueGenericProps } from 'react-select'; 4 | import { ColourOption, colourOptions } from '../data'; 5 | 6 | const MultiValueLabel = (props: MultiValueGenericProps<ColourOption>) => { 7 | return ( 8 | <Tooltip content={'Customise your multi-value label component!'}> 9 | <components.MultiValueLabel {...props} /> 10 | </Tooltip> 11 | ); 12 | }; 13 | 14 | export default () => ( 15 | <Select 16 | closeMenuOnSelect={false} 17 | components={{ MultiValueLabel }} 18 | styles={{ 19 | multiValueLabel: (base) => ({ 20 | ...base, 21 | backgroundColor: colourOptions[2].color, 22 | color: 'white', 23 | }), 24 | }} 25 | defaultValue={[colourOptions[4], colourOptions[5]]} 26 | isMulti 27 | options={colourOptions} 28 | /> 29 | ); 30 | -------------------------------------------------------------------------------- /docs/examples/CustomMultiValueRemove.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import EmojiIcon from '@atlaskit/icon/glyph/emoji'; 3 | import Tooltip from '@atlaskit/tooltip'; 4 | import Select, { components, MultiValueRemoveProps } from 'react-select'; 5 | import { ColourOption, colourOptions } from '../data'; 6 | 7 | const MultiValueRemove = (props: MultiValueRemoveProps<ColourOption>) => { 8 | return ( 9 | <Tooltip content={'Customise your multi-value remove component!'} truncate> 10 | <components.MultiValueRemove {...props}> 11 | <EmojiIcon label="Emoji" primaryColor={colourOptions[2].color} /> 12 | </components.MultiValueRemove> 13 | </Tooltip> 14 | ); 15 | }; 16 | 17 | export default () => ( 18 | <Select 19 | closeMenuOnSelect={false} 20 | components={{ MultiValueRemove }} 21 | styles={{ 22 | multiValueRemove: (base) => ({ 23 | ...base, 24 | border: `1px dotted ${colourOptions[2].color}`, 25 | height: '100%', 26 | }), 27 | }} 28 | defaultValue={[colourOptions[4], colourOptions[5]]} 29 | isMulti 30 | options={colourOptions} 31 | /> 32 | ); 33 | -------------------------------------------------------------------------------- /docs/examples/CustomNoOptionsMessage.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import Tooltip from '@atlaskit/tooltip'; 3 | import Select, { components, NoticeProps } from 'react-select'; 4 | import { colourOptions } from '../data'; 5 | 6 | const msgStyles = { 7 | background: colourOptions[2].color, 8 | color: 'white', 9 | }; 10 | 11 | const NoOptionsMessage = (props: NoticeProps) => { 12 | return ( 13 | <Tooltip content="Custom NoOptionsMessage Component"> 14 | <components.NoOptionsMessage {...props} /> 15 | </Tooltip> 16 | ); 17 | }; 18 | 19 | const CustomNoOptionsMessage = () => { 20 | return ( 21 | <Select 22 | isClearable 23 | components={{ NoOptionsMessage }} 24 | styles={{ noOptionsMessage: (base) => ({ ...base, ...msgStyles }) }} 25 | isSearchable 26 | name="color" 27 | options={[]} 28 | /> 29 | ); 30 | }; 31 | 32 | export default CustomNoOptionsMessage; 33 | -------------------------------------------------------------------------------- /docs/examples/CustomOption.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import Tooltip from '@atlaskit/tooltip'; 3 | import Select, { components, OptionProps } from 'react-select'; 4 | import { ColourOption, colourOptions } from '../data'; 5 | 6 | const Option = (props: OptionProps<ColourOption>) => { 7 | return ( 8 | <Tooltip content={'Customise your option component!'} truncate> 9 | <components.Option {...props} /> 10 | </Tooltip> 11 | ); 12 | }; 13 | 14 | export default () => ( 15 | <Select 16 | closeMenuOnSelect={false} 17 | components={{ Option }} 18 | styles={{ 19 | option: (base) => ({ 20 | ...base, 21 | border: `1px dotted ${colourOptions[2].color}`, 22 | height: '100%', 23 | }), 24 | }} 25 | defaultValue={colourOptions[4]} 26 | options={colourOptions} 27 | /> 28 | ); 29 | -------------------------------------------------------------------------------- /docs/examples/CustomPlaceholder.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import Select, { components, PlaceholderProps } from 'react-select'; 3 | import { ColourOption, colourOptions } from '../data'; 4 | 5 | const Placeholder = (props: PlaceholderProps<ColourOption>) => { 6 | return <components.Placeholder {...props} />; 7 | }; 8 | 9 | export default () => ( 10 | <Select 11 | closeMenuOnSelect={false} 12 | components={{ Placeholder }} 13 | placeholder={'custom placeholder component'} 14 | styles={{ 15 | placeholder: (base) => ({ 16 | ...base, 17 | fontSize: '1em', 18 | color: colourOptions[2].color, 19 | fontWeight: 400, 20 | }), 21 | }} 22 | options={colourOptions} 23 | /> 24 | ); 25 | -------------------------------------------------------------------------------- /docs/examples/CustomSelectContainer.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import Select, { components, ContainerProps } from 'react-select'; 3 | import Tooltip from '@atlaskit/tooltip'; 4 | import { ColourOption, colourOptions } from '../data'; 5 | 6 | const SelectContainer = ({ 7 | children, 8 | ...props 9 | }: ContainerProps<ColourOption>) => { 10 | return ( 11 | <Tooltip content={'customise your select container'} delay={0}> 12 | <components.SelectContainer {...props}> 13 | {children} 14 | </components.SelectContainer> 15 | </Tooltip> 16 | ); 17 | }; 18 | 19 | export default () => ( 20 | <Select 21 | closeMenuOnSelect={false} 22 | components={{ SelectContainer }} 23 | styles={{ 24 | container: (base) => ({ 25 | ...base, 26 | backgroundColor: colourOptions[2].color, 27 | padding: 5, 28 | }), 29 | }} 30 | options={colourOptions} 31 | /> 32 | ); 33 | -------------------------------------------------------------------------------- /docs/examples/CustomSelectProps.tsx: -------------------------------------------------------------------------------- 1 | import React, { MouseEventHandler, useState } from 'react'; 2 | import Select, { 3 | components, 4 | ControlProps, 5 | Props, 6 | StylesConfig, 7 | } from 'react-select'; 8 | import { ColourOption, colourOptions } from '../data'; 9 | 10 | const EMOJIS = ['👍', '🤙', '👏', '👌', '🙌', '✌️', '🖖', '👐']; 11 | 12 | const Control = ({ children, ...props }: ControlProps<ColourOption, false>) => { 13 | // @ts-ignore 14 | const { emoji, onEmojiClick } = props.selectProps; 15 | const style = { cursor: 'pointer' }; 16 | 17 | return ( 18 | <components.Control {...props}> 19 | <span onMouseDown={onEmojiClick} style={style}> 20 | {emoji} 21 | </span> 22 | {children} 23 | </components.Control> 24 | ); 25 | }; 26 | 27 | const CustomSelectProps = (props: Props<ColourOption>) => { 28 | const [clickCount, setClickCount] = useState(0); 29 | 30 | const onClick: MouseEventHandler<HTMLSpanElement> = (e) => { 31 | setClickCount(clickCount + 1); 32 | e.preventDefault(); 33 | e.stopPropagation(); 34 | }; 35 | 36 | const styles: StylesConfig<ColourOption, false> = { 37 | control: (css) => ({ ...css, paddingLeft: '1rem' }), 38 | }; 39 | 40 | const emoji = EMOJIS[clickCount % EMOJIS.length]; 41 | 42 | return ( 43 | <Select 44 | {...props} 45 | // @ts-ignore 46 | emoji={emoji} 47 | onEmojiClick={onClick} 48 | components={{ Control }} 49 | isSearchable 50 | name="emoji" 51 | options={colourOptions} 52 | styles={styles} 53 | /> 54 | ); 55 | }; 56 | 57 | export default CustomSelectProps; 58 | -------------------------------------------------------------------------------- /docs/examples/CustomSingleValue.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import Select, { components, SingleValueProps } from 'react-select'; 3 | import { ColourOption, colourOptions } from '../data'; 4 | 5 | const SingleValue = ({ 6 | children, 7 | ...props 8 | }: SingleValueProps<ColourOption>) => ( 9 | <components.SingleValue {...props}>{children}</components.SingleValue> 10 | ); 11 | 12 | export default () => ( 13 | <Select 14 | defaultValue={colourOptions[0]} 15 | isClearable 16 | styles={{ 17 | singleValue: (base) => ({ 18 | ...base, 19 | padding: 5, 20 | borderRadius: 5, 21 | background: colourOptions[2].color, 22 | color: 'white', 23 | display: 'flex', 24 | }), 25 | }} 26 | components={{ SingleValue }} 27 | isSearchable 28 | name="color" 29 | options={colourOptions} 30 | /> 31 | ); 32 | -------------------------------------------------------------------------------- /docs/examples/CustomValueContainer.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import Select, { components, ValueContainerProps } from 'react-select'; 3 | import { ColourOption, colourOptions } from '../data'; 4 | 5 | const ValueContainer = ({ 6 | children, 7 | ...props 8 | }: ValueContainerProps<ColourOption>) => ( 9 | <components.ValueContainer {...props}>{children}</components.ValueContainer> 10 | ); 11 | 12 | export default () => ( 13 | <Select 14 | defaultValue={colourOptions[0]} 15 | isClearable 16 | styles={{ 17 | singleValue: (base) => ({ ...base, color: 'white' }), 18 | valueContainer: (base) => ({ 19 | ...base, 20 | background: colourOptions[2].color, 21 | color: 'white', 22 | width: '100%', 23 | }), 24 | }} 25 | components={{ ValueContainer }} 26 | isSearchable 27 | name="color" 28 | options={colourOptions} 29 | /> 30 | ); 31 | -------------------------------------------------------------------------------- /docs/examples/DefaultOptions.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | import AsyncSelect from 'react-select/async'; 4 | import { ColourOption, colourOptions } from '../data'; 5 | 6 | const filterColors = (inputValue: string) => { 7 | return colourOptions.filter((i) => 8 | i.label.toLowerCase().includes(inputValue.toLowerCase()) 9 | ); 10 | }; 11 | 12 | const promiseOptions = (inputValue: string) => 13 | new Promise<ColourOption[]>((resolve) => { 14 | setTimeout(() => { 15 | resolve(filterColors(inputValue)); 16 | }, 1000); 17 | }); 18 | 19 | export default () => ( 20 | <AsyncSelect 21 | cacheOptions 22 | defaultOptions={colourOptions} 23 | loadOptions={promiseOptions} 24 | /> 25 | ); 26 | -------------------------------------------------------------------------------- /docs/examples/FixedOptions.tsx: -------------------------------------------------------------------------------- 1 | import React, { useState } from 'react'; 2 | 3 | import Select, { ActionMeta, OnChangeValue, StylesConfig } from 'react-select'; 4 | import { ColourOption, colourOptions } from '../data'; 5 | 6 | const styles: StylesConfig<ColourOption, true> = { 7 | multiValue: (base, state) => { 8 | return state.data.isFixed ? { ...base, backgroundColor: 'gray' } : base; 9 | }, 10 | multiValueLabel: (base, state) => { 11 | return state.data.isFixed 12 | ? { ...base, fontWeight: 'bold', color: 'white', paddingRight: 6 } 13 | : base; 14 | }, 15 | multiValueRemove: (base, state) => { 16 | return state.data.isFixed ? { ...base, display: 'none' } : base; 17 | }, 18 | }; 19 | 20 | const orderOptions = (values: readonly ColourOption[]) => { 21 | return values 22 | .filter((v) => v.isFixed) 23 | .concat(values.filter((v) => !v.isFixed)); 24 | }; 25 | 26 | export default () => { 27 | const [value, setValue] = useState<readonly ColourOption[]>( 28 | orderOptions([colourOptions[0], colourOptions[1], colourOptions[3]]) 29 | ); 30 | 31 | const onChange = ( 32 | newValue: OnChangeValue<ColourOption, true>, 33 | actionMeta: ActionMeta<ColourOption> 34 | ) => { 35 | switch (actionMeta.action) { 36 | case 'remove-value': 37 | case 'pop-value': 38 | if (actionMeta.removedValue.isFixed) { 39 | return; 40 | } 41 | break; 42 | case 'clear': 43 | newValue = colourOptions.filter((v) => v.isFixed); 44 | break; 45 | } 46 | 47 | setValue(orderOptions(newValue)); 48 | }; 49 | 50 | return ( 51 | <Select 52 | value={value} 53 | isMulti 54 | styles={styles} 55 | isClearable={value.some((v) => !v.isFixed)} 56 | name="colors" 57 | className="basic-multi-select" 58 | classNamePrefix="select" 59 | onChange={onChange} 60 | options={colourOptions} 61 | /> 62 | ); 63 | }; 64 | -------------------------------------------------------------------------------- /docs/examples/MenuBuffer.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import Select from 'react-select'; 3 | 4 | import { colourOptions } from '../data'; 5 | 6 | export default () => ( 7 | <Select 8 | defaultValue={colourOptions[0]} 9 | options={colourOptions} 10 | styles={{ menu: (base) => ({ ...base, marginBottom: 76 }) }} 11 | /> 12 | ); 13 | -------------------------------------------------------------------------------- /docs/examples/OnSelectResetsInput.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import Select, { InputActionMeta } from 'react-select'; 3 | import { colourOptions } from '../data'; 4 | 5 | export default () => { 6 | const [menuIsOpen, setMenuIsOpen] = React.useState<boolean>(); 7 | 8 | const onInputChange = ( 9 | inputValue: string, 10 | { action, prevInputValue }: InputActionMeta 11 | ) => { 12 | if (action === 'input-change') return inputValue; 13 | if (action === 'menu-close') { 14 | if (prevInputValue) setMenuIsOpen(true); 15 | else setMenuIsOpen(undefined); 16 | } 17 | return prevInputValue; 18 | }; 19 | 20 | return ( 21 | <Select 22 | isMulti 23 | defaultValue={colourOptions[0]} 24 | isClearable 25 | isSearchable 26 | onInputChange={onInputChange} 27 | name="color" 28 | options={colourOptions} 29 | menuIsOpen={menuIsOpen} 30 | /> 31 | ); 32 | }; 33 | -------------------------------------------------------------------------------- /docs/examples/StyleCompositionExample.tsx: -------------------------------------------------------------------------------- 1 | /** @jsx jsx */ 2 | import { jsx } from '@emotion/react'; 3 | import Select, { OptionProps } from 'react-select'; 4 | import { ColourOption, colourOptions } from '../data'; 5 | 6 | const Option = (props: OptionProps<ColourOption>) => { 7 | const { 8 | children, 9 | className, 10 | cx, 11 | getStyles, 12 | isDisabled, 13 | isFocused, 14 | isSelected, 15 | innerRef, 16 | innerProps, 17 | } = props; 18 | return ( 19 | <div 20 | ref={innerRef} 21 | css={getStyles('option', props)} 22 | className={cx( 23 | { 24 | option: true, 25 | 'option--is-disabled': isDisabled, 26 | 'option--is-focused': isFocused, 27 | 'option--is-selected': isSelected, 28 | }, 29 | className 30 | )} 31 | {...innerProps} 32 | > 33 | {children} 34 | </div> 35 | ); 36 | }; 37 | 38 | export default () => ( 39 | <Select 40 | closeMenuOnSelect={false} 41 | components={{ Option }} 42 | styles={{ 43 | option: (base) => ({ 44 | ...base, 45 | border: `1px dotted ${colourOptions[2].color}`, 46 | height: '100%', 47 | }), 48 | }} 49 | defaultValue={colourOptions[4]} 50 | options={colourOptions} 51 | /> 52 | ); 53 | -------------------------------------------------------------------------------- /docs/examples/StyledMulti.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import chroma from 'chroma-js'; 3 | 4 | import { ColourOption, colourOptions } from '../data'; 5 | import Select, { StylesConfig } from 'react-select'; 6 | 7 | const colourStyles: StylesConfig<ColourOption, true> = { 8 | control: (styles) => ({ ...styles, backgroundColor: 'white' }), 9 | option: (styles, { data, isDisabled, isFocused, isSelected }) => { 10 | const color = chroma(data.color); 11 | return { 12 | ...styles, 13 | backgroundColor: isDisabled 14 | ? undefined 15 | : isSelected 16 | ? data.color 17 | : isFocused 18 | ? color.alpha(0.1).css() 19 | : undefined, 20 | color: isDisabled 21 | ? '#ccc' 22 | : isSelected 23 | ? chroma.contrast(color, 'white') > 2 24 | ? 'white' 25 | : 'black' 26 | : data.color, 27 | cursor: isDisabled ? 'not-allowed' : 'default', 28 | 29 | ':active': { 30 | ...styles[':active'], 31 | backgroundColor: !isDisabled 32 | ? isSelected 33 | ? data.color 34 | : color.alpha(0.3).css() 35 | : undefined, 36 | }, 37 | }; 38 | }, 39 | multiValue: (styles, { data }) => { 40 | const color = chroma(data.color); 41 | return { 42 | ...styles, 43 | backgroundColor: color.alpha(0.1).css(), 44 | }; 45 | }, 46 | multiValueLabel: (styles, { data }) => ({ 47 | ...styles, 48 | color: data.color, 49 | }), 50 | multiValueRemove: (styles, { data }) => ({ 51 | ...styles, 52 | color: data.color, 53 | ':hover': { 54 | backgroundColor: data.color, 55 | color: 'white', 56 | }, 57 | }), 58 | }; 59 | 60 | export default () => ( 61 | <Select 62 | closeMenuOnSelect={false} 63 | defaultValue={[colourOptions[0], colourOptions[1]]} 64 | isMulti 65 | options={colourOptions} 66 | styles={colourStyles} 67 | /> 68 | ); 69 | -------------------------------------------------------------------------------- /docs/examples/StyledSingle.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import chroma from 'chroma-js'; 3 | 4 | import { ColourOption, colourOptions } from '../data'; 5 | import Select, { StylesConfig } from 'react-select'; 6 | 7 | const dot = (color = 'transparent') => ({ 8 | alignItems: 'center', 9 | display: 'flex', 10 | 11 | ':before': { 12 | backgroundColor: color, 13 | borderRadius: 10, 14 | content: '" "', 15 | display: 'block', 16 | marginRight: 8, 17 | height: 10, 18 | width: 10, 19 | }, 20 | }); 21 | 22 | const colourStyles: StylesConfig<ColourOption> = { 23 | control: (styles) => ({ ...styles, backgroundColor: 'white' }), 24 | option: (styles, { data, isDisabled, isFocused, isSelected }) => { 25 | const color = chroma(data.color); 26 | return { 27 | ...styles, 28 | backgroundColor: isDisabled 29 | ? undefined 30 | : isSelected 31 | ? data.color 32 | : isFocused 33 | ? color.alpha(0.1).css() 34 | : undefined, 35 | color: isDisabled 36 | ? '#ccc' 37 | : isSelected 38 | ? chroma.contrast(color, 'white') > 2 39 | ? 'white' 40 | : 'black' 41 | : data.color, 42 | cursor: isDisabled ? 'not-allowed' : 'default', 43 | 44 | ':active': { 45 | ...styles[':active'], 46 | backgroundColor: !isDisabled 47 | ? isSelected 48 | ? data.color 49 | : color.alpha(0.3).css() 50 | : undefined, 51 | }, 52 | }; 53 | }, 54 | input: (styles) => ({ ...styles, ...dot() }), 55 | placeholder: (styles) => ({ ...styles, ...dot('#ccc') }), 56 | singleValue: (styles, { data }) => ({ ...styles, ...dot(data.color) }), 57 | }; 58 | 59 | export default () => ( 60 | <Select 61 | defaultValue={colourOptions[2]} 62 | options={colourOptions} 63 | styles={colourStyles} 64 | /> 65 | ); 66 | -------------------------------------------------------------------------------- /docs/examples/Theme.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | import { flavourOptions } from '../data'; 4 | import Select from 'react-select'; 5 | 6 | export default () => ( 7 | <Select 8 | defaultValue={flavourOptions[2]} 9 | options={flavourOptions} 10 | theme={(theme) => ({ 11 | ...theme, 12 | borderRadius: 0, 13 | colors: { 14 | ...theme.colors, 15 | primary25: 'hotpink', 16 | primary: 'black', 17 | }, 18 | })} 19 | /> 20 | ); 21 | -------------------------------------------------------------------------------- /docs/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JedWatson/react-select/2a913698ad3d7759fb8e6bc5dd8a7d839227da2f/docs/favicon.ico -------------------------------------------------------------------------------- /docs/generate-magical-types/generate/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "main": "dist/react-select-generate-magical-types-generate.cjs.js", 3 | "module": "dist/react-select-generate-magical-types-generate.esm.js" 4 | } 5 | -------------------------------------------------------------------------------- /docs/generate-magical-types/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@react-select/generate-magical-types", 3 | "main": "dist/generate-magical-types.cjs.js", 4 | "exports": { 5 | "./generate": { 6 | "module": "./generate/dist/react-select-generate-magical-types-generate.esm.js", 7 | "import": "./generate/dist/react-select-generate-magical-types-generate.cjs.mjs", 8 | "default": "./generate/dist/react-select-generate-magical-types-generate.cjs.js" 9 | }, 10 | "./serialize": { 11 | "module": "./serialize/dist/react-select-generate-magical-types-serialize.esm.js", 12 | "import": "./serialize/dist/react-select-generate-magical-types-serialize.cjs.mjs", 13 | "default": "./serialize/dist/react-select-generate-magical-types-serialize.cjs.js" 14 | }, 15 | "./package.json": "./package.json" 16 | }, 17 | "//": "these deps aren't real, they're just to appease preconstruct", 18 | "dependencies": { 19 | "@babel/runtime": "*", 20 | "@magical-types/convert-type": "*", 21 | "@magical-types/serialization": "*", 22 | "ts-morph": "*", 23 | "fs-extra": "*", 24 | "flatted": "*" 25 | }, 26 | "preconstruct": { 27 | "entrypoints": [ 28 | "generate.ts", 29 | "serialize.ts" 30 | ] 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /docs/generate-magical-types/serialize/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "main": "dist/react-select-generate-magical-types-serialize.cjs.js", 3 | "module": "dist/react-select-generate-magical-types-serialize.esm.js" 4 | } 5 | -------------------------------------------------------------------------------- /docs/generate-magical-types/src/types.ts: -------------------------------------------------------------------------------- 1 | import { MagicalNode, MagicalNodeIndex } from '@magical-types/types'; 2 | 3 | export type MagicalNodeMetadata = Record< 4 | string, 5 | Record<string, MagicalNodeRecord> 6 | >; 7 | 8 | export type MagicalNodeRecord = { 9 | type: 'component' | 'other'; 10 | index: MagicalNodeIndex; 11 | }; 12 | 13 | export type MagicalNodesForPackage = Record< 14 | string, 15 | { type: 'component' | 'other'; node: MagicalNode } 16 | >; 17 | 18 | export type MagicalNodes = Record<string, MagicalNodesForPackage>; 19 | -------------------------------------------------------------------------------- /docs/index.css: -------------------------------------------------------------------------------- 1 | @import url('https://fonts.googleapis.com/css?family=Roboto+Mono|Roboto:400,500,700'); 2 | 3 | body { 4 | -moz-font-feature-settings: 'liga' on; 5 | -moz-osx-font-smoothing: grayscale; 6 | -webkit-font-smoothing: antialiased; 7 | color: #253858; 8 | font-family: 'Roboto', -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 9 | Helvetica, sans-serif; 10 | font-style: normal; 11 | font-weight: 400; 12 | margin: 0; 13 | padding: 0; 14 | text-rendering: optimizeLegibility; 15 | } 16 | p > a, 17 | p > a:hover, 18 | p > a:visited, 19 | li > a, 20 | li > a:hover, 21 | li > a:visited { 22 | color: #2684ff; 23 | } 24 | code { 25 | font-family: Roboto Mono, Monaco, monospace; 26 | } 27 | p > code { 28 | white-space: nowrap; 29 | } 30 | p, 31 | ul, 32 | ol { 33 | line-height: 1.5; 34 | } 35 | td p { 36 | margin: 0; 37 | } 38 | h1, 39 | h2, 40 | h3, 41 | h4, 42 | h5 { 43 | color: #091e42; 44 | } 45 | h6 { 46 | color: #777; 47 | margin-bottom: 0.25em; 48 | text-transform: uppercase; 49 | } 50 | @keyframes dropIn { 51 | from, 52 | 60%, 53 | 75%, 54 | 90%, 55 | to { 56 | animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1); 57 | } 58 | 0% { 59 | opacity: 0; 60 | transform: translate3d(0, -1666px, 0); 61 | } 62 | 60% { 63 | opacity: 1; 64 | transform: translate3d(0, 26px, 0); 65 | } 66 | 75% { 67 | transform: translate3d(0, -10px, 0); 68 | } 69 | 90% { 70 | transform: translate3d(0, 6px, 0); 71 | } 72 | to { 73 | transform: translate3d(0, 0, 0); 74 | } 75 | } 76 | .animate-dropin { 77 | animation: dropIn 0.66s; 78 | } 79 | -------------------------------------------------------------------------------- /docs/index.html: -------------------------------------------------------------------------------- 1 | <!DOCTYPE html> 2 | <head> 3 | <meta charset="utf-8" /> 4 | <title>React-Select 5 | 9 | 13 | 17 | 18 | 19 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 33 | 42 | 46 | 47 | 48 |
49 | 50 | 51 | -------------------------------------------------------------------------------- /docs/index.tsx: -------------------------------------------------------------------------------- 1 | import '@babel/polyfill'; 2 | import React from 'react'; 3 | import ReactDOM from 'react-dom'; 4 | import App from './App'; 5 | 6 | ReactDOM.render(, document.getElementById('root')); 7 | -------------------------------------------------------------------------------- /docs/isArray.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Alternative to Array.isArray that correctly narrows the type for readonly arrays. 3 | */ 4 | export default function isArray(arg: unknown): arg is readonly T[] { 5 | return Array.isArray(arg); 6 | } 7 | -------------------------------------------------------------------------------- /docs/markdown/store.ts: -------------------------------------------------------------------------------- 1 | export interface Data { 2 | key: string; 3 | label: string; 4 | level: number; 5 | path: string; 6 | } 7 | 8 | class HeadingStore { 9 | store: { [key: string]: Data } = {}; 10 | headings: { [key: string]: Data[] } = {}; 11 | 12 | add(key: string, data: Data) { 13 | console.log('add being called with', data.label); 14 | if (!this.headings[location.pathname]) { 15 | this.headings[location.pathname] = []; 16 | } 17 | 18 | if (!this.store[key]) { 19 | this.store[key] = data; 20 | this.headings[location.pathname].push(data); 21 | } 22 | } 23 | getStore() { 24 | return this.store; 25 | } 26 | getPageHeadings(page: string) { 27 | return this.headings[page]; 28 | } 29 | getAllHeadings() { 30 | return this.headings; 31 | } 32 | getHeadingByKey(key: string) { 33 | return this.store[key]; 34 | } 35 | } 36 | 37 | // global heading store 38 | const store = new HeadingStore(); 39 | 40 | export default store; 41 | -------------------------------------------------------------------------------- /docs/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es6", 4 | "module": "commonjs", 5 | "jsx": "react", 6 | "noEmit": true, 7 | "strict": true, 8 | "esModuleInterop": true, 9 | "forceConsistentCasingInFileNames": true, 10 | "resolveJsonModule": true 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /docs/utils.ts: -------------------------------------------------------------------------------- 1 | import { useEffect, useState } from 'react'; 2 | import { MagicalNode, MagicalNodeIndex } from '@magical-types/types'; 3 | import { deserialize } from '@magical-types/serialization/deserialize'; 4 | 5 | import type { MagicalNodeMetadata } from './generate-magical-types/src/types'; 6 | // @ts-ignore 7 | import manifest from './magical-types/magical-types-manifest.json'; 8 | 9 | export type getNodeType = 10 | | ((index: MagicalNodeIndex) => MagicalNode) 11 | | undefined; 12 | 13 | let getNode: getNodeType; 14 | 15 | export const metadata: MagicalNodeMetadata = (manifest as any).types; 16 | 17 | export function useMagicalNodes() { 18 | let [, forceUpdate] = useState(0); 19 | 20 | useEffect(() => { 21 | if (!getNode) { 22 | fetch(manifest.paths[0]) 23 | .then((x) => x.json()) 24 | .then((firstNodeGroup) => { 25 | getNode = deserialize([ 26 | firstNodeGroup, 27 | ...(manifest.paths as string[]) 28 | .slice(1) 29 | .map((path) => () => fetch(path).then((x) => x.json())), 30 | ]); 31 | forceUpdate(1); 32 | }); 33 | } 34 | }, []); 35 | return getNode; 36 | } 37 | -------------------------------------------------------------------------------- /docs/webpack.config.ts: -------------------------------------------------------------------------------- 1 | import * as path from 'path'; 2 | import * as webpack from 'webpack'; 3 | import CopyWebpackPlugin from 'copy-webpack-plugin'; 4 | import HtmlWebpackPlugin from 'html-webpack-plugin'; 5 | import ForkTsCheckerWebpackPlugin from 'fork-ts-checker-webpack-plugin'; 6 | import { config } from 'dotenv'; 7 | import { CleanWebpackPlugin } from 'clean-webpack-plugin'; 8 | 9 | config(); 10 | 11 | const webpackConfig: webpack.Configuration = { 12 | context: __dirname, 13 | entry: { 14 | index: './index', 15 | }, 16 | output: { 17 | path: path.resolve(__dirname, 'dist'), 18 | filename: '[name].js', 19 | publicPath: '/', 20 | }, 21 | devServer: { 22 | port: 8000, 23 | historyApiFallback: true, 24 | }, 25 | // devtool: 'source-map', 26 | devtool: 'cheap-module-eval-source-map', 27 | resolve: { 28 | extensions: ['.ts', '.tsx', '.js', '.jsx', '.json'], 29 | }, 30 | module: { 31 | rules: [ 32 | { 33 | test: /\.(ts|js)x?$/, 34 | exclude: [/node_modules/], 35 | use: [ 36 | { 37 | loader: 'babel-loader', 38 | options: { 39 | root: path.join(__dirname, '..'), 40 | }, 41 | }, 42 | ], 43 | }, 44 | { 45 | test: /\.css$/, 46 | use: [{ loader: 'style-loader' }, { loader: 'css-loader' }], 47 | }, 48 | ], 49 | }, 50 | plugins: [ 51 | // new webpack.DefinePlugin({ 52 | // 'process.env.CLIENT_ID': `'${process.env.CLIENT_ID}'`, 53 | // 'process.env.CLIENT_SECRET': `'${process.env.CLIENT_SECRET}'`, 54 | // }), 55 | new CleanWebpackPlugin(), 56 | new HtmlWebpackPlugin({ 57 | filename: 'index.html', 58 | inject: false, 59 | template: path.resolve(__dirname, 'index.html'), 60 | }), 61 | new CopyWebpackPlugin([ 62 | '_redirects', 63 | 'favicon.ico', 64 | 'index.css', 65 | 'magical-types/*', 66 | ]), 67 | new ForkTsCheckerWebpackPlugin({ 68 | async: false, 69 | typescript: { 70 | configFile: './tsconfig.json', 71 | }, 72 | }), 73 | ], 74 | }; 75 | 76 | export default webpackConfig; 77 | -------------------------------------------------------------------------------- /netlify.toml: -------------------------------------------------------------------------------- 1 | [build] 2 | command = "yarn build:docs" 3 | publish = "docs/dist" 4 | 5 | [build.environment] 6 | YARN_VERSION = "1.22.22" 7 | -------------------------------------------------------------------------------- /packages/react-select/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2022 Jed Watson 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /packages/react-select/animated/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "main": "dist/react-select-animated.cjs.js", 3 | "module": "dist/react-select-animated.esm.js", 4 | "types": "dist/react-select-animated.cjs.d.ts" 5 | } 6 | -------------------------------------------------------------------------------- /packages/react-select/async-creatable/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "main": "dist/react-select-async-creatable.cjs.js", 3 | "module": "dist/react-select-async-creatable.esm.js", 4 | "types": "dist/react-select-async-creatable.cjs.d.ts" 5 | } 6 | -------------------------------------------------------------------------------- /packages/react-select/async/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "main": "dist/react-select-async.cjs.js", 3 | "module": "dist/react-select-async.esm.js", 4 | "types": "dist/react-select-async.cjs.d.ts" 5 | } 6 | -------------------------------------------------------------------------------- /packages/react-select/base/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "main": "dist/react-select-base.cjs.js", 3 | "module": "dist/react-select-base.esm.js", 4 | "types": "dist/react-select-base.cjs.d.ts" 5 | } 6 | -------------------------------------------------------------------------------- /packages/react-select/creatable/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "main": "dist/react-select-creatable.cjs.js", 3 | "module": "dist/react-select-creatable.esm.js", 4 | "types": "dist/react-select-creatable.cjs.d.ts" 5 | } 6 | -------------------------------------------------------------------------------- /packages/react-select/src/Async.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { 3 | forwardRef, 4 | MutableRefObject, 5 | ReactElement, 6 | RefAttributes, 7 | } from 'react'; 8 | import Select from './Select'; 9 | import { GroupBase } from './types'; 10 | import useStateManager from './useStateManager'; 11 | import useAsync from './useAsync'; 12 | import type { AsyncProps } from './useAsync'; 13 | export type { AsyncProps }; 14 | 15 | type AsyncSelect = < 16 | Option = unknown, 17 | IsMulti extends boolean = false, 18 | Group extends GroupBase