From 50cbd2ef286d04c377e8146dd731294ad7d69706 Mon Sep 17 00:00:00 2001 From: Zheng Song Date: Fri, 5 Jul 2024 22:23:00 +1000 Subject: [PATCH 1/3] Auto focus feature --- dist/cjs/index.js | 25 ++++++- dist/esm/features/atom/autoFocus.js | 17 +++++ dist/esm/features/atom/inline.js | 4 +- dist/esm/features/molecule/supercomplete.js | 4 +- dist/esm/index.js | 1 + examples/features/autocompleteFocus.ts | 19 +++++ examples/pages/index.tsx | 83 +++++++++++---------- examples/pages/multiSelectAction.tsx | 5 +- src/common.ts | 2 +- src/features/atom/autoFocus.ts | 19 +++++ src/features/atom/inline.ts | 4 +- src/features/molecule/supercomplete.ts | 6 +- src/index.ts | 1 + types/common.d.ts | 2 +- types/features/atom/autoFocus.d.ts | 4 + types/features/atom/inline copy.d.ts | 4 + types/features/atom/inline.d.ts | 2 +- types/features/molecule/supercomplete.d.ts | 2 +- types/index.d.ts | 1 + 19 files changed, 149 insertions(+), 56 deletions(-) create mode 100644 dist/esm/features/atom/autoFocus.js create mode 100644 examples/features/autocompleteFocus.ts create mode 100644 src/features/atom/autoFocus.ts create mode 100644 types/features/atom/autoFocus.d.ts create mode 100644 types/features/atom/inline copy.d.ts diff --git a/dist/cjs/index.js b/dist/cjs/index.js index c5cb9f5..f1bffc6 100644 --- a/dist/cjs/index.js +++ b/dist/cjs/index.js @@ -286,6 +286,22 @@ const autocompleteLite = ({ }; }; +const autoFocus = ({ + getFocusItem +}) => ({ + setFocusItem +}) => ({ + getInputProps: () => ({ + onChange: async e => { + const nextValue = e.target.value; + if (nextValue) { + const item = await getFocusItem(nextValue); + item && setFocusItem(item); + } + } + }) +}); + const mergeObjects = (obj1, obj2) => { const merged = { ...obj1 @@ -445,7 +461,7 @@ const multiSelectDropdown = (props = {}) => mergeModules(autocompleteLite({ }), dropdownToggle(props), multiInput()); const inline = ({ - getInlineItem + getFocusItem }) => ({ getItemValue, setTmpValue, @@ -460,7 +476,7 @@ const inline = ({ return; } const nextValue = target.value; - const item = await getInlineItem(nextValue); + const item = await getFocusItem(nextValue); if (!item) return; setFocusItem(item); const itemValue = getItemValue(item); @@ -473,13 +489,13 @@ const inline = ({ }); const supercomplete = ({ - getInlineItem, + getFocusItem, ...rest }) => mergeModules(autocomplete({ ...rest, rovingText: true }), inline({ - getInlineItem + getFocusItem })); const linearTraversal = ({ @@ -537,6 +553,7 @@ const groupedTraversal = ({ }); }; +exports.autoFocus = autoFocus; exports.autocomplete = autocomplete; exports.autocompleteLite = autocompleteLite; exports.dropdown = dropdown; diff --git a/dist/esm/features/atom/autoFocus.js b/dist/esm/features/atom/autoFocus.js new file mode 100644 index 0000000..259f73c --- /dev/null +++ b/dist/esm/features/atom/autoFocus.js @@ -0,0 +1,17 @@ +const autoFocus = ({ + getFocusItem +}) => ({ + setFocusItem +}) => ({ + getInputProps: () => ({ + onChange: async e => { + const nextValue = e.target.value; + if (nextValue) { + const item = await getFocusItem(nextValue); + item && setFocusItem(item); + } + } + }) +}); + +export { autoFocus }; diff --git a/dist/esm/features/atom/inline.js b/dist/esm/features/atom/inline.js index fd4e9c7..b79050f 100644 --- a/dist/esm/features/atom/inline.js +++ b/dist/esm/features/atom/inline.js @@ -1,5 +1,5 @@ const inline = ({ - getInlineItem + getFocusItem }) => ({ getItemValue, setTmpValue, @@ -14,7 +14,7 @@ const inline = ({ return; } const nextValue = target.value; - const item = await getInlineItem(nextValue); + const item = await getFocusItem(nextValue); if (!item) return; setFocusItem(item); const itemValue = getItemValue(item); diff --git a/dist/esm/features/molecule/supercomplete.js b/dist/esm/features/molecule/supercomplete.js index cd99d6d..f9ba9eb 100644 --- a/dist/esm/features/molecule/supercomplete.js +++ b/dist/esm/features/molecule/supercomplete.js @@ -3,13 +3,13 @@ import { autocomplete } from './autocomplete.js'; import { inline } from '../atom/inline.js'; const supercomplete = ({ - getInlineItem, + getFocusItem, ...rest }) => mergeModules(autocomplete({ ...rest, rovingText: true }), inline({ - getInlineItem + getFocusItem })); export { supercomplete }; diff --git a/dist/esm/index.js b/dist/esm/index.js index 9a33d9a..b81e6cd 100644 --- a/dist/esm/index.js +++ b/dist/esm/index.js @@ -2,6 +2,7 @@ export { useCombobox } from './hooks/useCombobox.js'; export { useMultiSelect } from './hooks/useMultiSelect.js'; export { useAutoHeight } from './hooks/useAutoHeight.js'; export { autocompleteLite } from './features/atom/autocompleteLite.js'; +export { autoFocus } from './features/atom/autoFocus.js'; export { autocomplete } from './features/molecule/autocomplete.js'; export { dropdown } from './features/molecule/dropdown.js'; export { multiSelect } from './features/molecule/multiSelect.js'; diff --git a/examples/features/autocompleteFocus.ts b/examples/features/autocompleteFocus.ts new file mode 100644 index 0000000..bf8cfb7 --- /dev/null +++ b/examples/features/autocompleteFocus.ts @@ -0,0 +1,19 @@ +import { + mergeModules, + MergedFeature, + FeatureProps, + AutocompleteFeature, + AutoFocusFeature, + autocomplete, + autoFocus +} from '@szhsin/react-autocomplete'; + +type AutocompleteFocusFeature = MergedFeature< + T, + [AutocompleteFeature, AutoFocusFeature] +>; + +const autocompleteFocus = (props: FeatureProps): AutocompleteFocusFeature => + mergeModules(autocomplete(props), autoFocus(props)); + +export { autocompleteFocus }; diff --git a/examples/pages/index.tsx b/examples/pages/index.tsx index 63d6c0e..6c8a45a 100644 --- a/examples/pages/index.tsx +++ b/examples/pages/index.tsx @@ -8,6 +8,7 @@ import { } from '@szhsin/react-autocomplete'; import styles from '@/styles/Home.module.css'; import { LIST_GROUP_PLAIN, KEYED_GROUP_PLAIN, LIST_GROUP, KEYED_GROUP } from '../data'; +import { autocompleteFocus } from '../features/autocompleteFocus'; type Item = { name: string; abbr: string }; const getItemValue = (item: Item) => item.name; @@ -22,7 +23,7 @@ const getGroupedItems = (value: string) => })).filter((group) => !!group.states.length); export default function Home() { - const [isSupercomplete, setSupercomplete] = useState(true); + const [selectedFeature, setSelectedFeature] = useState('supercomplete'); const [select, setselect] = useState(false); const [rovingText, setRovingText] = useState(true); const [selectOnBlur, setSelectOnBlur] = useState(true); @@ -40,6 +41,15 @@ export default function Home() { // const [items, setItems] = useState(US_STATES); // const feature = supercomplete<{ name: string; abbr: string }>(); + const featureProps = { + select, + selectOnBlur, + deselectOnClear, + deselectOnChange, + closeOnSelect, + rovingText + }; + const groupedItems = getGroupedItems(value || ''); const { @@ -60,7 +70,7 @@ export default function Home() { isItemDisabled, value, onChange: (value) => { - // console.log('onChange', value); + console.log('onChange', value); setValue(value); }, selected: selectedItem, @@ -69,31 +79,28 @@ export default function Home() { setSelectedItem(item); }, - feature: isSupercomplete - ? supercomplete({ - select, - selectOnBlur, - deselectOnClear, - deselectOnChange, - closeOnSelect, - getInlineItem: (newValue) => - getGroupedItems(newValue)[0]?.states.find((item) => !isItemDisabled(item)) - // getInlineItem: (newValue) => - // new Promise((res) => - // setTimeout( - // () => res(getGroupedItems(newValue)[0]?.states.find((item) => !isItemDisabled(item))), - // 1000 - // ) - // ) - }) - : autocomplete({ - select, - selectOnBlur, - deselectOnClear, - deselectOnChange, - rovingText, - closeOnSelect - }), + feature: + selectedFeature === 'supercomplete' + ? supercomplete({ + ...featureProps, + getFocusItem: (newValue) => + getGroupedItems(newValue)[0]?.states.find((item) => !isItemDisabled(item)) + // getInlineItem: (newValue) => + // new Promise((res) => + // setTimeout( + // () => res(getGroupedItems(newValue)[0]?.states.find((item) => !isItemDisabled(item))), + // 1000 + // ) + // ) + }) + : selectedFeature === 'autocompleteFocus' + ? autocompleteFocus({ + ...featureProps, + getFocusItem: (newValue) => + getGroupedItems(newValue)[0]?.states.find((item) => !isItemDisabled(item)) + }) + : autocomplete(featureProps), + traversal: groupedTraversal({ traverseInput: true, groupedItems, @@ -108,16 +115,16 @@ export default function Home() {
value: {value}
Selected item: {selectedItem?.name}
Focus item: {focusItem?.name}
-
- -
+ + +
- {!isSupercomplete && ( + {selectedFeature !== 'supercomplete' && (