Compose: Add DaxSnackbar to ADS#9044
Conversation
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
| * Figma reference: https://www.figma.com/design/BOHDESHODUXK7wSRNBOHdu/%F0%9F%A4%96-Android-Components?node-id=6550-55049 | ||
| */ | ||
| @Composable | ||
| fun DaxSnackbar( |
There was a problem hiding this comment.
🔍 I think we should at least have a preview of this Composable variant 👍
| val shape: Shape | ||
| @Composable | ||
| @ReadOnlyComposable | ||
| get() = DuckDuckGoTheme.shapes.small | ||
|
|
||
| val containerColor: Color | ||
| @Composable | ||
| @ReadOnlyComposable | ||
| get() = DuckDuckGoTheme.colors.backgrounds.surface | ||
|
|
||
| val contentColor: Color | ||
| @Composable | ||
| @ReadOnlyComposable | ||
| get() = DuckDuckGoTheme.textColors.primary | ||
|
|
||
| val actionColor: Color | ||
| @Composable | ||
| @ReadOnlyComposable | ||
| get() = DuckDuckGoTheme.colors.brand.accentBlue | ||
| } |
There was a problem hiding this comment.
🔍 These properties should all be PascalCase to match Compose guidelines (yes we're being a bit inconsistent with existing Composables, I've made a task to address it)
| fun DaxSnackbar( | ||
| message: String, | ||
| modifier: Modifier = Modifier, | ||
| action: DaxAction? = null, |
There was a problem hiding this comment.
❓Why did we opt to use DaxAction here? If we need something similar I think ideally it's specific to the Snackbar, otherwise if we really do need it here then DaxAction needs to be extracted from DaxMessage
|
|
||
| @PreviewLightDark | ||
| @Composable | ||
| private fun DaxSnackbarLongMessagePreview() { |
There was a problem hiding this comment.
❓Any idea why the bottom padding for this long snackbar is particuarly small compared to the other snackbars?
| * Reads the message and optional action label from [snackbarData] and delegates to the visual | ||
| * [DaxSnackbar] overload; tapping the action invokes [SnackbarData.performAction]. Trigger snackbars | ||
| * via [SnackbarHostState.showSnackbar]. A dismiss action ([SnackbarData]'s `withDismissAction`) is | ||
| * not rendered — the DDG snackbar design exposes only the message and an optional action. |
There was a problem hiding this comment.
🔍 The suppression itself is correct, and matches the View Snackbar, which never had a dismiss "X". It's worth making the consequence explicit, since it diverges from the View world. The View Snackbar is swipe-dismissable by default (DDG even opts out via NonDismissibleBehavior), whereas a Compose
SnackbarHost has no swipe-to-dismiss, so an indefinite snackbar with no action can only be dismissed in code.
| * not rendered — the DDG snackbar design exposes only the message and an optional action. | |
| * not rendered. The DDG snackbar design exposes only the message and an optional action. Unlike the | |
| * View `Snackbar`, a Compose `SnackbarHost` has no swipe-to-dismiss, so a `SnackbarDuration.Indefinite` | |
| * snackbar with no `actionLabel` can only be dismissed in code via [SnackbarHostState.currentSnackbarData]. |
Task/Issue URL: https://app.asana.com/1/137249556945/project/1207418217763355/task/1211670072973944?focus=true
Description
Adds the Compose
DaxSnackbarto the ADS. Both overloads are thin wrappers over Material3Snackbarwith DDG design tokens (surface background, primary text, accent-blue action, 8dp corners per the component Figma):DaxSnackbar(message, action?)— the visual component (message + optional trailing action). For previews, the ADS catalog, or any caller that owns its own visibility.DaxSnackbar(snackbarData)— for use inside a ComposeSnackbarHost(SnackbarHost(hostState) { DaxSnackbar(it) }); reads the message/action label and wiresperformAction(). Duration, placement and swipe-to-dismiss are owned by the host'sSnackbarHostState.Also adds the
NoRawM3SnackbarUsagelint rule (errors on raw Material3Snackbaroutside the design-system modules; the legacy ViewSnackbar.makeAPI is untouched) and a showcase in the ADS internal catalog.Steps to test this PR
ADS catalog
DaxSnackbarcards render — message-only, and message + "Action"Note
Low Risk
New design-system UI and lint-only enforcement; no production feature flows or security-sensitive logic changed.
Overview
Introduces
DaxSnackbaras the design-system snackbar for Compose: a message-only overload for static/catalog use and aSnackbarDataoverload forSnackbarHost, styled with DDG tokens (surface background, primary text,DaxGhostButtonaction).The ADS internal catalog Snackbar section now shows the legacy View
Snackbar.makedemo alongside ComposeDaxSnackbarexamples (theme-aware viaisDarkTheme). A newNoRawM3SnackbarUsagelint rule (registered inDuckDuckGoIssueRegistry) errors on rawandroidx.compose.material3.Snackbaroutside design-system modules, with unit tests mirroring the existing raw-M3 component detectors.Reviewed by Cursor Bugbot for commit 66bd7c1. Bugbot is set up for automated code reviews on this repo. Configure here.