Repository URL to install this package:
|
Version:
0.9.5 ▾
|
import React from 'react'
import { observer } from 'xmobx/mobx-react'
import { EMPTY_ARRAY, isFunction } from 'exotic'
import {
SelectionState,
SelectableItemOnClick,
SelectableItem,
SelectableState,
isEveryItemInListDecoratedWithOnClick,
} from 'src/state/SelectionState'
import { OptionType } from '../typings'
import { toList, toOnChange } from '../meta/_deps'
import { Option, renderItem as defaultRenderItem } from '../Option'
import {
ActiveOption,
renderActiveItem as defaultRenderActive,
} from '../ActiveOption'
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,
}
observableState = new SelectionState()
private handleChange: SelectableItemOnClick = (
event: Event,
item: SelectableItem,
state: SelectableState
): void => {
console.debug('[adm:Select] handleChange()')
this.observableState.handleToggleVisibility()
if (isFunction(this.props.onChange)) {
console.info('[adm:Select] onChange passed in')
this.props.onChange(event, item, state)
} else {
console.warn('[adm:Select] had no onChangeProp')
}
this.observableState.setIsVisible(false)
}
private handleDecoratingList() {
const onChange = this.handleChange
const props = { ...this.props, onChange }
console.debug('[Select] handleDecoratingList()')
console.dir(props)
this.observableState.decorateWithProps(props)
}
// maybe should be didMount?
componentWillMount() {
this.handleDecoratingList()
}
componentWillReact() {
if (isEveryItemInListDecoratedWithOnClick(this.props) === false) {
this.handleDecoratingList()
}
}
render() {
// computed & stateful
const { props, observableState } = this
const list = toList(props)
const { isVisible, handleToggleVisibility } = observableState
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 = () => observableState.setIsVisible(false),
renderList,
renderActiveItem,
isDisabled,
className,
shouldBeAbsolute,
dropDownAlignmentType,
} = props
const listView = renderList({ ...this.props, list }, this.observableState)
// @todo improve, add to typings
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,
}
const activeView = renderActiveItem(activeProps, observableState)
// @todo TOO MANY PROPS PASSING THROUGH FOR LAYOUT
// THIS IS WHY WE HAVE PRESETS
const optionListView = (
<StyledOptionList
list={list}
children={listView}
isVisible={isVisible}
shouldBeAbsolute={shouldBeAbsolute}
dropDownAlignmentType={dropDownAlignmentType}
/>
)
// @todo - WHAT IS THIS?!!?!?!?!?!!?!? THIS IS A PRESET MOVE IT OUT
// we can also EASILY style this
const renderDropDownList = (item: string) => {
switch (item) {
case 'top':
return (
<React.Fragment>
{optionListView}
{activeView}
</React.Fragment>
)
case 'bottom':
default:
return (
<React.Fragment>
{activeView}
{optionListView}
</React.Fragment>
)
}
}
return (
<SelectBoundary
className={className}
onClickOutside={onClickOutside}
isDisabled={isDisabled}
isVisible={isVisible}
>
{renderDropDownList(dropDownAlignmentType)}
</SelectBoundary>
)
}
}
export { Select }
export default Select