Skip to content

Commit 4c6e446

Browse files
polish :)
1 parent 1a00008 commit 4c6e446

File tree

7 files changed

+82
-77
lines changed

7 files changed

+82
-77
lines changed

docs/pages/api-docs/autocomplete.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,18 +41,19 @@ You can learn more about the difference by [reading this guide](/guides/minimizi
4141
| <span class="prop-name">disabled</span> | <span class="prop-type">bool</span> | <span class="prop-default">false</span> | If `true`, the input will be disabled. |
4242
| <span class="prop-name">disableListWrap</span> | <span class="prop-type">bool</span> | <span class="prop-default">false</span> | If `true`, the list box in the popup will not wrap focus. |
4343
| <span class="prop-name">disablePortal</span> | <span class="prop-type">bool</span> | <span class="prop-default">false</span> | Disable the portal behavior. The children stay within it's parent DOM hierarchy. |
44-
| <span class="prop-name">filterMaxTags</span> | <span class="prop-type">number</span> | | The number of tags that will be visible. Set `-1` to display them all. |
4544
| <span class="prop-name">filterOptions</span> | <span class="prop-type">func</span> | | A filter function that determines the options that are eligible.<br><br>**Signature:**<br>`function(options: T[], state: object) => undefined`<br>*options:* The options to render.<br>*state:* The state of the component. |
4645
| <span class="prop-name">filterSelectedOptions</span> | <span class="prop-type">bool</span> | <span class="prop-default">false</span> | If `true`, hide the selected options from the list box. |
4746
| <span class="prop-name">forcePopupIcon</span> | <span class="prop-type">'auto'<br>&#124;&nbsp;bool</span> | <span class="prop-default">'auto'</span> | Force the visibility display of the popup icon. |
4847
| <span class="prop-name">freeSolo</span> | <span class="prop-type">bool</span> | <span class="prop-default">false</span> | If `true`, the Autocomplete is free solo, meaning that the user input is not bound to provided options. |
48+
| <span class="prop-name">getLimitTagsText</span> | <span class="prop-type">func</span> | <span class="prop-default">(more) => `+${more}`</span> | The label to display when the tags are truncated (`limitTags`).<br><br>**Signature:**<br>`function(more: any) => ReactNode`<br>*more:* The number of truncated tags. |
4949
| <span class="prop-name">getOptionDisabled</span> | <span class="prop-type">func</span> | | Used to determine the disabled state for a given option. |
5050
| <span class="prop-name">getOptionLabel</span> | <span class="prop-type">func</span> | <span class="prop-default">(x) => x</span> | Used to determine the string value for a given option. It's used to fill the input (and the list box options if `renderOption` is not provided). |
5151
| <span class="prop-name">getOptionSelected</span> | <span class="prop-type">func</span> | | Used to determine if an option is selected. Uses strict equality by default. |
5252
| <span class="prop-name">groupBy</span> | <span class="prop-type">func</span> | | If provided, the options will be grouped under the returned string. The groupBy value is also used as the text for group headings when `renderGroup` is not provided.<br><br>**Signature:**<br>`function(options: T) => string`<br>*options:* The option to group. |
5353
| <span class="prop-name">id</span> | <span class="prop-type">string</span> | | This prop is used to help implement the accessibility logic. If you don't provide this prop. It falls back to a randomly generated id. |
5454
| <span class="prop-name">includeInputInList</span> | <span class="prop-type">bool</span> | <span class="prop-default">false</span> | If `true`, the highlight can move to the input. |
5555
| <span class="prop-name">inputValue</span> | <span class="prop-type">string</span> | | The input value. |
56+
| <span class="prop-name">limitTags</span> | <span class="prop-type">number</span> | <span class="prop-default">-1</span> | The maximum number of tags that will be visible when not focused. Set `-1` to disable the limit. |
5657
| <span class="prop-name">ListboxComponent</span> | <span class="prop-type">elementType</span> | <span class="prop-default">'ul'</span> | The component used to render the listbox. |
5758
| <span class="prop-name">ListboxProps</span> | <span class="prop-type">object</span> | | Props applied to the Listbox element. |
5859
| <span class="prop-name">loading</span> | <span class="prop-type">bool</span> | <span class="prop-default">false</span> | If `true`, the component is in a loading state. |

docs/src/pages/components/autocomplete/FilterMaxTags.js renamed to docs/src/pages/components/autocomplete/LimitTags.js

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,29 +4,32 @@ import Autocomplete from '@material-ui/lab/Autocomplete';
44
import { makeStyles } from '@material-ui/core/styles';
55
import TextField from '@material-ui/core/TextField';
66

7-
const useStyles = makeStyles((theme) => ({
8-
root: {
9-
width: 500,
10-
'& > * + *': {
11-
marginTop: theme.spacing(3),
7+
const useStyles = makeStyles(
8+
(theme) => ({
9+
root: {
10+
width: 500,
11+
'& > * + *': {
12+
marginTop: theme.spacing(3),
13+
},
1214
},
13-
},
14-
}));
15+
}),
16+
Ò,
17+
);
1518

16-
export default function FilterMaxTags() {
19+
export default function LimitTags() {
1720
const classes = useStyles();
1821

1922
return (
2023
<div className={classes.root}>
2124
<Autocomplete
2225
multiple
23-
filterMaxTags={2}
26+
limitTags={2}
2427
id="tags-standard"
2528
options={top100Films}
2629
getOptionLabel={(option) => option.title}
2730
defaultValue={[top100Films[13], top100Films[12], top100Films[11]]}
2831
renderInput={(params) => (
29-
<TextField {...params} variant="outlined" label="filterMaxTags" placeholder="Favorites" />
32+
<TextField {...params} variant="outlined" label="limitTags" placeholder="Favorites" />
3033
)}
3134
/>
3235
</div>

docs/src/pages/components/autocomplete/FilterMaxTags.tsx renamed to docs/src/pages/components/autocomplete/LimitTags.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,23 +12,23 @@ const useStyles = makeStyles((theme: Theme) =>
1212
marginTop: theme.spacing(3),
1313
},
1414
},
15-
}),
15+
}),Ò
1616
);
1717

