Skip to content
Draft
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

98 changes: 98 additions & 0 deletions packages/design-system-react-native/MIGRATION.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,84 @@ This guide provides detailed instructions for migrating your project from one ve

## Version Updates

### From version 0.14.0 to 0.15.0

#### TitleStandard API

If you adopted `TitleStandard` from a prerelease or internal branch that used `topLabel` or an optional `title`, apply the following when upgrading to **0.15.0+** (the first stable release that includes this component with the API below).

**What changed:**

- `title` is **required**. Omitting it is a type error; if you only need a trailing inline control, pass an empty string or another minimal `ReactNode` and use `titleEndAccessory`.
- **`topLabel`** and **`topLabelProps`** are removed. Use **`topAccessory`** with a [`Text`](./src/components/Text/README.md) node (or any `ReactNode`) for content above the title row.
- **`title`** and **`bottomLabel`** are typed as **`ReactNode`** (strings still receive default typography via [`BoxHorizontal`](./src/components/BoxHorizontal/README.md) / `TextOrChildren`).
- The bottom row shows **`bottomLabel` or `bottomAccessory`**, not both: if `bottomLabel` is renderable, it is the only bottom row; otherwise a renderable `bottomAccessory` is rendered on its own.

**Migration:**

Before (preview / earlier API):

```tsx
<TitleStandard topLabel="Send" title="$4.42" bottomLabel="0.002 ETH" />

<TitleStandard topLabel="Send" topLabelProps={{ testID: 'top' }} title="$4.42" />

<TitleStandard titleAccessory={<Icon name={IconName.Info} size={IconSize.Sm} />} />
```

After (0.15.0+):

```tsx
import {
TitleStandard,
Text,
TextVariant,
TextColor,
FontWeight,
Icon,
IconName,
IconSize,
} from '@metamask/design-system-react-native';

<TitleStandard
topAccessory={
<Text
variant={TextVariant.BodySm}
fontWeight={FontWeight.Medium}
color={TextColor.TextAlternative}
>
Send
</Text>
}
title="$4.42"
bottomLabel="0.002 ETH"
/>

<TitleStandard
topAccessory={
<Text
variant={TextVariant.BodySm}
fontWeight={FontWeight.Medium}
color={TextColor.TextAlternative}
testID="top"
>
Send
</Text>
}
title="$4.42"
/>

<TitleStandard
title=""
titleEndAccessory={<Icon name={IconName.Info} size={IconSize.Sm} />}
/>
```

**Impact:**

- Affects any screen using `TitleStandard` with `topLabel` / `topLabelProps` or without `title`.
- Shared types: import `TitleStandardPropsShared` from `@metamask/design-system-shared` if you extend the layout contract across platforms.

### From version 0.13.0 to 0.14.0

#### BottomSheet navigation callback change
Expand Down Expand Up @@ -102,6 +180,26 @@ import { BoxRow, BoxColumn } from '@metamask/design-system-react-native';

- Any import of `BoxHorizontal` or `BoxVertical` must be renamed

#### TitleStandard `titleAccessory` renamed to `titleEndAccessory`

**What changed:**

- `TitleStandard` and `TitleStandardPropsShared` prop **`titleAccessory`** is now **`titleEndAccessory`**.

**Migration:**

```tsx
// Before (0.15.0)
<TitleStandard title="$4.42" titleAccessory={<Icon name={IconName.Info} size={IconSize.Sm} />} />

// After (0.16.0)
<TitleStandard title="$4.42" titleEndAccessory={<Icon name={IconName.Info} size={IconSize.Sm} />} />
```

**Impact:**

- Any `TitleStandard` usage that passed `titleAccessory`

#### KeyValueRow API

**What changed:**
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,241 @@
# TitleStandard

TitleStandard is used to display a required primary title with optional rows above and below the title, optional inline accessories next to the title and bottom label, and optional bottom label or custom bottom content.

```tsx
import { TitleStandard } from '@metamask/design-system-react-native';

<TitleStandard title="$4.42" />;
```

Cross-platform layout props are defined as `TitleStandardPropsShared` in `@metamask/design-system-shared`. This package adds `twClassName`, React Native `View` props, and `titleProps` / `bottomLabelProps` for the platform `Text` component.

## Props

### `title`

The primary title. The title row always renders. When `title` is a string, it is wrapped with heading typography (`TextVariant.HeadingLg` and `titleProps`); other `ReactNode` values render as provided.

| TYPE | REQUIRED | DEFAULT |
| ----------- | -------- | ------- |
| `ReactNode` | Yes | — |

```tsx
<TitleStandard title="$1,234.56" />
```

### `titleEndAccessory`

Optional node rendered to the right of the title (for example an info icon).

| TYPE | REQUIRED | DEFAULT |
| ----------- | -------- | ----------- |
| `ReactNode` | No | `undefined` |

