Repository URL to install this package:
|
Version:
0.9.5 ▾
|
import React from 'react'
// import { cloneJSON } from 'chain-able-boost'
import { observable, action } from 'xmobx/mobx'
import { observer } from 'xmobx/mobx-react'
import { storiesOf } from '@storybook/react'
import { OnSelectChange, SelectProps } from 'molecules/SelectDropDown'
import {
SelectDropDown,
Option,
ActiveOption,
Select,
ActiveOptionProps,
OptionType,
OptionLabelValueType,
} from 'molecules/SelectDropDown'
import {
SelectionState,
} from 'src/state/SelectionState'
const cloneJSON = x => JSON.parse(JSON.stringify(x || {}))
const list = [
{
label: 'Apple',
value: 'apple',
isSelected: false,
},
{
label: 'Orange',
value: 'orange',
isSelected: false,
},
{
label: 'Mango',
value: 'mango',
isSelected: false,
isDisabled: true,
},
{
// for hidden - or isDisabled works for this if we filter
isVisible: false,
// isSelected
// isDisabled
label: 'Watermelon',
value: 'watermelon',
isSelected: false,
},
]
const handleDropDownChange = () => {
console.info('[Story/SelectDropdown] handleDropdownChange() called')
}
// @todo renderProp & radioGroup example
storiesOf('molecules/SelectDropDown', module)
.add('list', () => <SelectDropDown options={list} />)
.add('renderProp', () => {
const renderList = (props: SelectProps, state: SelectionState) => {
return <span>eh</span>
}
return <SelectDropDown label="eh" renderList={renderList} options={list} />
})
.add('custom ActiveOption', () => {
const renderActiveItem = (props: ActiveOptionProps) => (
<ActiveOption {...props} label="color" />
)
return (
<SelectDropDown
name="noname"
renderActiveItem={renderActiveItem}
options={list}
/>
)
})
.add('dropdown issue on rendering top and button view together', () => {
const state = new SelectionState()
const listJustInCaseOtherStory = cloneJSON(list)
state.decorateWithProps({ list: listJustInCaseOtherStory })
/**
* if `forwardRef` we can check if click includes EITHER dom
*/
return (
<React.Fragment>
<SelectDropDown
onClickOutside={() => { }}
state={state}
options={listJustInCaseOtherStory}
onChange={handleDropDownChange}
/>
<SelectDropDown
onClickOutside={() => { }}
state={state}
options={listJustInCaseOtherStory}
onChange={handleDropDownChange}
shouldBeAbsolute={true}
dropDownAlignmentType={'top'}
/>
</React.Fragment>
)
})
// .add('dropdown issue on rendering top and button view together', () => {
// const list1 = cloneJSON(list)
// const state = new SelectionState()
// state.decorateWithProps({ list })
// const list2 = cloneJSON(list)
// const state2 = new SelectionState()
// state2.decorateWithProps({ list: list2 })
// return (
// <React.Fragment>
// <SelectDropDown state={state} options={list2} onChange={handleDropDownChange} />
// <SelectDropDown
// state={state2}
// options={list2}
// onChange={handleDropDownChange}
// shouldBeAbsolute={true}
// dropDownAlignmentType={'top'}
// />
// </React.Fragment>
// )
// })
// .add('dropdown issue on rendering top and button view together', () => {
// const list1 = cloneJSON(list)
// const list2 = cloneJSON(list)
// return (
// <React.Fragment>
// <SelectDropDown options={list} onChange={handleDropDownChange} />
// <SelectDropDown
// options={list2}
// onChange={handleDropDownChange}
// shouldBeAbsolute={true}
// dropDownAlignmentType={'top'}
// />
// </React.Fragment>
// )
// })
// .add('dropdown issue on rendering top and button view together', () => {
// const state = new SelectionState()
// // we could check
// // 1. the current scroll
// // 2. the distance to the bottom / left / right / top of the page
// // 3. according to scroll position, update the styles
// class SelectDropDownResponsive extends React.PureComponent {
// render() {
// const view = <SelectDropDown state={state} options={list} onChange={handleDropDownChange} />
// return view
// }
// }
// const view = <SelectDropDownResponsive />
// return (
// <React.Fragment>
// {view}
// {view}
// </React.Fragment>
// )
// })
.add('Absolute Dropdown', () => {
const renderActiveItem = (props: ActiveOptionProps) => (
<ActiveOption {...props} label="color" />
)
return (
<SelectDropDown
name="noname"
renderActiveItem={renderActiveItem}
options={list}
shouldBeAbsolute={true}
/>
)
})
.add('Top Alignment Dropdown', () => {
const renderActiveItem = (props: ActiveOptionProps) => (
<ActiveOption {...props} label="color" />
)
return (
<SelectDropDown
name="noname"
renderActiveItem={renderActiveItem}
options={list}
dropDownAlignmentType="top"
/>
)
})
.add('Top Alignment Dropdown with Absolute', () => {
const renderActiveItem = (props: ActiveOptionProps) => (
<ActiveOption {...props} label="color" />
)
return (
<SelectDropDown
name="noname"
renderActiveItem={renderActiveItem}
options={list}
shouldBeAbsolute={true}
dropDownAlignmentType="top"
/>
)
})
.add('isDisabled', () => {
return <SelectDropDown isDisabled={true} label={'eh'} list={[]} />
})
// @todo styled.withComponent
.add('with color', () => {
const colorList = [
{
label: 'Blue',
value: 'blue',
image: 'https://eh.com',
title: 'blues clues',
type: 'color',
name: 'color',
},
{
label: 'Green',
value: 'green',
image: 'https://green.com',
title: 'greens clues',
type: 'color',
name: 'color',
},
]
return <SelectDropDown name="colored" options={colorList} />
})
// .add('renderEmpty', () => {
// return '@todo'
// // @todo
// // if (list.length === 0) {
// // return renderEmpty(this.props, this.state)
// // }
// })
// .add('RadioGroup', () => {
// // const renderStoreLocatorFilter = (props, state) => {
// // return props.list.map(renderStoreLocatorItem)
// // }
// // <SelectDropDropDown renderList={renderStoreLocatorFilter} />
// })
.add('events', () => {
const onSelectChange: OnSelectChange = (
value,
props: SelectProps,
state: SelectionState
) => {
console.log('onSelectChange', value)
console.dir({ props, state })
}
return (
<SelectDropDown
name="eh"
onSelectChange={onSelectChange}
options={list}
/>
)
})
.add('SIMPLE MagicLabel option label', () => {
const MagicLabelActiveOption = styled.withComponent(ActiveOption) `
transition: color .5s cubic-bezier(0.075, 0.82, 0.165, 1);
${props =>
props.isVisible &&
props.isMagicLabel &&
styled.css `
color: grey;
`};
${props =>
!props.isVisible &&
props.isMagicLabel &&
styled.css `
color: red;
`};
`
class MagicSelect extends React.Component {
static defaultProps = {
label: 'Magic',
}
render() {
const renderActiveItem = (props: ActiveOptionProps, state) => {
const attributes = { ...props }
console.log('[SelectDropDown]', props)
// example: you have "Color", until you pick one (like "Blue")
if (!props.label) {
attributes.label = this.props.label
}
// example: you expand "Blue" => "Color" (since "Blue" is an option)
if (state.isVisible) {
attributes.label = this.props.label
// then we could do
// some extra styles when it's open and we show a label
attributes.isVisible = state.isVisible
attributes.isMagicLabel = true
}
return <MagicLabelActiveOption {...attributes} />
}
return (
<SelectDropDown renderActiveItem={renderActiveItem} options={list} />
)
}
}
return <MagicSelect label="@todo: Fix when auto selected" />
})
.add('reproducing updating props', () => {
/**
* @note - if these are not observable
* it always will reset when we make
* this.list = [one, two, three, four]
*/
const one = observable({
label: 'eh',
value: 'eh',
isDisabled: false,
isSelected: true,
})
const two = observable({
label: 'moose',
value: 'moose',
isDisabled: false,
isSelected: false,
})
const three = observable({
label: 'beaver',
value: 'beaver',
isDisabled: false,
isSelected: false,
})
/**
* @note - in this example, notice the 4th item isn't even added
* ^ now is fixed with componentWillReact
*/
const four = observable({
label: 'igloo',
value: 'igloo',
isDisabled: false,
isSelected: false,
})
class OneProduct {
// @note - when it is observable, it accurately reproduces
@observable list = [one, two, three]
// @note - reproducing it not being observable...
// when it is not obsrvable, adding an item only makes the last itejm added (after clicking) not update
// list = [one, two, three]
// for making sure NonUpdatingSelectDropDownProductOptions updates
@observable index: number = 0
@action
selectSku(value: OptionLabelValueType): void {
console.debug('[SelectDropDownStory] selectSku')
console.log(value)
// @note - this isn't reflected
// disable
this.list[0].isDisabled = true
// making a new list each time
this.index += 1
// could add/remove or enable/disable
// based on options
// for full reproducing
this.list = [one, two, three, four]
// if (this.list.length === 3) {
// this.list.push(four)
// }
}
}
const state = new OneProduct()
@observer
class NonUpdatingSelectDropDownProductOptions extends React.Component {
handleOnChange(event: Event, item: OptionType, selectState: SelectionState) {
console.debug('[SelectDropDownStory] handleOnChange')
state.selectSku(item.value)
}
render() {
// triggering index, if list isn't observable
console.debug('[SelectDropDownStory] render: ' + state.index)
// dir doesn't trigger until it's expanded
console.dir({ list: state.list, index: state.index })
return <SelectDropDown list={state.list} onChange={this.handleOnChange} />
}
}
return <NonUpdatingSelectDropDownProductOptions />
})
// .add('OVERCOMPLICATED NOT WORKING MagicLabel option label', () => {
// /**
// * 1. by default, this magic label isSelected - so it shows
// * 2. when we expand, we take it out of the array
// */
// const magicLabelItem = {
// label: 'Fruit',
// value: 'fruit',
// isSelected: true,
// }
// const magicList = [
// magicLabelItem,
// {
// label: 'Apple',
// value: 'apple',
// isSelected: false,
// },
// {
// label: 'Orange',
// value: 'orange',
// isSelected: false,
// },
// ].map(toCommonState)
// @observer
// class MagicLabel extends React.Component {
// render() {
// const onSelectChange: OnSelectChange = (
// value,
// props: SelectProps,
// state: SelectableState
// ) => {
// console.debug('[SelectDropDown_Story] onSelectChange')
// console.dir({ props, state, value })
// }
// // @note - this probably would need to be called onChange
// // event
// const onClickActiveOption = (activeOptionProps, activeState) => {
// console.debug('[SelectDropDown_Story] onClickActiveOption')
// console.dir(activeOptionProps)
// // is hidden, and after calling original click handler, isVisible = true
// if (activeState.isVisible === false) {
// // then we want to do the pop shift stuff
// } else {
// // would mean we closed it
// return
// }
// // could also be done with isVisible & isSelected
// if (magicList.length === 3) {
// // if we have 3, remove the first one
// magicList.shift()
// } else {
// // otherwise, add to the begining
// magicList.unshift(magicLabelItem)
// }
// }
// const attributes = {
// renderActiveItem: undefined,
// // onSelectChange,
// // onChange: onSelectChange,
// list: magicList,
// }
// /**
// * @note - we also could handle this in the active item
// */
// attributes.renderActiveItem = (activeProps: OptionType, activeState: SelectableState) => {
// const onClick = event => {
// // so this is called before
// onClickActiveOption(activeProps, activeState)
// // this will make it visible...
// activeProps.onClick(activeProps, activeState)
// }
// return <ActiveOption {...activeProps} onClick={onClick} state={activeState} />
// }
// return (
// <SelectDropDown {...attributes} />
// )
// }
// }
// return <MagicLabel />
// // })
// .add('Option', () => <Option />)
// .add('Select', () => <Select />)