split out home/end handling into a helper as not all roving-tab-index widgets want it

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>
This commit is contained in:
Michael Telatynski 2020-01-16 01:35:42 +00:00
parent 8c1fdf4cab
commit 781db63fa6
2 changed files with 20 additions and 12 deletions

View file

@ -39,7 +39,7 @@ import * as sdk from "../../../index";
import * as Receipt from "../../../utils/Receipt"; import * as Receipt from "../../../utils/Receipt";
import {Resizer} from '../../../resizer'; import {Resizer} from '../../../resizer';
import {Layout, Distributor} from '../../../resizer/distributors/roomsublist2'; import {Layout, Distributor} from '../../../resizer/distributors/roomsublist2';
import {RovingTabIndexContextProvider} from "../../../contexts/RovingTabIndexContext"; import {RovingTabIndexContextProvider, RovingTabIndexHomeEndHelper} from "../../../contexts/RovingTabIndexContext";
const HIDE_CONFERENCE_CHANS = true; const HIDE_CONFERENCE_CHANS = true;
const STANDARD_TAGS_REGEX = /^(m\.(favourite|lowpriority|server_notice)|im\.vector\.fake\.(invite|recent|direct|archived))$/; const STANDARD_TAGS_REGEX = /^(m\.(favourite|lowpriority|server_notice)|im\.vector\.fake\.(invite|recent|direct|archived))$/;
@ -789,7 +789,9 @@ export default createReactClass({
onMouseLeave={this.onMouseLeave} onMouseLeave={this.onMouseLeave}
> >
<RovingTabIndexContextProvider> <RovingTabIndexContextProvider>
{ subListComponents } <RovingTabIndexHomeEndHelper>
{ subListComponents }
</RovingTabIndexHomeEndHelper>
</RovingTabIndexContextProvider> </RovingTabIndexContextProvider>
</div> </div>
); );

View file

@ -134,19 +134,30 @@ export const RovingTabIndexContextProvider = ({children}) => {
refs: [], refs: [],
}); });
const context = useMemo(() => ({state, dispatch}), [state]);
return <RovingTabIndexContext.Provider value={context}>
{children}
</RovingTabIndexContext.Provider>;
};
// Helper to handle Home/End to jump to first/last roving-tab-index for widgets such as treeview
export const RovingTabIndexHomeEndHelper = ({children}) => {
const context = useContext(RovingTabIndexContext);
const onKeyDown = useCallback((ev) => { const onKeyDown = useCallback((ev) => {
// check if we actually have any items // check if we actually have any items
if (state.refs.length <= 0) return; if (context.state.refs.length <= 0) return;
let handled = true; let handled = true;
switch (ev.key) { switch (ev.key) {
case Key.HOME: case Key.HOME:
// move focus to first item // move focus to first item
setImmediate(() => state.refs[0].current.focus()); setImmediate(() => context.state.refs[0].current.focus());
break; break;
case Key.END: case Key.END:
// move focus to last item // move focus to last item
state.refs[state.refs.length - 1].current.focus(); context.state.refs[context.state.refs.length - 1].current.focus();
break; break;
default: default:
handled = false; handled = false;
@ -156,15 +167,10 @@ export const RovingTabIndexContextProvider = ({children}) => {
ev.preventDefault(); ev.preventDefault();
ev.stopPropagation(); ev.stopPropagation();
} }
}, [state]); }, [context.state]);
const context = useMemo(() => ({state, dispatch}), [state]);
// wrap in a div with key-down handling for HOME/END keys
return <div onKeyDown={onKeyDown}> return <div onKeyDown={onKeyDown}>
<RovingTabIndexContext.Provider value={context}> { children }
{children}
</RovingTabIndexContext.Provider>
</div>; </div>;
}; };