Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[RFR] New AutocompleteArrayInput #3667

Merged
merged 6 commits into from
Sep 12, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 24 additions & 3 deletions UPGRADE.md
Original file line number Diff line number Diff line change
Expand Up @@ -891,11 +891,11 @@ const PostFilter = props =>
</Filter>;
```

## Complete rewrite of the AutocompleteInput component
## Complete rewrite of the AutocompleteInput and AutocompleteArrayInput components

We rewrote the `<AutocompleteInput>` component from scratch using [`downshift`](https://github.com/downshift-js/downshift), while the previous version was based on [react-autosuggest](http://react-autosuggest.js.org/). The new `<AutocompleteInput>` component is more robust and more future-proof, and its API didn't change.
We rewrote the `<AutocompleteInput>` and `<AutocompleteArrayInput>` components from scratch using [`downshift`](https://github.com/downshift-js/downshift), while the previous version was based on [react-autosuggest](http://react-autosuggest.js.org/). The new components are more robust and more future-proof, and their API didn't change.

There are two breaking changes in the new `<AutocompleteInput>`:
There are two breaking changes in the new `<AutocompleteInput>` and `<AutocompleteArrayInput>` components:

- The `inputValueMatcher` prop is gone. We removed a feature many found confusing: the auto-selection of an item when it was matched exactly. So react-admin no longer selects anything automatically, therefore the `inputValueMatcher` prop is obsolete

Expand All @@ -904,6 +904,10 @@ There are two breaking changes in the new `<AutocompleteInput>`:
source="role"
- inputValueMatcher={() => null}
/>
<AutocompleteArrayInput
source="role"
- inputValueMatcher={() => null}
/>
```

