Skip to content

Commit

Permalink
- Improve tabs keyboard controls 3
Browse files Browse the repository at this point in the history
  • Loading branch information
duduBTW committed Nov 3, 2024
1 parent d072a68 commit 4e0d32e
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 30 deletions.
9 changes: 7 additions & 2 deletions src/renderer/src/components/tabs/TabsList.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { useTabs } from "./Tabs";
import { cn } from "@renderer/lib/css.utils";
import { JSX, onMount, ParentComponent, splitProps } from "solid-js";
import { createMemo, JSX, onMount, ParentComponent, splitProps } from "solid-js";

type Props = JSX.IntrinsicElements["div"];
export const TabsList: ParentComponent<Props> = (_props) => {
Expand All @@ -9,11 +9,16 @@ export const TabsList: ParentComponent<Props> = (_props) => {

onMount(state.onListmounted);

const hasSelectedValue = createMemo(() => {
return state.registeredTabs.has(state.value());
});

return (
<div
{...state.attrs}
{...rest}
tabindex={0}
tabindex={hasSelectedValue() ? -1 : 0}
onFocus={state.tryFocusFirstItem}
class={cn(
"relative flex rounded-xl bg-thin-material p-1 gap-1 ring-1 ring-stroke",
props.class,
Expand Down
44 changes: 16 additions & 28 deletions src/renderer/src/lib/roving-focus-group/rovingFocusGroup.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { DOMElement } from "solid-js/jsx-runtime";
import useControllableState from "../controllable-state";
import { Accessor, createMemo, createSignal, onMount } from "solid-js";
import { Accessor, createMemo, createSignal, onCleanup, onMount } from "solid-js";

const ITEM_DATA_ATTR = "data-item";
const DEFAULT_SELECTED_VALUE = "";
Expand All @@ -26,6 +26,9 @@ type Params = {
};
export function useRovingFocusGroup(props: Params = {}) {
let container!: HTMLElement;

const registeredTabs = new Set<string>();

const [hasMounted, setHasMounted] = createSignal(false);
const [currentStopId, setCurrentStopId] = useControllableState({
defaultProp: props.defaultProp || DEFAULT_SELECTED_VALUE,
Expand Down Expand Up @@ -59,32 +62,6 @@ export function useRovingFocusGroup(props: Params = {}) {
setCurrentStopId(firstNode.getAttribute(ITEM_DATA_ATTR)!);
};

const handleListKeyUp = (
event: KeyboardEvent & {
currentTarget: DOMElement;
target: DOMElement;
},
) => {
if (!event.currentTarget.isSameNode(event.target)) {
return;
}

switch (event.key) {
case "ArrowUp":
case "ArrowLeft":
case "ArrowDown":
case "ArrowRight": {
event.preventDefault();
tryFocusFirstItem();
break;
}

default: {
break;
}
}
};

const handleItemKeyUp = (
event: KeyboardEvent & {
currentTarget: DOMElement;
Expand Down Expand Up @@ -171,12 +148,12 @@ export function useRovingFocusGroup(props: Params = {}) {
});

return {
registeredTabs,
currentlyActiveElement,
onListmounted,
tryFocusFirstItem,
value: currentStopId,
attrs: {
onKeyUp: handleListKeyUp,
ref: (node: HTMLElement) => {
container = node;
},
Expand Down Expand Up @@ -234,6 +211,17 @@ export function useRovingFocusGroup(props: Params = {}) {
return isSelected() ? 0 : -1;
});

onMount(() => {
if (!tabStopId) {
return;
}

registeredTabs.add(tabStopId);
onCleanup(() => {
registeredTabs.delete(tabStopId);
});
});

return {
isSelected,
tabIndex,
Expand Down

0 comments on commit 4e0d32e

Please sign in to comment.