feat(Filters): use RovingTabIndex to navigate filter sections

This commit is contained in:
Aminejv 2022-01-03 19:07:08 +01:00
parent 8a442d5cad
commit 41c8ddffd5

View File

@ -7,6 +7,7 @@ import * as Utilities from "~/common/utilities";
import * as Tooltip from "~/components/system/components/fragments/Tooltip";
import * as System from "~/components/system";
import * as Actions from "~/common/actions";
import * as RovingTabIndex from "~/components/core/RovingTabIndex";
import ProfilePhoto from "~/components/core/ProfilePhoto";
@ -15,6 +16,7 @@ import { useFilterContext } from "~/components/core/Filter/Provider";
import { Link } from "~/components/core/Link";
import { ButtonPrimary, ButtonSecondary } from "~/components/system/components/Buttons";
import { motion } from "framer-motion";
import { FocusRing } from "../FocusRing";
/* -------------------------------------------------------------------------------------------------
* Shared components between filters
@ -63,9 +65,8 @@ const STYLES_FILTERS_GROUP = css`
}
`;
const FilterButton = ({ children, Icon, image, isSelected, ...props }) => (
<li>
<Link {...props}>
const FilterButton = React.forwardRef(({ children, Icon, image, isSelected, ...props }, ref) => (
<Link {...props} ref={ref}>
<span as="span" css={[STYLES_FILTER_BUTTON, isSelected && STYLES_FILTER_BUTTON_HIGHLIGHTED]}>
{Icon ? <Icon height={16} width={16} style={{ flexShrink: 0 }} /> : null}
{image ? image : null}
@ -74,19 +75,19 @@ const FilterButton = ({ children, Icon, image, isSelected, ...props }) => (
</Typography.P2>
</span>
</Link>
</li>
);
));
const FilterSection = ({ title, children, ...props }) => {
const FilterSection = React.forwardRef(({ title, children, ...props }, ref) => {
const [isExpanded, setExpanded] = React.useState(true);
const toggleExpandState = () => setExpanded((prev) => !prev);
const titleButtonId = `sidebar-${title}-button`;
return (
<div {...props}>
<div {...props} ref={ref}>
{title && (
<Tooltip.Root vertical="above" horizontal="right">
<Tooltip.Trigger aria-describedby={titleButtonId} aria-expanded={isExpanded}>
<FocusRing>
<Typography.H6
as={motion.button}
layoutId={title + "title"}
@ -97,6 +98,7 @@ const FilterSection = ({ title, children, ...props }) => {
>
{title}
</Typography.H6>
</FocusRing>
</Tooltip.Trigger>
<Tooltip.Content css={Styles.HORIZONTAL_CONTAINER_CENTERED} style={{ marginTop: -4.5 }}>
<System.H6 id={titleButtonId} as="p" color="textGrayDark">
@ -117,7 +119,7 @@ const FilterSection = ({ title, children, ...props }) => {
) : null}
</div>
);
};
});
/* -------------------------------------------------------------------------------------------------
* InitialFilters
@ -149,10 +151,13 @@ function Tags({ viewer, data, onAction, ...props }) {
const [, { hidePopup }] = useFilterContext();
return (
<RovingTabIndex.Provider axis="vertical">
<RovingTabIndex.List>
<FilterSection title="Tags" {...props}>
{viewer.slates.map((slate) => (
{viewer.slates.map((slate, index) => (
<li key={slate.id}>
<RovingTabIndex.Item index={index}>
<FilterButton
key={slate.id}
href={`/$/slate/${slate.id}`}
isSelected={slate.id === data?.id}
onAction={onAction}
@ -161,8 +166,12 @@ function Tags({ viewer, data, onAction, ...props }) {
>
{slate.slatename}
</FilterButton>
</RovingTabIndex.Item>
</li>
))}
</FilterSection>
</RovingTabIndex.List>
</RovingTabIndex.Provider>
);
}
@ -170,10 +179,13 @@ function Following({ viewer, onAction, ...props }) {
const [, { hidePopup }] = useFilterContext();
return (
<RovingTabIndex.Provider axis="vertical">
<RovingTabIndex.List>
<FilterSection title="Following" {...props}>
{viewer.following.map((user) => (
{viewer.following.map((user, index) => (
<li key={user.id}>
<RovingTabIndex.Item index={index}>
<FilterButton
key={user.id}
href={`/${user.username}`}
isSelected={false}
onAction={onAction}
@ -183,8 +195,12 @@ function Following({ viewer, onAction, ...props }) {
>
{user.username}
</FilterButton>
</RovingTabIndex.Item>
</li>
))}
</FilterSection>
</RovingTabIndex.List>
</RovingTabIndex.Provider>
);
}
@ -281,10 +297,13 @@ function ProfileTags({ data, page, onAction, ...props }) {
}
return (
<RovingTabIndex.Provider axis="vertical">
<RovingTabIndex.List>
<FilterSection {...props}>
{user?.slates?.map((slate) => (
{user?.slates?.map((slate, index) => (
<li key={slate.id}>
<RovingTabIndex.Item index={index}>
<FilterButton
key={slate.id}
href={`/$/slate/${slate.id}`}
isSelected={slate.id === data?.id}
onAction={onAction}
@ -293,8 +312,12 @@ function ProfileTags({ data, page, onAction, ...props }) {
>
{slate.slatename}
</FilterButton>
</RovingTabIndex.Item>
</li>
))}
</FilterSection>
</RovingTabIndex.List>
</RovingTabIndex.Provider>
);
}