feat: modernize drawer - #5052
Open
ziarno wants to merge 13 commits into
Open
Conversation
Bring `Drawer.Item` and `Drawer.Section` in line with the current `md.comp.navigation-drawer` token set and extract component-specific tokens. The public API is unchanged. - Extract `Drawer/tokens.ts` with `DrawerItemTokens`, `DrawerSectionTokens` and `DrawerCollapsedItemTokens`. The last one cites `md.comp.navigation-rail`, which is what actually specifies `Drawer.CollapsedItem`. - Correct the item's trailing padding from 36dp to the spec'd 28dp, so both container insets match. - Emphasize the active destination's label, per `md.comp.navigation-drawer.active.label-text.weight`. - Add the MD3 focus indicator. It uses the *inner* offset, so the ring is drawn inside the active indicator: destinations sit flush, and an outer ring would overlap its neighbours. - Resolve the active indicator radius from the `full` shape token instead of hardcoding `extraLarge`. - Drop the hardcoded `Palette.neutralVariant50` section divider colour, which ignored the theme and was wrong in dark mode. Drawer divider tokens are deprecated in MD3, so the standalone divider spec (`outlineVariant`, 1dp) applies. - Use `marginStart`/`marginEnd` for directional spacing. React Native auto-swaps left/right in RTL, but react-native-web does not. - Collapse the leftover v2/v3 style splits and the duplicated typescale spread in `Drawer.Item` and `Drawer.Section`. Supporting theme changes, both additive: - `TypescaleKey` gains the 15 `*Emphasized` keys. The values already existed in `md.sys.typescale` but no type exposed them. - `md.sys.state.focusIndicator` gains `innerOffset`. `Drawer.CollapsedItem` renders identically; only its magic numbers moved into tokens. Refs: callstack#4981 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
- Add a `Drawer` screen to the example app, inside a 360dp surface standing in for the drawer container so the active indicator sits at its spec'd proportions. Covers active/inactive destinations, no icon, a truncated label, disabled, both trailing-slot shapes, sections separated by a divider, and collapsed destinations. - Give the example app's own drawer the MD3 container: 360dp wide, `surfaceContainerLow`, and rounded corners on the ending edge only. Collapse its leftover v3 style split while there. - Document the section divider and focus indicator colour roles. - Add a `Drawer` section to the 6.x migration guide. The API is unchanged, but four visual changes are worth calling out for anyone pixel-matching against 5.x. - Recapture `drawer-item` and `drawer-section` screenshots against the new rendering. Both are now device-agnostic crops; the old `drawer-section` shot was an Android emulator window, which cannot be reproduced from an iOS Simulator. `drawer-collapsed` is unchanged, since `Drawer.CollapsedItem` renders identically. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Add `.agents/CONTEXT.md`, a glossary of the Material Design terms this project keeps getting wrong in review — the ref/sys/comp token tiers, state layer, focus indicator, active indicator, standard vs modal drawer. Add `.agents/adr/` with the three Drawer decisions a future reader would otherwise have to reverse-engineer: why Paper ships drawer destinations but no container, why `TypescaleKey` grew the emphasized keys, and why `Drawer.Item` alone among modernized components keeps `TouchableRipple` rather than rendering its own state layer. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The hand-maintained `docs/src/data/themeColors.ts` still referenced v5 color roles and pre-v6 component behaviour, so the generated `ThemeColorsTable` documented roles that no longer exist on `ThemeColors`. Removed roles that are not on the type: - `surfaceDisabled` / `onSurfaceDisabled` - v6 draws disabled states from `onSurface` at a reduced opacity - `backdrop` (Modal) - now `scrim` at 32% - `elevarion.level3` - typo, and the surface FAB variant no longer exists Re-checked every remaining entry against what the component renders: - Appbar / Appbar.Header elevated: `surfaceContainer`, not `elevation.level2` - Button elevated: `surfaceContainerLow`; outlined border: `outlineVariant` - Dialog and Searchbar: `surfaceContainerHigh` - IconButton outlined border: `outlineVariant` - SegmentedButtons checked border: `outline`; disabled border: `outlineVariant` - FAB: replaced the old variant list with the MD3 `primary`/`secondary`/ `tertiary`/`tonal*` variants, and swapped the removed `AnimatedFAB` entry for `FAB.Extended` - Snackbar: document container and label colors alongside the icon color Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
`disabled` blocked touch but had no visual effect, so a disabled destination was indistinguishable from an enabled one. MD3's navigation drawer and rail token sets define no disabled state, so fall back to the generic disabled-content opacity (`md.sys.state.opacity.disabled`) via a shared `stateOpacity` token. Applied at container level, as Checkbox and Menu.Item do, so the active indicator, icon, label and trailing slot dim together. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Git worktrees created under .claude/worktrees/ were crawled by Jest from the repo root, doubling the collected suites (110 instead of 55) and producing spurious failures from mismatched snapshots and duplicate module registration across checkouts. This also hit the lefthook pre-commit hook, which runs `test` from the repo root. Add <rootDir>/.claude/ to modulePathIgnorePatterns, which scopes both test discovery and module resolution. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This reverts commit ad5c200.
Revert changes that belong in their own PR, and finish wiring up the token modules introduced earlier in this branch. - Revert the theme colour table corrections for Appbar, Button, Dialog, FAB, IconButton, Menu, Modal, Searchbar, SegmentedButtons and Snackbar, along with the `.claude` jest ignore. The Drawer's own entries (`Drawer.Item` focus indicator, `Drawer.Section` divider) stay, since those document changes made here. - Drive the collapsed item's press animation from `theme.motion` rather than a hardcoded 150ms. `short3` is that same duration; the easing now follows the MD3 standard curve instead of Animated's default. - Resolve the collapsed item's active indicator radius through `resolveCornerRadius`, as `Drawer.Item` already does. - Colour the `Drawer.Item` label from the `*LabelTextColor` tokens, which were declared but never read. - Hide the focus indicator on disabled destinations. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The screenshots taken in b746c65 showed different views than the ones they replaced, so they no longer read as a before/after of the same UI. Recapture both against the views the originals used: - `drawer-item`: a tight crop of a single active "Sent mail" destination, with the same relative margins as the 5.x crop. - `drawer-section`: the example app's own drawer, open on the "Example items" section with Inbox active. Both are Android emulator captures. They lack the macOS window chrome the 5.x shots had, since that needs an interactive window capture. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
Motivation
Spec alignment
Drawer.Itemreserved 36dp trailing / 28dp leading. Both are now 28dp per spec, so items sit 8dp wider.Drawer.Itemlabels now uselabelLargeEmphasized(700). Inactive labels stay at 500.Drawer.Sectiondrew its divider in a fixedPalette.neutralVariant50grey that ignored the theme and was wrong in dark mode. It now usestheme.colors.outlineVariant, like every otherDivider.Drawer.CollapsedItemcomputed its radius asitemSize / 2; it now resolves thefullshape token through the theme.150mslinear ramp. It now uses theshort3duration andstandardeasing tokens.state.opacity.disabledtoken.Drawer.Itemgains a focus ring intheme.colors.secondary.Token extraction
New
src/components/Drawer/tokens.tsexportsDrawerItemTokens,DrawerSectionTokensandDrawerCollapsedItemTokens.Supporting theme changes
TypescaleKeygains the 15*Emphasizedkeys. The values already existed in the token set — only the types were missing.state.focusIndicatorgainsinnerOffset, needed to inset the focus ring.A note on drawer width. The example app deliberately sets no drawer width.
react-native-drawer-layout's default —min(360dp, containerWidth − 56dp)— is MD3's 360dp container plus MD2's 56dp edge gap; a flat 360dp leaves almost no scrim to tap and dismiss on narrow phones (also noticed by flutter/flutter#123380).Related issue
Closes #4981
Test plan
yarn test(Drawer unit tests + snapshots updated in this branch)Drawer.Item,Drawer.CollapsedItemandDrawer.Sectionin the example app (expanded, collapsed/rail, active/inactive/disabled states) in both light and dark themes