@szhsin/react-autocomplete
Advanced tools
Comparing version 0.9.4 to 0.9.5
@@ -23,6 +23,4 @@ 'use strict'; | ||
const useAutocomplete = ({ | ||
value, | ||
onChange, | ||
feature: useFeature, | ||
traversal: useTraversal, | ||
isItemSelected, | ||
@@ -43,14 +41,9 @@ ...passthrough | ||
}; | ||
const contextual = { | ||
const featureYield = useFeature({ | ||
id: useId(), | ||
tmpValue, | ||
setTmpValue, | ||
value, | ||
onChange: newValue => value != newValue && (onChange == null ? void 0 : onChange(newValue)), | ||
onChange: newValue => passthrough.value != newValue && (onChange == null ? void 0 : onChange(newValue)), | ||
...passthrough, | ||
...state | ||
}; | ||
const featureYield = useFeature({ | ||
...contextual, | ||
...useTraversal(contextual) | ||
}); | ||
@@ -196,3 +189,2 @@ return { | ||
onAction, | ||
traverse, | ||
value, | ||
@@ -232,2 +224,21 @@ onChange, | ||
}; | ||
const traverse = isForward => { | ||
const baseIndex = rovingText ? -1 : 0; | ||
let newItem, | ||
nextIndex = items.findIndex(item => isEqual(focusItem, item)), | ||
itemCounter = 0; | ||
const itemLength = items.length; | ||
for (;;) { | ||
if (isForward) { | ||
if (++nextIndex >= itemLength) nextIndex = baseIndex; | ||
} else { | ||
if (--nextIndex < baseIndex) nextIndex = itemLength - 1; | ||
} | ||
newItem = items[nextIndex]; | ||
if (!newItem || !(isItemDisabled != null && isItemDisabled(newItem))) break; | ||
if (++itemCounter >= itemLength) return; | ||
} | ||
setFocusItem(newItem); | ||
if (rovingText) setTmpValue(getItemValue(newItem)); | ||
}; | ||
const listId = getId(id, 'l'); | ||
@@ -306,4 +317,3 @@ let ariaActivedescendant; | ||
if (open) { | ||
const nextItem = traverse(e.key != 'ArrowUp'); | ||
if (rovingText) setTmpValue(getItemValue(nextItem)); | ||
traverse(e.key != 'ArrowUp'); | ||
} else { | ||
@@ -572,47 +582,9 @@ setOpen(true); | ||
const linearTraversal = ({ | ||
traverseInput, | ||
items | ||
}) => ({ | ||
focusItem, | ||
setFocusItem, | ||
isItemDisabled, | ||
isEqual | ||
}) => { | ||
return { | ||
items, | ||
traverse: isForward => { | ||
const baseIndex = traverseInput ? -1 : 0; | ||
let newItem, | ||
nextIndex = items.findIndex(item => isEqual(focusItem, item)), | ||
itemCounter = 0; | ||
const itemLength = items.length; | ||
for (;;) { | ||
if (isForward) { | ||
if (++nextIndex >= itemLength) nextIndex = baseIndex; | ||
} else { | ||
if (--nextIndex < baseIndex) nextIndex = itemLength - 1; | ||
} | ||
newItem = items[nextIndex]; | ||
if (!newItem || !(isItemDisabled != null && isItemDisabled(newItem))) break; | ||
if (++itemCounter >= itemLength) return focusItem; | ||
} | ||
setFocusItem(newItem); | ||
return newItem; | ||
} | ||
}; | ||
}; | ||
const isArray = Array.isArray; | ||
const groupedTraversal = ({ | ||
groupedItems, | ||
getItemsInGroup, | ||
...restProps | ||
const getGroupedItems = ({ | ||
groups, | ||
getItemsInGroup | ||
}) => { | ||
const groups = isArray(groupedItems) ? groupedItems : Object.values(groupedItems); | ||
const items = groups.reduce((accu, group) => accu.concat(isArray(group) ? group : getItemsInGroup ? getItemsInGroup(group) : []), []); | ||
return linearTraversal({ | ||
...restProps, | ||
items | ||
}); | ||
const groupArray = isArray(groups) ? groups : Object.values(groups); | ||
return groupArray.reduce((accu, group) => accu.concat(isArray(group) ? group : getItemsInGroup ? getItemsInGroup(group) : []), []); | ||
}; | ||
@@ -624,4 +596,3 @@ | ||
exports.dropdown = dropdown; | ||
exports.groupedTraversal = groupedTraversal; | ||
exports.linearTraversal = linearTraversal; | ||
exports.getGroupedItems = getGroupedItems; | ||
exports.mergeModules = mergeModules; | ||
@@ -628,0 +599,0 @@ exports.multiSelect = multiSelect; |
@@ -23,3 +23,2 @@ import { ButtonProps, getId } from '../../common.js'; | ||
onAction, | ||
traverse, | ||
value, | ||
@@ -59,2 +58,21 @@ onChange, | ||
}; | ||
const traverse = isForward => { | ||
const baseIndex = rovingText ? -1 : 0; | ||
let newItem, | ||
nextIndex = items.findIndex(item => isEqual(focusItem, item)), | ||
itemCounter = 0; | ||
const itemLength = items.length; | ||
for (;;) { | ||
if (isForward) { | ||
if (++nextIndex >= itemLength) nextIndex = baseIndex; | ||
} else { | ||
if (--nextIndex < baseIndex) nextIndex = itemLength - 1; | ||
} | ||
newItem = items[nextIndex]; | ||
if (!newItem || !(isItemDisabled != null && isItemDisabled(newItem))) break; | ||
if (++itemCounter >= itemLength) return; | ||
} | ||
setFocusItem(newItem); | ||
if (rovingText) setTmpValue(getItemValue(newItem)); | ||
}; | ||
const listId = getId(id, 'l'); | ||
@@ -133,4 +151,3 @@ let ariaActivedescendant; | ||
if (open) { | ||
const nextItem = traverse(e.key != 'ArrowUp'); | ||
if (rovingText) setTmpValue(getItemValue(nextItem)); | ||
traverse(e.key != 'ArrowUp'); | ||
} else { | ||
@@ -137,0 +154,0 @@ setOpen(true); |
@@ -5,6 +5,4 @@ import { useRef, useState } from 'react'; | ||
const useAutocomplete = ({ | ||
value, | ||
onChange, | ||
feature: useFeature, | ||
traversal: useTraversal, | ||
isItemSelected, | ||
@@ -25,14 +23,9 @@ ...passthrough | ||
}; | ||
const contextual = { | ||
const featureYield = useFeature({ | ||
id: useId(), | ||
tmpValue, | ||
setTmpValue, | ||
value, | ||
onChange: newValue => value != newValue && (onChange == null ? void 0 : onChange(newValue)), | ||
onChange: newValue => passthrough.value != newValue && (onChange == null ? void 0 : onChange(newValue)), | ||
...passthrough, | ||
...state | ||
}; | ||
const featureYield = useFeature({ | ||
...contextual, | ||
...useTraversal(contextual) | ||
}); | ||
@@ -39,0 +32,0 @@ return { |
@@ -11,4 +11,3 @@ export { useCombobox } from './hooks/useCombobox.js'; | ||
export { supercomplete } from './features/molecule/supercomplete.js'; | ||
export { linearTraversal } from './traversals/linearTraversal.js'; | ||
export { groupedTraversal } from './traversals/groupedTraversal.js'; | ||
export { getGroupedItems } from './utils/getGroupedItems.js'; | ||
export { mergeModules } from './utils/mergeModules.js'; |
{ | ||
"name": "@szhsin/react-autocomplete", | ||
"version": "0.9.4", | ||
"version": "0.9.5", | ||
"description": "", | ||
@@ -5,0 +5,0 @@ "author": "Zheng Song", |
/// <reference types="react" /> | ||
import type { AutocompleteProps } from '../types'; | ||
declare const useAutocomplete: <T, FeatureYield extends object>({ value, onChange, feature: useFeature, traversal: useTraversal, isItemSelected, ...passthrough }: AutocompleteProps<T, FeatureYield>) => { | ||
declare const useAutocomplete: <T, FeatureYield extends object>({ onChange, feature: useFeature, isItemSelected, ...passthrough }: AutocompleteProps<T, FeatureYield>) => { | ||
inputRef: import("react").RefObject<HTMLInputElement>; | ||
@@ -5,0 +5,0 @@ focusItem: T | undefined; |
@@ -11,5 +11,4 @@ export { useCombobox } from './hooks/useCombobox'; | ||
export { type SupercompleteFeature, supercomplete } from './features/molecule/supercomplete'; | ||
export { linearTraversal } from './traversals/linearTraversal'; | ||
export { groupedTraversal } from './traversals/groupedTraversal'; | ||
export { getGroupedItems } from './utils/getGroupedItems'; | ||
export { mergeModules } from './utils/mergeModules'; | ||
export type { ComboboxProps, MultiSelectProps, Feature, MergedFeature, FeatureProps } from './types'; |
@@ -37,4 +37,5 @@ import type { HTMLAttributes, InputHTMLAttributes, ButtonHTMLAttributes, LabelHTMLAttributes } from 'react'; | ||
onAction?: (item: T) => void; | ||
value: string | undefined; | ||
value?: string | undefined; | ||
onChange: (value?: string | undefined) => void; | ||
items: T[]; | ||
} | ||
@@ -55,9 +56,2 @@ export interface AdapterProps<T> extends ContextualOrReturn<T> { | ||
} | ||
export interface TraversalProps { | ||
traverseInput?: boolean; | ||
} | ||
export type Traversal<T> = (cx: Contextual<T>) => { | ||
traverse: (isForward: boolean) => T | null | undefined; | ||
items: T[]; | ||
}; | ||
export interface FeatureProps<T> { | ||
@@ -73,9 +67,8 @@ rovingText?: boolean; | ||
export type AutocompleteFeatureProps<T> = Pick<FeatureProps<T>, 'rovingText' | 'select' | 'selectOnBlur' | 'deselectOnClear' | 'deselectOnChange' | 'closeOnSelect'>; | ||
export type Feature<T, Yield extends object> = (cx: Contextual<T> & ReturnType<Traversal<T>>) => Yield; | ||
export type Feature<T, Yield extends object> = (cx: Contextual<T>) => Yield; | ||
export type MergedFeatureYield<T, Features> = Features extends readonly [Feature<T, infer S>] ? S : Features extends readonly [Feature<T, infer F>, ...infer R] ? F & MergedFeatureYield<T, R> : never; | ||
export type MergedFeature<T, Features> = Feature<T, MergedFeatureYield<T, Features>>; | ||
export type BaseProps<T, FeatureYield extends object> = Partial<PassthroughProps<T>> & { | ||
export interface BaseProps<T, FeatureYield extends object> extends PassthroughProps<T> { | ||
feature: Feature<T, FeatureYield>; | ||
traversal: Traversal<T>; | ||
}; | ||
} | ||
export type AutocompleteProps<T, FeatureYield extends object> = BaseProps<T, FeatureYield> & AdapterProps<T> & Equality<T>; | ||
@@ -82,0 +75,0 @@ export type GetItemValue<T> = { |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
51503
58
1456