Skip to content

Commit

Permalink
Merge pull request #4340 from JedWatson/#3006-Documentation-Additions…
Browse files Browse the repository at this point in the history
…-and-Revisions

#3006: Documentation clarifications and Defining Components section
  • Loading branch information
JedWatson authored Jan 13, 2021
2 parents ef2d357 + 9c4dec3 commit 500398d
Show file tree
Hide file tree
Showing 5 changed files with 126 additions and 2 deletions.
50 changes: 50 additions & 0 deletions docs/examples/CustomSelectProps.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import React, { useState } from 'react';
import Select, { components } from 'react-select';
import { colourOptions } from '../data';

const EMOJIS = ['👍', '🤙', '👏', '👌', '🙌', '✌️', '🖖', '👐'];

const Control = ({ children, ...props }) => {
const { emoji, onEmojiClick } = props.selectProps;
const style = { cursor: 'pointer' };

return (
<components.Control {...props}>
<span onMouseDown={onEmojiClick} style={style}>
{emoji}
</span>
{children}
</components.Control>
);
};

const CustomSelectProps = props => {
const [clickCount, setClickCount] = useState(0);

const onClick = e => {
setClickCount(clickCount + 1);
e.preventDefault();
e.stopPropagation();
};

const styles = {
control: css => ({ ...css, paddingLeft: '1rem' }),
};

const emoji = EMOJIS[clickCount % EMOJIS.length];

return (
<Select
{...props}
emoji={emoji}
onEmojiClick={onClick}
components={{ Control }}
isSearchable
name="emoji"
options={colourOptions}
styles={styles}
/>
);
};

export default CustomSelectProps;
1 change: 1 addition & 0 deletions docs/examples/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ export { default as CreatableInputOnly } from './CreatableInputOnly';
export { default as CreateFilter } from './CreateFilter';
export { default as CreatableMulti } from './CreatableMulti';
export { default as CreatableSingle } from './CreatableSingle';
export { default as CustomSelectProps } from './CustomSelectProps';
export { default as CustomClearIndicator } from './CustomClearIndicator';
export { default as CustomDropdownIndicator } from './CustomDropdownIndicator';
export { default as CustomLoadingIndicator } from './CustomLoadingIndicator';
Expand Down
20 changes: 19 additions & 1 deletion docs/pages/advanced/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,15 @@ export default function Advanced() {
React-Select exports a createFilter function that returns a filterOption method. By using this, users can pick and choose bits of the filtration logic to customise,
without having to rewrite the logic wholesale.
~~~jsx
// default filter configuration
ignoreCase: true,
ignoreAccents: true,
matchFrom: 'any',
stringify: option => \`\${option.label} \${option.value}\`,
trim: true,
~~~
Below is an example of how you could use the createFilter function to customise filtration logic in react-select.
${(
Expand All @@ -78,6 +87,15 @@ export default function Advanced() {
<CustomFilterOptions />
</ExampleWrapper>
)}
~~~jsx
~~~
> Please note that if you are using a Select that is creatable, you would also likey want to include the "Create" option.
~~~jsx
const filterOption = (candidate, input) => {
return candidate.data.__isNew__ || candidate.label.includes(input);
};
~~~
## Replacing builtins
For a list of builtins that we expose, please see the API docs [here](/props#prop-types).
Expand Down Expand Up @@ -161,7 +179,7 @@ export default function Advanced() {
By explicitly passing you what type of change event has been fired, we allow you to have more granular control
over how the select behaves after an onChange even is fired.
Below is an example of replicating the behaviour supported by the (deprecated) onSelectResetsInput and (deprecated) closeMenuOnSelect props in react-select v1
Below is an example of replicating the behaviour of the deprecated props from react-select v1, onSelectResetsInput and closeOnSelect
${(
<ExampleWrapper
Expand Down
55 changes: 55 additions & 0 deletions docs/pages/components/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { Helmet } from 'react-helmet';
import md from '../../markdown/renderer';
import ExampleWrapper from '../../ExampleWrapper';
import {
CustomSelectProps,
CustomClearIndicator,
CustomDropdownIndicator,
CustomLoadingIndicator,
Expand Down Expand Up @@ -125,6 +126,60 @@ export default function Components() {
~~~
## Defining components
When defining replacement components, it is important to do so __outside__ the scope of
rendering the Select. Defining a replacement component directly in the components prop can
cause issues.
On this topic, React
[documentation](https://reactjs.org/docs/higher-order-components.html#dont-use-hocs-inside-the-render-method)
has the following to say:
> The problem here isn’t just about performance — remounting a component causes the state
of that component and all of its children to be lost.
This statement applies as well when replacing components in react-select with inline definitions.
~~~jsx
// Bad: Inline declaration will cause remounting issues
const BadSelect = props => (
<Select {...props} components={{
Control: ({ children, ...rest }) => (
<components.Control {...rest}>
👎 {children}
</components.Control>
)}}
/>
)
// Good: Custom component declared outside of the Select scope
const Control = props => ({ children, ...rest }) => (
<components.Control {...rest}>
👍 {children}
</components.Control>
);
const GoodSelect = props => <Select {...props} components={{ Control }} />
~~~
There will likely be times that data or methods may need to be shared,
but this can be achieved with the \`selectProps\` prop passed to each component.
${(
<ExampleWrapper
label="Custom Component with selectProps Example"
urlPath="docs/examples/CustomSelectProps.js"
raw={require('!!raw-loader!../../examples/CustomSelectProps.js')}
>
<CustomSelectProps />
</ExampleWrapper>
)}
~~~
~~~
## Adjusting the Styling
The \`styles\` prop allows you to pass styles to a particular component, without
Expand Down
2 changes: 1 addition & 1 deletion packages/react-select/src/Select.js
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ export type Props = {
'aria-labelledby'?: string,
/* Focus the control when it is mounted */
autoFocus?: boolean,
/* Remove the currently focused option when the user presses backspace */
/* Remove the currently focused option when the user presses backspace when Select isClearable or isMulti */
backspaceRemovesValue: boolean,
/* Remove focus from the input when the user selects an option (handy for dismissing the keyboard on touch devices) */
blurInputOnSelect: boolean,
Expand Down

0 comments on commit 500398d

Please sign in to comment.