Skip to content

Instantly share code, notes, and snippets.

@natew
Created February 4, 2016 00:58
Show Gist options
  • Save natew/f9fa2adea669c3c40d5f to your computer and use it in GitHub Desktop.
Save natew/f9fa2adea669c3c40d5f to your computer and use it in GitHub Desktop.
attempting to corral giant view
function getSource() {
if (source.hasOwnProperty('length')) {
return new Map(source.map((item) => [item, item]))
} else {
return new Map(Object.keys(source).map((key) => [key, source[key]]))
}
}
function getQuery(key) {
return !multiple && value ? getSource().get(key) : ''
}
function suggestions(_query) {
const suggestions = new Map()
const query = _query.toLowerCase().trim() || ''
const values = values()
for (const [key, value] of getSource()) {
if (!values.has(key) && value.toLowerCase().trim().startsWith(query)) {
suggestions.set(key, value)
}
}
return suggestions
}
function calculateDirection(current, input) {
if (current === 'auto') {
const client = ReactDOM.findDOMNode(input).getBoundingClientRect()
const screen_height = window.innerHeight || document.documentElement.offsetHeight
const up = client.top > ((screen_height / 2) + client.height)
return up ? 'up' : 'down'
} else {
return current
}
}
view Autocomplete {
prop className:? string
prop direction:? string = 'auto'//oneOf(['auto', 'up', 'down'])
prop disabled:? bool
prop error:? string
prop label:? string
prop multiple:? bool = true
prop onChange:? func = Flint.noop
prop source:? any = {}
prop value: any
let active = false
let query = ''
let focus = false
// shouldupdate
view.shouldUpdate((nextProps, nextState) => {
if (!focus && nextState.focus && direction === POSITION.AUTO) {
const _direction = calculateDirection(direction, view.refs.input)
if (direction !== nextProps.direction) {
direction = _direction
return false
}
}
return true
})
// state mutations
let handleChange = (keys, event) => {
const key = multiple ? keys : keys[0]
onChange(key, event)
query = getQuery(key)
focus = false
view.refs.input.blur()
}
let handleQueryKeyUp = (event) => {
if (event.which === 13 && active) select(active, event)
if (event.which === 27) view.refs.input.blur()
if ([40, 38].indexOf(event.which) !== -1) {
const suggestionsKeys = [...suggestions(query).keys()]
let index = suggestionsKeys.indexOf(active) + (event.which === 40 ? +1 : -1)
if (index < 0) index = suggestionsKeys.length - 1
if (index >= suggestionsKeys.length) index = 0
active = suggestionsKeys[index]
}
}
let values = () => {
const valueMap = new Map()
console.log(value)
const values = multiple ? value : [value]
for (const [k, v] of getSource()) {
console.log(values)
if (values.indexOf(k) !== -1) valueMap.set(k, v)
}
return valueMap
}
let select = (key, event) => {
events.pauseEvent(event)
const values = values(value)
handleChange([key, ...values.keys()], event)
}
let unselect = (key, event) => {
const values = values(value)
values.delete(key)
handleChange([...values.keys()], event)
}
let renderSelected = () => {
if (multiple) {
const selectedItems = [...values()].map(([key, value]) => {
return <li key={key} className={style.value} onClick={unselect.bind( key)}>{value}</li>
})
return <ul className={style.values}>{selectedItems}</ul>
}
}
let renderSuggestions = () => {
const suggestions = suggestions(query).map(([key, value]) => {
const className = ClassNames(style.suggestion, {[style.active]: active === key})
return (
<li
key={key}
className={className}
onMouseDown={() => select(key)}
onMouseOver={() => active = key}>
{value}
</li>
)
})
const className = ClassNames(style.suggestions, {[style.up]: direction === 'up'})
return <ul ref='suggestions' className={className}>{suggestions}</ul>
return <h1>Iiiii</h1>
}
// end state mutations
// dom
view.render(() => {
return (
<autocomplete>
<area class={{ focus }}>
{renderSelected()}
<Input
ref='input'
class="input"
error={error}
label={label}
onBlur={() => focus = false}
onChange={(value) => query = value}
onFocus={() => {
view.refs.suggestions.scrollTop = 0
active = ''
focus = true
}}
onKeyUp={handleQueryKeyUp}
value={query}
/>
{renderSuggestions()}
</area>
<area class={{ focus }}>
<Input ref='input' class="" />
{renderSuggestions()}
</area>
</autocomplete>
)
})
// style
$ = {
position: `relative`,
padding: [unit(1), 0],
}
$label = {
fontSize: fontSizeTiny,
color: focus ? autocompleteColorPrimary : colorTextSecondary,
transition: `color animationDuration animationCurveDefault`,
}
$values = {
flexDirection: row,
flexWrap: `wrap`,
paddingBottom: $unit / 2,
}
$value = {
display: `inline-block`,
padding: autocompleteValuePadding,
margin: autocompleteValueMargin,
fontSize: fontSizeTiny,
color: autocompleteColorPrimaryContrast,
cursor: `pointer`,
backgroundColor: autocompleteColorPrimary,
borderRadius: autocompleteValueBorderRadius,
}
$suggestions = [
{
// @include no-webkit-scrollbar,
position: `absolute`,
zIndex: zIndexHigh,
width: percent(100),
maxHeight: 0,
marginTop: errored ? -inputUnderlineHeight : 0,
overflowX: `hidden`,
overflowY: `auto`,
visibility: `hidden`,
backgroundColor: autocompleteSuggestionsBackground,
transitionTimingFunction: animationCurveDefault,
transitionDuration: animationDuration,
transitionProperty: maxHeight, boxShadow,
bottom: up ? 0 : `auto`
},
focus && {
maxHeight: autocompleteOverflowMaxHeight,
visibility: `visible`,
boxShadow: zdepthShadow-1,
}
]
$suggestion = {
padding: autocompleteSuggestionPadding,
cursor: `pointer`,
backgroundColor: active ? autocompleteSuggestionActiveBackground : `auto`,
}
$input = {
paddingTop: 0,
paddingBottom: 0,
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment