Redesign: Tweaks and fixes for collapsible navigation sections in new navigation (#40450)

This commit is contained in:
diondiondion
2026-09-10 15:53:31 +00:00
committed by GitHub
parent df213ecb1d
commit 2407851f04
3 changed files with 32 additions and 14 deletions

View File

@@ -70,6 +70,8 @@ function useFollowedHashtags() {
return { followedHashtags: tags };
}
const MAX_HASHTAG_COUNT = 5;
export const RedesignNavigationPanel: React.FC<{
siteName?: string;
/**
@@ -151,6 +153,7 @@ export const RedesignNavigationPanel: React.FC<{
/>
</NavigationLink>
<ListSection
id='custom-feeds'
title={
<FormattedMessage
id='tabs_bar.custom_feeds'
@@ -186,6 +189,7 @@ export const RedesignNavigationPanel: React.FC<{
{followedHashtags.length > 0 && (
<ListSection
id='followed-hashtags'
title={
<FormattedMessage
id='tabs_bar.followed_hashtags'
@@ -193,17 +197,19 @@ export const RedesignNavigationPanel: React.FC<{
/>
}
>
{followedHashtags.slice(0, 4).map((tag) => (
{followedHashtags.slice(0, MAX_HASHTAG_COUNT).map((tag) => (
<NavigationLink key={tag.name} to={`/tags/${tag.name}`}>
#{tag.name}
</NavigationLink>
))}
<NavigationLink key='view-all' to='/followed_tags'>
<FormattedMessage
id='tabs_bar.followed_tags_view_all'
defaultMessage='View all'
/>
</NavigationLink>
{followedHashtags.length > MAX_HASHTAG_COUNT && (
<NavigationLink key='view-all' to='/followed_tags'>
<FormattedMessage
id='tabs_bar.followed_tags_view_all'
defaultMessage='View all'
/>
</NavigationLink>
)}
</ListSection>
)}
</ul>

View File

@@ -21,9 +21,8 @@
}
.toggleButton {
// Compensate for the button's outer spacing, subtracting a mystery
// pixel that I can't explain, but is needed for proper alignment.
--button-padding: calc(var(--space-xs) - 1px);
// Compensate for the button's outer spacing
--button-padding: calc(var(--space-xs) - var(--space-3xs));
margin: calc(-1 * var(--button-padding));
margin-inline-end: var(--button-padding);

View File

@@ -1,3 +1,4 @@
import { useCallback } from 'react';
import type { ReactNode } from 'react';
import { FormattedMessage } from 'react-intl';
@@ -6,7 +7,8 @@ import { CaretDownIcon } from '@phosphor-icons/react';
import { Button, IconButton } from '@/mastodon/components/button/redesign';
import type { MastodonLocationDescriptor } from '@/mastodon/components/router';
import { useToggle } from '@/mastodon/hooks/useToggle';
import { useStorageState } from '@/mastodon/hooks/useStorage';
import { useIdentity } from '@/mastodon/identity_context';
import { hasReactChildren } from '@/mastodon/utils/has_react_children';
import classes from './list_section.module.scss';
@@ -17,11 +19,22 @@ export const ListSection: React.FC<{
label: ReactNode;
link: MastodonLocationDescriptor;
};
/**
* Unique identifier of this section, used for storing the
* open/close state of the section in localStorage
*/
id: string;
children: ReactNode;
emptyMessage?: ReactNode;
}> = ({ title, action, children, emptyMessage }) => {
}> = ({ title, action, id, children, emptyMessage }) => {
const hasContent = hasReactChildren(children);
const [isOpen, { onToggle }] = useToggle(true);
const { accountId } = useIdentity();
const storageKey = `ListSection-${id}-toggle-state-${accountId}`;
const [isOpen, setIsOpen] = useStorageState<boolean>(storageKey, true);
const toggleIsOpen = useCallback(() => {
setIsOpen(!isOpen);
}, [isOpen, setIsOpen]);
return (
<li className={classes.root}>
@@ -31,7 +44,7 @@ export const ListSection: React.FC<{
size='sm'
variant='ghost'
icon={CaretDownIcon}
onClick={onToggle}
onClick={toggleIsOpen}
noActiveHighlight
aria-expanded={isOpen}
className={classes.toggleButton}