45 lines
1.5 KiB
JavaScript
45 lines
1.5 KiB
JavaScript
import * as React from 'react';
|
|
/**
|
|
* A hook for managing a collection of child Options
|
|
*/ export const useOptionCollection = ()=>{
|
|
const optionsById = React.useRef(new Map());
|
|
const collectionAPI = React.useMemo(()=>{
|
|
const getCount = ()=>optionsById.current.size;
|
|
// index searches are no longer used
|
|
const getOptionAtIndex = ()=>undefined;
|
|
const getIndexOfId = ()=>-1;
|
|
const getOptionById = (id)=>{
|
|
return optionsById.current.get(id);
|
|
};
|
|
const getOptionsMatchingText = (matcher)=>{
|
|
return Array.from(optionsById.current.values()).filter(({ text })=>matcher(text));
|
|
};
|
|
const getOptionsMatchingValue = (matcher)=>{
|
|
const matches = [];
|
|
for (const option of optionsById.current.values()){
|
|
if (matcher(option.value)) {
|
|
matches.push(option);
|
|
}
|
|
}
|
|
return matches;
|
|
};
|
|
return {
|
|
getCount,
|
|
getOptionAtIndex,
|
|
getIndexOfId,
|
|
getOptionById,
|
|
getOptionsMatchingText,
|
|
getOptionsMatchingValue
|
|
};
|
|
}, []);
|
|
const registerOption = React.useCallback((option)=>{
|
|
optionsById.current.set(option.id, option);
|
|
return ()=>optionsById.current.delete(option.id);
|
|
}, []);
|
|
return {
|
|
...collectionAPI,
|
|
options: Array.from(optionsById.current.values()),
|
|
registerOption
|
|
};
|
|
};
|