Redesign: Design tweaks for new navigation (#40565)

This commit is contained in:
diondiondion
2026-09-17 11:57:22 +00:00
committed by GitHub
parent 4e58dca2be
commit d38cbfefd8
6 changed files with 97 additions and 107 deletions

View File

@@ -104,10 +104,10 @@ export const AccountMenuItems: React.FC<{
<>
{context === 'mobile' && <ProfileMenuItem />}
<MenuItemLink to='/profile/edit' icon={UserIcon}>
<MenuItemLink to={accountBasePath} icon={UserIcon}>
<FormattedMessage
id='account.edit_profile'
defaultMessage='Edit profile'
id='account.view_profile'
defaultMessage='View profile'
/>
</MenuItemLink>

View File

@@ -2,6 +2,8 @@ import { useCallback, useEffect } from 'react';
import { defineMessages, FormattedMessage, useIntl } from 'react-intl';
import { Link } from 'react-router-dom';
import {
PenNibIcon,
HouseIcon,
@@ -10,6 +12,7 @@ import {
BellIcon,
ChatCircleDotsIcon,
BookmarkSimpleIcon,
PlusIcon,
} from '@phosphor-icons/react';
import FediIcon from '@/images/icons/icon_fediverse.svg?react';
@@ -162,31 +165,44 @@ export const RedesignNavigationPanel: React.FC<{
defaultMessage='Custom Feeds'
/>
}
action={{
label: (
<FormattedMessage
id='tabs_bar.create_custom_feed'
defaultMessage='Create'
/>
),
link: '/lists/new',
}}
emptyMessage={
<FormattedMessage
id='tabs_bar.custom_feeds_empty'
defaultMessage='You have no custom feeds yet.'
/>
<>
<FormattedMessage
id='tabs_bar.custom_feeds_empty'
defaultMessage='You have no custom feeds yet.'
/>{' '}
<Link to='/lists/new'>
<FormattedMessage
id='tabs_bar.create_custom_feed'
defaultMessage='Create feed'
/>
</Link>
</>
}
>
{customFeeds.map((feed) => (
<NavigationLink
key={feed.id}
to={`/lists/${feed.id}`}
iconComponent={RssSimpleIcon}
>
{feed.title}
</NavigationLink>
))}
{customFeeds.length > 0 && (
<>
<NavigationLink
key='new'
to='/lists/new'
iconComponent={PlusIcon}
>
<FormattedMessage
id='tabs_bar.create_custom_feed'
defaultMessage='Create feed'
/>
</NavigationLink>
{customFeeds.map((feed) => (
<NavigationLink
key={feed.id}
to={`/lists/${feed.id}`}
iconComponent={RssSimpleIcon}
>
{feed.title}
</NavigationLink>
))}
</>
)}
</ListSection>
{followedHashtags.length > 0 && (

View File

@@ -1,45 +1,42 @@
@use '@/styles/mastodon/mixins';
@use './navigation_link.module.scss' as navigation-link;
.root {
&:not(:last-child) {
margin-bottom: var(--space-md);
}
}
.titleWrapper {
display: flex;
align-items: center;
padding-inline: var(--space-xs);
padding-block: calc(var(--space-xs) - var(--space-3xs));
:any-link {
color: inherit;
&:hover,
&:focus-visible {
text-decoration: none;
}
}
}
.title {
@include mixins.type-label-sm;
@include navigation-link.link-base;
min-height: 32px;
padding: var(--space-2xs) var(--space-xs);
margin-bottom: var(--space-3xs);
@include mixins.type-label-md;
color: var(--color-text-secondary);
cursor: default;
}
.toggleButton {
// 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);
--fg: var(--color-text-tertiary);
svg {
transition: rotate 100ms ease-in;
}
&[aria-expanded='false'] svg {
rotate: -90deg;
}
}
.action {
.toggleIcon {
width: 20px;
height: 20px;
margin-inline-start: auto;
transition: rotate 100ms ease-in;
.title[aria-expanded='true'] & {
rotate: -180deg;
}
}
.emptyState {

View File

@@ -1,12 +1,8 @@
import { useCallback } from 'react';
import type { ReactNode } from 'react';
import { FormattedMessage } from 'react-intl';
import { CaretDownIcon } from '@phosphor-icons/react';
import { Button, IconButton } from '@/mastodon/components/button/redesign';
import type { MastodonLocationDescriptor } from '@/mastodon/components/router';
import { useStorageState } from '@/mastodon/hooks/useStorage';
import { useIdentity } from '@/mastodon/identity_context';
import { hasReactChildren } from '@/mastodon/utils/has_react_children';
@@ -15,10 +11,6 @@ import classes from './list_section.module.scss';
export const ListSection: React.FC<{
title: ReactNode;
action?: {
label: ReactNode;
link: MastodonLocationDescriptor;
};
/**
* Unique identifier of this section, used for storing the
* open/close state of the section in localStorage
@@ -26,7 +18,7 @@ export const ListSection: React.FC<{
id: string;
children: ReactNode;
emptyMessage?: ReactNode;
}> = ({ title, action, id, children, emptyMessage }) => {
}> = ({ title, id, children, emptyMessage }) => {
const hasContent = hasReactChildren(children);
const { accountId } = useIdentity();
@@ -39,33 +31,18 @@ export const ListSection: React.FC<{
return (
<li className={classes.root}>
<div className={classes.titleWrapper}>
{hasContent && (
<IconButton
size='sm'
variant='ghost'
icon={CaretDownIcon}
onClick={toggleIsOpen}
noActiveHighlight
{hasContent ? (
<button
type='button'
aria-expanded={isOpen}
className={classes.toggleButton}
className={classes.title}
onClick={toggleIsOpen}
>
<FormattedMessage
id='tabs_bar.open_section'
defaultMessage='Open {title} menu'
values={{ title }}
/>
</IconButton>
)}
<span className={classes.title}>{title}</span>
{action && (
<Button
as='link'
to={action.link}
size='xs'
className={classes.action}
>
{action.label}
</Button>
{title}
<CaretDownIcon className={classes.toggleIcon} />
</button>
) : (
<span className={classes.title}>{title}</span>
)}
</div>
{hasContent

View File

@@ -9,7 +9,7 @@
padding-bottom: var(--space-md);
}
.link {
@mixin link-base {
--icon-size: 20px;
--border-radius: var(--radius-sm);
@@ -18,38 +18,23 @@
display: flex;
align-items: center;
width: 100%;
min-height: 40px;
padding: var(--space-xs);
column-gap: var(--space-sm);
border-radius: var(--border-radius);
border: none;
color: inherit;
color: var(--color-text-primary);
background-color: transparent;
@include mixins.type-body-compact;
transition: background-color 200ms;
text-decoration: none;
text-align: start;
&:not(:where(.linkStacked, .linkMobile)) {
color: var(--color-text-secondary);
}
@media (width < variables.$mobile-menu-breakpoint) {
min-height: 48px;
}
&:hover,
&:where(button, a):hover,
&:focus-visible,
&[aria-current='page'] {
background-color: var(--color-bg-highlight);
text-decoration: none;
}
&[aria-current='page'] {
color: var(--color-text-primary);
}
&:focus-visible {
outline: var(--outline-focus-default);
}
@@ -60,6 +45,21 @@
}
}
.link {
@include link-base;
min-height: 40px;
@include mixins.type-body;
@media (width < variables.$mobile-menu-breakpoint) {
min-height: 48px;
}
&[aria-current='page']:not(:where(.linkStacked, .linkMobile)) {
@include mixins.type-body-strong;
}
}
.linkStacked {
--icon-size: 24px;

View File

@@ -147,6 +147,7 @@
"account.unmute": "Unmute @{name}",
"account.unmute_notifications_short": "Unmute notifications",
"account.unmute_short": "Unmute",
"account.view_profile": "View profile",
"account_edit.advanced_settings.bot_hint": "Signal to others that the account mainly performs automated actions and might not be monitored",
"account_edit.advanced_settings.bot_label": "Automated account",
"account_edit.advanced_settings.title": "Advanced settings",
@@ -1465,7 +1466,7 @@
"subscribed_languages.target": "Change subscribed languages for {target}",
"tab_bar.messages": "Messages",
"tabs_bar.account_settings": "Account settings",
"tabs_bar.create_custom_feed": "Create",
"tabs_bar.create_custom_feed": "Create feed",
"tabs_bar.custom_feeds": "Custom Feeds",
"tabs_bar.custom_feeds_empty": "You have no custom feeds yet.",
"tabs_bar.explore": "Explore",
@@ -1476,7 +1477,6 @@
"tabs_bar.menu": "Menu",
"tabs_bar.messages": "Messages",
"tabs_bar.notifications": "Notifications",
"tabs_bar.open_section": "Open {title} menu",
"tabs_bar.publish": "New Post",
"tabs_bar.quick_links": "Quick links",
"tabs_bar.saved": "Saved",