```tsx
import {
TitleStandard,
Box,
Icon,
IconName,
IconSize,
} from '@metamask/design-system-react-native';

<TitleStandard
title="$4.42"
titleEndAccessory={
<Box twClassName="ml-2">
<Icon name={IconName.Info} size={IconSize.Sm} />
</Box>
}
/>;
```

### `topAccessory`

Optional row above the title (for example secondary label text or a row with icons).

| TYPE | REQUIRED | DEFAULT |
| ----------- | -------- | ----------- |
| `ReactNode` | No | `undefined` |

```tsx
import {
TitleStandard,
Text,
TextVariant,
TextColor,
FontWeight,
} from '@metamask/design-system-react-native';

<TitleStandard
topAccessory={
<Text
variant={TextVariant.BodySm}
fontWeight={FontWeight.Medium}
color={TextColor.TextAlternative}
>
Send
</Text>
}
title="$4.42"
bottomLabel="0.002 ETH"
/>;
```

### `bottomLabel`

Optional bottom row with secondary label typography when the value is a string (`BodySm`, medium, `TextColor.TextAlternative`). If `bottomLabel` is renderable, `bottomAccessory` is not shown.

| TYPE | REQUIRED | DEFAULT |
| ----------- | -------- | ----------- |
| `ReactNode` | No | `undefined` |

```tsx
<TitleStandard title="$4.42" bottomLabel="0.002 ETH" />
```

### `bottomLabelEndAccessory`

Optional node rendered to the right of the bottom label. Only used when `bottomLabel` is renderable (same row as the default bottom label typography).

| TYPE | REQUIRED | DEFAULT |
| ----------- | -------- | ----------- |
| `ReactNode` | No | `undefined` |

```tsx
import {
TitleStandard,
Box,
Icon,
IconName,
IconSize,
IconColor,
} from '@metamask/design-system-react-native';

<TitleStandard
title="$4.42"
bottomLabel="0.002 ETH"
bottomLabelEndAccessory={
<Box twClassName="ml-2">
<Icon
name={IconName.Info}
size={IconSize.Sm}
color={IconColor.IconAlternative}
/>
</Box>
}
/>;
```

### `bottomAccessory`

Optional custom bottom row when `bottomLabel` is not renderable. Renders without default label typography; compose layout inside the node.

| TYPE | REQUIRED | DEFAULT |
| ----------- | -------- | ----------- |
| `ReactNode` | No | `undefined` |

```tsx
import {
TitleStandard,
Box,
BoxFlexDirection,
BoxAlignItems,
Icon,
IconName,
IconSize,
Text,
TextVariant,
} from '@metamask/design-system-react-native';

<TitleStandard
title="$4.42"
bottomAccessory={
<Box
flexDirection={BoxFlexDirection.Row}
alignItems={BoxAlignItems.Center}
gap={1}
>
<Icon name={IconName.Gas} size={IconSize.Xs} />
<Text variant={TextVariant.BodySm}>~$0.50 fee</Text>
</Box>
}
/>;
```

### `titleProps`

Optional props merged into the heading `Text` when `title` is a string. Use for `testID` or typography overrides.

| TYPE | REQUIRED | DEFAULT |
| -------------------- | -------- | ----------- |
| `Partial<TextProps>` | No | `undefined` |

```tsx
<TitleStandard title="$4.42" titleProps={{ testID: 'title-standard-title' }} />
```

### `bottomLabelProps`

Optional props merged into the bottom label `Text` when `bottomLabel` is a string.

| TYPE | REQUIRED | DEFAULT |
| -------------------- | -------- | ----------- |
| `Partial<TextProps>` | No | `undefined` |

```tsx
<TitleStandard
title="$4.42"
bottomLabel="0.002 ETH"
bottomLabelProps={{ testID: 'title-standard-bottom' }}
/>
```

### `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 `tw.style()`, 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
// Add additional styles
<TitleStandard twClassName="mt-4" title="$4.42" />

// Override default styles
<TitleStandard twClassName="px-6" title="$4.42" />
```

### `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. Other `View` props (for example `testID` and accessibility fields) are also accepted on the root container.

| TYPE | REQUIRED | DEFAULT |
| ---------------------- | -------- | ----------- |
| `StyleProp<ViewStyle>` | No | `undefined` |

```tsx
import { useTailwind } from '@metamask/design-system-twrnc-preset';

import { TitleStandard } from '@metamask/design-system-react-native';

export const ConditionalExample = ({ isActive }: { isActive: boolean }) => {
const tw = useTailwind();

return (
<TitleStandard
title="$4.42"
style={tw.style('opacity-90', isActive && 'opacity-100')}
/>
);
};
```

## References

[MetaMask Design System Guides](https://www.notion.so/MetaMask-Design-System-Guides-Design-f86ecc914d6b4eb6873a122b83c12940)
Loading
Loading