feat: Label migration (extensions)#1152
Conversation
📖 Storybook Preview |
georgewrmarshall
left a comment
There was a problem hiding this comment.
The Label migration looks close, but I found a few Storybook/docs issues worth tightening before we treat this as the reference migration. The main ones are that two Label stories currently render Input without its required controlled value, the implicit wrapping example currently uses invalid label markup, and the story meta exposes a className control even though our docs rule says not to for React components.
| render: () => ( | ||
| <Box flexDirection={BoxFlexDirection.Column} gap={2}> | ||
| <Label htmlFor="email-input">Email address</Label> | ||
| <Input id="email-input" placeholder="you@example.com" /> |
There was a problem hiding this comment.
suggestion: Input requires a controlled value: string via InputPropsShared, so this story is currently type-invalid. Can we pass value="" here (or use a small controlled wrapper like the Input stories do)?
| <Label> | ||
| <Box flexDirection={BoxFlexDirection.Column} gap={2} className="w-full"> | ||
| Email address | ||
| <Input placeholder="you@example.com" /> |
There was a problem hiding this comment.
suggestion: Same type issue here: Input requires value: string, so this example is missing value="" or a controlled wrapper.
| export const WrappingInput: Story = { | ||
| render: () => ( | ||
| <Label> | ||
| <Box flexDirection={BoxFlexDirection.Column} gap={2} className="w-full"> |
There was a problem hiding this comment.
suggestion: This wrapper turns the example into invalid label markup because <label> only permits phrasing content plus its labeled control. Could we switch the inner wrapper to Text asChild with a <span>, for example:
<Label className="inline-flex w-full flex-col gap-2">
<Text asChild>
<span>Email address</span>
</Text>
<Input value="" placeholder="you@example.com" />
</Label>That keeps the implicit-label example valid HTML while still using MMDS typography primitives.
| }, | ||
| argTypes: { | ||
| htmlFor: { control: 'text' }, | ||
| className: { control: 'text' }, |
There was a problem hiding this comment.
suggestion: .cursor/rules/component-documentation.md says not to create Storybook controls for className on React components. Can we drop this control and leave className documented in the README only?
cbdb70b to
f2f5d7f
Compare
📖 Storybook Preview |
📖 Storybook Preview |
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 2dfed75. Configure here.
📖 Storybook Preview |
brianacnguyen
left a comment
There was a problem hiding this comment.
Can you address Bugbot comments?
📖 Storybook Preview |
📖 Storybook Preview |
## Release 40.0.0 This release updates the shared layer and both UI packages: new extension-aligned primitives and form helpers on web, new selection and multi-line input components on React Native, shared types and context for those APIs, coordinated **`BannerBase`** close behavior, and **`ButtonBase`** defaults driven by **`size`** (with migration guidance for wrappers that overrode label, icon, or spacing). ### Package versions - `@metamask/design-system-shared`: **0.18.0** - `@metamask/design-system-react`: **0.23.0** - `@metamask/design-system-react-native`: **0.25.0** ### Shared type updates (0.18.0) #### Component type additions ([#1172](#1172), [#1164](#1164), [#1169](#1169), [#1141](#1141)) **What changed** - **`SelectButton`** shared props and variants (`SelectButtonPropsShared`, `SelectButtonVariant`, `SelectButtonEndArrow`). - **`SegmentGroup`** shared props and **`SegmentGroupContext`** (`SegmentGroupPropsShared`, `SegmentGroupContext`, `SegmentGroupContextValue`). - **`SensitiveText`** shared types (`SensitiveTextLength`, `SensitiveTextPropsShared`, and related exports). - **`HelpText`** shared types (`HelpTextSeverity`, `HelpTextPropsShared`, and related exports). - **`TextAreaPropsShared`** for multi-line input wrappers. **Impact** - React and React Native stay aligned on the same ADR-0003/0004-style contracts for the new and updated surfaces above. ### React web updates (0.23.0) #### Added - **`PopoverHeader`** — popover title rows and trailing actions, extension migration patterns ([#1158](#1158)). - **`ModalHeader`** — modal title rows and accessory slots ([#1144](#1144)). - **`Label`** — captions paired with form controls ([#1152](#1152)). - **`SensitiveText`** — mask/reveal for sensitive strings with configurable visible length ([#1164](#1164)). - **`HelpText`** — helper, success, warning, and error copy under inputs and controls ([#1169](#1169)). #### Changed - **`ButtonBase`** — label **`Text`** variant, start/end icon sizes, and internal spacing are derived from **`size`** for each **`ButtonBaseSize`** ([#1150](#1150)). See [Migration guide — ButtonBase](https://github.com/MetaMask/metamask-design-system/blob/main/packages/design-system-react/MIGRATION.md#buttonbase-size-defaults). - **`BannerBase`** — close behavior uses **`onClose`** only; **`closeButtonProps.onClick`** is not the dismiss API; **`closeButtonProps`** is for customization ([#1166](#1166)). ### React Native updates (0.25.0) #### Added - **`SelectButton`**, **`SegmentButton`**, **`SegmentGroup`** ([#1172](#1172)). - **`SensitiveText`**, aligned with the shared contract ([#1164](#1164)). - **`HeaderStandardAnimated`** and **`useHeaderStandardAnimated`** ([#1151](#1151)). - **`TextArea`** ([#1141](#1141)). #### Changed - **`ButtonBase`** — same size-driven defaults as web ([#1150](#1150)). See [Migration guide — ButtonBase](https://github.com/MetaMask/metamask-design-system/blob/main/packages/design-system-react-native/MIGRATION.md#buttonbase-size-defaults). - **`BannerBase`** — close behavior uses **`onClose`** only; **`closeButtonProps.onPress`** is not the dismiss API ([#1166](#1166)). ### Breaking changes #### `BannerBase` close API (both platforms) **What changed** - **React:** Use **`onClose`** for dismiss behavior. **`closeButtonProps.onClick`** is removed from that role. The close control is tied to **`onClose`**. **`closeButtonProps`** remains for non-behavioral customization (e.g. **`data-testid`**, accessibility, styling hooks). - **React Native:** Same pattern: **`onClose`** instead of **`closeButtonProps.onPress`** for dismiss behavior. **Migration** - Move any close action from **`closeButtonProps.onClick`** / **`closeButtonProps.onPress`** to **`onClose`**. - If you previously forced a close button with only **`closeButtonProps`**, also provide **`onClose`**. **Impact** - Call sites that dismissed via **`closeButtonProps`** or showed a close button without **`onClose`** must be updated. See: - [React — From version 0.22.0 to 0.x.0](https://github.com/MetaMask/metamask-design-system/blob/main/packages/design-system-react/MIGRATION.md#from-version-0220-to-0x0) - [React Native — From version 0.24.0 to 0.x.0](https://github.com/MetaMask/metamask-design-system/blob/main/packages/design-system-react-native/MIGRATION.md#from-version-0240-to-0x0) **`ButtonBase`:** not called out here as a semver-breaking API change; consumers who overrode typography, icon size, or spacing on **`ButtonBase`** wrappers should follow the ButtonBase migration sections linked above. ### Checklist - [x] Changelogs updated with human-readable descriptions - [x] `yarn changelog:validate` passes - [x] Version bumps follow semantic versioning - [x] `@metamask/design-system-shared`: **minor** (0.17.x → 0.18.0) — new shared exports for select/segment, sensitive text, help text, text area - [x] `@metamask/design-system-react`: **minor** (0.22.x → 0.23.0) — new components; **`BannerBase`** / **`ButtonBase`** behavior - [x] `@metamask/design-system-react-native`: **minor** (0.24.x → 0.25.0) — new components; **`BannerBase`** / **`ButtonBase`** behavior - [x] Breaking changes documented (**`BannerBase`**) in MIGRATION with before/after examples - [x] PR references present in changelog entries ## Pre-merge author checklist - [ ] [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) - [ ] [Release Workflow](https://github.com/MetaMask/metamask-design-system/blob/main/.cursor/rules/release-workflow.md) - [ ] `yarn build && yarn test && yarn lint` - [ ] `yarn changelog:validate` ## Pre-merge reviewer checklist - [ ] [Reviewing Release PRs](https://github.com/MetaMask/metamask-design-system/blob/main/docs/reviewing-release-prs.md) - [ ] Package versions and semver match what this PR actually publishes - [ ] Changelogs are consumer-facing - [ ] Breaking changes covered in MIGRATION.md - [ ] No unpublished package is missing from the changelogs / version list for **this** PR

Description
Added
Labelcomponent to DSR.Related issues
Fixes: https://consensyssoftware.atlassian.net/browse/DSYS-315
Manual testing steps
LabelcomponentScreenshots/Recordings
Before
After
Pre-merge author checklist
Pre-merge reviewer checklist
Note
Low Risk
Adds a new exported
Labelcomponent plus Storybook/docs/tests; risk is low and mostly limited to styling/typography defaults and HTML attribute forwarding behavior.Overview
Adds a new
Labelcomponent to@metamask/design-system-react, implemented as a semantic<label>composed viaText asChildwith defaultBodyMd/Mediumtypography,inline-flex items-centerlayout, and conditionalcursor-pointerwhenhtmlForis provided.Exports
Label/LabelPropsfrom the component barrel, and adds Storybook stories, MDX docs, and unit tests validating rendering, class merging,htmlFor/attribute/ref forwarding.Updates
MIGRATION.mdwith extension-to-design-system guidance forLabel, including removed polymorphic/SCSS hooks and the expected import-path swap.Reviewed by Cursor Bugbot for commit 52a4570. Bugbot is set up for automated code reviews on this repo. Configure here.