-
-
Notifications
You must be signed in to change notification settings - Fork 8
feat: [DSR+DSRN] Migrate Textarea component from extension #1036
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Draft
georgewrmarshall
wants to merge
1
commit into
main
Choose a base branch
from
textarea
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Draft
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
149 changes: 149 additions & 0 deletions
149
packages/design-system-react-native/src/components/Textarea/README.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,149 @@ | ||
| # Textarea | ||
|
|
||
| Textarea is a light-weight, controlled-only borderless multi-line text input component. | ||
|
|
||
| ```tsx | ||
| import { Textarea, TextVariant } from '@metamask/design-system-react-native'; | ||
|
|
||
| <Textarea value="" placeholder="Enter text" textVariant={TextVariant.BodyMd} />; | ||
| ``` | ||
|
|
||
| ## Props | ||
|
|
||
| This component extends React Native's [TextInput](https://reactnative.dev/docs/textinput) component with `multiline` enabled. | ||
|
|
||
| ### `value` | ||
|
|
||
| Required controlled value for the Textarea. | ||
|
|
||
| | TYPE | REQUIRED | DEFAULT | | ||
| | -------- | -------- | ------- | | ||
| | `string` | Yes | N/A | | ||
|
|
||
| ### `textVariant` | ||
|
|
||
| Optional enum to select between Typography variants. | ||
|
|
||
| | TYPE | REQUIRED | DEFAULT | | ||
| | ------------- | -------- | -------------------- | | ||
| | `TextVariant` | No | `TextVariant.BodyMd` | | ||
|
|
||
| ```tsx | ||
| import { Textarea, TextVariant } from '@metamask/design-system-react-native'; | ||
|
|
||
| <Textarea value="" placeholder="BodyMd (default)" textVariant={TextVariant.BodyMd} /> | ||
| <Textarea value="" placeholder="BodySm" textVariant={TextVariant.BodySm} /> | ||
| ``` | ||
|
|
||
| ### `isDisabled` | ||
|
|
||
| Optional boolean to disable the Textarea. | ||
|
|
||
| | TYPE | REQUIRED | DEFAULT | | ||
| | --------- | -------- | ------- | | ||
| | `boolean` | No | `false` | | ||
|
|
||
| ```tsx | ||
| <Textarea value="Not editable" isDisabled /> | ||
| ``` | ||
|
|
||
| ### `isReadOnly` | ||
|
|
||
| Optional boolean to make the Textarea read-only. | ||
|
|
||
| | TYPE | REQUIRED | DEFAULT | | ||
| | --------- | -------- | ------- | | ||
| | `boolean` | No | `false` | | ||
|
|
||
| ```tsx | ||
| <Textarea value="Read-only value" isReadOnly /> | ||
| ``` | ||
|
|
||
| ### `isError` | ||
|
|
||
| Optional boolean to indicate an error state. Applies error border styling. | ||
|
|
||
| | TYPE | REQUIRED | DEFAULT | | ||
| | --------- | -------- | ------- | | ||
| | `boolean` | No | `false` | | ||
|
|
||
| ```tsx | ||
| <Textarea value="" placeholder="Invalid input" isError /> | ||
| ``` | ||
|
|
||
| ### `numberOfLines` | ||
|
|
||
| Optional number of visible lines. Controls the minimum height of the textarea. | ||
|
|
||
| | TYPE | REQUIRED | DEFAULT | | ||
| | -------- | -------- | ------- | | ||
| | `number` | No | `4` | | ||
|
|
||
| ```tsx | ||
| <Textarea value="" placeholder="4 lines (default)" numberOfLines={4} /> | ||
| <Textarea value="" placeholder="8 lines" numberOfLines={8} /> | ||
| ``` | ||
|
|
||
| ### `isStateStylesDisabled` | ||
|
|
||
| Optional boolean to disable state styles (focus border, disabled opacity). | ||
|
|
||
| | TYPE | REQUIRED | DEFAULT | | ||
| | --------- | -------- | ------- | | ||
| | `boolean` | No | `false` | | ||
|
|
||
| ```tsx | ||
| import { Textarea } from '@metamask/design-system-react-native'; | ||
|
|
||
| <Textarea value="Disabled, full opacity" isDisabled isStateStylesDisabled />; | ||
| ``` | ||
|
|
||
| ### `twClassName` | ||
|
|
||
| Use the `twClassName` prop to add Tailwind CSS classes to the component. These classes will be merged with the component's default classes using `twMerge`, allowing you to: | ||
|
|
||
| - Add new styles that don't exist in the default component | ||
| - Override the component's default styles when needed | ||
|
|
||
| | TYPE | REQUIRED | DEFAULT | | ||
| | -------- | -------- | ----------- | | ||
| | `string` | No | `undefined` | | ||
|
|
||
| ```tsx | ||
| import { Textarea } from '@metamask/design-system-react-native'; | ||
|
|
||
| // Add additional styles | ||
| <Textarea value="" twClassName="mt-4" placeholder="With margin" /> | ||
|
|
||
| // Override default styles | ||
| <Textarea value="" twClassName="bg-error-muted" placeholder="Override background" /> | ||
| ``` | ||
|
|
||
| ### `style` | ||
|
|
||
| Use the `style` prop to customize the component's appearance with React Native styles. For consistent styling, prefer using `twClassName` with Tailwind classes when possible. Use `style` with `tw.style()` for conditionals or dynamic values. | ||
|
|
||
| | TYPE | REQUIRED | DEFAULT | | ||
| | ---------------------- | -------- | ----------- | | ||
| | `StyleProp<TextStyle>` | No | `undefined` | | ||
|
|
||
| ```tsx | ||
| import { useTailwind } from '@metamask/design-system-twrnc-preset'; | ||
| import { Textarea } from '@metamask/design-system-react-native'; | ||
|
|
||
| export const ConditionalExample = ({ isActive }: { isActive: boolean }) => { | ||
| const tw = useTailwind(); | ||
|
|
||
| return ( | ||
| <Textarea | ||
| value="" | ||
| placeholder="Conditional styling" | ||
| style={tw.style('text-default', isActive && 'border-primary-default')} | ||
| /> | ||
| ); | ||
| }; | ||
| ``` | ||
|
|
||
| ## References | ||
|
|
||
| [MetaMask Design System Guides](https://www.notion.so/MetaMask-Design-System-Guides-Design-f86ecc914d6b4eb6873a122b83c12940) |
75 changes: 75 additions & 0 deletions
75
packages/design-system-react-native/src/components/Textarea/Textarea.constants.ts
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,75 @@ | ||
| import { typography } from '@metamask/design-tokens'; | ||
|
|
||
| import { TextVariant } from '../../types'; | ||
|
|
||
| /** | ||
| * Typographic metrics for Textarea: same tokens as `text-*` utilities but **without** `lineHeight`. | ||
| * React Native `TextInput` with multiline aligns text more predictably when line height is not set | ||
| * from the design-system paragraph specs. | ||
| */ | ||
| export const MAP_TEXT_VARIANT_TEXTAREA_METRICS: Record< | ||
| TextVariant, | ||
| { fontSize: number; letterSpacing: number } | ||
| > = { | ||
| [TextVariant.DisplayLg]: { | ||
| fontSize: typography.sDisplayLG.fontSize, | ||
| letterSpacing: typography.sDisplayLG.letterSpacing, | ||
| }, | ||
| [TextVariant.DisplayMd]: { | ||
| fontSize: typography.sDisplayMD.fontSize, | ||
| letterSpacing: typography.sDisplayMD.letterSpacing, | ||
| }, | ||
| [TextVariant.HeadingLg]: { | ||
| fontSize: typography.sHeadingLG.fontSize, | ||
| letterSpacing: typography.sHeadingLG.letterSpacing, | ||
| }, | ||
| [TextVariant.HeadingMd]: { | ||
| fontSize: typography.sHeadingMD.fontSize, | ||
| letterSpacing: typography.sHeadingMD.letterSpacing, | ||
| }, | ||
| [TextVariant.HeadingSm]: { | ||
| fontSize: typography.sHeadingSM.fontSize, | ||
| letterSpacing: typography.sHeadingSM.letterSpacing, | ||
| }, | ||
| [TextVariant.BodyLg]: { | ||
| fontSize: typography.sBodyLGMedium.fontSize, | ||
| letterSpacing: typography.sBodyLGMedium.letterSpacing, | ||
| }, | ||
| [TextVariant.BodyMd]: { | ||
| fontSize: typography.sBodyMD.fontSize, | ||
| letterSpacing: typography.sBodyMD.letterSpacing, | ||
| }, | ||
| [TextVariant.BodySm]: { | ||
| fontSize: typography.sBodySM.fontSize, | ||
| letterSpacing: typography.sBodySM.letterSpacing, | ||
| }, | ||
| [TextVariant.BodyXs]: { | ||
| fontSize: typography.sBodyXS.fontSize, | ||
| letterSpacing: typography.sBodyXS.letterSpacing, | ||
| }, | ||
| [TextVariant.PageHeading]: { | ||
| fontSize: typography.sPageHeading.fontSize, | ||
| letterSpacing: typography.sPageHeading.letterSpacing, | ||
| }, | ||
| [TextVariant.SectionHeading]: { | ||
| fontSize: typography.sSectionHeading.fontSize, | ||
| letterSpacing: typography.sSectionHeading.letterSpacing, | ||
| }, | ||
| [TextVariant.ButtonLabelMd]: { | ||
| fontSize: typography.sButtonLabelMd.fontSize, | ||
| letterSpacing: typography.sButtonLabelMd.letterSpacing, | ||
| }, | ||
| [TextVariant.ButtonLabelLg]: { | ||
| fontSize: typography.sButtonLabelLg.fontSize, | ||
| letterSpacing: typography.sButtonLabelLg.letterSpacing, | ||
| }, | ||
| [TextVariant.AmountDisplayLg]: { | ||
| fontSize: typography.sAmountDisplayLg.fontSize, | ||
| letterSpacing: typography.sAmountDisplayLg.letterSpacing, | ||
| }, | ||
| }; | ||
|
|
||
| /** | ||
| * Default number of lines displayed in the Textarea. | ||
| */ | ||
| export const TEXTAREA_DEFAULT_NUMBER_OF_LINES = 4; | ||
37 changes: 37 additions & 0 deletions
37
packages/design-system-react-native/src/components/Textarea/Textarea.figma.tsx
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,37 @@ | ||
| // import figma needs to remain as figma otherwise it breaks code connect | ||
| // eslint-disable-next-line import-x/no-named-as-default | ||
| import figma from '@figma/code-connect'; | ||
| import React from 'react'; | ||
|
|
||
| import { Textarea } from './Textarea'; | ||
|
|
||
| /** | ||
| * -- This file was auto-generated by Code Connect -- | ||
| * React Native implementation of Textarea component | ||
| * `props` includes a mapping from Figma properties and variants to | ||
| * suggested values. You should update this to match the props of your | ||
| * code component, and update the `example` function to return the | ||
| * code example you'd like to see in Figma | ||
| */ | ||
|
|
||
| figma.connect( | ||
| Textarea, | ||
| 'https://www.figma.com/design/1D6tnzXqWgnUC3spaAOELN/%F0%9F%A6%8A-WIP--MMDS-Components?node-id=12091%3A104', | ||
| { | ||
| props: { | ||
| isDisabled: figma.boolean('isDisabled'), | ||
| isError: figma.boolean('isError'), | ||
| isReadOnly: figma.boolean('isReadOnly'), | ||
| placeholder: figma.string('placeholder'), | ||
| }, | ||
| example: ({ isDisabled, isError, isReadOnly, placeholder }) => ( | ||
| <Textarea | ||
| value="" | ||
| isDisabled={isDisabled} | ||
| isError={isError} | ||
| isReadOnly={isReadOnly} | ||
| placeholder={placeholder ?? 'Enter text'} | ||
| /> | ||
| ), | ||
| }, | ||
| ); |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Textarea metrics constant duplicates Input's identical constant
Low Severity
MAP_TEXT_VARIANT_TEXTAREA_METRICSis an exact copy ofMAP_TEXT_VARIANT_INPUT_METRICSfromInput.constants.ts— same type signature, same values for everyTextVariantkey. This duplication means any typography-metric fix or new variant addition needs to be applied in both files, risking drift.