UNPKG

choices.js

Version:

A vanilla JS customisable text input/select box plugin

87 lines (73 loc) 2.29 kB
/* eslint-disable */ import { ActionType, Options, State } from '../interfaces'; import { StateUpdate } from '../interfaces/store'; import { ChoiceActions } from '../actions/choices'; import { ItemActions } from '../actions/items'; import { SearchResult } from '../interfaces/search'; import { ChoiceFull } from '../interfaces/choice-full'; type ActionTypes = ChoiceActions | ItemActions; type StateType = State['choices']; export default function choices(s: StateType, action: ActionTypes, context?: Options): StateUpdate<StateType> { let state = s; let update = true; switch (action.type) { case ActionType.ADD_CHOICE: { state.push(action.choice); break; } case ActionType.REMOVE_CHOICE: { action.choice.choiceEl = undefined; if (action.choice.group) { action.choice.group.choices = action.choice.group.choices.filter((obj) => obj.id !== action.choice.id); } state = state.filter((obj) => obj.id !== action.choice.id); break; } case ActionType.ADD_ITEM: case ActionType.REMOVE_ITEM: { action.item.choiceEl = undefined; break; } case ActionType.FILTER_CHOICES: { // avoid O(n^2) algorithm complexity when searching/filtering choices const scoreLookup: SearchResult<ChoiceFull>[] = []; action.results.forEach((result) => { scoreLookup[result.item.id] = result; }); state.forEach((choice) => { const result = scoreLookup[choice.id]; if (result !== undefined) { choice.score = result.score; choice.rank = result.rank; choice.active = true; } else { choice.score = 0; choice.rank = 0; choice.active = false; } if (context && context.appendGroupInSearch) { choice.choiceEl = undefined; } }); break; } case ActionType.ACTIVATE_CHOICES: { state.forEach((choice) => { choice.active = action.active; if (context && context.appendGroupInSearch) { choice.choiceEl = undefined; } }); break; } case ActionType.CLEAR_CHOICES: { state = []; break; } default: { update = false; break; } } return { state, update }; }