18-
export default function FilterMaxTags() {
18+
export default function LimitTags() {
1919
const classes = useStyles();
2020

2121
return (
2222
<div className={classes.root}>
2323
<Autocomplete
2424
multiple
25-
filterMaxTags={2}
25+
limitTags={2}
2626
id="tags-standard"
2727
options={top100Films}
2828
getOptionLabel={(option) => option.title}
2929
defaultValue={[top100Films[13], top100Films[12], top100Films[11]]}
3030
renderInput={(params) => (
31-
<TextField {...params} variant="outlined" label="filterMaxTags" placeholder="Favorites" />
31+
<TextField {...params} variant="outlined" label="limitTags" placeholder="Favorites" />
3232
)}
3333
/>
3434
</div>

docs/src/pages/components/autocomplete/autocomplete.md

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -100,12 +100,6 @@ Also known as tags, the user is allowed to enter more than one value.
100100

101101
{{"demo": "pages/components/autocomplete/Tags.js"}}
102102

103-
## Filter Max Tags
104-
105-
Do you want to show only a few tags? Use the `filterMaxTags` prop.
106-
107-
{{"demo": "pages/components/autocomplete/FilterMaxTags.js"}}
108-
109103
### Fixed options
110104

111105
In the event that you need to lock certain tag so that they can't be removed in the interface, you can set the chips disabled.
@@ -116,6 +110,12 @@ In the event that you need to lock certain tag so that they can't be removed in
116110

117111
{{"demo": "pages/components/autocomplete/CheckboxesTags.js"}}
118112

113+
### Limit max tags
114+
115+
You can use the `limitMaxTags` prop to avoid displaying a very long list of options.
116+
117+
{{"demo": "pages/components/autocomplete/LimitMaxTags.js"}}
118+
119119
## Sizes
120120

121121
Fancy smaller inputs? Use the `size` prop.
@@ -149,14 +149,13 @@ import { createFilterOptions } from '@material-ui/lab/Autocomplete';
149149

150150
#### Arguments
151151

152-
1. `config` (_Object_ [optional]):
153-
154-
- `config.ignoreAccents` (_Boolean_ [optional]): Defaults to `true`. Remove diacritics.
155-
- `config.ignoreCase` (_Boolean_ [optional]): Defaults to `true`. Lowercase everything.
156-
- `config.matchFrom` (_'any' | 'start'_ [optional]): Defaults to `'any'`.
157-
- `config.stringify` (_Func_ [optional]): Controls how an option is converted into a string so that it can be matched against the input text fragment.
158-
- `config.trim` (_Boolean_ [optional]): Defaults to `false`. Remove trailing spaces.
159-
- `config.limit` (_Number_ [optional]): Default to null. Limit the number of suggested options to be shown. For example, if `config.limit` is `100`, only the first `100` matching options are shown. It can be useful if a lot of options match and virtualization wasn't set up.
152+
1. `config` (*Object* [optional]):
153+
- `config.ignoreAccents` (*Boolean* [optional]): Defaults to `true`. Remove diacritics.
154+
- `config.ignoreCase` (*Boolean* [optional]): Defaults to `true`. Lowercase everything.
155+
- `config.matchFrom` (*'any' | 'start'* [optional]): Defaults to `'any'`.
156+
- `config.stringify` (*Func* [optional]): Controls how an option is converted into a string so that it can be matched against the input text fragment.
157+
- `config.trim` (*Boolean* [optional]): Defaults to `false`. Remove trailing spaces.
158+
- `config.limit` (*Number* [optional]): Default to null. Limit the number of suggested options to be shown. For example, if `config.limit` is `100`, only the first `100` matching options are shown. It can be useful if a lot of options match and virtualization wasn't set up.
160159

161160
#### Returns
162161

@@ -170,7 +169,7 @@ const filterOptions = createFilterOptions({
170169
stringify: option => option.title,
171170
});
172171

173-
<Autocomplete filterOptions={filterOptions} />;
172+
<Autocomplete filterOptions={filterOptions} />
174173
```
175174

176175
{{"demo": "pages/components/autocomplete/Filter.js", "defaultCodeOpen": false}}
@@ -182,9 +181,10 @@ For richer filtering mechanisms, like fuzzy matching, it's recommended to look a
182181
```jsx
183182
import matchSorter from 'match-sorter';
184183

185-
const filterOptions = (options, { inputValue }) => matchSorter(options, inputValue);
184+
const filterOptions = (options, { inputValue }) =>
185+
matchSorter(options, inputValue);
186186

187-
<Autocomplete filterOptions={filterOptions} />;
187+
<Autocomplete filterOptions={filterOptions} />
188188
```
189189

190190
## Virtualization

packages/material-ui-lab/src/Autocomplete/Autocomplete.d.ts

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,9 +84,12 @@ export interface AutocompleteProps<T>
8484
*/
8585
forcePopupIcon?: true | false | 'auto';
8686
/**
87-
* The number of tags that will be visible. Set `-1` to display them all.
87+
* The label to display when the tags are truncated (`limitTags`).
88+
*
89+
* @param {any} more The number of truncated tags.
90+
* @returns {ReactNode}
8891
*/
89-
filterMaxTags?: number;
92+
getLimitTagsText?: (more: number) => React.ReactNode;
9093
/**
9194
* The component used to render the listbox.
9295
*/
@@ -105,6 +108,11 @@ export interface AutocompleteProps<T>
105108
* For localization purposes, you can use the provided [translations](/guides/localization/).
106109
*/
107110
loadingText?: React.ReactNode;
111+
/**
112+
* The maximum number of tags that will be visible when not focused.
113+
* Set `-1` to disable the limit.
114+
*/
115+
limitTags?: number;
108116
/**
109117
* Text to display when there are no options.
110118
*

packages/material-ui-lab/src/Autocomplete/Autocomplete.js

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -257,19 +257,20 @@ const Autocomplete = React.forwardRef(function Autocomplete(props, ref) {
257257
filterSelectedOptions = false,
258258
forcePopupIcon = 'auto',
259259
freeSolo = false,
260+
getLimitTagsText = (more) => `+${more}`,
260261
getOptionDisabled,
261262
getOptionLabel = (x) => x,
262263
getOptionSelected,
263264
groupBy,
264265
id: idProp,
265266
includeInputInList = false,
266267
inputValue: inputValueProp,
268+
limitTags = -1,
267269
ListboxComponent = 'ul',
268270
ListboxProps,
269271
loading = false,
270272
loadingText = 'Loading…',
271273
multiple = false,
272-
filterMaxTags,
273274
noOptionsText = 'No options',
274275
onChange,
275276
onClose,
@@ -341,11 +342,15 @@ const Autocomplete = React.forwardRef(function Autocomplete(props, ref) {
341342
}
342343
}
343344

344-
if (filterMaxTags && Array.isArray(startAdornment)) {
345-
const more = startAdornment.length - filterMaxTags;
346-
if (filterMaxTags && !focused && more > 0) {
347-
startAdornment = startAdornment.splice(0, filterMaxTags);
348-
startAdornment.push(<span key={filterMaxTags} data-testid="more">{` + ${more} more`}</span>);
345+
if (limitTags && Array.isArray(startAdornment)) {
346+
const more = startAdornment.length - limitTags;
347+
if (limitTags && !focused && more > 0) {
348+
startAdornment = startAdornment.splice(0, limitTags);
349+
startAdornment.push(
350+
<span className={classes.tag} key={startAdornment.length}>
351+
{getLimitTagsText(more)}
352+
</span>,
353+
);
349354
}
350355
}
351356

@@ -581,10 +586,6 @@ Autocomplete.propTypes = {
581586
* The children stay within it's parent DOM hierarchy.
582587
*/
583588
disablePortal: PropTypes.bool,
584-
/**
585-
* The number of tags that will be visible. Set `-1` to display them all.
586-
*/
587-
filterMaxTags: PropTypes.number,
588589
/**
589590
* A filter function that determines the options that are eligible.
590591
*
@@ -605,6 +606,13 @@ Autocomplete.propTypes = {
605606
* If `true`, the Autocomplete is free solo, meaning that the user input is not bound to provided options.
606607
*/
607608
freeSolo: PropTypes.bool,
609+
/**
610+
* The label to display when the tags are truncated (`limitTags`).
611+
*
612+
* @param {any} more The number of truncated tags.
613+
* @returns {ReactNode}
614+
*/
615+
getLimitTagsText: PropTypes.func,
608616
/**
609617
* Used to determine the disabled state for a given option.
610618
*/
@@ -640,6 +648,11 @@ Autocomplete.propTypes = {
640648
* The input value.
641649
*/
642650
inputValue: PropTypes.string,
651+
/**
652+
* The maximum number of tags that will be visible when not focused.
653+
* Set `-1` to disable the limit.
654+
*/
655+
limitTags: PropTypes.number,
643656
/**
644657
* The component used to render the listbox.
645658
*/

packages/material-ui-lab/src/Autocomplete/Autocomplete.test.js

Lines changed: 13 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -97,48 +97,28 @@ describe('<Autocomplete />', () => {
9797
});
9898
});
9999

100-
describe('prop: filterMaxTags', () => {
101-
it('show only the max number of items', () => {
102-
const { queryByTestId, getAllByRole } = render(
103-
<Autocomplete
104-
multiple
105-
filterMaxTags={2}
106-
{...defaultProps}
107-
options={['one', 'two', 'three', 'four']}
108-
defaultValue={['one', 'two', 'three']}
109-
renderInput={params => <TextField {...params} />}
110-
/>,
111-
);
112-
113-
const tags = getAllByRole('button');
114-
expect(queryByTestId('more')).to.be.exist;
115-
expect(tags[0].textContent).to.be.equal('one');
116-
expect(tags[1].textContent).to.be.equal('two');
117-
expect(tags[2].textContent).to.not.be.equal('three');
118-
});
119-
100+
describe('prop: limitTags', () => {
120101
it('show all items on focus', () => {
121-
const { getAllByRole, queryByTestId, getByRole } = render(
102+
const { container, getAllByRole, getByRole } = render(
122103
<Autocomplete
123104
multiple
124-
filterMaxTags={2}
105+
limitTags={2}
125106
{...defaultProps}
126-
options={['one', 'two', 'three', 'four']}
107+
options={['one', 'two', 'three']}
127108
defaultValue={['one', 'two', 'three']}
128-
renderInput={params => <TextField {...params} />}
109+
renderInput={(params) => <TextField {...params} />}
129110
/>,
130111
);
131112

132-
const input = getByRole('textbox');
133-
expect(getAllByRole('button')[2].textContent).to.not.be.equal('three');
134-
expect(queryByTestId('more')).to.exist;
113+
let tags;
114+
tags = getAllByRole('button');
115+
expect(container.textContent).to.equal('onetwo+1');
116+
expect(tags.length).to.be.equal(4);
135117

136-
input.focus();
137-
const tags = getAllByRole('button');
138-
expect(queryByTestId('more')).to.not.exist;
139-
expect(tags[0].textContent).to.be.equal('one');
140-
expect(tags[1].textContent).to.be.equal('two');
141-
expect(tags[2].textContent).to.be.equal('three');
118+
getByRole('textbox').focus();
119+
tags = getAllByRole('button');
120+
expect(container.textContent).to.equal('onetwothree');
121+
expect(tags.length).to.be.equal(5);
142122
});
143123
});
144124

0 commit comments

Comments
 (0)