From bafbdd483837c24974928b939cb09201cd527dc9 Mon Sep 17 00:00:00 2001 From: Echo Date: Thu, 27 Aug 2026 15:36:08 +0000 Subject: [PATCH] Composer redesign: Update language picker and toolbar button design (#40294) --- .../components/button/redesign.module.scss | 18 +++ .../components/button/redesign.stories.tsx | 10 +- .../mastodon/components/button/redesign.tsx | 37 +++-- .../form_fields/redesign.module.scss | 11 ++ .../components/form_fields/redesign.tsx | 6 +- .../form_fields/text_input_field.tsx | 20 ++- .../mastodon/components/menu/card.tsx | 2 +- .../mastodon/components/menu/index.tsx | 2 +- .../features/compose/redesign/hints.tsx | 9 +- .../features/compose/redesign/hooks.ts | 109 ++++++++++++- .../features/compose/redesign/index.tsx | 28 ++-- .../features/compose/redesign/language.tsx | 144 +++++++++--------- .../compose/redesign/styles.module.scss | 30 ++-- .../features/compose/redesign/visibility.tsx | 3 +- app/javascript/mastodon/locales/en.json | 1 + app/javascript/types/polymorphic.ts | 2 +- 16 files changed, 304 insertions(+), 128 deletions(-) diff --git a/app/javascript/mastodon/components/button/redesign.module.scss b/app/javascript/mastodon/components/button/redesign.module.scss index 857fca0f6a1..186fb0b6be2 100644 --- a/app/javascript/mastodon/components/button/redesign.module.scss +++ b/app/javascript/mastodon/components/button/redesign.module.scss @@ -200,3 +200,21 @@ a.base { .loading { color: inherit; } + +// Toggle tonal buttons by default show the neutral color, but when pressed show the brand color. +.toggle { + &.tonal { + @include active { + --bg: rgb(from var(--color-bg-brand-base) r g b / 10%); + --fg: var(--color-text-brand); + } + } + + &.solid, + &.ghost { + @include active { + --bg: var(--color-bg-brand-base); + --fg: var(--color-text-on-brand-base); + } + } +} diff --git a/app/javascript/mastodon/components/button/redesign.stories.tsx b/app/javascript/mastodon/components/button/redesign.stories.tsx index 1175b759d41..f2b4ef3d8ce 100644 --- a/app/javascript/mastodon/components/button/redesign.stories.tsx +++ b/app/javascript/mastodon/components/button/redesign.stories.tsx @@ -1,11 +1,12 @@ import type { Meta, StoryObj } from '@storybook/react-vite'; import { fn } from 'storybook/test'; +import { useToggle } from '@/mastodon/hooks/useToggle'; import ChatIcon from '@/material-icons/400-24px/chat.svg?react'; import DownloadIcon from '@/material-icons/400-24px/download.svg?react'; import HeadphonesIcon from '@/material-icons/400-24px/headphones.svg?react'; -import { Button, IconButton } from './redesign'; +import { Button, IconButton, ToggleButton } from './redesign'; const iconArgType = { control: 'select', @@ -98,3 +99,10 @@ export const Link: Story = { as: 'link', }, }; + +export const Toggle: Story = { + render(args) { + const [active, { onToggle }] = useToggle(); + return ; + }, +}; diff --git a/app/javascript/mastodon/components/button/redesign.tsx b/app/javascript/mastodon/components/button/redesign.tsx index d9fc4caec69..3543da046ba 100644 --- a/app/javascript/mastodon/components/button/redesign.tsx +++ b/app/javascript/mastodon/components/button/redesign.tsx @@ -32,9 +32,9 @@ type ButtonAnchorProps = { as: 'a' } & ButtonPropsBase<'a'> & type ButtonLinkProps = { as: 'link' } & ButtonPropsBase<'a'> & Omit; -type ButtonProps = ButtonButtonProps | ButtonAnchorProps | ButtonLinkProps; +type BaseButtonProps = ButtonButtonProps | ButtonAnchorProps | ButtonLinkProps; -const BaseButton: React.FC = ({ +const BaseButton: React.FC = ({ size = 'md', variant = 'tonal', color = 'neutral', @@ -91,12 +91,17 @@ const BaseButton: React.FC = ({ ); }; -export const Button: React.FC< - ButtonProps & { - leadingIcon?: IconProp; - trailingIcon?: IconProp; - } -> = ({ children, leadingIcon, trailingIcon, ...props }) => ( +type ButtonProps = BaseButtonProps & { + leadingIcon?: IconProp; + trailingIcon?: IconProp; +}; + +export const Button: React.FC = ({ + children, + leadingIcon, + trailingIcon, + ...props +}) => ( {leadingIcon && !props.loading && ( @@ -109,7 +114,7 @@ export const Button: React.FC< ); -export const IconButton: React.FC = ({ +export const IconButton: React.FC = ({ icon, className, children, @@ -133,3 +138,17 @@ const LoadingIcon: React.FC = () => ( role='none' /> ); + +export const ToggleButton: React.FC = ({ + active, + className, + ...props +}) => ( +