Skip to content

Commit

Permalink
Feat: Add scroll on autocomplete (#1448)
Browse files Browse the repository at this point in the history
#### What is the purpose of this pull request?

Add a maxHeight property con Autocompleteinput

#### Screenshots or example usage

![Jul-23-2024
19-09-38](https://github.com/user-attachments/assets/0ee03afc-57ce-4d17-95b9-db04cda22ffc)

#### Types of changes

- [ ] Bug fix (a non-breaking change which fixes an issue)
- [x] New feature (a non-breaking change which adds functionality)
- [ ] Breaking change (fix or feature that would cause existing
functionality to change)
- [ ] Requires change to documentation, which has been updated
accordingly.

---------

Co-authored-by: Arthur Andrade <[email protected]>
  • Loading branch information
ArthurTriis1 and ArthurTriis1 authored Aug 1, 2024
1 parent 60f4cd1 commit 47bdbf7
Show file tree
Hide file tree
Showing 6 changed files with 184 additions and 4 deletions.
5 changes: 4 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
[9.146.4]: https://github.com/vtex/styleguide/compare/v9.146.3...v9.146.4
93 changes: 93 additions & 0 deletions react/components/AutocompleteInput/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,99 @@ const UsersAutocomplete = () => {
;<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 <AutocompleteInput input={input} options={options} />
}

;<UsersAutocomplete />
```

#### Custom option rendering

```jsx
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,53 @@ exports[`AutocompleteInput should render a regular version of search bar if size
</DocumentFragment>
`;

exports[`AutocompleteInput should render with a 300px max height 1`] = `
<DocumentFragment>
<div
class="flex flex-column w-100"
>
<div
class="flex flex-row"
>
<label
class="relative w-100"
>
<div
class="flex flex-row items-stretch overflow-hidden bw1 br2 b--solid b--muted-4 hover-b--muted-3 bg-base c-on-base br--left h-regular"
>
<input
class="ma0 border-box w-100 bn outline-0 b--muted-4 hover-b--muted-3 bg-base c-on-base pr5 pl5"
placeholder=""
value=""
/>
</div>
</label>
<button
class="b--muted-4 hover-b--muted-3 bg-base c-on-base bg-base br2 br--right w3 bw1 ba pa0 bl-0 c-link pointer"
>
<svg
class="vtex__icon-search "
fill="none"
height="16"
viewBox="0 0 16 16"
width="16"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
>
<path
d="M15.707 13.293L13 10.586C13.63 9.536 14 8.311 14 7C14 3.14 10.859 0 7 0C3.141 0 0 3.14 0 7C0 10.86 3.141 14 7 14C8.312 14 9.536 13.631 10.586 13L13.293 15.707C13.488 15.902 13.744 16 14 16C14.256 16 14.512 15.902 14.707 15.707L15.707 14.707C16.098 14.316 16.098 13.684 15.707 13.293ZM7 12C4.239 12 2 9.761 2 7C2 4.239 4.239 2 7 2C9.761 2 12 4.239 12 7C12 9.761 9.761 12 7 12Z"
fill="currentColor"
/>
</svg>
</button>
</div>
<div
class="relative"
/>
</div>
</DocumentFragment>
`;

exports[`AutocompleteInput should render with a large size bar 1`] = `
<DocumentFragment>
<div
Expand Down
3 changes: 3 additions & 0 deletions react/components/AutocompleteInput/autocomplete.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.scroll {
overflow: scroll;
}
27 changes: 26 additions & 1 deletion react/components/AutocompleteInput/index.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,31 @@ describe('AutocompleteInput', () => {
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(
<AutocompleteInput input={input} options={options} />
)

const result = asFragment()

expect(result).toMatchSnapshot()
})

it('should render with a regular size bar', () => {
const options = {
onSelect: () => `''`,
Expand Down Expand Up @@ -108,7 +133,7 @@ describe('AutocompleteInput', () => {
onSelect: () => `''`,
loading: false,
value: [],
size: 'medium',
size: 'regular',
}

const input = {
Expand Down
13 changes: 11 additions & 2 deletions react/components/AutocompleteInput/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down Expand Up @@ -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,
}

Expand Down Expand Up @@ -124,6 +130,7 @@ const AutocompleteInput: React.FunctionComponent<AutocompleteInputProps> = ({
icon,
size,
customMessage,
maxHeight = 'fit-content',
},
}) => {
const [term, setTerm] = useState(value || '')
Expand Down Expand Up @@ -261,7 +268,7 @@ const AutocompleteInput: React.FunctionComponent<AutocompleteInputProps> = ({
const errorStyle = error || Boolean(errorMessage)

return (
<div ref={containerRef} className="flex flex-column w-100">
<div ref={containerRef} className={`flex flex-column w-100`}>
<SearchInput
{...inputProps}
value={
Expand All @@ -280,7 +287,9 @@ const AutocompleteInput: React.FunctionComponent<AutocompleteInputProps> = ({
/>
<div className="relative">
{popoverOpened ? (
<div className="absolute br--bottom br2 bb bl br bw1 b--muted-2 bg-base w-100 z-1 shadow-5">
<div
style={{ maxHeight }}
className={`absolute br--bottom br2 bb bl br bw1 b--muted-2 bg-base w-100 z-1 shadow-5 ${styles.scroll}`}>
{renderOptions()}
{loading && (
<div className="flex flex-row justify-center items-center pa4">
Expand Down

0 comments on commit 47bdbf7

Please sign in to comment.