diff --git a/app/javascript/mastodon/features/navigation_panel/redesign/index.tsx b/app/javascript/mastodon/features/navigation_panel/redesign/index.tsx
index 2e09992fae1..dadf643506f 100644
--- a/app/javascript/mastodon/features/navigation_panel/redesign/index.tsx
+++ b/app/javascript/mastodon/features/navigation_panel/redesign/index.tsx
@@ -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<{
/>
0 && (
}
>
- {followedHashtags.slice(0, 4).map((tag) => (
+ {followedHashtags.slice(0, MAX_HASHTAG_COUNT).map((tag) => (
#{tag.name}
))}
-
-
-
+ {followedHashtags.length > MAX_HASHTAG_COUNT && (
+
+
+
+ )}
)}
diff --git a/app/javascript/mastodon/features/navigation_panel/redesign/list_section.module.scss b/app/javascript/mastodon/features/navigation_panel/redesign/list_section.module.scss
index 7e07cd4f7b7..76cc22a59cb 100644
--- a/app/javascript/mastodon/features/navigation_panel/redesign/list_section.module.scss
+++ b/app/javascript/mastodon/features/navigation_panel/redesign/list_section.module.scss
@@ -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);
diff --git a/app/javascript/mastodon/features/navigation_panel/redesign/list_section.tsx b/app/javascript/mastodon/features/navigation_panel/redesign/list_section.tsx
index a5f50759f7a..bbc621418c4 100644
--- a/app/javascript/mastodon/features/navigation_panel/redesign/list_section.tsx
+++ b/app/javascript/mastodon/features/navigation_panel/redesign/list_section.tsx
@@ -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(storageKey, true);
+ const toggleIsOpen = useCallback(() => {
+ setIsOpen(!isOpen);
+ }, [isOpen, setIsOpen]);
return (
@@ -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}