Repository URL to install this package:
|
Version:
2.8.0-studio-release ▾
|
import React from 'react'
import { observer } from 'xmobx/mobx-react'
import { isFunction } from 'exotic'
import {
SelectionState,
SelectableItemOnClick,
SelectableItem,
SelectableState,
isEveryItemInListDecoratedWithOnClick,
} from 'src/state/SelectionState'
import { toList } from '../meta/_deps'
import { renderItem as defaultRenderItem } from '../Option'
import { renderActiveItem as defaultRenderActive } from '../ActiveOption/_circularRenderProp'
import { StyledOptionList } from './styled'
import { SelectBoundary } from './SelectBoundary'
import { SelectProps } from './typings'
import { renderList as defaultRenderList } from './renderProps'
@observer
class Select extends React.Component<SelectProps> {
static defaultProps = {
renderList: defaultRenderList,
renderItem: defaultRenderItem,
renderActiveItem: defaultRenderActive,
shouldBeAbsolute: false,
dropDownAlignmentType: false,
}
/**
* @todo could make this a normal prop
*/
observableState = new SelectionState()
protected handleChange: SelectableItemOnClick = (
event: Event,
item: SelectableItem,
state: SelectableState
): void => {
console.debug('[adm:Select] handleChange()')
this.observableState.handleToggleVisibility()
// this.observableState.setIsVisible(false)
if (isFunction(this.props.onChange)) {
console.info('[adm:Select] onChange passed in')
/**
* @todo should be this.props.onChange({event, item, state})
*/
this.props.onChange(event, item, state)
} else {
console.warn('[adm:Select] had no onChangeProp')
}
}
protected handleDecoratingList() {
const onChange = this.handleChange
const props = { ...this.props, onChange }
console.debug('[Select] handleDecoratingList()')
console.dir(props)
this.observableState.decorateWithProps(props)
}
/**
* @todo this code makes no sense
* - after setting isVisible to false, onBlur never calls
*/
protected handleClickOutside = () => {
const { onBlur } = this.props
if (this.observableState.isVisible) {
this.observableState.setIsVisible(false)
if (isFunction(onBlur)) {
onBlur()
}
}
}
/**
* @todo this area is probably the confusing part
* perhaps we separate the state decorating out of here
*/
componentWillMount() {
this.handleDecoratingList()
}
componentWillReact() {
if (isEveryItemInListDecoratedWithOnClick(this.props) === false) {
this.handleDecoratingList()
}
}
render() {
// computed & stateful
const { props, observableState } = this
/**
* @todo for perf & simplicity, change to props.list
*/
const list = toList(props)
const { isVisible, handleToggleVisibility } = observableState
const { onBlur, onFocus } = props
const {
/**
* @see https://www.typescriptlang.org/play/#src=const%20obj%20%3D%20%7B%7D%0D%0Aconst%20%7B%0D%0A%20%20defaulted%20%3D%20()%20%3D%3E%20'eh'%2C%0D%0A%7D%20%3D%20obj
* @description inline `hide`
* @todo probably should make a function that is the default for this
* and pass in props + observable state
*/
onClickOutside = this.handleClickOutside,
renderList,
renderActiveItem,
isDisabled,
className,
shouldBeAbsolute,
dropDownAlignmentType,
} = props
/**
* @todo !!! this is probably where we have issues, log here
*/
const activeProps = {
/**
* @nagavelli
* - props needed here since overwriiten function should be supported
*
* @james ^
* - why do we spread observable state?
* 1. this is error prone
* 2. we already pass in state
*/
...observableState.selectedItem,
...props,
...observableState,
onClick: handleToggleVisibility,
}
if (isFunction(onFocus) && isVisible) {
onFocus()
}
const listView = renderList({ ...this.props, list }, this.observableState)
const activeView = renderActiveItem(activeProps, observableState)
const optionListView = (
<StyledOptionList
list={list}
children={listView}
isVisible={isVisible}
shouldBeAbsolute={shouldBeAbsolute}
dropDownAlignmentType={dropDownAlignmentType}
/>
)
return (
<SelectBoundary
className={className}
onClickOutside={onClickOutside}
isDisabled={isDisabled}
isVisible={isVisible}
data-qa={this.props['data-qa']}
>
{activeView}
{optionListView}
</SelectBoundary>
)
}
}
export { Select }
export default Select