Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

674 - Update OdsSnackbarHost API #679

Merged
merged 5 commits into from
Oct 24, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ fun ComponentSnackbars() {
bottomSheetScaffoldState = bottomSheetScaffoldState,
snackbarHost = {
OdsSnackbarHost(hostState = it) { data ->
OdsSnackbar(snackbarData = data, actionOnNewLine = actionOnNewLineChecked, onActionClick = {
OdsSnackbar(data = data, actionOnNewLine = actionOnNewLineChecked, onActionClick = {
clickOnElement(context = context, clickedElement = snackbarActionButton)
})
}
Expand Down Expand Up @@ -97,7 +97,10 @@ fun ComponentSnackbars() {
contentBackground = false
) {
OdsTextBody2(
modifier = Modifier.padding(bottom = dimensionResource(id = com.orange.ods.R.dimen.spacing_xs)),
modifier = Modifier.padding(
top = dimensionResource(id = com.orange.ods.R.dimen.spacing_s),
bottom = dimensionResource(id = com.orange.ods.R.dimen.spacing_xs)
),
text = stringResource(id = R.string.component_snackbar_code_first_step)
)
CodeBackgroundColumn {
Expand Down
1 change: 1 addition & 0 deletions changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- \[Lib\] Update `OdsBottomNavigation`, `OdsChoiceChipsFlowRow`, `OdsSlider` and `OdsSliderLockups` APIs ([#661](https://github.com/Orange-OpenSource/ods-android/issues/661))
- \[Lib\] Review and update technical documentation ([#638](https://github.com/Orange-OpenSource/ods-android/issues/638))
- \[Lib\] Update `OdsListItem` API ([#650](https://github.com/Orange-OpenSource/ods-android/issues/650))
- \[Lib\] Update `OdsSnackbarHost` API ([#674](https://github.com/Orange-OpenSource/ods-android/issues/674))

### Fixed

Expand Down
14 changes: 13 additions & 1 deletion docs/components/Snackbars.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ action that was just taken, or retrying an action that had failed.
* [Accessibility](#accessibility)
* [Implementation](#implementation)
* [Jetpack Compose](#jetpack-compose)
* [OdsSnackbarHost API](#odssnackbarhost-api)
florentmaitre marked this conversation as resolved.
Show resolved Hide resolved

---

Expand Down Expand Up @@ -61,7 +62,9 @@ Scaffold(
scaffoldState = scaffoldState,
snackbarHost = {
OdsSnackbarHost(hostState = it) { data ->
OdsSnackbar(snackbarData = data)
OdsSnackbar(data = data, actionOnNewLine = true, onActionClick = {
doSomething()
})
}
}) {
OdsButton(
Expand All @@ -80,3 +83,12 @@ Scaffold(
)
}
```

#### OdsSnackbarHost API

Parameter | Default value | Description
-- | -- | --
`hostState: SnackbarHostState` | | State of this component to read and show `OdsSnackbar` accordingly.
`modifier: Modifier` | `Modifier` | `Modifier` applied to the snackbar host
`snackbar: (SnackbarData) -> OdsSnackbar` | `{ OdsSnackbar(it) }` | Instance of the `OdsSnackbar` to be shown at the appropriate time with appearance based on the `SnackbarData` provided as a param
{:.table}
Original file line number Diff line number Diff line change
Expand Up @@ -26,26 +26,73 @@ import com.orange.ods.R
import com.orange.ods.compose.component.OdsComposable
import com.orange.ods.compose.component.button.OdsTextButton
import com.orange.ods.compose.component.button.OdsTextButtonStyle
import com.orange.ods.compose.component.content.OdsComponentContent
import com.orange.ods.compose.component.utilities.BasicPreviewParameterProvider
import com.orange.ods.compose.component.utilities.Preview
import com.orange.ods.compose.component.utilities.UiModePreviews
import com.orange.ods.compose.theme.OdsDisplaySurface

/**
* <a href="https://system.design.orange.com/0c1af118d/p/887440-toast--snackbars/b/043ece" class="external" target="_blank">ODS snackbar</a>.
* Host for [OdsSnackbar]s to be used in [Scaffold] to properly show, hide and dismiss items based
* on Material specification and the [hostState].
* The [OdsSnackbarHost] uses the padding provided by the Orange Design System.
*
* @see androidx.compose.material.SnackbarHost
*
* @param hostState State of this component to read and show [OdsSnackbar]s accordingly.
* @param modifier [Modifier] applied to the snackbar host.
* @param snackbar Instance of the [OdsSnackbar] to be shown at the appropriate time with appearance based on
* the [SnackbarData] provided as a param.
*/
@OdsComposable
@Composable
fun OdsSnackbarHost(
hostState: SnackbarHostState,
modifier: Modifier = Modifier,
snackbar: (SnackbarData) -> OdsSnackbar = { OdsSnackbar(it) }
) {
SnackbarHost(
modifier = modifier.padding(dimensionResource(id = R.dimen.spacing_s)),
hostState = hostState,
snackbar = { snackbar(it).Content(modifier = Modifier) }
)
}

/**
* A snackbar in an [OdsSnackbarHost].
*
* @see androidx.compose.material.Snackbar
* @constructor Creates an instance of [OdsSnackbar].
* @param data Data used to create the snackbar.
* @param actionOnNewLine Whether or not the action should be put on a separate line. Recommended for action with long action text.
* @param onActionClick Callback invoked when the action button is clicked.
*/
class OdsSnackbar(private val data: SnackbarData, private val actionOnNewLine: Boolean = false, private val onActionClick: () -> Unit = {}) :
OdsComponentContent<Nothing>() {

@Composable
override fun Content(modifier: Modifier) {
OdsSnackbar(
modifier = modifier,
message = data.message,
actionLabel = data.actionLabel,
actionOnNewLine = actionOnNewLine,
onActionClick = onActionClick
)
}
}

/**
* Please directly use [OdsSnackbarHost] to display a snackbar.
*
* @param message text displayed in the snackbar.
* @param modifier modifiers for the Snackbar layout.
* @param actionLabel if set, it displays an [OdsTextButton] with the given [actionLabel] as an action of the snackbar.
* @param actionOnNewLine whether or not action should be put on the separate line. Recommended
* for action with long action text
* @param onActionClick executed on action button click.
* @param message Text displayed into the snackbar.
* @param modifier [Modifier] applied to the snackbar layout.
* @param actionLabel If set, it displays an [OdsTextButton] with the given [actionLabel] as an action of the snackbar.
* @param actionOnNewLine Whether or not action should be put on a separate line. Recommended for action with long action text.
* @param onActionClick Callback invoked when the action button is clicked.
*/
@Composable
@OdsComposable
fun OdsSnackbar(
private fun OdsSnackbar(
message: String,
modifier: Modifier = Modifier,
actionLabel: String? = null,
Expand All @@ -68,67 +115,31 @@ fun OdsSnackbar(
) { Text(text = message) }
}

/**
* <a href="https://system.design.orange.com/0c1af118d/p/887440-toast--snackbars/b/043ece" class="external" target="_blank">ODS snackbar</a>.
*
* @see androidx.compose.material.Snackbar
*
* @param snackbarData data about the current snackbar showing via [SnackbarHostState].
* @param modifier modifiers for the Snackbar layout.
* @param actionOnNewLine whether or not action should be put on the separate line. Recommended
* for action with long action text
* @param onActionClick executed on action button click.
*/
@UiModePreviews.Default
@Composable
fun OdsSnackbar(
snackbarData: SnackbarData,
modifier: Modifier = Modifier,
actionOnNewLine: Boolean = false,
onActionClick: () -> Unit = {}
) {
OdsSnackbar(
modifier = modifier,
message = snackbarData.message,
actionLabel = snackbarData.actionLabel,
actionOnNewLine = actionOnNewLine,
onActionClick = onActionClick
)
private fun PreviewOdsSnackbar(@PreviewParameter(OdsSnackbarPreviewParameterProvider::class) parameter: OdsSnackbarPreviewParameter) = Preview {
with(parameter) {
OdsSnackbar(
message = "This is the message of the snackbar.",
actionLabel = if (action) "Action" else null,
actionOnNewLine = actionOnNewLine
)
}
}

/**
* Host for [OdsSnackbar]s to be used in [Scaffold] to properly show, hide and dismiss items based
* on material specification and the [hostState].
* The [OdsSnackbarHost] use the padding provided by the Orange Design System.
*
* @see androidx.compose.material.SnackbarHost
*
* @param hostState state of this component to read and show [OdsSnackbar]s accordingly.
* @param modifier optional modifier for this component.
* @param snackbar the instance of the [OdsSnackbar] to be shown at the appropriate time with.
* appearance based on the [SnackbarData] provided as a param
*/
@OdsComposable
@Composable
fun OdsSnackbarHost(
hostState: SnackbarHostState,
modifier: Modifier = Modifier,
snackbar: @Composable (SnackbarData) -> Unit = { OdsSnackbar(snackbarData = it) }
) {
SnackbarHost(
modifier = modifier.padding(dimensionResource(id = R.dimen.spacing_s)),
hostState = hostState,
snackbar = snackbar
)
}
private data class OdsSnackbarPreviewParameter(
val action: Boolean,
val actionOnNewLine: Boolean = false
)

@UiModePreviews.Default
@Composable
private fun PreviewOdsSnackbar(@PreviewParameter(OdsSnackbarPreviewParameterProvider::class) actionOnNewLine: Boolean) = Preview {
OdsSnackbar(
message = "This is the message of the snackbar.",
actionLabel = "Action",
actionOnNewLine = actionOnNewLine
)
}
private class OdsSnackbarPreviewParameterProvider :
BasicPreviewParameterProvider<OdsSnackbarPreviewParameter>(*previewParameterValues.toTypedArray())

private class OdsSnackbarPreviewParameterProvider : BasicPreviewParameterProvider<Boolean>(false, true)
private val previewParameterValues: List<OdsSnackbarPreviewParameter>
get() {
return listOf(
OdsSnackbarPreviewParameter(action = false),
OdsSnackbarPreviewParameter(action = true),
OdsSnackbarPreviewParameter(action = true, actionOnNewLine = true),
)
}