Skip to content

refactor: align List tokens, spacing and typography with MD3 - #5041

Open
adam-sajko wants to merge 6 commits into
callstack:mainfrom
adam-sajko:feat/list-md3-tokens-spacing
Open

refactor: align List tokens, spacing and typography with MD3#5041
adam-sajko wants to merge 6 commits into
callstack:mainfrom
adam-sajko:feat/list-md3-tokens-spacing

Conversation

@adam-sajko

@adam-sajko adam-sajko commented Aug 7, 2026

Copy link
Copy Markdown

Motivation

List.Item and List.Accordion now follow the MD3 list spec for padding, type, and colour instead of hardcoded sizes and the old expanded primary tint.

Visual changes

  • One-line rows: 16dp vertical padding, was 14. Height 56dp.
  • Three-line rows: 12dp vertical padding when the description wraps. Height 88dp.
  • Title is bodyLarge, supporting text is bodyMedium (line height 24 / 20). Two-line rows keep the 14dp that main already had, but land on 72dp now.
  • Trailing inset 16dp, was 24. Checkboxes and chevrons sit 8dp closer to the edge.
  • Expanded accordion title and leading icon stay onSurface / onSurfaceVariant, no primary tint.
  • Accordion chevron is centered with alignSelf instead of the old fixed 40dp box, so it shifts a little on two-line accordions.

Two cleanups in utils.ts. getAccordionColors only existed to return the primary tint on expand, so it goes away together with its tests. getLeftStyles and getRightStyles were the same function twice, now one helper with the same output.

Related issue

Related to #4976

Test plan

  • Unit tests for the theme override reaching title/description typography
  • Unit tests for 12dp padding when the description wraps
  • Snapshots updated on purpose (padding, type, trailing inset)

@adam-sajko
adam-sajko marked this pull request as ready for review August 18, 2026 08:26

@MikitasK MikitasK left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good job 👏 overall, this refactoring looks solid 👍
just a few thing to consider before merge:

Comment thread src/components/List/ListItem.tsx
Comment thread src/components/List/ListItem.tsx
Comment thread src/components/List/ListAccordion.tsx
Comment thread src/components/List/ListItem.tsx
Comment thread src/components/List/ListAccordion.tsx

@MikitasK MikitasK left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM ✅

Comment thread src/components/List/ListAccordion.tsx Outdated
<MaterialCommunityIcon
name={isExpanded ? 'chevron-up' : 'chevron-down'}
color={descriptionColor}
color={theme.colors[ListTokens.trailingIconColor]}

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should the chevron use the expand set rather than the generic list-item one? On the
Lists specs md.comp.list.expand.collapsed.list-item.trailing-icon.icon.color and its expanded twin both resolve to md.sys.color.on-surface, where md.comp.list.list-item.trailing-icon.color is on-surface-variant.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch, done

Comment thread src/components/List/ListItem.tsx Outdated
setIsDescriptionMultiline(nativeEvent.lines.length >= 2);
};

const getVerticalPaddingStyle = () => {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

react-native-web doesn't implement onTextLayout, and a function description never gets it either, so in both cases a wrapped description stays on the 14dp tier and renders 92dp against md.comp.list.list-item.three-line.container.height = 88dp. Would minHeight: description ? 72 : 56 with a flat 12dp padding work instead? It lands on 56 / 72 / 88 without measuring anything.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did what you suggested with one exception. I kept onTextLayout. The height no longer reads it, but the same flag still top-aligns the left and right elements on three line items, which was all it did before this PR. Please take another look :)

@adam-sajko
adam-sajko force-pushed the feat/list-md3-tokens-spacing branch from 6a7b135 to 0dfd5f9 Compare August 28, 2026 16:18
@adam-sajko
adam-sajko force-pushed the feat/list-md3-tokens-spacing branch from 0dfd5f9 to d92fdfa Compare August 28, 2026 16:37
const {
wrapper: { queryByText, getByText, findByText },
} = await setup({ enterTouchDelay: 50, leaveTouchDelay: 0 });
} = await setup({ enterTouchDelay: 50, leaveTouchDelay: 100 });

@adam-sajko adam-sajko Aug 28, 2026

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stolen from #4996 (CI fix)

import type { ColorRole } from '../../theme/types';

const sizes = {
verticalPadding: 12,

@MikitasK MikitasK Aug 28, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could we avoid applying 12dp root padding to every row?

with the PR’s own 40dp avatar example, one-line item becomes 64dp (40 + 12 + 12) instead of 56dp, List.Image (56dp) becomes 80dp instead of 72dp. compose uses 8dp vertical padding for one/two-line items & 12dp only for 3-line items

maybe we can preserve measurement-free 56/72/88dp text rows by using 8dp container padding plus 4dp content padding with the same 4dp offset for top-aligned accessories? and could we also cover a 40dp avatar or List.Image case?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants