Skip to content

Commit

Permalink
Merge pull request #281 from zeit-ui/rc
Browse files Browse the repository at this point in the history
chore: release v1.7.0
  • Loading branch information
unix authored Jun 20, 2020
2 parents 0e95e52 + b3a4f69 commit a222687
Show file tree
Hide file tree
Showing 50 changed files with 2,142 additions and 39 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ exports[`AutoComplete should render correctly 1`] = `
<AutoComplete
className=""
clearable={false}
disableFreeSolo={false}
disableMatchWidth={false}
disabled={false}
initialValue=""
Expand Down
13 changes: 9 additions & 4 deletions components/auto-complete/__tests__/index.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import React from 'react'
import { mount } from 'enzyme'
import { AutoComplete } from 'components'
import { nativeEvent } from 'tests/utils'
import { act } from 'react-dom/test-utils'

describe('AutoComplete', () => {
it('should render correctly', () => {
Expand Down Expand Up @@ -32,23 +33,27 @@ describe('AutoComplete', () => {
expect((input as HTMLInputElement).value).toEqual('value2')
})

it('should render clear icon', () => {
it('should render clear icon', async () => {
const wrapper = mount(<AutoComplete initialValue="value" />)
expect(wrapper.find('svg').length).toBe(0)

wrapper.setProps({ clearable: true })
await act(async () => {
wrapper.setProps({ clearable: true })
})
expect(wrapper.find('svg').length).toBe(1)

wrapper.find('svg').simulate('click', nativeEvent)
const input = wrapper.find('input').at(0).getDOMNode()
expect((input as HTMLInputElement).value).toEqual('')
})

it('should reponse width change', () => {
it('should reponse width change', async () => {
const wrapper = mount(<AutoComplete initialValue="value" width="100px" />)
expect(wrapper.prop('width')).toEqual('100px')
await act(async () => {
wrapper.setProps({ width: '200px' })
})

wrapper.setProps({ width: '200px' })
expect(wrapper.prop('width')).toEqual('200px')
})
})
20 changes: 17 additions & 3 deletions components/auto-complete/__tests__/search.test.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import React from 'react'
import { mount, render } from 'enzyme'
import { AutoComplete } from 'components'
import { nativeEvent } from 'tests/utils'
import { nativeEvent, updateWrapper } from 'tests/utils'
import { act } from 'react-dom/test-utils'
const mockOptions = [{ label: 'London', value: 'london' }]

describe('AutoComplete Search', () => {
Expand Down Expand Up @@ -33,9 +34,11 @@ describe('AutoComplete Search', () => {
expect(value).not.toEqual('london')
})

it('should render searching component', () => {
it('should render searching component', async () => {
let wrapper = mount(<AutoComplete searching={false} options={mockOptions} />)
wrapper.setProps({ searching: true })
await act(async () => {
wrapper.setProps({ searching: true })
})
wrapper.find('input').at(0).simulate('focus')
let dropdown = wrapper.find('.auto-complete-dropdown')
expect(dropdown.text()).not.toContain('london')
Expand Down Expand Up @@ -136,4 +139,15 @@ describe('AutoComplete Search', () => {
const wrapper = mount(<AutoComplete options={[]} />)
expect(() => wrapper.unmount()).not.toThrow()
})

it('value should be reset when freeSolo disabled', async () => {
const wrapper = mount(<AutoComplete initialValue="value" disableFreeSolo />)
const input = wrapper.find('input').at(0)
input.simulate('focus')
input.simulate('change', { target: { value: 'test' } })
expect((input.getDOMNode() as HTMLInputElement).value).toEqual('test')
input.simulate('blur')
await updateWrapper(wrapper, 200)
expect((input.getDOMNode() as HTMLInputElement).value).toEqual('value')
})
})
60 changes: 60 additions & 0 deletions components/auto-complete/__tests__/use-input.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import React, { useEffect } from 'react'
import { mount } from 'enzyme'
import { AutoComplete, useInput } from 'components'

describe('UseInput', () => {
it('should follow change with use-input', () => {
let log = ''
const logSpy = jest.spyOn(console, 'log').mockImplementation(msg => (log = msg))
const MockInput: React.FC<{ value?: string }> = ({ value }) => {
const { state, setState, bindings } = useInput('')
useEffect(() => {
if (value) setState(value)
}, [value])
useEffect(() => {
if (state) console.log(state)
}, [state])
return <AutoComplete {...bindings} />
}

const wrapper = mount(<MockInput />)
wrapper.setProps({ value: 'test' })
const input = wrapper.find('input').at(0).getDOMNode() as HTMLInputElement

expect(input.value).toEqual('test')
expect(log).toContain('test')

log = ''
wrapper
.find('input')
.at(0)
.simulate('change', { target: { value: 'test-change' } })
expect(log).toContain('test-change')
logSpy.mockRestore()
})

it('should follow change with use-input', () => {
const MockInput: React.FC<{ value?: string; resetValue?: boolean }> = ({
value,
resetValue,
}) => {
const { reset, setState, bindings } = useInput('')
useEffect(() => {
if (value) setState(value)
}, [value])
useEffect(() => {
if (resetValue) reset()
}, [resetValue])
return <AutoComplete {...bindings} />
}

const wrapper = mount(<MockInput />)
wrapper.setProps({ value: 'test' })
let input = wrapper.find('input').at(0).getDOMNode() as HTMLInputElement
expect(input.value).toEqual('test')

wrapper.setProps({ resetValue: true })
input = wrapper.find('input').at(0).getDOMNode() as HTMLInputElement
expect(input.value).toEqual('')
})
})
3 changes: 2 additions & 1 deletion components/auto-complete/auto-complete-item.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,10 @@ const AutoCompleteItem: React.FC<React.PropsWithChildren<AutoCompleteItemProps>>
children,
}) => {
const theme = useTheme()
const { value, updateValue, size } = useAutoCompleteContext()
const { value, updateValue, size, updateVisible } = useAutoCompleteContext()
const selectHandler = () => {
updateValue && updateValue(identValue)
updateVisible && updateVisible(false)
}

const isActive = useMemo(() => value === identValue, [identValue, value])
Expand Down
29 changes: 27 additions & 2 deletions components/auto-complete/auto-complete.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { AutoCompleteContext, AutoCompleteConfig } from './auto-complete-context
import { NormalSizes, NormalTypes } from '../utils/prop-types'
import Loading from '../loading'
import { pickChild } from '../utils/collections'
import useCurrentState from '../utils/use-current-state'

export type AutoCompleteOption = {
label: string
Expand All @@ -31,6 +32,7 @@ interface Props {
dropdownClassName?: string
dropdownStyle?: object
disableMatchWidth?: boolean
disableFreeSolo?: boolean
className?: string
}

Expand All @@ -41,6 +43,7 @@ const defaultProps = {
clearable: false,
size: 'medium' as NormalSizes,
disableMatchWidth: false,
disableFreeSolo: false,
className: '',
}

Expand Down Expand Up @@ -83,11 +86,16 @@ const AutoComplete: React.FC<React.PropsWithChildren<AutoCompleteProps>> = ({
dropdownClassName,
dropdownStyle,
disableMatchWidth,
disableFreeSolo,
...props
}) => {
const ref = useRef<HTMLDivElement>(null)
const [state, setState] = useState<string>(customInitialValue)
const inputRef = useRef<HTMLInputElement>(null)
const resetTimer = useRef<number>()
const [state, setState, stateRef] = useCurrentState<string>(customInitialValue)
const [selectVal, setSelectVal] = useState<string>(customInitialValue)
const [visible, setVisible] = useState<boolean>(false)

const [, searchChild] = pickChild(children, AutoCompleteSearching)
const [, emptyChild] = pickChild(children, AutoCompleteEmpty)
const autoCompleteItems = useMemo(() => {
Expand All @@ -110,14 +118,24 @@ const AutoComplete: React.FC<React.PropsWithChildren<AutoCompleteProps>> = ({

const updateValue = (val: string) => {
if (disabled) return
setSelectVal(val)
onSelect && onSelect(val)
setState(val)
inputRef.current && inputRef.current.focus()
}
const updateVisible = (next: boolean) => setVisible(next)
const onInputChange = (event: React.ChangeEvent<HTMLInputElement>) => {
setVisible(true)
onSearch && onSearch(event.target.value)
setState(event.target.value)
}
const resetInputValue = () => {
if (!disableFreeSolo) return
if (!state || state === '') return
if (state !== selectVal) {
setState(selectVal)
}
}

useEffect(() => {
onChange && onChange(state)
Expand All @@ -140,9 +158,15 @@ const AutoComplete: React.FC<React.PropsWithChildren<AutoCompleteProps>> = ({
)

const toggleFocusHandler = (next: boolean) => {
clearTimeout(resetTimer.current)
setVisible(next)
if (next) {
onSearch && onSearch(state)
onSearch && onSearch(stateRef.current)
} else {
resetTimer.current = window.setTimeout(() => {
resetInputValue()
clearTimeout(resetTimer.current)
}, 100)
}
}

Expand All @@ -157,6 +181,7 @@ const AutoComplete: React.FC<React.PropsWithChildren<AutoCompleteProps>> = ({
<AutoCompleteContext.Provider value={initialValue}>
<div ref={ref} className="auto-complete">
<Input
ref={inputRef}
size={size}
status={status}
onChange={onInputChange}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`Breadcrumbs should redefined all separators 1`] = `
"<nav class=\\"\\"><span class=\\"breadcrums-item \\">test-1</span><div class=\\"separator \\">*<style>
.separator {
display: inline-flex;
margin: 0 8px;
user-select: none;
pointer-events: none;
align-items: center;
}
</style></div><span class=\\"breadcrums-item \\">test-2</span><style>
nav {
margin: 0;
padding: 0;
line-height: inherit;
color: #888;
font-size: 1rem;
box-sizing: border-box;
display: flex;
align-items: center;
}
nav :global(.link:hover) {
color: rgba(0, 112, 243, 0.85);
}
nav > :global(span:last-of-type) {
color: #444;
}
nav > :global(.separator:last-child) {
display: none;
}
nav :global(svg) {
width: 1em;
height: 1em;
margin: 0 4px;
}
nav :global(.breadcrums-item) {
display: inline-flex;
align-items: center;
}
</style></nav>"
`;

exports[`Breadcrumbs should render correctly 1`] = `
"<nav class=\\"\\"><span class=\\"breadcrums-item \\">test-1</span><style>
nav {
margin: 0;
padding: 0;
line-height: inherit;
color: #888;
font-size: 1rem;
box-sizing: border-box;
display: flex;
align-items: center;
}
nav :global(.link:hover) {
color: rgba(0, 112, 243, 0.85);
}
nav > :global(span:last-of-type) {
color: #444;
}
nav > :global(.separator:last-child) {
display: none;
}
nav :global(svg) {
width: 1em;
height: 1em;
margin: 0 4px;
}
nav :global(.breadcrums-item) {
display: inline-flex;
align-items: center;
}
</style></nav>"
`;
Loading

0 comments on commit a222687

Please sign in to comment.