- Specific [`react-autosuggest` props](https://github.com/moroshko/react-autosuggest#props) (like `onSuggestionsFetchRequested`, `theme`, or `highlightFirstSuggestion`) are no longer supported, because the component now passes extra props to a `<Downshift>` component.
Expand All @@ -913,6 +917,23 @@ There are two breaking changes in the new `<AutocompleteInput>`:
source="role"
- highlightFirstSuggestion={true}
/>
<AutocompleteArrayInput
source="role"
- highlightFirstSuggestion={true}
/>
```

Besides, some props which were applicable to both components did not make sense for the `<AutocompleteArrayInput>` component:

- `allowEmpty`: As the `<AutocompleteArrayInput>` deals with arrays, it does not make sense to add an empty choice. This prop is no longer accepted and will be ignored.
- `limitChoicesToValue`: As the `<AutocompleteArrayInput>` deals with arrays and only accepts unique items, it does not make sense to show only the already selected items. This prop is no longer accepted and will be ignored.

```diff
<AutocompleteArrayInput
source="role"
- allowEmpty={true}
- limitChoicesToValue={true}
/>
```

## The `exporter` function has changed signature
Expand Down
31 changes: 3 additions & 28 deletions docs/Inputs.md
Original file line number Diff line number Diff line change
Expand Up @@ -165,19 +165,6 @@ In that case, set the `translateChoice` prop to false.
<AutocompleteInput source="gender" choices={choices} translateChoice={false}/>
```

By default the component matches choices with the current input searchText: if it finds a match, this choice will be selected.
For example, given the choices `[{ id: 'M', name: 'Male', id: 'F', name: 'Female' }]`, when the user enters the text `male`, then the component will set the input value to `M`.
If you need to change how choices are matched, pass a custom function as `inputValueMatcher` prop.
For example, given the choices: `[{id:1,iso2:'NL',name:'Dutch'},{id:2,iso2:'EN',name:'English'},{id:3,iso2:'FR',name:'French'}]`, if you want to match choices on the iso2 code, you can create the following `inputValueMatcher` function:

```javascript
<AutocompleteInput inputValueMatcher={
(input, suggestion, getOptionText) =>
input.toUpperCase().trim() === suggestion.iso2 ||
input.toLowerCase().trim() === getOptionText(suggestion).toLowerCase().trim()
}/>
```

If you want to limit the initial choices shown to the current value only, you can set the `limitChoicesToValue` prop.

When dealing with a large amount of `choices` you may need to limit the number of suggestions that are rendered in order to maintain usable performance. The `shouldRenderSuggestions` is an optional prop that allows you to set conditions on when to render suggestions. An easy way to improve performance would be to skip rendering until the user has entered 2 or 3 characters in the search box. This lowers the result set significantly, and might be all you need (depending on your data set).
Expand Down Expand Up @@ -232,7 +219,9 @@ Lastly, would you need to override the props of the suggestions container (a `Po

## `<AutocompleteArrayInput>`

To let users choose multiple values in a list using a dropdown with autocompletion, use `<AutocompleteArrayInput>`. It renders using [material-ui-chip-input](https://github.com/TeamWertarbyte/material-ui-chip-input), [react-autosuggest](http://react-autosuggest.js.org/) and a `fuzzySearch` filter. Set the `choices` attribute to determine the options list (with `id`, `name` tuples).
To let users choose multiple values in a list using a dropdown with autocompletion, use `<AutocompleteArrayInput>`.
It renders using [downshift](https://github.com/downshift-js/downshift) and a `fuzzySearch` filter.
Set the `choices` attribute to determine the options list (with `id`, `name` tuples).

```jsx
import { AutocompleteArrayInput } from 'react-admin';
Expand Down Expand Up @@ -280,18 +269,6 @@ However, in some cases (e.g. inside a `<ReferenceInput>`), you may not want the
<AutocompleteArrayInput source="gender" choices={choices} translateChoice={false}/>
```

By default the component matches choices with the current input searchText. For example, given the choices `[{ id: 'M', name: 'Male', id: 'F', name: 'Female' }]`, when the user enters the text `male`, then the component will set the input value to `M`. If you need to change how choices are matched, pass a custom function as `inputValueMatcher` prop. For example, given the choices: `[{id:1,iso2:'NL',name:'Dutch'},{id:2,iso2:'EN',name:'English'},{id:3,iso2:'FR',name:'French'}]`, if you want to match choices on the iso2 code, you can create the following `inputValueMatcher` function:

```javascript
<AutocompleteArrayInput inputValueMatcher={
(input, suggestion, getOptionText) =>
input.toUpperCase().trim() === suggestion.iso2 ||
input.toLowerCase().trim() === getOptionText(suggestion).toLowerCase().trim()
}/>
```

If you want to limit the initial choices shown to the current value only, you can set the `limitChoicesToValue` prop.

When dealing with a large amount of `choices` you may need to limit the number of suggestions that are rendered in order to maintain usable performance. The `shouldRenderSuggestions` is an optional prop that allows you to set conditions on when to render suggestions. An easy way to improve performance would be to skip rendering until the user has entered 2 or 3 characters in the search box. This lowers the result set significantly, and might be all you need (depending on your data set).
Ex. `<AutocompleteArrayInput shouldRenderSuggestions={(val) => { return val.trim().length > 2 }} />` would not render any suggestions until the 3rd character was entered. This prop is passed to the underlying `react-autosuggest` component and is documented [here](https://github.com/moroshko/react-autosuggest#should-render-suggestions-prop).

Expand Down Expand Up @@ -338,8 +315,6 @@ If you need to override the props of the suggestions container (a `Popper` eleme
| `choices` | Required | `Object[]` | - | List of items to autosuggest |
| `resource` | Required | `string` | - | The resource working on. This field is passed down by wrapped components like `Create` and `Edit`. |
| `source` | Required | `string` | - | Name of field to edit, its type should match the type retrieved from `optionValue` |
| `allowEmpty` | Optional | `boolean` | `false` | If `false` and the searchText typed did not match any suggestion, the searchText will revert to the current value when the field is blurred. If `true` and the `searchText` is set to `''` then the field will set the input value to `null`. |
| `inputValueMatcher` | Optional | `Function` | `(input, suggestion, getOptionText) => input.toLowerCase().trim() === getOptionText(suggestion).toLowerCase().trim()` | Allows to define how choices are matched with the searchText while typing. |
| `optionValue` | Optional | `string` | `id` | Fieldname of record containing the value to use as input value |
| `optionText` | Optional | <code>string &#124; Function</code> | `name` | Fieldname of record to display in the suggestion item or function which accepts the current record as argument (`(record)=> {string}`) |
| `setFilter` | Optional | `Function` | null | A callback to inform the `searchText` has changed and new `choices` can be retrieved based on this `searchText`. Signature `searchText => void`. This function is automatically setup when using `ReferenceInput`. |
Expand Down
2 changes: 0 additions & 2 deletions packages/ra-ui-materialui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -55,10 +55,8 @@
"inflection": "~1.12.0",
"jsonexport": "^2.4.1",
"lodash": "~4.17.5",
"material-ui-chip-input": "1.0.0",
"prop-types": "^15.6.1",
"ra-core": "^3.0.0-alpha.4",
"react-autosuggest": "^9.4.2",
"react-dropzone": "^10.1.7",
"react-final-form": "^6.3.0",
"react-final-form-arrays": "^3.1.1",
Expand Down
Loading