From 7cfdc6d53d037de95ea15fdf65ef500a05deb550 Mon Sep 17 00:00:00 2001 From: Nico Rehwaldt Date: Sat, 26 Mar 2022 17:55:15 +0100 Subject: [PATCH] feat: improve mouse + keyboard interaction --- src/append-menu/AppendMenu.js | 32 ++++++----------- src/change-menu/ChangeMenu.css | 3 +- src/create-menu/CreateMenu.js | 31 ++++++---------- .../ElementTemplateChooser.js | 35 +++++++------------ src/replace-menu/ReplaceMenu.js | 32 ++++++----------- 5 files changed, 44 insertions(+), 89 deletions(-) diff --git a/src/append-menu/AppendMenu.js b/src/append-menu/AppendMenu.js index d0e493d..35ac37c 100644 --- a/src/append-menu/AppendMenu.js +++ b/src/append-menu/AppendMenu.js @@ -188,9 +188,7 @@ function AppendMenuComponent(props) { const [ value, setValue ] = useState(''); const [ templates, setTemplates ] = useState(props.entries); - const [ keyboardSelectedTemplate, setKeyboardSelectedTemplate ] = useState(null); - const [ mouseSelectedTemplate, setMouseSelectedTemplate ] = useState(null); - const [ selectedTemplate, setSelectedTemplate ] = useState(null); + const [ selectedTemplate, setSelectedTemplate ] = useState(templates[0]); useEffect(() => { @@ -212,16 +210,12 @@ function AppendMenuComponent(props) { const templates = entries.filter(filter); - if (!templates.includes(keyboardSelectedTemplate)) { - setKeyboardSelectedTemplate(templates[0]); - } - - if (!templates.includes(mouseSelectedTemplate)) { - setMouseSelectedTemplate(null); + if (!templates.includes(selectedTemplate)) { + setSelectedTemplate(templates[0]); } setTemplates(templates); - }, [ value, keyboardSelectedTemplate, mouseSelectedTemplate, props.templates ]); + }, [ value, selectedTemplate, props.templates ]); // focus input on initial mount useLayoutEffect(() => { @@ -238,16 +232,11 @@ function AppendMenuComponent(props) { if (selectedEl) { selectedEl.scrollIntoViewIfNeeded(); } - }, [ keyboardSelectedTemplate ]); - - useEffect(() => { - setSelectedTemplate(mouseSelectedTemplate || keyboardSelectedTemplate); - }, [ keyboardSelectedTemplate, mouseSelectedTemplate ]); - + }, [ selectedTemplate ]); const keyboardSelect = useCallback(direction => { - const idx = templates.indexOf(keyboardSelectedTemplate); + const idx = templates.indexOf(selectedTemplate); let nextIdx = idx + direction; @@ -259,8 +248,8 @@ function AppendMenuComponent(props) { nextIdx = 0; } - setKeyboardSelectedTemplate(templates[nextIdx]); - }, [ templates, keyboardSelectedTemplate ]); + setSelectedTemplate(templates[nextIdx]); + }, [ templates, selectedTemplate ]); const handleKeyDown = useCallback(event => { @@ -319,9 +308,8 @@ function AppendMenuComponent(props) { ${templates.map(template => html`
  • setMouseSelectedTemplate(template) } - onMouseLeave=${ () => setMouseSelectedTemplate(null) } + class=${ clsx('cmd-change-menu__entry', { selected: template === selectedTemplate }) } + onMouseEnter=${ () => setSelectedTemplate(template) } draggable onDragStart=${ (event) => { event.stopPropagation(); event.preventDefault(); onSelect(event, template, true); } } onClick=${ (event) => { event.stopPropagation(); onSelect(event, template); } } diff --git a/src/change-menu/ChangeMenu.css b/src/change-menu/ChangeMenu.css index 07aecd6..99ae8f8 100644 --- a/src/change-menu/ChangeMenu.css +++ b/src/change-menu/ChangeMenu.css @@ -153,8 +153,7 @@ color: var(--text-muted-color); } -.cmd-change-menu__results:not(:hover) .cmd-change-menu__entry.selected, -.cmd-change-menu__entry:hover { +.cmd-change-menu__entry.selected { background-color: var(--hover-background-color); } diff --git a/src/create-menu/CreateMenu.js b/src/create-menu/CreateMenu.js index 19d3865..52a8590 100644 --- a/src/create-menu/CreateMenu.js +++ b/src/create-menu/CreateMenu.js @@ -171,9 +171,7 @@ function CreateMenuComponent(props) { const [ value, setValue ] = useState(''); const [ templates, setTemplates ] = useState(props.entries); - const [ keyboardSelectedTemplate, setKeyboardSelectedTemplate ] = useState(null); - const [ mouseSelectedTemplate, setMouseSelectedTemplate ] = useState(null); - const [ selectedTemplate, setSelectedTemplate ] = useState(null); + const [ selectedTemplate, setSelectedTemplate ] = useState(templates[0]); useEffect(() => { @@ -195,16 +193,12 @@ function CreateMenuComponent(props) { const templates = entries.filter(filter); - if (!templates.includes(keyboardSelectedTemplate)) { - setKeyboardSelectedTemplate(templates[0]); - } - - if (!templates.includes(mouseSelectedTemplate)) { - setMouseSelectedTemplate(null); + if (!templates.includes(selectedTemplate)) { + setSelectedTemplate(templates[0]); } setTemplates(templates); - }, [ value, keyboardSelectedTemplate, mouseSelectedTemplate, props.templates ]); + }, [ value, selectedTemplate, props.templates ]); // focus input on initial mount useLayoutEffect(() => { @@ -221,16 +215,12 @@ function CreateMenuComponent(props) { if (selectedEl) { selectedEl.scrollIntoViewIfNeeded(); } - }, [ keyboardSelectedTemplate ]); - - useEffect(() => { - setSelectedTemplate(mouseSelectedTemplate || keyboardSelectedTemplate); - }, [ keyboardSelectedTemplate, mouseSelectedTemplate ]); + }, [ selectedTemplate ]); const keyboardSelect = useCallback(direction => { - const idx = templates.indexOf(keyboardSelectedTemplate); + const idx = templates.indexOf(selectedTemplate); let nextIdx = idx + direction; @@ -242,8 +232,8 @@ function CreateMenuComponent(props) { nextIdx = 0; } - setKeyboardSelectedTemplate(templates[nextIdx]); - }, [ templates, keyboardSelectedTemplate ]); + setSelectedTemplate(templates[nextIdx]); + }, [ templates, selectedTemplate ]); const handleKeyDown = useCallback(event => { @@ -302,9 +292,8 @@ function CreateMenuComponent(props) { ${templates.map(template => html`
  • setMouseSelectedTemplate(template) } - onMouseLeave=${ () => setMouseSelectedTemplate(null) } + class=${ clsx('cmd-change-menu__entry', { selected: template === selectedTemplate }) } + onMouseEnter=${ () => setSelectedTemplate(template) } draggable onDragStart=${ (event) => { event.stopPropagation(); event.preventDefault(); onSelect(event, template, true); } } onClick=${ (event) => { event.stopPropagation(); onSelect(event, template); } } diff --git a/src/element-template-chooser/ElementTemplateChooser.js b/src/element-template-chooser/ElementTemplateChooser.js index 081dedc..11ac972 100644 --- a/src/element-template-chooser/ElementTemplateChooser.js +++ b/src/element-template-chooser/ElementTemplateChooser.js @@ -99,9 +99,7 @@ function TemplateComponent(props) { const [ value, setValue ] = useState(''); const [ templates, setTemplates ] = useState(props.entries); - const [ keyboardSelectedTemplate, setKeyboardSelectedTemplate ] = useState(null); - const [ mouseSelectedTemplate, setMouseSelectedTemplate ] = useState(null); - const [ selectedTemplate, setSelectedTemplate ] = useState(null); + const [ selectedTemplate, setSelectedTemplate ] = useState(templates[0]); useEffect(() => { @@ -110,21 +108,19 @@ function TemplateComponent(props) { return true; } - return [ template.name, template.description || '' ].join('---').toLowerCase().includes(value.toLowerCase()); + return [ + template.name, template.description || '' + ].join('---').toLowerCase().includes(value.toLowerCase()); }; const templates = props.entries.filter(filter); - if (!templates.includes(keyboardSelectedTemplate)) { - setKeyboardSelectedTemplate(templates[0]); - } - - if (!templates.includes(mouseSelectedTemplate)) { - setMouseSelectedTemplate(null); + if (!templates.includes(selectedTemplate)) { + setSelectedTemplate(templates[0]); } setTemplates(templates); - }, [ value, keyboardSelectedTemplate, mouseSelectedTemplate, props.entries ]); + }, [ value, selectedTemplate, props.entries ]); // focus input on initial mount @@ -142,15 +138,11 @@ function TemplateComponent(props) { if (selectedEl) { selectedEl.scrollIntoViewIfNeeded(); } - }, [ keyboardSelectedTemplate ]); - - useEffect(() => { - setSelectedTemplate(mouseSelectedTemplate || keyboardSelectedTemplate); - }, [ keyboardSelectedTemplate, mouseSelectedTemplate ]); + }, [ selectedTemplate ]); const keyboardSelect = useCallback(direction => { - const idx = templates.indexOf(keyboardSelectedTemplate); + const idx = templates.indexOf(selectedTemplate); let nextIdx = idx + direction; @@ -162,8 +154,8 @@ function TemplateComponent(props) { nextIdx = 0; } - setKeyboardSelectedTemplate(templates[nextIdx]); - }, [ templates, keyboardSelectedTemplate ]); + setSelectedTemplate(templates[nextIdx]); + }, [ templates, selectedTemplate ]); const handleKeyDown = useCallback(event => { @@ -220,9 +212,8 @@ function TemplateComponent(props) { ${templates.map(template => html`
  • setMouseSelectedTemplate(template) } - onMouseLeave=${ () => setMouseSelectedTemplate(null) } + class=${ clsx('cmd-change-menu__entry', { selected: template === selectedTemplate }) } + onMouseEnter=${ () => setSelectedTemplate(template) } onClick=${ () => onClose(template) } data-entry-id=${template.id} > diff --git a/src/replace-menu/ReplaceMenu.js b/src/replace-menu/ReplaceMenu.js index 91a7d2c..d831cbf 100644 --- a/src/replace-menu/ReplaceMenu.js +++ b/src/replace-menu/ReplaceMenu.js @@ -155,9 +155,7 @@ function ReplaceMenuComponent(props) { const [ value, setValue ] = useState(''); const [ templates, setTemplates ] = useState(props.entries); - const [ keyboardSelectedTemplate, setKeyboardSelectedTemplate ] = useState(null); - const [ mouseSelectedTemplate, setMouseSelectedTemplate ] = useState(null); - const [ selectedTemplate, setSelectedTemplate ] = useState(null); + const [ selectedTemplate, setSelectedTemplate ] = useState(templates[0]); useEffect(() => { @@ -179,16 +177,12 @@ function ReplaceMenuComponent(props) { const templates = props.entries.filter(filter); - if (!templates.includes(keyboardSelectedTemplate)) { - setKeyboardSelectedTemplate(templates[0]); - } - - if (!templates.includes(mouseSelectedTemplate)) { - setMouseSelectedTemplate(null); + if (!templates.includes(selectedTemplate)) { + setSelectedTemplate(templates[0]); } setTemplates(templates); - }, [ value, keyboardSelectedTemplate, mouseSelectedTemplate, props.templates ]); + }, [ value, selectedTemplate, props.templates ]); // focus input on initial mount @@ -206,16 +200,11 @@ function ReplaceMenuComponent(props) { if (selectedEl) { selectedEl.scrollIntoViewIfNeeded(); } - }, [ keyboardSelectedTemplate ]); - - useEffect(() => { - setSelectedTemplate(mouseSelectedTemplate || keyboardSelectedTemplate); - }, [ keyboardSelectedTemplate, mouseSelectedTemplate ]); - + }, [ selectedTemplate ]); const keyboardSelect = useCallback(direction => { - const idx = templates.indexOf(keyboardSelectedTemplate); + const idx = templates.indexOf(selectedTemplate); let nextIdx = idx + direction; @@ -227,8 +216,8 @@ function ReplaceMenuComponent(props) { nextIdx = 0; } - setKeyboardSelectedTemplate(templates[nextIdx]); - }, [ templates, keyboardSelectedTemplate ]); + setSelectedTemplate(templates[nextIdx]); + }, [ templates, selectedTemplate ]); const handleKeyDown = useCallback(event => { @@ -292,9 +281,8 @@ function ReplaceMenuComponent(props) { ${templates.map(template => html`
  • setMouseSelectedTemplate(template) } - onMouseLeave=${ () => setMouseSelectedTemplate(null) } + class=${ clsx('cmd-change-menu__entry', { selected: template === selectedTemplate }) } + onMouseEnter=${ () => setSelectedTemplate(template) } onClick=${ (event) => onSelect(event, template) } data-entry-id=${ template.id } >