From 986ea16dbb08bfaa69716620cf9eef328329e9c7 Mon Sep 17 00:00:00 2001 From: Echo Date: Fri, 24 Jul 2026 12:26:42 +0200 Subject: [PATCH] Redesign Components: Text Input (#39941) --- .storybook/preview.tsx | 8 +++ .storybook/storybook.d.ts | 2 + .../form_fields/redesign.module.scss | 38 ++++++++++++- .../form_fields/redesign.stories.tsx | 11 +++- .../components/form_fields/redesign.tsx | 56 ++++++++++++++----- 5 files changed, 98 insertions(+), 17 deletions(-) diff --git a/.storybook/preview.tsx b/.storybook/preview.tsx index e718a56a4f5..17e9e14a554 100644 --- a/.storybook/preview.tsx +++ b/.storybook/preview.tsx @@ -204,6 +204,14 @@ const preview: Preview = { ); }, + (Story, { parameters }) => { + useEffect(() => { + document.documentElement.dataset.redesign = parameters.redesign + ? 'true' + : 'false'; + }, [parameters.redesign]); + return ; + }, ], loaders: [ mswLoader, diff --git a/.storybook/storybook.d.ts b/.storybook/storybook.d.ts index 5f3d17486b7..e9c02f7a1bd 100644 --- a/.storybook/storybook.d.ts +++ b/.storybook/storybook.d.ts @@ -39,6 +39,8 @@ declare module 'storybook/internal/csf' { state?: TypedRootState; /** Callback that is run with the story arguments to generate Redux state for the component. */ stateFn?: (args: any) => TypedRootState; + /** True to set the redesign global settings. */ + redesign?: boolean; } } diff --git a/app/javascript/mastodon/components/form_fields/redesign.module.scss b/app/javascript/mastodon/components/form_fields/redesign.module.scss index 5072e0efe84..87337e3af16 100644 --- a/app/javascript/mastodon/components/form_fields/redesign.module.scss +++ b/app/javascript/mastodon/components/form_fields/redesign.module.scss @@ -1,5 +1,41 @@ +.inputWrapper { + label { + font-size: var(--fs-sm); + } + + span { + color: var(--color-text-tertiary); + font-size: var(--fs-2xs); + line-height: var(--fs-lg); + } +} + +input.input { + font-size: var(--fs-lg); + background: none; + border-radius: var(--space-xs); + border: 0.5px solid var(--color-text-tertiary); + padding: var(--space-xs); + transition: background 200ms; + + &:hover:not(:disabled) { + box-shadow: 0 1px var(--space-2xs) 0 + rgb(from var(--color-text-primary) r g b / 10%); + background: var(--color-bg-highlight); + } + + &:focus { + outline: 2px solid var(--color-border-strong); + } + + &:disabled { + border-color: var(--color-bg-disabled); + } +} + +// Use double class to override original styles. .toggle.toggle { - background: rgb(from var(--color-bg-inverted) r g b / 70%); + background: var(--color-text-tertiary); &::before { box-shadow: none; diff --git a/app/javascript/mastodon/components/form_fields/redesign.stories.tsx b/app/javascript/mastodon/components/form_fields/redesign.stories.tsx index d87460c8cdc..a8b45e3fff4 100644 --- a/app/javascript/mastodon/components/form_fields/redesign.stories.tsx +++ b/app/javascript/mastodon/components/form_fields/redesign.stories.tsx @@ -1,6 +1,6 @@ import type { Meta, StoryObj } from '@storybook/react-vite'; -import { ToggleField } from './redesign'; +import { TextInputField, ToggleField } from './redesign'; interface FieldProps { label: string; @@ -19,12 +19,21 @@ const meta = { hint: 'This is a description of this form field', disabled: false, }, + parameters: { + redesign: true, + }, } satisfies Meta; export default meta; type Story = StoryObj; +export const TextInput: Story = { + render(args) { + return ; + }, +}; + export const Toggle: Story = { render(args) { return ; diff --git a/app/javascript/mastodon/components/form_fields/redesign.tsx b/app/javascript/mastodon/components/form_fields/redesign.tsx index e5b73b44ee5..e2f00456dd6 100644 --- a/app/javascript/mastodon/components/form_fields/redesign.tsx +++ b/app/javascript/mastodon/components/form_fields/redesign.tsx @@ -3,22 +3,49 @@ import classNames from 'classnames'; import type { Merge } from 'type-fest'; import classes from './redesign.module.scss'; +import { + TextInput as OldTextInput, + TextInputField as OldTextInputField, +} from './text_input_field'; import { Toggle as OldToggle, ToggleField as OldToggleField, } from './toggle_field'; -// eslint-disable-next-line @typescript-eslint/no-explicit-any -type ToggleComponent> = React.FC< - Merge< - React.ComponentProps, - { - size?: 'sm' | 'lg'; - } - > ->; +type RedesignComponent< + // eslint-disable-next-line @typescript-eslint/no-explicit-any + T extends React.JSXElementConstructor, + P = object, +> = React.FC, P>>; -export const Toggle: ToggleComponent = ({ +// Text field + +export const TextInputField: RedesignComponent = ({ + className, + wrapperClassName, + ...props +}) => ( + +); + +export const TextInput: RedesignComponent = ({ + className, + ...props +}) => ( + +); + +// Toggles + +interface ToggleProps { + size?: 'sm' | 'lg'; +} + +export const Toggle: RedesignComponent = ({ className, size, ...props @@ -33,11 +60,10 @@ export const Toggle: ToggleComponent = ({ /> ); -export const ToggleField: ToggleComponent = ({ - className, - size, - ...props -}) => ( +export const ToggleField: RedesignComponent< + typeof OldToggleField, + ToggleProps +> = ({ className, size, ...props }) => (