feat(EditSlates): only show menu selection when the input is focused

This commit is contained in:
Aminejv 2022-01-21 19:58:09 +01:00 committed by Martina
parent 324123fce9
commit 04461097e8

View File

@ -25,6 +25,9 @@ const comboboxContext = React.createContext({});
const useComboboxContext = () => React.useContext(comboboxContext); const useComboboxContext = () => React.useContext(comboboxContext);
function ComboboxProvider({ children, isMobile = false, onItemSelect }) { function ComboboxProvider({ children, isMobile = false, onItemSelect }) {
const [isInputFocused, setInputFocus] = React.useState(true);
const menuSelectionDisabled = isMobile || !isInputFocused;
const menuItemsRef = React.useRef({}); const menuItemsRef = React.useRef({});
const menuElementRef = React.useRef({}); const menuElementRef = React.useRef({});
@ -32,24 +35,25 @@ function ComboboxProvider({ children, isMobile = false, onItemSelect }) {
const [selectedIdx, setSelectedIdx] = React.useState(initialIndex); const [selectedIdx, setSelectedIdx] = React.useState(initialIndex);
const registerMenuRef = (node) => { const registerMenuRef = (node) => {
if (isMobile) return; if (menuSelectionDisabled) return;
menuElementRef.current = node; menuElementRef.current = node;
}; };
const registerMenuItem = ({ index, onSelectRef, ref }) => { const registerMenuItem = ({ index, onSelectRef, ref }) => {
if (isMobile) return; if (menuSelectionDisabled) return;
menuItemsRef.current[index] = { index, onSelectRef, ref }; menuItemsRef.current[index] = { index, onSelectRef, ref };
}; };
const cleanupMenuItem = (index) => { const cleanupMenuItem = (index) => {
if (isMobile) return; if (menuSelectionDisabled) return;
if (index === selectedIdx) setSelectedIdx(initialIndex); if (index === selectedIdx) setSelectedIdx(initialIndex);
delete menuItemsRef.current[index]; delete menuItemsRef.current[index];
}; };
const isNavigatingViaKeyboard = React.useRef(true); const isNavigatingViaKeyboard = React.useRef(true);
const moveSelectionOnArrowUp = () => { const moveSelectionOnArrowUp = () => {
isNavigatingViaKeyboard.current = true; isNavigatingViaKeyboard.current = true;
if (isMobile) return; if (menuSelectionDisabled) return;
const prevIndex = selectedIdx - 1; const prevIndex = selectedIdx - 1;
let prevFocusedIndex = null; let prevFocusedIndex = null;
if (prevIndex >= initialIndex) { if (prevIndex >= initialIndex) {
@ -62,7 +66,7 @@ function ComboboxProvider({ children, isMobile = false, onItemSelect }) {
const moveSelectionOnArrowDown = () => { const moveSelectionOnArrowDown = () => {
isNavigatingViaKeyboard.current = true; isNavigatingViaKeyboard.current = true;
if (isMobile) return; if (menuSelectionDisabled) return;
const nextIndex = selectedIdx + 1; const nextIndex = selectedIdx + 1;
const elementExists = menuItemsRef.current[nextIndex]; const elementExists = menuItemsRef.current[nextIndex];
const nextFocusedIndex = elementExists ? nextIndex : initialIndex; const nextFocusedIndex = elementExists ? nextIndex : initialIndex;
@ -80,12 +84,12 @@ function ComboboxProvider({ children, isMobile = false, onItemSelect }) {
}; };
const applySelectedElement = () => { const applySelectedElement = () => {
if (isMobile) return; if (menuSelectionDisabled) return;
menuItemsRef.current[selectedIdx].onSelectRef.current(), onItemSelect?.(); menuItemsRef.current[selectedIdx].onSelectRef.current(), onItemSelect?.();
}; };
React.useLayoutEffect(() => { React.useLayoutEffect(() => {
if (isMobile) return; if (menuSelectionDisabled) return;
//NOTE(amine): don't scroll automatically when the user is navigating using a mouse //NOTE(amine): don't scroll automatically when the user is navigating using a mouse
if (!isNavigatingViaKeyboard.current) return; if (!isNavigatingViaKeyboard.current) return;
@ -108,14 +112,16 @@ function ComboboxProvider({ children, isMobile = false, onItemSelect }) {
top: selectedNodeBottom - menuNode.offsetHeight + selectedNode.offsetHeight, top: selectedNodeBottom - menuNode.offsetHeight + selectedNode.offsetHeight,
}); });
} }
}, [selectedIdx, isMobile]); }, [selectedIdx, menuSelectionDisabled]);
const contextValue = React.useMemo( const contextValue = React.useMemo(
() => [ () => [
{ selectedIdx, isMobile }, { selectedIdx, menuSelectionDisabled },
{ {
onItemSelect, onItemSelect,
setInputFocus,
registerMenuItem, registerMenuItem,
cleanupMenuItem, cleanupMenuItem,
@ -127,7 +133,7 @@ function ComboboxProvider({ children, isMobile = false, onItemSelect }) {
registerMenuRef, registerMenuRef,
}, },
], ],
[selectedIdx, isMobile] [selectedIdx, menuSelectionDisabled]
); );
return <comboboxContext.Provider value={contextValue}>{children}</comboboxContext.Provider>; return <comboboxContext.Provider value={contextValue}>{children}</comboboxContext.Provider>;
@ -135,9 +141,11 @@ function ComboboxProvider({ children, isMobile = false, onItemSelect }) {
/* -----------------------------------------------------------------------------------------------*/ /* -----------------------------------------------------------------------------------------------*/
const ComboboxInput = React.forwardRef(({ onKeyDown, ...props }, ref) => { const ComboboxInput = React.forwardRef(({ onKeyDown, onFocus, onBlur, ...props }, ref) => {
const [, { moveSelectionOnArrowUp, moveSelectionOnArrowDown, applySelectedElement }] = const [
useComboboxContext(); ,
{ setInputFocus, moveSelectionOnArrowUp, moveSelectionOnArrowDown, applySelectedElement },
] = useComboboxContext();
const keyDownHandler = (e) => { const keyDownHandler = (e) => {
switch (e.key) { switch (e.key) {
@ -165,7 +173,15 @@ const ComboboxInput = React.forwardRef(({ onKeyDown, ...props }, ref) => {
} }
}; };
return <System.Input onKeyDown={mergeEvents(keyDownHandler, onKeyDown)} {...props} ref={ref} />; return (
<System.Input
onFocus={mergeEvents(() => setInputFocus(true), onFocus)}
onBlur={mergeEvents(() => setInputFocus(false), onBlur)}
onKeyDown={mergeEvents(keyDownHandler, onKeyDown)}
{...props}
ref={ref}
/>
);
}); });
/* -----------------------------------------------------------------------------------------------*/ /* -----------------------------------------------------------------------------------------------*/
@ -239,9 +255,9 @@ const Combobox = {
}; };
const useCombobox = () => { const useCombobox = () => {
const [{ selectedIdx, isMobile }] = useComboboxContext(); const [{ selectedIdx, menuSelectionDisabled }] = useComboboxContext();
const checkIfIndexSelected = (index) => { const checkIfIndexSelected = (index) => {
if (isMobile) return false; if (menuSelectionDisabled) return false;
return selectedIdx === index; return selectedIdx === index;
}; };
return { checkIfIndexSelected }; return { checkIfIndexSelected };
@ -843,6 +859,7 @@ export function EditSlates({ file, viewer, onClose, ...props }) {
/* -----------------------------------------------------------------------------------------------*/ /* -----------------------------------------------------------------------------------------------*/
export function EditSlatesMobile({ file, viewer, onClose }) { export function EditSlatesMobile({ file, viewer, onClose }) {
const memoizedFiles = React.useMemo(() => (Array.isArray(file) ? file : [file]), [file]);
const { const {
slates, slates,
filteredSlates, filteredSlates,
@ -853,7 +870,7 @@ export function EditSlatesMobile({ file, viewer, onClose }) {
checkIfSlateIsApplied, checkIfSlateIsApplied,
} = useSlates({ } = useSlates({
viewer, viewer,
object: file, objects: memoizedFiles,
}); });
const [value, { handleInputChange, clearInputValue }] = useInput(); const [value, { handleInputChange, clearInputValue }] = useInput();