mirror of
https://github.com/wu736139669/hapi.git
synced 2026-11-07 01:21:37 +00:00
* feat(android): anchor the Material type scale on the shared reading tokens MaterialTheme was built with only a colorScheme, leaving HapiTypography's body/code/caption tokens an island that never influenced Material typography. Derive the app-wide Material type scale from those tokens so Material widgets and direct token consumers share one type system: the body token drives bodyLarge (the chat reading size) and the caption token drives bodySmall (the metadata size), while every other slot keeps its Material platform default so existing MaterialTheme.typography call sites stay pixel-identical. Only size and leading come from the tokens; weight, tracking and family stay Material's. HapiTheme now accepts a typography argument (defaulting to the shared scale) and passes it through, and the monospace code token stays a direct-consumer token because Material has no code slot. Co-Authored-By: Claude Code <noreply@anthropic.com> via [HAPI](https://hapi.run) Co-Authored-By: HAPI <noreply@hapi.run> * feat(android): render settings pickers as expressive choice dialogs The theme and language pickers were the last bare AlertDialog + radio-row surfaces in the app: plain stacked radio buttons with no visual anchor for what each option means, and two focus targets per row (the row and the RadioButton each carried their own click handler). Give small exclusive pickers a shared expressive form: each option renders as a full-width choice card whose selected state is a secondaryContainer fill plus a trailing check, and options can carry a fixed preview swatch. The theme modes show two-tone palette chips — follow-system spans the light and dark palettes, OLED is outlined pure black, dark uses the dark canvas rather than black so the two stay distinguishable at a glance. Swatch colors are fixed values depicting the mode they name, not derived from the active scheme, mirroring how the web color-theme cards hardcode their previews: a "light" chip must stay light even inside a dark dialog. Rows keep radio semantics through Modifier.selectable with Role.RadioButton inside a selectableGroup, so TalkBack still announces the standard "selected, n of m" picker phrasing while each option becomes a single focus target. Tapping an option still applies it immediately. Language options skip the swatch slot; the component stays generic over the value. Co-Authored-By: Claude Code <noreply@anthropic.com> via [HAPI](https://hapi.run) Co-Authored-By: HAPI <noreply@hapi.run> --------- Co-authored-by: Claude Code <noreply@anthropic.com> Co-authored-by: HAPI <noreply@hapi.run>