diff --git a/CHANGELOG.md b/CHANGELOG.md index 003671c00..62b584562 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,9 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ## [Unreleased] +### Added +- Add scroll on Autocompleteinput + ## [9.146.9] - 2023-06-07 ## [9.146.8] - 2023-06-01 @@ -4189,4 +4192,4 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. [9.146.7]: https://github.com/vtex/styleguide/compare/v9.146.6...v9.146.7 [9.146.6]: https://github.com/vtex/styleguide/compare/v9.146.5...v9.146.6 [9.146.5]: https://github.com/vtex/styleguide/compare/v9.146.4...v9.146.5 -[9.146.4]: https://github.com/vtex/styleguide/compare/v9.146.3...v9.146.4 \ No newline at end of file +[9.146.4]: https://github.com/vtex/styleguide/compare/v9.146.3...v9.146.4 diff --git a/react/components/AutocompleteInput/README.md b/react/components/AutocompleteInput/README.md index 2b6f05646..5d4742f3a 100644 --- a/react/components/AutocompleteInput/README.md +++ b/react/components/AutocompleteInput/README.md @@ -135,6 +135,99 @@ const UsersAutocomplete = () => { ; ``` +#### Defined height with scroll + +```jsx +import { uniq } from 'lodash' +import { useState, useRef } from 'react' + +const allUsers = [ + 'Ana Clara', + 'Ana Luiza', + 'Carlos', + 'Daniela', + 'Beatriz', + 'Bruno', + 'Camila', + 'Diego', + 'Eduardo', + 'Fernanda', + 'Gabriel', + 'Heloisa', + 'Igor', + 'Juliana', + 'Kaique', + 'Larissa', + 'Marcos', + 'Natália', + 'Otávio', + 'Patrícia', + 'Renato', + 'Sabrina', + 'Thiago', + 'Vanessa', + 'Wagner', + 'Xavier', + 'Yasmin', + 'Zeca', + 'Adriana', + 'Bernardo' +]; + +const UsersAutocomplete = () => { + const [term, setTerm] = useState('') + const [loading, setLoading] = useState(false) + const [lastSearched, setLastSearched] = useState([]) + const timeoutRef = useRef(null) + + const options = { + onSelect: (...args) => console.log('onSelect: ', ...args), + loading, + value: !term.length + ? [] + : allUsers.filter(user => + typeof user === 'string' + ? user.toLowerCase().includes(term.toLowerCase()) + : user.label.toLowerCase().includes(term.toLowerCase()) + ), + // --- This is what makes the Last Searched Terms work! + // This can be stored anywhere the dev wants. To be persistent, for example. + lastSearched: { + value: lastSearched, + label: 'Last searched users', + onChange: option => + option && setLastSearched(uniq([...lastSearched, option])), + }, + maxHeight: 300, + } + + const input = { + onChange: term => { + if (term) { + setLoading(true) + if (timeoutRef.current) { + clearTimeout(timeoutRef.current) + } + timeoutRef.current = setTimeout(() => { + setLoading(false) + setTerm(term) + timeoutRef.current = null + }, 1000) + } else { + setTerm(term) + } + }, + onSearch: (...args) => console.log('onSearch:', ...args), + onClear: () => setTerm(''), + placeholder: 'Search user... (e.g.: Ana)', + value: term, + } + return +} + +; +``` + #### Custom option rendering ```jsx diff --git a/react/components/AutocompleteInput/__snapshots__/index.test.tsx.snap b/react/components/AutocompleteInput/__snapshots__/index.test.tsx.snap index 62ffa4437..3db96b2a4 100644 --- a/react/components/AutocompleteInput/__snapshots__/index.test.tsx.snap +++ b/react/components/AutocompleteInput/__snapshots__/index.test.tsx.snap @@ -47,6 +47,53 @@ exports[`AutocompleteInput should render a regular version of search bar if size `; +exports[`AutocompleteInput should render with a 300px max height 1`] = ` + +
+
+ + +
+
+
+ +`; + exports[`AutocompleteInput should render with a large size bar 1`] = `
{ expect(result).toMatchSnapshot() }) + it('should render with a 300px max height', () => { + const options = { + onSelect: () => `''`, + loading: false, + value: [], + maxHeight: 300, + } + + const input = { + onChange: () => `''`, + onSearch: () => `''`, + onClear: () => `''`, + placeholder: '', + value: '', + } + + const { asFragment } = render( + + ) + + const result = asFragment() + + expect(result).toMatchSnapshot() + }) + it('should render with a regular size bar', () => { const options = { onSelect: () => `''`, @@ -108,7 +133,7 @@ describe('AutocompleteInput', () => { onSelect: () => `''`, loading: false, value: [], - size: 'medium', + size: 'regular', } const input = { diff --git a/react/components/AutocompleteInput/index.tsx b/react/components/AutocompleteInput/index.tsx index 7f985935e..0979950f6 100644 --- a/react/components/AutocompleteInput/index.tsx +++ b/react/components/AutocompleteInput/index.tsx @@ -9,6 +9,7 @@ import Option, { getTermFromOption, } from './Option' import SearchInput from './SearchInput' +import styles from './autocomplete.css' const propTypes = { /** Input props. All HTMLInput props can be added too */ @@ -92,6 +93,11 @@ const propTypes = { * It can be a warning, an error, or a hint about the options. */ customMessage: PropTypes.node, + /** + * Max height value for options dropdown. + * `fit-content` is the default value. + */ + maxHeight: PropTypes.number, }).isRequired, } @@ -124,6 +130,7 @@ const AutocompleteInput: React.FunctionComponent = ({ icon, size, customMessage, + maxHeight = 'fit-content', }, }) => { const [term, setTerm] = useState(value || '') @@ -261,7 +268,7 @@ const AutocompleteInput: React.FunctionComponent = ({ const errorStyle = error || Boolean(errorMessage) return ( -
+
= ({ />
{popoverOpened ? ( -
+
{renderOptions()} {loading && (