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