diff --git a/CHANGELOG.md b/CHANGELOG.md index ff5cb27a..a1231565 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -24,6 +24,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Keep a new public method or other contract change on the brief and spec path when the objection is that another package should own the edit. Put that objection in the brief. - Skip a planning brief for an unkept spike or POC and for routine CI-only work, including a workflow edit that changes how jobs or E2E launch. A CI change that is a new design, a contract or API change, or multi-surface work still stops for a brief and a spec. For a revert of a merged pull request or commit, name the target and files, then ask one yes/no, and name the risk when security or privacy is involved. Recommend a spec for a new design, a contract or API change, or multi-surface work even when the ask is fully specified or single-file; any other fully specified ask gets one line of scope and one yes/no instead of a brief, unless it touches auth, secrets, logs or exports of state, permissions, keyring or vault, migrations, or persisted state, which still gets a brief. Always read the installed skill catalog, including for reverts and fully specified asks. - Document confirmed Appium interaction-stability patterns in `testing/mobile-testing` (`references/appium-e2e.md`): child readiness, fresh interactive queries, shared open retries, virtualized-list proof, native control state, action postconditions, and single assertions for short-lived alerts. +- Make the MetaMask Extension `ui/ui-development` overlay and the agentic design system strategy work without Storybook MCP. Agents read the installed `@metamask/design-system-react` types and component READMEs at the MMDS release tag, with a pinned reference for `@metamask/design-system-react@0.49.0` and `@metamask/design-system-tailwind-preset@0.15.0` (MMDS release v77.0.0, `references/mmds-react.md`) covering exports, key props, Tailwind classes, the type scale, deprecations, and hero typography. Storybook MCP stays an optional extra. During an incremental migration, alias a legacy `ui/components/component-library` import with a `Legacy` prefix when its name clashes with `@metamask/design-system-react`, and keep the MMDS name plain. ## [0.3.1] diff --git a/domains/ui/knowledge/agentic-design-system-strategy.md b/domains/ui/knowledge/agentic-design-system-strategy.md index 50d6dd6f..ca39c477 100644 --- a/domains/ui/knowledge/agentic-design-system-strategy.md +++ b/domains/ui/knowledge/agentic-design-system-strategy.md @@ -25,25 +25,26 @@ This applies wherever UI is built and reviewed: Cursor and other coding agents, ## Core model -One knowledge layer, three deliveries. MMDS holds tokens, components, and patterns. Tools are delivery mechanisms only — do not maintain separate copies of MMDS guidance inside each tool. +One knowledge layer, several deliveries. MMDS holds tokens, components, and patterns. Tools are delivery mechanisms only; skills keep a small, release-pinned summary and link to MMDS for everything else. | Moment | What happens | | :---- | :---- | -| **Create** | Agents read current MMDS guidance before building — through skills, Storybook MCP, Figma MCP, and Code Connect. | +| **Create** | Agents read current MMDS guidance before building — the installed package types, component READMEs at the release tag, and the skill's pinned reference; Figma MCP, Code Connect, and Storybook MCP when available. | | **Review** | Deterministic checks (ESLint, fitness functions) plus agentic review for judgment calls. | | **Audit** | Recurring queries across existing screens to find drift, custom UI, and documentation gaps. | ## Producer / consumer split -- **Consumer skills** (`ui-development` repo overlays) route agents to current MMDS guidance for product UI create and review workflows. +- **Consumer skills** (`ui-development` repo overlays) give agents the product UI create and review workflows, plus a release-pinned MMDS reference per platform (`references/mmds-react.md`, `references/mmds-react-native.md`). - **Provider skills** (future `design-system` domain) support MMDS authoring, release, and documentation maintenance. -- **Storybook MCP** (`storybook-broker-mcp`) is the preferred delivery mechanism for current MMDS knowledge in coding agents. Package exports and consumer Tailwind configuration are the ordered fallback when the broker is unavailable. +- **Baseline delivery** needs no MCP server: the installed `@metamask/design-system-*` package (exports and `.d.cts` types), component READMEs on GitHub at the release tag (`https://github.com/MetaMask/metamask-design-system/blob//packages//src/components//README.md[x]`), and the consumer's Tailwind configuration. +- **Storybook MCP** (`storybook-broker-mcp`, served through Context Forge) is an optional extra. It depends on Context Forge being up, so no skill may require it. When it responds, agents may use it for pattern docs and story examples; when it does not, they carry on with the baseline sources without blocking. ## Foundation workstreams -1. **Thin consumer gateway skills** — Refine `ui-development` overlays into stable routers (Create + Review) instead of static component inventories. -2. **Storybook MCP integration** — Treat Context Forge's preconfigured `storybook-broker-mcp` as the primary source; document explicit fallback behavior without embedding setup instructions in skills. -3. **MMDS source and broker readiness** — Keep Storybook documentation, exports, and broker surfaces current for agent consumption. +1. **Consumer gateway skills** — Keep `ui-development` overlays as Create + Review routers with a small, release-pinned reference (versions, inventory, key props, deprecations, tokens), refreshed on each MMDS release. +2. **Storybook MCP integration** — Keep Context Forge's `storybook-broker-mcp` usable as an optional source; skills document it as optional and never embed setup instructions. +3. **MMDS source and broker readiness** — Keep component READMEs, exports, JSDoc, and Storybook current for agent consumption. README drift from the types (for example a documented prop that does not exist) is a documentation bug. 4. **Automated alignment checks** — Extend CI and review workflows to validate tokens, components, and patterns where feasible. 5. **Provider-side skills** — Add a `design-system` domain and `metamask-design-system` maintainer overlay in the skills repo. @@ -51,14 +52,14 @@ One knowledge layer, three deliveries. MMDS holds tokens, components, and patter | Horizon | Focus | | :---- | :---- | -| **Now** | Build the shared knowledge path and establish quality baselines — point MetaMask Skills to Storybook MCP, begin Figma/React/React Native alignment, expand Code Connect, audit MMDS and product usage. | +| **Now** | Build the shared knowledge path and establish quality baselines — point MetaMask Skills at release-pinned MMDS docs that work without MCP, keep Storybook MCP as an optional extra, begin Figma/React/React Native alignment, expand Code Connect, audit MMDS and product usage. | | **Next** | Operationalize Create, Review, and Audit in normal delivery — enable the gateway by default in Extension and Mobile, run MMDS-focused review, load relevant skills per UI PR, run recurring audits. | | **Later** | Build a trusted feedback and remediation loop — agents create issues or PRs for alignment gaps, automate low-risk fixes, retain human approval for judgment calls. | ## Principles for skills - MMDS is the default; intentional documented custom UI is allowed. -- Skills are gateways and durable constraints, not second copies of MMDS documentation. -- Do not maintain static component inventories, deprecated-name lists, or MCP setup instructions in consumer skills. -- Query current Storybook guidance before choosing components, APIs, tokens, or patterns. -- When Storybook MCP is unavailable, follow the ordered fallback defined in the relevant repo overlay. +- Skills are gateways and durable constraints. A skill may carry a small reference pinned to a named MMDS release (versions, inventory, key props, deprecations, tokens), but not copies of full component READMEs. +- Every pinned reference names the package versions and release tag it was synced to, and says that the installed package wins when they differ. +- Skills must work with no MCP server. Do not make Storybook MCP, Figma MCP, or any other server a precondition, and do not put MCP setup instructions in consumer skills. +- Read the installed package types and the README at the matching release tag before choosing components, APIs, tokens, or patterns. When a README and the types disagree, the types win. diff --git a/domains/ui/skills/ui-development/references/mmds-react.md b/domains/ui/skills/ui-development/references/mmds-react.md new file mode 100644 index 00000000..8ca9f39f --- /dev/null +++ b/domains/ui/skills/ui-development/references/mmds-react.md @@ -0,0 +1,231 @@ +# MMDS React quick reference (MetaMask Extension) + +A pinned snapshot of `@metamask/design-system-react` and its Tailwind preset for +agents that cannot reach Storybook MCP. It is a summary, not the contract: the +installed package in `node_modules` wins over this file, and the component README +at the release tag wins over memory. + +## Synced versions + +| Package | Version | Extension `main` pin (Nov 2026) | +| --- | --- | --- | +| `@metamask/design-system-react` | [0.49.0](https://www.npmjs.com/package/@metamask/design-system-react/v/0.49.0) | `^0.47.0` (resolves to 0.47.x) | +| `@metamask/design-system-tailwind-preset` | [0.15.0](https://www.npmjs.com/package/@metamask/design-system-tailwind-preset/v/0.15.0) (Tailwind CSS v3) | `^0.15.0` | +| `@metamask/design-tokens` | [12.0.0](https://www.npmjs.com/package/@metamask/design-tokens/v/12.0.0) | `^12.0.0` | +| `@metamask/design-system-shared` | [0.43.0](https://www.npmjs.com/package/@metamask/design-system-shared/v/0.43.0) | `^0.41.0` | + +MMDS release: [v77.0.0](https://github.com/MetaMask/metamask-design-system/releases/tag/v77.0.0) (2026-10-28). + +0.47.0 and 0.49.0 export the same components. The differences that matter for +Extension code: + +- 0.49.0 (breaking): `TextFieldSearch` requires `inputAriaLabel`. On 0.47.x the + prop does not exist; label the field through `inputProps={{ 'aria-label': ... }}`. +- 0.48.0: `IconName.Pause` and `IconName.Play`; `AvatarToken` / `AvatarNetwork` + image sources render on a white background. +- 0.49.0: `IconName.FeedPost`; the info `IconAlert` uses `IconColor.IconDefault`. + +Read the [CHANGELOG](https://github.com/MetaMask/metamask-design-system/blob/v77.0.0/packages/design-system-react/CHANGELOG.md) +and [MIGRATION](https://github.com/MetaMask/metamask-design-system/blob/v77.0.0/packages/design-system-react/MIGRATION.md) +for the installed version before trusting this file. + +## Stable documentation URLs + +Component READMEs are not shipped in the npm tarball. Read them from GitHub at the +release tag, which does not move: + +``` +https://github.com/MetaMask/metamask-design-system/blob/v77.0.0/packages/design-system-react/src/components//README.mdx +``` + +- Component types: `.../v77.0.0/packages/design-system-react/src/components//.types.ts` +- Shared enums (`TextVariant`, `FontFamily`, `ButtonVariant`, `IconName`, ...): `.../v77.0.0/packages/design-system-shared/src/types/` +- Tailwind preset: [`packages/design-system-tailwind-preset`](https://github.com/MetaMask/metamask-design-system/tree/v77.0.0/packages/design-system-tailwind-preset) +- Token CSS: [`packages/design-tokens/src/css`](https://github.com/MetaMask/metamask-design-system/tree/v77.0.0/packages/design-tokens/src/css) +- Styling rules used by the MMDS team: [`.cursor/rules/styling.md`](https://github.com/MetaMask/metamask-design-system/blob/v77.0.0/.cursor/rules/styling.md) +- Legacy Extension component-library to MMDS mapping: the React `MIGRATION.md` above +- Hosted Storybook (optional, built from `main`, so it can show unreleased changes): + +When a README and the installed `.d.cts` types disagree, the types win. + +## Exports at 0.49.0 + +Everything is imported from `@metamask/design-system-react`, including the +re-exported shared enums and the `twMerge` helper. + +| Area | Components | +| --- | --- | +| Layout | `Box` | +| Text | `Text`, `SensitiveText`, `Label`, `HelpText` | +| Actions | `Button`, `ButtonBase`, `ButtonIcon`, `TextButton` | +| Inputs | `Input`, `TextField`, `FormTextField`, `TextArea`, `TextFieldSearch`, `Checkbox` | +| Overlays | `Modal`, `ModalOverlay`, `ModalContent`, `ModalHeader`, `ModalBody`, `ModalFooter`, `ModalFocus`, `useModalContext`, `Popover`, `PopoverHeader` | +| Headers | `HeaderBase`, `HeaderSubpage` | +| Feedback | `BannerAlert`, `BannerBase`, `Toast`, `Toaster`, `toast`, `Skeleton`, `Tag` | +| Icons and avatars | `Icon`, `IconAlert`, `AvatarAccount`, `AvatarBase`, `AvatarFavicon`, `AvatarGroup`, `AvatarIcon`, `AvatarNetwork`, `AvatarToken`, `Blockies`, `Jazzicon`, `Maskicon` | +| Badges | `BadgeCount`, `BadgeIcon`, `BadgeNetwork`, `BadgeStatus`, `BadgeWrapper` | +| Utility | `twMerge` | + +The React package does not have the React Native layout and list components +(`ListItem`, `KeyValueRow`, `BottomSheet`, `HeaderStandard`, `Card`, ...). Do not +port them from Mobile; reuse existing Extension UI or record the gap. + +Deprecated (still exported, do not add new usage): + +| Deprecated | Use instead | +| --- | --- | +| `ButtonHero` | `Button` (Primary is the default `variant`) | +| `ButtonFilter` | The JSDoc says `FilterButton`, but the React package does not export one yet. Keep existing usage, and record the gap if new UI needs a filter button | +| `FontFamily.Accent` (MM Sans) | `FontFamily.Hero` or `FontFamily.Default`. Removed on MMDS `main` in [#1645](https://github.com/MetaMask/metamask-design-system/pull/1645); still exported in 0.49.0 | +| Extension `ui/components/component-library/*` marked `@deprecated` | The MMDS component named in the JSDoc | + +## Key props of the most-used components + +Common to almost every component: `className` (Tailwind classes, merged with +`twMerge`), `style`, and the native HTML attributes of the root element. + +| Component | Key props | +| --- | --- | +| `Box` | `flexDirection`, `flexWrap`, `alignItems`, `justifyContent`, `gap`, `padding*` / `margin*` (`0`–`12`, 4px steps), `backgroundColor` (`BoxBackgroundColor`), `borderColor` (`BoxBorderColor`), `borderWidth`, `asChild` | +| `Text` | `variant` (default `BodyMd`, also picks the HTML tag), `color` (`TextColor`), `fontWeight`, `fontFamily`, `fontStyle`, `textAlign`, `textTransform`, `overflowWrap`, `ellipsis`, `asChild` | +| `Button` | `variant` (`ButtonVariant.Primary` default / `Secondary` / `Tertiary`), `size` (`ButtonSize.Sm` / `Md` / `Lg`), `onClick`, `isDanger`, `isInverse`, `isDisabled`, `isLoading`, `loadingText`, `isFullWidth`, `startIconName`, `endIconName` | +| `ButtonIcon` | `iconName` and `ariaLabel` (both required), `size`, `variant`, `isDisabled`, `iconProps` | +| `TextButton` | `children`, `size`, `isInverse`, `isDisabled`, `startIconName`, `endIconName`, `textVariant`, `asChild` | +| `Icon` | `name` (`IconName`), `size` (`IconSize.Xs`–`Xl`), `color` (`IconColor`) | +| `Modal` family | `Modal`: `isOpen`, `onClose`, `isClosedOnOutsideClick`, `isClosedOnEscapeKey`, focus props. Compose `ModalOverlay` + `ModalContent` (`size`) + `ModalHeader` (`onClose`, `onBack`, `closeButtonProps={{ ariaLabel }}`) + `ModalBody` + `ModalFooter` (`primaryButtonProps`, `secondaryButtonProps`, `buttonsAlignment`) | +| `Popover` | `isOpen`, `referenceElement`, `position` (`PopoverPosition`), `role`, `hasArrow`, `matchWidth`, `isPortal`, `onClickOutside`, `onPressEscKey` | +| `TextField` | `size` (`TextFieldSize`), `type` (`TextFieldType`), `isError`, `isDisabled`, `isReadOnly`, `startAccessory`, `endAccessory`, `inputProps`, `inputRef`, `onChange` | +| `FormTextField` | `label`, `helpText`, `isError`, `id`, `labelProps`, `helpTextProps`, `textFieldProps` | +| `TextFieldSearch` | `TextField` props + `clearButtonOnClick`, `clearButtonProps`, and `inputAriaLabel` (required from 0.49.0) | +| `BannerAlert` | `severity` (`BannerAlertSeverity.Neutral` / `Info` / `Success` / `Warning` / `Danger`), `title`, `description`, `actionButtonLabel`, `actionButtonOnClick`, `onClose` | +| `Tag` | `severity` (`TagSeverity`), `children`, `startIconName`, `endIconName`, `startAccessory`, `endAccessory` | +| `Toast` / `toast()` | `toast({ title, description, severity })` needs one mounted ``; search Extension for an existing mount before adding one | +| `SensitiveText` | `Text` props + `isHidden`, `length` (`SensitiveTextLength`) | +| `Skeleton` | `width`, `height`, `hideChildren` | +| `Checkbox` | `id`, `isSelected`, `onChange`, `label`, `isDisabled`, `isInvalid` | +| `HeaderSubpage` | `title`, `description`, `avatar`, `onBack`, `onClose`, `startAccessory`, `endAccessory` | + +## Tailwind preset and tokens + +Extension uses Tailwind CSS 3.4 with `presets: [require('@metamask/design-system-tailwind-preset')]` +in `tailwind.config.js`. Its theme drops the default palette and default font +sizes, so only MMDS tokens exist. (Tailwind CSS v4 consumers use +`@metamask/design-tokens/tailwind/theme.css` instead; Extension does not.) + +- Colors drop the category prefix: `bg-default`, `bg-alternative`, `bg-section`, + `bg-subsection`, `bg-muted`, `bg-hover`, `bg-pressed`, `text-default`, + `text-alternative`, `text-muted`, `border-default`, `border-muted`, plus semantic + sets `primary-*`, `error-*`, `warning-*`, `success-*`, `info-*` + (`bg-error-muted`, `text-success-default`, `border-primary-default`). +- Interaction states: `hover:bg-hover`, `active:bg-pressed`, or the + `*-default-hover` / `*-default-pressed` tokens. +- Typography: prefer `Text`. Raw classes exist for cases `Text` cannot cover + (inputs, measuring spans) and are paired per breakpoint: + `text-s-body-md leading-s-body-md tracking-s-body-md md:text-l-body-md md:leading-l-body-md md:tracking-l-body-md`. + The preset README's `font-s-heading-lg` example is out of date. +- Font families: `font-default` (Inter), `font-hero` (Grotzec Cond). `font-accent` + is still generated by 0.15.0 but removed on MMDS `main`; do not use it. +- Weights: `font-regular` (400), `font-medium` (500), `font-bold` (600). +- CSS variables for non-Tailwind contexts: `var(--color-background-default)`, + `var(--font-family-hero)`. Do not hardcode hex values + (`@metamask/design-tokens/color-no-hex`). + +## Typography scale + +Web switches from the small scale to the large scale at `md` (768px). + +| `TextVariant` | HTML tag | Below 768px | 768px and up | Default weight | +| --- | --- | --- | --- | --- | +| `DisplayXl` | `h1` | 60 / 75 | 60 / 75 | bold, `md:` medium | +| `DisplayLg` | `h1` | 40 / 50 | 60 / 75 | bold, `md:` medium | +| `DisplayMd` | `h1` | 32 / 40 | 48 / 56 | bold, `md:` medium | +| `HeadingLg` | `h2` | 24 / 32 | 32 / 40 | bold | +| `HeadingMd` | `h3` | 20 / 24 | 24 / 32 | bold | +| `HeadingSm` | `h4` | 16 / 24 | 20 / 24 | bold | +| `BodyLg` | `p` | 20 / 24 | 20 / 24 | medium | +| `BodyMd` (default) | `p` | 16 / 24 | 16 / 24 | regular | +| `BodySm` | `p` | 14 / 22 | 14 / 22 | regular | +| `BodyXs` | `p` | 12 / 20 | 12 / 20 | regular | +| `PageHeading` | `h1` | 24 / 32 | 32 / 40 | bold | +| `SectionHeading` | `h2` | 20 / 24 | 24 / 32 | bold | +| `ButtonLabelMd` | `span` | 16 / 24 | 16 / 24 | medium | +| `ButtonLabelLg` | `span` | 20 / 24 | 20 / 24 | medium | +| `AmountDisplayLg` | `span` | 48 / 56 | 60 / 75 | bold, `md:` medium | + +## Font families and hero typography + +| `FontFamily` | Face | Status at 0.49.0 | +| --- | --- | --- | +| `Default` | Inter | Use for everything by default | +| `Hero` | Grotzec Cond (Bold cut only) | Use only for the cases below | +| `Accent` | MM Sans | Exported but removed on `main` (#1645); never add new usage | + +What the code does: + +- Only the Bold cut of Grotzec is licensed. Extension registers one + `@font-face 'Grotzec Cond'` for weights 400–700 from `GrotzecCond-Bold.woff2`, + so every weight renders Bold. A weight class on hero text does nothing; leave + it off. +- Grotzec covers Latin scripts only (no Cyrillic, Greek, CJK, Devanagari, or + Vietnamese stacked tone marks). Extension has no language gate: the browser + falls back per character, so unsupported text renders in a mix of faces. + `MarketingMomentTitle` adds `[font-size-adjust:from-font]` to keep the fallback + metrics close. +- Some number characters are missing too (₹, ₩, ₿, U+202F used by `fr` grouping, + and native digits in `fa`, `bn`, `mr`). Test INR/KRW currencies and `fr`/`fa` + locales when a number moves to hero. + +When to use hero (stop at the first rule that matches): + +1. Body copy, labels, rows, buttons, form labels, tables, or anything 24px or + smaller: `Default`. Never hero. +2. The single primary money or number value of a screen (balance, price, total, + P&L): `TextVariant.AmountDisplayLg` + `FontFamily.Hero`, no weight. It renders + 48px below 768px and 60px at 768px and up (full-screen view); confirm the 60px + size with design for wide layouts. +3. A marketing moment headline: use Extension's `MarketingMoment` / + `MarketingMomentTitle` (`ui/components/ui/marketing-moment*`). Do not set + `fontFamily` on translated copy by hand. +4. Anything else, including amount inputs: `Default`, and ask design first. + +Rules: one hero element per view; size hero text with the variant, not +`text-[56px]`; size loaders to the variant line height +(``); keep the same variant and family on +the `SensitiveText` mask; when hero must go on an `` or measuring span, put +`font-hero` and the paired `AmountDisplayLg` classes on every element that is +measured or rendered. + +```tsx +import { + FontFamily, + SensitiveText, + Skeleton, + TextVariant, +} from '@metamask/design-system-react'; + +{isLoading ? ( + +) : ( + + {formattedBalance} + +)} +``` + +## Do and don't + +| Do | Don't | +| --- | --- | +| `Box` with layout props, `className` for the rest | `
` when `Box` props cover it | +| `Text variant={TextVariant.BodySm} color={TextColor.TextAlternative}` | `

