Initial commit with files

Still need to fix the imports
This commit is contained in:
Ryan Gossiaux
2021-12-13 17:13:47 -08:00
parent 42aba8a158
commit db9ec57065
56 changed files with 4034 additions and 0 deletions

View File

@@ -0,0 +1,84 @@
function assertNever(x: never): never {
throw new Error('Unexpected object: ' + x)
}
export enum Focus {
/** Focus the first non-disabled item. */
First,
/** Focus the previous non-disabled item. */
Previous,
/** Focus the next non-disabled item. */
Next,
/** Focus the last non-disabled item. */
Last,
/** Focus a specific item based on the `id` of the item. */
Specific,
/** Focus no items at all. */
Nothing,
}
export function calculateActiveIndex<TItem>(
action: { focus: Focus.Specific; id: string } | { focus: Exclude<Focus, Focus.Specific> },
resolvers: {
resolveItems(): TItem[]
resolveActiveIndex(): number | null
resolveId(item: TItem): string
resolveDisabled(item: TItem): boolean
}
) {
let items = resolvers.resolveItems()
if (items.length <= 0) return null
let currentActiveIndex = resolvers.resolveActiveIndex()
let activeIndex = currentActiveIndex ?? -1
let nextActiveIndex = (() => {
switch (action.focus) {
case Focus.First:
return items.findIndex(item => !resolvers.resolveDisabled(item))
case Focus.Previous: {
let idx = items
.slice()
.reverse()
.findIndex((item, idx, all) => {
if (activeIndex !== -1 && all.length - idx - 1 >= activeIndex) return false
return !resolvers.resolveDisabled(item)
})
if (idx === -1) return idx
return items.length - 1 - idx
}
case Focus.Next:
return items.findIndex((item, idx) => {
if (idx <= activeIndex) return false
return !resolvers.resolveDisabled(item)
})
case Focus.Last: {
let idx = items
.slice()
.reverse()
.findIndex(item => !resolvers.resolveDisabled(item))
if (idx === -1) return idx
return items.length - 1 - idx
}
case Focus.Specific:
return items.findIndex(item => resolvers.resolveId(item) === action.id)
case Focus.Nothing:
return null
default:
assertNever(action)
}
})()
return nextActiveIndex === -1 ? currentActiveIndex : nextActiveIndex
}