Skip to content
This repository was archived by the owner on Mar 4, 2020. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
- Expose `Popup`'s content Ref @sophieH29 ([#913](https://github.com/stardust-ui/react/pull/913))
- Fix `Button` Teams theme styles to use semibold weight @notandrew ([#829](https://github.com/stardust-ui/react/pull/829))
- Fix conflicts of generated names in Fela with FontAwesome @layershifter ([#951](https://github.com/stardust-ui/react/pull/951))
- Call callbacks after the clear action in `Input` and `Dropdown` @layershifter ([#956](https://github.com/stardust-ui/react/pull/956))

### Documentation
- Add `Editable Area with Dropdown` prototype for mentioning people using `@` character (only available in development mode) @Bugaa92 ([#931](https://github.com/stardust-ui/react/pull/931))
Expand Down
24 changes: 19 additions & 5 deletions packages/react/src/components/Dropdown/Dropdown.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -367,9 +367,9 @@ class Dropdown extends AutoControlledComponent<Extendable<DropdownProps>, Dropdo
xSpacing: 'none',
},
overrideProps: (predefinedProps: IconProps) => ({
onClick: (e, iconProps: IconProps) => {
onClick: (e: React.SyntheticEvent<HTMLElement>, iconProps: IconProps) => {
_.invoke(predefinedProps, 'onClick', e, iconProps)
this.handleClear()
this.handleClear(e)
},
}),
})
Expand Down Expand Up @@ -802,10 +802,24 @@ class Dropdown extends AutoControlledComponent<Extendable<DropdownProps>, Dropdo
}
}

private handleClear = () => {
const initialState = this.getInitialAutoControlledState(this.props)
private handleClear = (e: React.SyntheticEvent<HTMLElement>) => {
const {
activeSelectedIndex,
defaultHighlightedIndex,
searchQuery,
value,
} = this.getInitialAutoControlledState(this.props)

_.invoke(this.props, 'onSelectedChange', e, {
...this.props,
activeSelectedIndex,
defaultHighlightedIndex,
searchQuery,
value,
})

this.setState({ value: initialState.value })
this.trySetState({ activeSelectedIndex, searchQuery, value })
this.setState({ defaultHighlightedIndex })

this.tryFocusSearchInput()
this.tryFocusTriggerButton()
Expand Down
5 changes: 3 additions & 2 deletions packages/react/src/components/Input/Input.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ class Input extends AutoControlledComponent<ReactProps<InputProps>, InputState>

private handleIconOverrides = predefinedProps => ({
onClick: (e: React.SyntheticEvent) => {
this.handleOnClear()
this.handleOnClear(e)
this.inputRef.current.focus()
_.invoke(predefinedProps, 'onClick', e, this.props)
},
Expand All @@ -191,8 +191,9 @@ class Input extends AutoControlledComponent<ReactProps<InputProps>, InputState>
this.trySetState({ value })
}

private handleOnClear = () => {
private handleOnClear = (e: React.SyntheticEvent) => {
if (this.props.clearable) {
_.invoke(this.props, 'onChange', e, { ...this.props, value: '' })
this.trySetState({ value: '' })
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,37 @@
import { isConformant } from 'test/specs/commonTests'
import * as faker from 'faker'
import * as React from 'react'

import Dropdown from 'src/components/Dropdown/Dropdown'
import { isConformant } from 'test/specs/commonTests'
import { mountWithProvider } from 'test/utils'

describe('Dropdown', () => {
isConformant(Dropdown, { hasAccessibilityProp: false })

describe('clearable', () => {
it('calls onChange on Icon click with an `empty` value', () => {
const onSelectedChange = jest.fn()
const options = [faker.lorem.word(), faker.lorem.word(), faker.lorem.word()]
const wrapper = mountWithProvider(
<Dropdown
clearable
onSelectedChange={onSelectedChange}
options={options}
value={options[0]}
/>,
)

wrapper.find({ className: Dropdown.slotClassNames.clearIndicator }).simulate('click')
expect(onSelectedChange).toBeCalledTimes(1)
expect(onSelectedChange).toHaveBeenCalledWith(
expect.objectContaining({ type: 'click' }),
expect.objectContaining({
activeSelectedIndex: undefined,
defaultHighlightedIndex: null,
searchQuery: undefined,
value: null,
}),
)
})
})
})
17 changes: 17 additions & 0 deletions packages/react/test/specs/components/Input/Input-test.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import * as faker from 'faker'
import * as React from 'react'

import { ReactWrapper } from 'enzyme'
Expand Down Expand Up @@ -78,6 +79,22 @@ describe('Input', () => {
})
})

describe('clearable', () => {
it('calls onChange on Icon click with an `empty` value', () => {
const onChange = jest.fn()
const wrapper = mount(
<Input clearable defaultValue={faker.lorem.word()} onChange={onChange} />,
)

wrapper.find('Icon').simulate('click')
expect(onChange).toBeCalledTimes(1)
expect(onChange).toHaveBeenCalledWith(
expect.objectContaining({ type: 'click' }),
expect.objectContaining({ value: '' }),
)
})
})

describe('icon', () => {
it('creates the Icon component when the icon shorthand is provided', () => {
const inputComp = mount(<Input icon={{ name: 'search' }} />)
Expand Down