` | +| `className="bg-muted rounded-xl hover:bg-hover"` | `bg-[#F2F4F6]`, `bg-gray-100`, SCSS for new styles | +| `Button` (`variant` defaults to Primary) | New `ButtonHero` | +| `ButtonIcon iconName={IconName.Close} ariaLabel={t('close')}` | `ButtonIcon` without `ariaLabel` | +| MMDS `Modal` family | New usage of a deprecated `ui/components/component-library` modal | +| `AmountDisplayLg` + `FontFamily.Hero`, no weight | Hero + `font-semibold` / `fontWeight={FontWeight.Medium}` | +| `FontFamily.Hero` / `Default` | `FontFamily.Accent`, `font-accent` | +| React components from `@metamask/design-system-react` | React Native or twrnc packages in Extension | diff --git a/domains/ui/skills/ui-development/repos/metamask-extension.md b/domains/ui/skills/ui-development/repos/metamask-extension.md index 120f26dc..463b5fa0 100644 --- a/domains/ui/skills/ui-development/repos/metamask-extension.md +++ b/domains/ui/skills/ui-development/repos/metamask-extension.md @@ -10,14 +10,16 @@ Strategy: [Agentic Design System Strategy](../../../knowledge/agentic-design-sys For Extension UI, the MetaMask Design System (MMDS) is the default source for components, tokens, and documented patterns. Align new and changed UI with MMDS -wherever it supports the need, using current Storybook documentation as the -source of truth. Custom UI remains valid when it serves an intentional product -need that MMDS does not cover, but the rationale should be recorded. +wherever it supports the need. Custom UI remains valid when it serves an +intentional product need that MMDS does not cover, but the rationale should be +recorded. -This is a consumer gateway, not a second MMDS knowledge base. Do not add static -component inventories, release-specific API lists, or copied component -documentation here. Storybook MCP and the installed package provide current -knowledge; this skill provides the Extension workflow and durable constraints. +This overlay gives the Extension workflow and durable constraints. The pinned +component inventory, key props, Tailwind classes, type scale, and hero typography +rules for `@metamask/design-system-react@0.49.0` (MMDS release +[v77.0.0](https://github.com/MetaMask/metamask-design-system/releases/tag/v77.0.0)) +are in [references/mmds-react.md](references/mmds-react.md). Extension `main` +pins `^0.47.0`; that reference lists what differs. ## When to Use @@ -29,13 +31,55 @@ quality, component file scaffolding, and PR process remain separate concerns and may be used alongside it. If a repository-specific scaffolding skill is available, use it for file and test setup; do not duplicate its templates here. +## Where Current Guidance Comes From + +Use these sources in order. None of them needs an MCP server. + +1. **The installed package.** `node_modules/@metamask/design-system-react/dist/components/index.d.cts` + for exports, and `dist/components//.types.d.cts` for props + and JSDoc (shared props and enums come from + `node_modules/@metamask/design-system-shared/dist/types/`). The installed + version is the source of truth for the code being changed. +2. **The component README at the release tag** (READMEs are not in the npm + tarball): `https://github.com/MetaMask/metamask-design-system/blob/v77.0.0/packages/design-system-react/src/components//README.mdx`. + For an older installed version, use that release's tag; the + [CHANGELOG](https://github.com/MetaMask/metamask-design-system/blob/v77.0.0/packages/design-system-react/CHANGELOG.md) + says which release shipped it. +3. **[references/mmds-react.md](references/mmds-react.md)**: pinned inventory, + key props, deprecations, Tailwind classes, type scale, and hero typography. +4. **The Extension styling surface.** `tailwind.config.js` uses + `@metamask/design-system-tailwind-preset` (Tailwind CSS v3) and removes the + default palette and font sizes. Use only class names generated by that + configuration. If a class is in doubt, check the preset source or the built + CSS instead of inventing one. Do not use default Tailwind colors, arbitrary + values, or a manual safelist as a substitute for an MMDS token. +5. **Current Extension usage and stories** found by searching the repository for + the component or token. Treat examples as usage evidence, not as a + replacement for the installed package contract. +6. **Storybook MCP (optional).** If a Storybook MCP server (for example + `storybook-broker-mcp`) is configured and responds, `list-all-documentation`, + `get-documentation`, and `get-documentation-for-story` may add pattern docs and + story examples. Never block on it, and do not install, configure, + authenticate, or invent an endpoint for it. If it is missing or a call fails, + carry on with the sources above; you do not need to report its absence unless + a question could only be answered there. + +Never infer an API from a name, a previous implementation, another platform, or +another UI library. If the required guidance is absent from all of the above, +record the gap rather than guessing. Do not apply React Native guidance or +components (`ListItem`, `BottomSheet`, `twClassName`, twrnc) to Extension. + +`@metamask/design-system-shared` may be relevant to Tailwind content scanning, +but import components and enums from `@metamask/design-system-react`. + ## Create Workflow -1. Query current MMDS guidance before choosing a component, pattern, API, token, - or interaction. +1. Read the installed package and README for each component, pattern, token, or + interaction you plan to use. 2. Use `@metamask/design-system-react` when it supports the need. 3. Search the Extension codebase and reuse suitable existing UI, including UI - that is not yet in MMDS or is intentionally feature-specific. + that is not yet in MMDS or is intentionally feature-specific (for example + `ui/components/ui/marketing-moment`). 4. Use Tailwind classes and the repository's design-token configuration for styling and layout not provided by MMDS. 5. Build new feature UI only when no suitable MMDS or existing Extension UI can @@ -52,16 +96,17 @@ evidence and leave PR mechanics to the relevant workflow. 1. Identify changed UI files, components, stories, styles, tokens, themes, and renderable behavior. -2. Query current Storybook guidance for each changed MMDS building block and - relevant pattern, using the Extension React/web documentation first. -3. Check that the implementation uses documented or story-proven props, +2. For each changed MMDS building block, read the installed types and the + README at the matching release tag (or Storybook MCP, if it is available). +3. Check that the implementation uses typed, documented, or story-proven props, variants, tokens, composition, and behavior. 4. Check component and pattern choice, existing-UI reuse, styling/token usage, accessibility, localization, keyboard behavior, and platform fit. -5. Check for new use of APIs or components marked `@deprecated` in current - package metadata or documentation. Do not maintain a deprecated-name list in - this skill; read the current replacement guidance and report a finding when - no replacement is documented. +5. Check for new use of APIs or components marked `@deprecated` in the installed + package or in `ui/components/component-library`. At 0.49.0 that includes + `ButtonHero` (use `Button`), `ButtonFilter` (no React replacement yet; record + the gap), and `FontFamily.Accent`. Read the JSDoc for the replacement and + report a finding when none is documented. 6. Identify custom UI and overrides. Treat them as findings when their product rationale or exception record is missing, not as automatic failures. 7. Separate deterministic issues from judgment findings, and report each finding @@ -71,87 +116,71 @@ Component or pattern choice, custom UI, and missing documentation are design-system findings that generally need human judgment. Deterministic repository checks may enforce token or deprecated-usage rules separately. -## Required Storybook MCP Workflow - -Before creating, changing, or reviewing UI: - -1. Start by querying `storybook-broker-mcp` with `list-all-documentation` so the - available guidance reflects the current MMDS release. -2. Find the relevant Extension pattern documentation in the React/web Storybook. -3. Query `get-documentation` for the selected pattern and each UI building block. -4. Query `get-documentation-for-story` when documentation does not answer the - question or a story is needed to establish real usage. -5. Use only props, variants, tokens, composition, and behavior explicitly - documented or demonstrated by a story. - -The Context Forge-provided `storybook-broker-mcp` is expected to be -preconfigured by the agent environment. Do not install, configure, authenticate, -or invent an endpoint for it from this skill. If the server or a required tool -is unavailable, or a call fails, state that the broker could not be reached and -use the fallback below. - -Never infer an API from a name, a previous implementation, another platform, or -another UI library. If the required guidance is absent, record the gap and use -the fallback process below rather than guessing. - -Do not apply guidance from another platform without an Extension mapping -documented in Storybook. If no mapping exists, treat it as a documentation gap. - -## Fallback When Storybook MCP Is Unavailable - -Use these sources in order: - -1. The installed `@metamask/design-system-react` package and its type - definitions under `node_modules`. -2. The installed Extension-facing MMDS styling surfaces: - `@metamask/design-system-tailwind-preset` for Tailwind CSS v3, or the - `@metamask/design-tokens/tailwind/theme.css` export for Tailwind CSS v4. - Use `@metamask/design-tokens` for the installed token exports and styles. -3. The Extension's current Tailwind configuration and package configuration. - Check the installed Tailwind version, preset or theme import, content - globs, plugins, and safelist. Use only class names generated by that - configuration and the installed MMDS preset or theme. If availability is - unclear, verify the generated CSS or build output instead of inventing a - class. Do not use default Tailwind colors, arbitrary values, or a manual - safelist as a substitute for an MMDS token. -4. Current Extension usage and stories found by searching the repository for - the installed component or token. Treat examples as usage evidence, not as - a replacement for the installed package contract. -5. A generated MMDS release manifest or repository-provided release guidance. -6. The MMDS source repository as a last resort. - -`@metamask/design-system-shared` may be relevant to Tailwind content scanning -when required by the installed MMDS configuration, but it is not a source for -Extension component APIs. Do not use React Native or TWRNC packages for -Extension UI. - -The installed package version is the source of truth for the code being -changed. Read the matching exports and type definitions before writing or -reviewing usage. Do not restore a static inventory or copy undocumented APIs -into this skill to compensate for missing MCP. - ## Durable Extension Constraints -- Prefer `@metamask/design-system-react` components. +- Prefer `@metamask/design-system-react` components over the legacy + `ui/components/component-library`, whose components are being deprecated in + favor of MMDS (the React + [MIGRATION.md](https://github.com/MetaMask/metamask-design-system/blob/v77.0.0/packages/design-system-react/MIGRATION.md) + maps props). - Reuse suitable existing Extension UI before creating new feature UI. - Use Tailwind class names instead of SCSS for styling and layout. - Do not create or modify SASS or SCSS files. +- Use `Text` variants for typography; do not hand-set font sizes or use + arbitrary `text-[..px]` values. +- Use `FontFamily.Hero` only for the single primary amount of a view + (`TextVariant.AmountDisplayLg`, no weight) or through `MarketingMomentTitle`; + see [references/mmds-react.md](references/mmds-react.md#font-families-and-hero-typography). + Do not use `FontFamily.Accent`. +- Give every icon-only control an accessible name (`ButtonIcon` requires + `ariaLabel`; `TextFieldSearch` requires `inputAriaLabel` from 0.49.0). - Reuse an existing feature-level solution when the documented pattern calls for one; otherwise compose the smallest supported solution. - Preserve accessibility, localization, and keyboard interaction requirements - shown in the relevant Storybook documentation and stories. + shown in the component README and stories. - Use repository-approved exception documentation when custom UI is necessary; do not invent a new annotation format in this skill. +## Incremental migrations + +When a file still imports a legacy `ui/components/component-library` component +whose name is also exported by `@metamask/design-system-react`, alias the legacy +import with a `Legacy` prefix. Leave the MMDS import on the plain name. Finishing +the migration is then deleting the `Legacy*` import and its usages. + +The barrel is `ui/components/component-library` (`Box`, `Text`, `Button`, +`Icon`, and the rest). Adjust the `../` depth to the file. Do the same for any +other clashing export from that barrel, including enums such as `IconName`. Do +not alias a legacy export whose name does not exist on MMDS, and do not put the +`Legacy` prefix on the MMDS import. + +```tsx +// Do: MMDS keeps the plain names. Legacy gets the prefix. +import { Box, Text } from '@metamask/design-system-react'; +import { Box as LegacyBox, Text as LegacyText } from '../../component-library'; + +Migrated +Still legacy + +// Don't: prefix the MMDS import, or leave both on the plain name. +import { Box as LegacyBox, Text as LegacyText } from '@metamask/design-system-react'; +import { Box, Text } from '../../component-library'; +``` + ## Create and Review Checklist -- [ ] Current Storybook pattern and building-block guidance was queried, or the - MCP fallback, Tailwind configuration checks, and any documentation gap - were recorded. +- [ ] The installed package types and the README at the matching release tag + were read for each MMDS building block (Storybook MCP used only if + available), and any documentation gap was recorded. - [ ] MMDS was used wherever it supports the need, and suitable existing Extension UI was considered. - [ ] Only documented, story-proven, or installed-package-typed APIs are used. - [ ] No new deprecated API or component usage was introduced. +- [ ] Where a legacy `ui/components/component-library` import clashes with an + MMDS name, the legacy import has a `Legacy` prefix and the MMDS import + keeps the plain name. +- [ ] Only classes generated by the Extension Tailwind config and MMDS preset + are used; no default palette colors or arbitrary color values. - [ ] No undocumented platform substitution was made. - [ ] Custom UI has an intentional product rationale and exception record when required by repository practice.