diff --git a/CHANGELOG.md b/CHANGELOG.md index 544869a3a..ba087f9c1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,12 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ## [Unreleased] +## [9.123.0] - 2020-06-26 + +### Added + +- `size` prop to AutocompleteInput + ## [9.122.0] - 2020-06-25 ### Fixed diff --git a/manifest.json b/manifest.json index e812487db..dd5237f76 100644 --- a/manifest.json +++ b/manifest.json @@ -2,7 +2,7 @@ "vendor": "vtex", "name": "styleguide", "title": "VTEX Styleguide", - "version": "9.122.0", + "version": "9.123.0", "description": "The VTEX Styleguide components for the Render framework", "builders": { "react": "3.x" diff --git a/package.json b/package.json index 7134a4f80..f9d480196 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@vtex/styleguide", - "version": "9.122.0", + "version": "9.123.0", "scripts": { "lint": "eslint react --ext js,jsx,ts,tsx", "test": "node config/test.js", diff --git a/react/components/AutocompleteInput/README.md b/react/components/AutocompleteInput/README.md index f53b3f707..03cace90b 100644 --- a/react/components/AutocompleteInput/README.md +++ b/react/components/AutocompleteInput/README.md @@ -273,3 +273,100 @@ const DisabledAutocompleteInput = () => ( ; ``` + +#### Size + +```jsx +import { uniq } from 'lodash' +import { useState, useRef } from 'react' + +const allUsers = [ + 'Ana Clara', + 'Ana Luiza', + { value: 1, label: 'Bruno' }, + 'Carlos', + 'Daniela', +] + +const UsersAutocomplete = () => { + const [term, setTerm] = useState('') + const [loading, setLoading] = useState(false) + const timeoutRef = useRef(null) + + const optionsSmall = { + 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()) + ), + size: 'small', + } + + const optionsRegular = { + 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()) + ), + size: 'regular', + } + + const optionsLarge = { + 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()) + ), + size: 'large', + } + + 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 ( +
+ + + + + + + + + +
+ ) +} + +; +``` diff --git a/react/components/AutocompleteInput/SearchInput/index.tsx b/react/components/AutocompleteInput/SearchInput/index.tsx index 8dc5500d0..d4f4d0f76 100644 --- a/react/components/AutocompleteInput/SearchInput/index.tsx +++ b/react/components/AutocompleteInput/SearchInput/index.tsx @@ -24,6 +24,8 @@ const propTypes = { onBlur: PropTypes.func, /** Determine if the input and the button should be disabled */ disabled: PropTypes.bool, + /** Determine the search bar size */ + size: PropTypes.oneOf(['small', 'regular', 'large']), } const defaultProps = { @@ -31,7 +33,10 @@ const defaultProps = { } const SearchInput: React.FC & - Omit, 'onChange' | 'value'>> = props => { + Omit< + React.HTMLProps, + 'onChange' | 'value' | 'size' + >> = props => { const { onClear, onSearch, @@ -41,6 +46,7 @@ const SearchInput: React.FC & onFocus, onBlur, disabled, + size, ...inputProps } = props @@ -63,18 +69,20 @@ const SearchInput: React.FC & setFocused(false) onBlur && onBlur(e) } - + const regularSize = size !== 'small' && size !== 'large' const activeClass = classNames({ 'b--muted-3': focused, 'b--muted-4': !focused, 'br--top': !roundedBottom, 'bg-disabled c-disabled': disabled, 'bg-base c-on-base': !disabled, + [`h-${size}`]: !regularSize, + 'h-regular': regularSize, }) const buttonClasses = classNames( activeClass, - 'bg-base br2 br--right h-regular w3 bw1 ba pa0 bl-0', + 'bg-base br2 br--right w3 bw1 ba pa0 bl-0', { 'c-link pointer': !disabled, 'c-disabled': disabled, @@ -85,7 +93,7 @@ const SearchInput: React.FC &
+
+
+
+ +
+ +
+
+ +`; + +exports[`AutocompleteInput should render with a large size bar 1`] = ` + +
+
+
+ +
+ +
+
+
+`; + +exports[`AutocompleteInput should render with a regular size bar 1`] = ` + +
+
+
+ +
+ +
+
+
+`; + +exports[`AutocompleteInput should render with a regular size bar when prop is absent 1`] = ` + +
+
+
+ +
+ +
+
+
+`; + +exports[`AutocompleteInput should render with a small size bar 1`] = ` + +
+
+
+ +
+ +
+
+
+`; diff --git a/react/components/AutocompleteInput/index.test.tsx b/react/components/AutocompleteInput/index.test.tsx new file mode 100644 index 000000000..21606e580 --- /dev/null +++ b/react/components/AutocompleteInput/index.test.tsx @@ -0,0 +1,130 @@ +import React from 'react' +import { render } from '@testing-library/react' + +import AutocompleteInput from './index' + +describe('AutocompleteInput', () => { + it('should render with a small size bar', () => { + const options = { + onSelect: () => `''`, + loading: false, + value: [], + size: 'small', + } + + 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: () => `''`, + loading: false, + value: [], + size: 'regular', + } + + const input = { + onChange: () => `''`, + onSearch: () => `''`, + onClear: () => `''`, + placeholder: '', + value: '', + } + + const { asFragment } = render( + + ) + + const result = asFragment() + + expect(result).toMatchSnapshot() + }) + + it('should render with a large size bar', () => { + const options = { + onSelect: () => `''`, + loading: false, + value: [], + size: 'large', + } + + const input = { + onChange: () => `''`, + onSearch: () => `''`, + onClear: () => `''`, + placeholder: '', + value: '', + } + + const { asFragment } = render( + + ) + + const result = asFragment() + + expect(result).toMatchSnapshot() + }) + + it('should render with a regular size bar when prop is absent', () => { + const options = { + onSelect: () => `''`, + loading: false, + value: [], + } + + const input = { + onChange: () => `''`, + onSearch: () => `''`, + onClear: () => `''`, + placeholder: '', + value: '', + } + + const { asFragment } = render( + + ) + + const result = asFragment() + + expect(result).toMatchSnapshot() + }) + + it('should render a regular version of search bar if size prop isnt small, regular or large', () => { + const options = { + onSelect: () => `''`, + loading: false, + value: [], + size: 'medium', + } + + const input = { + onChange: () => `''`, + onSearch: () => `''`, + onClear: () => `''`, + placeholder: '', + value: '', + } + + const { asFragment } = render( + + ) + + const result = asFragment() + + expect(result).toMatchSnapshot() + }) +}) diff --git a/react/components/AutocompleteInput/index.tsx b/react/components/AutocompleteInput/index.tsx index 05e4d5fcf..316eb08f3 100644 --- a/react/components/AutocompleteInput/index.tsx +++ b/react/components/AutocompleteInput/index.tsx @@ -71,6 +71,11 @@ const propTypes = { /** Last Searched options's title */ label: PropTypes.node.isRequired, }), + /** + * Selects a size of the input bar, could be set to `small`, `regular` or `large`. + * `regular` is the default value. + */ + size: PropTypes.oneOf(['small', 'regular', 'large']), }).isRequired, } @@ -87,6 +92,7 @@ const AutocompleteInput: React.FunctionComponent { const [term, setTerm] = useState(value || '') @@ -210,6 +216,7 @@ const AutocompleteInput: React.FunctionComponent onSearch(term)} onClear={handleClear} onChange={handleTermChange} + size={size} /> {popoverOpened ? (