Skip to content
This repository was archived by the owner on Mar 4, 2020. It is now read-only.

refactor(Dropdown): rename DropdownLabel to DropdownSelectedItem #725

Merged
merged 11 commits into from
Jan 15, 2019
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm

## [Unreleased]

### BREAKING
- Rename `DropdownLabel` to `DropdownSelectedItem` and extract styles @layershifter ([#725](https://github.com/stardust-ui/react/pull/725))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please before merging move this to BREAKING CHANGES.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, also added update notes 👍


### Documentation
- Fix ignored initial state of knobs @layershifter ([#720](https://github.com/stardust-ui/react/pull/720))
- Fix unclearable example's code @layershifter ([#720](https://github.com/stardust-ui/react/pull/720))
Expand Down
25 changes: 12 additions & 13 deletions src/components/Dropdown/Dropdown.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ import Text from '../Text/Text'
import Ref from '../Ref/Ref'
import { UIComponentProps } from '../../lib/commonPropInterfaces'
import DropdownItem from './DropdownItem'
import DropdownLabel, { DropdownLabelProps } from './DropdownLabel'
import DropdownSelectedItem, { DropdownSelectedItemProps } from './DropdownSelectedItem'
import DropdownSearchInput, { DropdownSearchInputProps } from './DropdownSearchInput'
import Button from '../Button/Button'

Expand Down Expand Up @@ -70,7 +70,7 @@ export interface DropdownProps extends UIComponentProps<DropdownProps, DropdownS
*/
getA11yStatusMessage?: (options: A11yStatusMessageOptions<ShorthandValue>) => string

/** Array of props for generating list options (Dropdown.Item[]) and selected item labels(Dropdown.Label[]), if it's a multiple selection. */
/** Array of props for generating list options (Dropdown.Item[]) and selected item labels(Dropdown.SelectedItem[]), if it's a multiple selection. */
items?: ShorthandValue[]

/**
Expand Down Expand Up @@ -191,8 +191,8 @@ export default class Dropdown extends AutoControlledComponent<
static autoControlledProps = ['searchQuery', 'value']

static Item = DropdownItem
static Label = DropdownLabel
static SearchInput = DropdownSearchInput
static SelectedItem = DropdownSelectedItem

getInitialAutoControlledState({ multiple, search }: DropdownProps): DropdownState {
return {
Expand Down Expand Up @@ -252,7 +252,7 @@ export default class Dropdown extends AutoControlledComponent<
className={classes.container}
onClick={multiple ? this.handleContainerClick.bind(this, isOpen) : undefined}
>
{multiple && this.renderSelectedItems(styles)}
{multiple && this.renderSelectedItems()}
{search
? this.renderSearchInput(
accessibilityRootPropsRest,
Expand Down Expand Up @@ -442,23 +442,22 @@ export default class Dropdown extends AutoControlledComponent<
]
}

private renderSelectedItems(styles: ComponentSlotStylesInput) {
private renderSelectedItems() {
const value = this.state.value as ShorthandValue[]

if (value.length === 0) {
return null
}

return value.map(item =>
DropdownLabel.create(item, {
DropdownSelectedItem.create(item, {
defaultProps: {
styles: styles.label,
...(typeof item === 'object' &&
!item.hasOwnProperty('key') && {
key: (item as any).header,
}),
},
overrideProps: (predefinedProps: DropdownLabelProps) =>
overrideProps: (predefinedProps: DropdownSelectedItemProps) =>
this.handleSelectedItemOverrides(predefinedProps, item),
}),
)
Expand Down Expand Up @@ -552,16 +551,16 @@ export default class Dropdown extends AutoControlledComponent<
})

private handleSelectedItemOverrides = (
predefinedProps: DropdownLabelProps,
predefinedProps: DropdownSelectedItemProps,
item: ShorthandValue,
) => ({
onRemove: (e: React.SyntheticEvent, dropdownLabelProps: DropdownLabelProps) => {
onRemove: (e: React.SyntheticEvent, DropdownSelectedItemProps: DropdownSelectedItemProps) => {
this.handleSelectedItemRemove(e, item)
_.invoke(predefinedProps, 'onRemove', e, dropdownLabelProps)
_.invoke(predefinedProps, 'onRemove', e, DropdownSelectedItemProps)
},
onClick: (e: React.SyntheticEvent, dropdownLabelProps: DropdownLabelProps) => {
onClick: (e: React.SyntheticEvent, DropdownSelectedItemProps: DropdownSelectedItemProps) => {
e.stopPropagation()
_.invoke(predefinedProps, 'onClick', e, dropdownLabelProps)
_.invoke(predefinedProps, 'onClick', e, DropdownSelectedItemProps)
},
})

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import {
import { Image, Icon, Label } from '../..'
import { IconProps } from '../Icon/Icon'

export interface DropdownLabelProps extends UIComponentProps<DropdownLabelProps> {
export interface DropdownSelectedItemProps extends UIComponentProps<DropdownSelectedItemProps> {
/** Header of the selected item. */
header?: string

Expand All @@ -31,27 +31,27 @@ export interface DropdownLabelProps extends UIComponentProps<DropdownLabelProps>
* @param {SyntheticEvent} event - React's original SyntheticEvent.
* @param {object} data - All props and proposed value.
*/
onClick?: ComponentEventHandler<DropdownLabelProps>
onClick?: ComponentEventHandler<DropdownSelectedItemProps>

/**
* Called when item is removed from the selection list.
*
* @param {SyntheticEvent} event - React's original SyntheticEvent.
* @param {object} data - All props and proposed value.
*/
onRemove?: ComponentEventHandler<DropdownLabelProps>
onRemove?: ComponentEventHandler<DropdownSelectedItemProps>
}

/**
* A DropdownLabel is a sub-component of a multiple selection Dropdown.
* A DropdownSelectedItem is a sub-component of a multiple selection Dropdown.
* It is used to display selected item.
*/
class DropdownLabel extends UIComponent<ReactProps<DropdownLabelProps>, any> {
displayName = 'DropdownLabel'
class DropdownSelectedItem extends UIComponent<ReactProps<DropdownSelectedItemProps>, any> {
static displayName = 'DropdownSelectedItem'

static create: Function

className = 'ui-dropdown__label'
static className = 'ui-dropdown__selected-item'

static propTypes = {
...commonPropTypes.createCommon({
Expand All @@ -72,35 +72,7 @@ class DropdownLabel extends UIComponent<ReactProps<DropdownLabelProps>, any> {
_.invoke(this.props, 'onClick', e, this.props)
}

public renderComponent({ unhandledProps, styles }: RenderResultConfig<DropdownLabelProps>) {
const { header, icon, image } = this.props

return (
<Label
styles={styles.root}
role="presentation"
circular
onClick={this.handleClick}
content={header}
icon={Icon.create(icon, {
defaultProps: {
'aria-label': `Remove ${header} from selection.`, // TODO: Extract this in a behaviour.
'aria-hidden': false,
role: 'button',
},
overrideProps: this.handleIconOverrides,
})}
image={Image.create(image, {
defaultProps: {
avatar: true,
},
})}
{...unhandledProps}
/>
)
}

private handleIconOverrides = (predefinedProps: DropdownLabelProps) => ({
private handleIconOverrides = (predefinedProps: IconProps) => ({
onClick: (e: React.SyntheticEvent, iconProps: IconProps) => {
e.stopPropagation()
_.invoke(this.props, 'onRemove', e, this.props)
Expand All @@ -114,8 +86,42 @@ class DropdownLabel extends UIComponent<ReactProps<DropdownLabelProps>, any> {
_.invoke(predefinedProps, 'onKeyDown', e, iconProps)
},
})

public renderComponent({
unhandledProps,
styles,
}: RenderResultConfig<DropdownSelectedItemProps>) {
const { header, icon, image } = this.props

const iconElement = Icon.create(icon, {
defaultProps: {
'aria-label': `Remove ${header} from selection.`, // TODO: Extract this in a behaviour.
'aria-hidden': false,
role: 'button',
},
overrideProps: this.handleIconOverrides,
})
const imageElement = Image.create(image, {
defaultProps: {
avatar: true,
},
})

return (
<Label
styles={styles.root}
role="presentation"
circular
onClick={this.handleClick}
content={header}
icon={iconElement}
image={imageElement}
{...unhandledProps}
/>
)
}
}

DropdownLabel.create = createShorthandFactory(DropdownLabel, 'header')
DropdownSelectedItem.create = createShorthandFactory(DropdownSelectedItem, 'header')

export default DropdownLabel
export default DropdownSelectedItem
5 changes: 4 additions & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,10 @@ export {

export { default as DropdownItem, DropdownItemProps } from './components/Dropdown/DropdownItem'

export { default as DropdownLabel, DropdownLabelProps } from './components/Dropdown/DropdownLabel'
export {
default as DropdownSelectedItem,
DropdownSelectedItemProps,
} from './components/Dropdown/DropdownSelectedItem'

export {
default as DropdownSearchInput,
Expand Down
1 change: 1 addition & 0 deletions src/themes/teams/componentStyles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ export { default as Divider } from './components/Divider/dividerStyles'

export { default as Dropdown } from './components/Dropdown/dropdownStyles'
export { default as DropdownSearchInput } from './components/Dropdown/dropdownSearchInputStyles'
export { default as DropdownSelectedItem } from './components/Dropdown/dropdownSelectedItemStyles'
export { default as DropdownItem } from './components/Dropdown/dropdownItemStyles'

export { default as Form } from './components/Form/formStyles'
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { DropdownSelectedItemProps } from '../../../../components/Dropdown/DropdownSelectedItem'
import { ComponentSlotStylesInput, ICSSInJSStyle } from '../../../types'

const dropdownSelectedItemStyles: ComponentSlotStylesInput<DropdownSelectedItemProps> = {
root: (): ICSSInJSStyle => ({
margin: '.4rem 0 0 .4rem',
}),
}

export default dropdownSelectedItemStyles
4 changes: 0 additions & 4 deletions src/themes/teams/components/Dropdown/dropdownStyles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,10 +60,6 @@ const dropdownStyles: ComponentSlotStylesInput<DropdownProps, DropdownVariables>
}
},

label: (): ICSSInJSStyle => ({
margin: '.4rem 0 0 .4rem',
}),

list: ({
variables: { listMaxHeight, width, listBackgroundColor },
props: { fluid },
Expand Down