@szhsin/react-autocomplete
Advanced tools
Comparing version 0.8.10 to 0.9.0
@@ -5,11 +5,11 @@ 'use strict'; | ||
const adaptGetItemValue = getItemValue => item => item == null ? '' : getItemValue ? getItemValue(item) : item.toString(); | ||
const useAutocomplete = ({ | ||
value, | ||
onChange, | ||
selectedItem, | ||
onSelectedItemChange, | ||
isItemDisabled = () => false, | ||
feature: useFeature, | ||
traversal: useTraversal, | ||
getItemValue: _getItemValue | ||
...adapterProps | ||
}) => { | ||
@@ -20,3 +20,2 @@ const inputRef = react.useRef(null); | ||
const [focusItem, setFocusItem] = react.useState(); | ||
const getItemValue = item => item == null ? '' : _getItemValue ? _getItemValue(item) : item.toString(); | ||
const state = { | ||
@@ -29,11 +28,9 @@ focusItem, | ||
const contextual = { | ||
inputRef, | ||
isItemDisabled, | ||
tmpValue, | ||
setTmpValue, | ||
getItemValue, | ||
isItemDisabled, | ||
value, | ||
onChange: newValue => value != newValue && (onChange == null ? void 0 : onChange(newValue)), | ||
selectedItem, | ||
onSelectedItemChange: newItem => newItem !== selectedItem && (onSelectedItemChange == null ? void 0 : onSelectedItemChange(newItem)), | ||
inputRef, | ||
...adapterProps, | ||
...state | ||
@@ -51,2 +48,58 @@ }; | ||
const useCombobox = ({ | ||
getItemValue: _getItemValue, | ||
selected, | ||
onSelectChange, | ||
flipOnSelect, | ||
...passthrough | ||
}) => { | ||
const getItemValue = adaptGetItemValue(_getItemValue); | ||
return useAutocomplete({ | ||
...passthrough, | ||
getItemValue, | ||
getSelectedValue: () => getItemValue(selected), | ||
onSelectChange: newItem => { | ||
if (newItem !== selected) { | ||
onSelectChange == null || onSelectChange(newItem); | ||
} else if (flipOnSelect) { | ||
onSelectChange == null || onSelectChange(); | ||
} | ||
} | ||
}); | ||
}; | ||
const useMultiSelect = ({ | ||
getItemValue, | ||
selected, | ||
onSelectChange: _onSelectChange = () => {}, | ||
flipOnSelect, | ||
...passthrough | ||
}) => { | ||
const removeItem = item => _onSelectChange(selected.filter(s => s !== item)); | ||
const removeSelect = item => { | ||
if (item) { | ||
removeItem(item); | ||
} else { | ||
_onSelectChange(selected.slice(0, selected.length - 1)); | ||
} | ||
}; | ||
return { | ||
...useAutocomplete({ | ||
...passthrough, | ||
getItemValue: adaptGetItemValue(getItemValue), | ||
getSelectedValue: () => '', | ||
onSelectChange: item => { | ||
if (!item) return; | ||
if (selected.includes(item)) { | ||
if (flipOnSelect) removeItem(item); | ||
} else { | ||
_onSelectChange([...selected, item]); | ||
} | ||
}, | ||
removeSelect | ||
}), | ||
removeSelect | ||
}; | ||
}; | ||
const useLayoutEffect = typeof window !== 'undefined' && window.document && window.document.createElement ? react.useLayoutEffect : react.useEffect; | ||
@@ -87,2 +140,16 @@ const findOverflowAncestor = element => { | ||
const useFocusCapture = focusRef => { | ||
const mutable = useMutableState({}); | ||
return [() => { | ||
if (document.activeElement === focusRef.current) mutable.a = 1; | ||
}, () => { | ||
if (mutable.a) { | ||
var _focusRef$current; | ||
mutable.a = 0; | ||
(_focusRef$current = focusRef.current) == null || _focusRef$current.focus(); | ||
return true; | ||
} | ||
}]; | ||
}; | ||
const scrollIntoView = element => element == null ? void 0 : element.scrollIntoView({ | ||
@@ -96,5 +163,8 @@ block: 'nearest' | ||
deselectOnClear = true, | ||
deselectOnChange = true | ||
deselectOnChange = true, | ||
closeOnSelect = true | ||
} = {}) => ({ | ||
getItemValue, | ||
getSelectedValue, | ||
onSelectChange, | ||
isItemDisabled, | ||
@@ -106,4 +176,2 @@ traverse, | ||
setTmpValue, | ||
selectedItem, | ||
onSelectedItemChange, | ||
focusItem, | ||
@@ -116,18 +184,18 @@ setFocusItem, | ||
var _ref; | ||
const mutable = useMutableState({}); | ||
const inputValue = (_ref = tmpValue || value) != null ? _ref : getItemValue(selectedItem); | ||
const updateValue = newValue => { | ||
const endIndex = newValue.length; | ||
const [startCapture, stopCapture] = useFocusCapture(inputRef); | ||
const inputValue = (_ref = tmpValue || value) != null ? _ref : getSelectedValue(); | ||
const selectItem = item => { | ||
onSelectChange(item); | ||
const itemValue = getItemValue(item); | ||
const endIndex = itemValue.length; | ||
inputRef.current.setSelectionRange(endIndex, endIndex); | ||
if (!select) onChange(newValue); | ||
if (!select) onChange(itemValue); | ||
}; | ||
const updateAll = item => { | ||
onSelectedItemChange(item); | ||
updateValue(getItemValue(item)); | ||
}; | ||
const closeList = () => { | ||
setOpen(false); | ||
const closeList = isSelecting => { | ||
setFocusItem(); | ||
setTmpValue(); | ||
if (select) onChange(); | ||
if (!isSelecting || closeOnSelect) { | ||
setOpen(false); | ||
if (select) onChange(); | ||
} | ||
}; | ||
@@ -138,5 +206,3 @@ return { | ||
tabIndex: -1, | ||
onMouseDown: () => { | ||
if (document.activeElement === inputRef.current) mutable.a = 1; | ||
}, | ||
onMouseDown: startCapture, | ||
onClick: () => { | ||
@@ -149,9 +215,7 @@ var _inputRef$current; | ||
setFocusItem(); | ||
if (deselectOnClear) onSelectedItemChange(); | ||
if (deselectOnClear) onSelectChange(); | ||
} | ||
}), | ||
getListProps: () => ({ | ||
onMouseDown: () => { | ||
mutable.a = 1; | ||
} | ||
onMouseDown: startCapture | ||
}), | ||
@@ -164,4 +228,4 @@ getItemProps: ({ | ||
if (!isItemDisabled(item)) { | ||
updateAll(item); | ||
closeList(); | ||
selectItem(item); | ||
closeList(true); | ||
} | ||
@@ -179,15 +243,10 @@ } | ||
onChange(newValue); | ||
if (!select && deselectOnChange || deselectOnClear && !newValue) onSelectedItemChange(); | ||
if (!select && deselectOnChange || deselectOnClear && !newValue) { | ||
onSelectChange(); | ||
} | ||
}, | ||
onBlur: ({ | ||
target | ||
}) => { | ||
if (mutable.a) { | ||
mutable.a = 0; | ||
target.focus(); | ||
return; | ||
} | ||
if (!open) return; | ||
onBlur: () => { | ||
if (stopCapture() || !open) return; | ||
if (selectOnBlur && focusItem) { | ||
updateAll(focusItem); | ||
selectItem(focusItem); | ||
} | ||
@@ -210,4 +269,4 @@ closeList(); | ||
if (open && focusItem) { | ||
updateAll(focusItem); | ||
closeList(); | ||
selectItem(focusItem); | ||
closeList(true); | ||
} | ||
@@ -220,2 +279,3 @@ break; | ||
}, | ||
onMouseDown: e => e.stopPropagation(), | ||
onClick: () => setOpen(true) | ||
@@ -249,2 +309,13 @@ }) | ||
const useToggle = (open, setOpen) => { | ||
const mutable = useMutableState({}); | ||
return [() => mutable.a = open, () => { | ||
if (mutable.a) { | ||
mutable.a = 0; | ||
} else { | ||
setOpen(true); | ||
} | ||
}]; | ||
}; | ||
const inputToggle = () => ({ | ||
@@ -255,3 +326,4 @@ inputRef, | ||
}) => { | ||
const mutable = useMutableState({}); | ||
const [startToggle, stopToggle] = useToggle(open, setOpen); | ||
const [startCapture, stopCapture] = useFocusCapture(inputRef); | ||
return { | ||
@@ -261,12 +333,8 @@ getToggleProps: () => ({ | ||
onMouseDown: () => { | ||
mutable.b = open; | ||
mutable.c = 1; | ||
startToggle(); | ||
startCapture(); | ||
}, | ||
onClick: () => { | ||
var _inputRef$current; | ||
if (mutable.b) { | ||
mutable.b = 0; | ||
} else { | ||
setOpen(true); | ||
} | ||
stopToggle(); | ||
(_inputRef$current = inputRef.current) == null || _inputRef$current.focus(); | ||
@@ -276,10 +344,3 @@ } | ||
getInputProps: () => ({ | ||
onBlur: ({ | ||
target | ||
}) => { | ||
if (mutable.c) { | ||
mutable.c = 0; | ||
target.focus(); | ||
} | ||
} | ||
onBlur: stopCapture | ||
}) | ||
@@ -289,5 +350,7 @@ }; | ||
const autocomplete = props => mergeFeatures(autocompleteLite(props), inputToggle()); | ||
const autocomplete = (props = {}) => mergeFeatures(autocompleteLite(props), inputToggle()); | ||
const dropdownToggle = () => ({ | ||
const dropdownToggle = ({ | ||
closeOnSelect = true | ||
}) => ({ | ||
inputRef, | ||
@@ -300,3 +363,3 @@ open, | ||
}) => { | ||
const mutable = useMutableState({}); | ||
const [startToggle, stopToggle] = useToggle(open, setOpen); | ||
const toggleRef = react.useRef(null); | ||
@@ -316,12 +379,4 @@ const inputValue = tmpValue || value || ''; | ||
ref: toggleRef, | ||
onMouseDown: () => { | ||
mutable.a = open; | ||
}, | ||
onClick: () => { | ||
if (mutable.a) { | ||
mutable.a = 0; | ||
} else { | ||
setOpen(true); | ||
} | ||
}, | ||
onMouseDown: startToggle, | ||
onClick: stopToggle, | ||
onKeyDown: e => { | ||
@@ -343,5 +398,3 @@ const { | ||
} = e; | ||
if (key === 'Escape') focusToggle(); | ||
if (key === 'Enter' && focusItem) { | ||
e.preventDefault(); | ||
if (key === 'Escape' || closeOnSelect && focusItem && key === 'Enter') { | ||
focusToggle(); | ||
@@ -354,8 +407,51 @@ } | ||
const dropdown = props => mergeFeatures(autocompleteLite({ | ||
const dropdown = (props = {}) => mergeFeatures(autocompleteLite({ | ||
...props, | ||
select: true, | ||
deselectOnClear: false | ||
}), dropdownToggle()); | ||
}), dropdownToggle(props)); | ||
const inputFocus = () => () => { | ||
const [focused, setFocused] = react.useState(false); | ||
return { | ||
focused, | ||
getInputProps: () => ({ | ||
onFocusCapture: () => setFocused(true), | ||
onBlurCapture: () => setFocused(false) | ||
}) | ||
}; | ||
}; | ||
const multiInput = () => ({ | ||
inputRef, | ||
removeSelect | ||
}) => { | ||
const [startCapture, stopCapture] = useFocusCapture(inputRef); | ||
return { | ||
getInputWrapperProps: () => ({ | ||
onMouseDown: startCapture, | ||
onClick: () => { | ||
var _inputRef$current; | ||
return (_inputRef$current = inputRef.current) == null ? void 0 : _inputRef$current.focus(); | ||
} | ||
}), | ||
getInputProps: () => ({ | ||
onBlur: stopCapture, | ||
onKeyDown: e => !e.target.value && e.key === 'Backspace' && (removeSelect == null ? void 0 : removeSelect()) | ||
}) | ||
}; | ||
}; | ||
const multiSelect = (props = {}) => mergeFeatures(autocomplete({ | ||
...props, | ||
select: true, | ||
selectOnBlur: false | ||
}), inputFocus(), multiInput()); | ||
const multiSelectDropdown = (props = {}) => mergeFeatures(autocompleteLite({ | ||
...props, | ||
select: true, | ||
selectOnBlur: false | ||
}), dropdownToggle(props), multiInput()); | ||
const inline = ({ | ||
@@ -367,25 +463,23 @@ getInlineItem | ||
setFocusItem | ||
}) => { | ||
return { | ||
getInputProps: () => ({ | ||
onChange: async ({ | ||
target, | ||
nativeEvent | ||
}) => { | ||
if (nativeEvent.inputType !== 'insertText') { | ||
return; | ||
} | ||
const nextValue = target.value; | ||
const item = await getInlineItem(nextValue); | ||
if (!item) return; | ||
setFocusItem(item); | ||
const itemValue = getItemValue(item); | ||
const start = nextValue.length; | ||
const end = itemValue.length; | ||
setTmpValue(nextValue + itemValue.slice(start)); | ||
setTimeout(() => target.setSelectionRange(start, end), 0); | ||
}) => ({ | ||
getInputProps: () => ({ | ||
onChange: async ({ | ||
target, | ||
nativeEvent | ||
}) => { | ||
if (nativeEvent.inputType !== 'insertText') { | ||
return; | ||
} | ||
}) | ||
}; | ||
}; | ||
const nextValue = target.value; | ||
const item = await getInlineItem(nextValue); | ||
if (!item) return; | ||
setFocusItem(item); | ||
const itemValue = getItemValue(item); | ||
const start = nextValue.length; | ||
const end = itemValue.length; | ||
setTmpValue(nextValue + itemValue.slice(start)); | ||
setTimeout(() => target.setSelectionRange(start, end), 0); | ||
} | ||
}) | ||
}); | ||
@@ -462,4 +556,7 @@ const supercomplete = ({ | ||
exports.mergeFeatures = mergeFeatures; | ||
exports.multiSelect = multiSelect; | ||
exports.multiSelectDropdown = multiSelectDropdown; | ||
exports.supercomplete = supercomplete; | ||
exports.useAutoHeight = useAutoHeight; | ||
exports.useAutocomplete = useAutocomplete; | ||
exports.useCombobox = useCombobox; | ||
exports.useMultiSelect = useMultiSelect; |
@@ -1,2 +0,2 @@ | ||
import { useMutableState } from '../../hooks/useMutableState.js'; | ||
import { useFocusCapture } from '../../hooks/useFocusCapture.js'; | ||
@@ -11,5 +11,8 @@ const scrollIntoView = element => element == null ? void 0 : element.scrollIntoView({ | ||
deselectOnClear = true, | ||
deselectOnChange = true | ||
deselectOnChange = true, | ||
closeOnSelect = true | ||
} = {}) => ({ | ||
getItemValue, | ||
getSelectedValue, | ||
onSelectChange, | ||
isItemDisabled, | ||
@@ -21,4 +24,2 @@ traverse, | ||
setTmpValue, | ||
selectedItem, | ||
onSelectedItemChange, | ||
focusItem, | ||
@@ -31,18 +32,18 @@ setFocusItem, | ||
var _ref; | ||
const mutable = useMutableState({}); | ||
const inputValue = (_ref = tmpValue || value) != null ? _ref : getItemValue(selectedItem); | ||
const updateValue = newValue => { | ||
const endIndex = newValue.length; | ||
const [startCapture, stopCapture] = useFocusCapture(inputRef); | ||
const inputValue = (_ref = tmpValue || value) != null ? _ref : getSelectedValue(); | ||
const selectItem = item => { | ||
onSelectChange(item); | ||
const itemValue = getItemValue(item); | ||
const endIndex = itemValue.length; | ||
inputRef.current.setSelectionRange(endIndex, endIndex); | ||
if (!select) onChange(newValue); | ||
if (!select) onChange(itemValue); | ||
}; | ||
const updateAll = item => { | ||
onSelectedItemChange(item); | ||
updateValue(getItemValue(item)); | ||
}; | ||
const closeList = () => { | ||
setOpen(false); | ||
const closeList = isSelecting => { | ||
setFocusItem(); | ||
setTmpValue(); | ||
if (select) onChange(); | ||
if (!isSelecting || closeOnSelect) { | ||
setOpen(false); | ||
if (select) onChange(); | ||
} | ||
}; | ||
@@ -53,5 +54,3 @@ return { | ||
tabIndex: -1, | ||
onMouseDown: () => { | ||
if (document.activeElement === inputRef.current) mutable.a = 1; | ||
}, | ||
onMouseDown: startCapture, | ||
onClick: () => { | ||
@@ -64,9 +63,7 @@ var _inputRef$current; | ||
setFocusItem(); | ||
if (deselectOnClear) onSelectedItemChange(); | ||
if (deselectOnClear) onSelectChange(); | ||
} | ||
}), | ||
getListProps: () => ({ | ||
onMouseDown: () => { | ||
mutable.a = 1; | ||
} | ||
onMouseDown: startCapture | ||
}), | ||
@@ -79,4 +76,4 @@ getItemProps: ({ | ||
if (!isItemDisabled(item)) { | ||
updateAll(item); | ||
closeList(); | ||
selectItem(item); | ||
closeList(true); | ||
} | ||
@@ -94,15 +91,10 @@ } | ||
onChange(newValue); | ||
if (!select && deselectOnChange || deselectOnClear && !newValue) onSelectedItemChange(); | ||
if (!select && deselectOnChange || deselectOnClear && !newValue) { | ||
onSelectChange(); | ||
} | ||
}, | ||
onBlur: ({ | ||
target | ||
}) => { | ||
if (mutable.a) { | ||
mutable.a = 0; | ||
target.focus(); | ||
return; | ||
} | ||
if (!open) return; | ||
onBlur: () => { | ||
if (stopCapture() || !open) return; | ||
if (selectOnBlur && focusItem) { | ||
updateAll(focusItem); | ||
selectItem(focusItem); | ||
} | ||
@@ -125,4 +117,4 @@ closeList(); | ||
if (open && focusItem) { | ||
updateAll(focusItem); | ||
closeList(); | ||
selectItem(focusItem); | ||
closeList(true); | ||
} | ||
@@ -135,2 +127,3 @@ break; | ||
}, | ||
onMouseDown: e => e.stopPropagation(), | ||
onClick: () => setOpen(true) | ||
@@ -137,0 +130,0 @@ }) |
import { useRef, useEffect } from 'react'; | ||
import { useMutableState } from '../../hooks/useMutableState.js'; | ||
import { useToggle } from '../../hooks/useToggle.js'; | ||
const dropdownToggle = () => ({ | ||
const dropdownToggle = ({ | ||
closeOnSelect = true | ||
}) => ({ | ||
inputRef, | ||
@@ -12,3 +14,3 @@ open, | ||
}) => { | ||
const mutable = useMutableState({}); | ||
const [startToggle, stopToggle] = useToggle(open, setOpen); | ||
const toggleRef = useRef(null); | ||
@@ -28,12 +30,4 @@ const inputValue = tmpValue || value || ''; | ||
ref: toggleRef, | ||
onMouseDown: () => { | ||
mutable.a = open; | ||
}, | ||
onClick: () => { | ||
if (mutable.a) { | ||
mutable.a = 0; | ||
} else { | ||
setOpen(true); | ||
} | ||
}, | ||
onMouseDown: startToggle, | ||
onClick: stopToggle, | ||
onKeyDown: e => { | ||
@@ -55,5 +49,3 @@ const { | ||
} = e; | ||
if (key === 'Escape') focusToggle(); | ||
if (key === 'Enter' && focusItem) { | ||
e.preventDefault(); | ||
if (key === 'Escape' || closeOnSelect && focusItem && key === 'Enter') { | ||
focusToggle(); | ||
@@ -60,0 +52,0 @@ } |
@@ -7,26 +7,24 @@ const inline = ({ | ||
setFocusItem | ||
}) => { | ||
return { | ||
getInputProps: () => ({ | ||
onChange: async ({ | ||
target, | ||
nativeEvent | ||
}) => { | ||
if (nativeEvent.inputType !== 'insertText') { | ||
return; | ||
} | ||
const nextValue = target.value; | ||
const item = await getInlineItem(nextValue); | ||
if (!item) return; | ||
setFocusItem(item); | ||
const itemValue = getItemValue(item); | ||
const start = nextValue.length; | ||
const end = itemValue.length; | ||
setTmpValue(nextValue + itemValue.slice(start)); | ||
setTimeout(() => target.setSelectionRange(start, end), 0); | ||
}) => ({ | ||
getInputProps: () => ({ | ||
onChange: async ({ | ||
target, | ||
nativeEvent | ||
}) => { | ||
if (nativeEvent.inputType !== 'insertText') { | ||
return; | ||
} | ||
}) | ||
}; | ||
}; | ||
const nextValue = target.value; | ||
const item = await getInlineItem(nextValue); | ||
if (!item) return; | ||
setFocusItem(item); | ||
const itemValue = getItemValue(item); | ||
const start = nextValue.length; | ||
const end = itemValue.length; | ||
setTmpValue(nextValue + itemValue.slice(start)); | ||
setTimeout(() => target.setSelectionRange(start, end), 0); | ||
} | ||
}) | ||
}); | ||
export { inline }; |
@@ -1,2 +0,3 @@ | ||
import { useMutableState } from '../../hooks/useMutableState.js'; | ||
import { useToggle } from '../../hooks/useToggle.js'; | ||
import { useFocusCapture } from '../../hooks/useFocusCapture.js'; | ||
@@ -8,3 +9,4 @@ const inputToggle = () => ({ | ||
}) => { | ||
const mutable = useMutableState({}); | ||
const [startToggle, stopToggle] = useToggle(open, setOpen); | ||
const [startCapture, stopCapture] = useFocusCapture(inputRef); | ||
return { | ||
@@ -14,12 +16,8 @@ getToggleProps: () => ({ | ||
onMouseDown: () => { | ||
mutable.b = open; | ||
mutable.c = 1; | ||
startToggle(); | ||
startCapture(); | ||
}, | ||
onClick: () => { | ||
var _inputRef$current; | ||
if (mutable.b) { | ||
mutable.b = 0; | ||
} else { | ||
setOpen(true); | ||
} | ||
stopToggle(); | ||
(_inputRef$current = inputRef.current) == null || _inputRef$current.focus(); | ||
@@ -29,10 +27,3 @@ } | ||
getInputProps: () => ({ | ||
onBlur: ({ | ||
target | ||
}) => { | ||
if (mutable.c) { | ||
mutable.c = 0; | ||
target.focus(); | ||
} | ||
} | ||
onBlur: stopCapture | ||
}) | ||
@@ -39,0 +30,0 @@ }; |
@@ -5,4 +5,4 @@ import { mergeFeatures } from '../../utils/mergeFeatures.js'; | ||
const autocomplete = props => mergeFeatures(autocompleteLite(props), inputToggle()); | ||
const autocomplete = (props = {}) => mergeFeatures(autocompleteLite(props), inputToggle()); | ||
export { autocomplete }; |
@@ -5,8 +5,8 @@ import { mergeFeatures } from '../../utils/mergeFeatures.js'; | ||
const dropdown = props => mergeFeatures(autocompleteLite({ | ||
const dropdown = (props = {}) => mergeFeatures(autocompleteLite({ | ||
...props, | ||
select: true, | ||
deselectOnClear: false | ||
}), dropdownToggle()); | ||
}), dropdownToggle(props)); | ||
export { dropdown }; |
@@ -6,8 +6,6 @@ import { useRef, useState } from 'react'; | ||
onChange, | ||
selectedItem, | ||
onSelectedItemChange, | ||
isItemDisabled = () => false, | ||
feature: useFeature, | ||
traversal: useTraversal, | ||
getItemValue: _getItemValue | ||
...adapterProps | ||
}) => { | ||
@@ -18,3 +16,2 @@ const inputRef = useRef(null); | ||
const [focusItem, setFocusItem] = useState(); | ||
const getItemValue = item => item == null ? '' : _getItemValue ? _getItemValue(item) : item.toString(); | ||
const state = { | ||
@@ -27,11 +24,9 @@ focusItem, | ||
const contextual = { | ||
inputRef, | ||
isItemDisabled, | ||
tmpValue, | ||
setTmpValue, | ||
getItemValue, | ||
isItemDisabled, | ||
value, | ||
onChange: newValue => value != newValue && (onChange == null ? void 0 : onChange(newValue)), | ||
selectedItem, | ||
onSelectedItemChange: newItem => newItem !== selectedItem && (onSelectedItemChange == null ? void 0 : onSelectedItemChange(newItem)), | ||
inputRef, | ||
...adapterProps, | ||
...state | ||
@@ -38,0 +33,0 @@ }; |
@@ -1,2 +0,3 @@ | ||
export { useAutocomplete } from './hooks/useAutocomplete.js'; | ||
export { useCombobox } from './hooks/useCombobox.js'; | ||
export { useMultiSelect } from './hooks/useMultiSelect.js'; | ||
export { useAutoHeight } from './hooks/useAutoHeight.js'; | ||
@@ -6,2 +7,4 @@ export { autocompleteLite } from './features/atom/autocompleteLite.js'; | ||
export { dropdown } from './features/molecule/dropdown.js'; | ||
export { multiSelect } from './features/molecule/multiSelect.js'; | ||
export { multiSelectDropdown } from './features/molecule/multiSelectDropdown.js'; | ||
export { supercomplete } from './features/molecule/supercomplete.js'; | ||
@@ -8,0 +11,0 @@ export { linearTraversal } from './traversals/linearTraversal.js'; |
{ | ||
"name": "@szhsin/react-autocomplete", | ||
"version": "0.8.10", | ||
"version": "0.9.0", | ||
"description": "", | ||
@@ -5,0 +5,0 @@ "author": "Zheng Song", |
@@ -9,2 +9,3 @@ import type { HTMLAttributes, InputHTMLAttributes, ButtonHTMLAttributes } from 'react'; | ||
getClearProps: () => ButtonHTMLAttributes<HTMLButtonElement>; | ||
getInputWrapperProps: () => HTMLAttributes<HTMLElement>; | ||
getListProps: () => HTMLAttributes<HTMLElement>; | ||
@@ -24,14 +25,17 @@ getItemProps: (option: { | ||
} | ||
export interface ContextualProps<T> { | ||
export interface PassthroughProps<T> { | ||
isItemDisabled: (item: T) => boolean; | ||
value: string | undefined; | ||
onChange: (value?: string | undefined) => void; | ||
selectedItem: T | undefined; | ||
onSelectedItemChange: (item?: T | undefined) => void; | ||
} | ||
export interface Contextual<T> extends ContextualProps<T>, AutocompleteState<T> { | ||
export interface AdapterProps<T> { | ||
getItemValue: (item: T | undefined | null) => string; | ||
getSelectedValue: () => string; | ||
onSelectChange: (item?: T | undefined) => void; | ||
removeSelect?: (item?: T | undefined) => void; | ||
} | ||
export interface Contextual<T> extends PassthroughProps<T>, AdapterProps<T>, AutocompleteState<T> { | ||
tmpValue?: string; | ||
setTmpValue: (value?: string | undefined) => void; | ||
inputRef: React.RefObject<HTMLInputElement>; | ||
getItemValue: (item: T | undefined | null) => string; | ||
} | ||
@@ -53,15 +57,28 @@ export interface Clearable { | ||
deselectOnChange?: boolean; | ||
closeOnSelect?: boolean; | ||
getInlineItem: (value: string) => T | undefined | null | void | Promise<T | undefined | null | void>; | ||
} | ||
export type AutocompleteFeatureProps<T> = Pick<FeatureProps<T>, 'rovingText' | 'select' | 'selectOnBlur' | 'deselectOnClear' | 'deselectOnChange'>; | ||
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 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>>; | ||
interface GetItemValue<T> { | ||
getItemValue: (item: T) => string; | ||
} | ||
export type AutocompleteProps<T, FeatureYield extends object = object> = Partial<ContextualProps<T>> & { | ||
export type BaseProps<T, FeatureYield extends object> = Partial<PassthroughProps<T>> & { | ||
feature: Feature<T, FeatureYield>; | ||
traversal: Traversal<T>; | ||
} & (T extends string ? Partial<GetItemValue<T>> : GetItemValue<T>); | ||
export {}; | ||
}; | ||
export type AutocompleteProps<T, FeatureYield extends object> = BaseProps<T, FeatureYield> & AdapterProps<T>; | ||
export type GetItemValue<T> = { | ||
getItemValue: (item: T) => string; | ||
}; | ||
export type MaybeGetItemValue<T> = T extends string ? Partial<GetItemValue<T>> : GetItemValue<T>; | ||
export type Flippable = { | ||
flipOnSelect?: boolean; | ||
}; | ||
export type ComboboxProps<T, FeatureYield extends object = object> = BaseProps<T, FeatureYield> & MaybeGetItemValue<T> & Flippable & { | ||
selected?: T | undefined; | ||
onSelectChange?: ((item?: T | undefined) => void) | undefined; | ||
}; | ||
export type MultiSelectProps<T, FeatureYield extends object = object> = BaseProps<T, FeatureYield> & MaybeGetItemValue<T> & Flippable & { | ||
selected: T[]; | ||
onSelectChange?: (items: T[]) => void; | ||
}; |
import type { Feature, GetPropsFunctions, GetPropsWithRefFunctions, AutocompleteFeatureProps, Clearable } from '../../common'; | ||
type AutocompleteLiteFeature<T> = Feature<T, Pick<GetPropsFunctions<T>, 'getListProps' | 'getItemProps' | 'getClearProps'> & Pick<GetPropsWithRefFunctions<T>, 'getInputProps'> & Clearable>; | ||
declare const autocompleteLite: <T>({ rovingText, select, selectOnBlur, deselectOnClear, deselectOnChange }?: AutocompleteFeatureProps<T>) => AutocompleteLiteFeature<T>; | ||
declare const autocompleteLite: <T>({ rovingText, select, selectOnBlur, deselectOnClear, deselectOnChange, closeOnSelect }?: AutocompleteFeatureProps<T>) => AutocompleteLiteFeature<T>; | ||
export { type AutocompleteLiteFeature, autocompleteLite }; |
@@ -1,4 +0,4 @@ | ||
import type { Feature, GetPropsFunctions, GetPropsWithRefFunctions, Clearable } from '../../common'; | ||
import type { Feature, FeatureProps, GetPropsFunctions, GetPropsWithRefFunctions, Clearable } from '../../common'; | ||
type DropdownToggleFeature<T> = Feature<T, Pick<GetPropsWithRefFunctions<T>, 'getToggleProps'> & Pick<GetPropsFunctions<T>, 'getInputProps'> & Clearable>; | ||
declare const dropdownToggle: <T>() => DropdownToggleFeature<T>; | ||
declare const dropdownToggle: <T>({ closeOnSelect }: Pick<FeatureProps<T>, "closeOnSelect">) => DropdownToggleFeature<T>; | ||
export { type DropdownToggleFeature, dropdownToggle }; |
import type { MergedFeature, AutocompleteFeatureProps } from '../../common'; | ||
import { type AutocompleteLiteFeature } from '../atom/autocompleteLite'; | ||
import { type InputToggleFeature } from '../atom/inputToggle'; | ||
type AutocompleteFeature<T> = MergedFeature<T, [AutocompleteLiteFeature<T>, InputToggleFeature<T>]>; | ||
declare const autocomplete: <T>(props: AutocompleteFeatureProps<T>) => AutocompleteFeature<T>; | ||
type AutocompleteFeature<T> = MergedFeature<T, [ | ||
AutocompleteLiteFeature<T>, | ||
InputToggleFeature<T> | ||
]>; | ||
declare const autocomplete: <T>(props?: AutocompleteFeatureProps<T>) => AutocompleteFeature<T>; | ||
export { type AutocompleteFeature, autocomplete }; |
import type { MergedFeature, FeatureProps } from '../../common'; | ||
import { type AutocompleteLiteFeature } from '../atom/autocompleteLite'; | ||
import { type DropdownToggleFeature } from '../atom/dropdownToggle'; | ||
type DropdownFeature<T> = MergedFeature<T, [AutocompleteLiteFeature<T>, DropdownToggleFeature<T>]>; | ||
declare const dropdown: <T>(props?: Pick<FeatureProps<T>, "rovingText" | "selectOnBlur"> | undefined) => DropdownFeature<T>; | ||
type DropdownFeature<T> = MergedFeature<T, [ | ||
AutocompleteLiteFeature<T>, | ||
DropdownToggleFeature<T> | ||
]>; | ||
declare const dropdown: <T>(props?: Pick<FeatureProps<T>, "rovingText" | "selectOnBlur" | "closeOnSelect">) => DropdownFeature<T>; | ||
export { type DropdownFeature, dropdown }; |
import type { AutocompleteProps } from '../common'; | ||
declare const useAutocomplete: <T, FeatureYield extends object>({ value, onChange, selectedItem, onSelectedItemChange, isItemDisabled, feature: useFeature, traversal: useTraversal, getItemValue: _getItemValue }: AutocompleteProps<T, FeatureYield>) => { | ||
declare const useAutocomplete: <T, FeatureYield extends object>({ value, onChange, isItemDisabled, feature: useFeature, traversal: useTraversal, ...adapterProps }: AutocompleteProps<T, FeatureYield>) => { | ||
focusItem: T | undefined; | ||
@@ -4,0 +4,0 @@ setFocusItem: (item?: T | undefined) => void; |
@@ -1,2 +0,3 @@ | ||
export { useAutocomplete } from './hooks/useAutocomplete'; | ||
export { useCombobox } from './hooks/useCombobox'; | ||
export { useMultiSelect } from './hooks/useMultiSelect'; | ||
export { useAutoHeight } from './hooks/useAutoHeight'; | ||
@@ -6,2 +7,4 @@ export { type AutocompleteLiteFeature, autocompleteLite } from './features/atom/autocompleteLite'; | ||
export { type DropdownFeature, dropdown } from './features/molecule/dropdown'; | ||
export { type MultiSelectFeature, multiSelect } from './features/molecule/multiSelect'; | ||
export { type MultiSelectDropdownFeature, multiSelectDropdown } from './features/molecule/multiSelectDropdown'; | ||
export { type SupercompleteFeature, supercomplete } from './features/molecule/supercomplete'; | ||
@@ -8,0 +11,0 @@ export { linearTraversal } from './traversals/linearTraversal'; |
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
46140
52
1307