diff --git a/DEVELOP.md b/DEVELOP.md index ea83b8bfa..6c45bf1ee 100644 --- a/DEVELOP.md +++ b/DEVELOP.md @@ -18,7 +18,7 @@ repositories { ```groovy dependencies { - implementation 'com.orange.ods.android:ods-lib:0.17.0' + implementation 'com.orange.ods.android:ods-lib:0.18.0' } ``` diff --git a/app/build.gradle.kts b/app/build.gradle.kts index a6d3f171f..09c322610 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -35,7 +35,7 @@ android { minSdk = Versions.minSdk targetSdk = Versions.targetSdk val versionCodeProperty = project.findTypedProperty("versionCode") - versionCode = versionCodeProperty?.toInt() ?: 9 + versionCode = versionCodeProperty?.toInt() ?: 10 versionName = version.toString() val versionNameSuffixProperty = project.findTypedProperty("versionNameSuffix") versionNameSuffix = versionNameSuffixProperty diff --git a/changelog.md b/changelog.md index 89d762af3..b9b73432f 100644 --- a/changelog.md +++ b/changelog.md @@ -5,7 +5,7 @@ All notable changes done in ODS library will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## [Unreleased](https://github.com/Orange-OpenSource/ods-android/compare/0.17.0...develop) +## [0.18.0](https://github.com/Orange-OpenSource/ods-android/compare/0.17.0...0.18.0) - 2023-12-11 ### Added diff --git a/docs/0.18.0/404.html b/docs/0.18.0/404.html new file mode 100644 index 000000000..dd331eb8e --- /dev/null +++ b/docs/0.18.0/404.html @@ -0,0 +1,26 @@ +--- +permalink: /404.html +layout: default +--- + + + +
+

404

+ +

Page not found :(

+

The requested page could not be found.

+
\ No newline at end of file diff --git a/docs/0.18.0/components/AppBarsBottom.md b/docs/0.18.0/components/AppBarsBottom.md new file mode 100644 index 000000000..19ce0cca0 --- /dev/null +++ b/docs/0.18.0/components/AppBarsBottom.md @@ -0,0 +1,31 @@ +--- +layout: detail +title: "App bars: bottom" +description: A bottom app bar displays navigation and key actions at the bottom of mobile screens. +--- + +
**On this page** + +* [Specifications references](#specifications-references) +* [Accessibility](#accessibility) + +--- + +## Specifications references + +- [Design System Manager - App bars](https://system.design.orange.com/0c1af118d/p/23e0e6-app-bars/b/620966) +- [Material Design - App bars: bottom](https://material.io/components/app-bars-bottom) + +## Accessibility + +Please follow [accessibility criteria for development](https://a11y-guidelines.orange.com/en/mobile/android/development/). + +Android's bottom app bar component APIs provide support for the navigation icon, +action items, overflow menu and more for informing the user as to what each +action performs. While optional, their use is strongly encouraged. + +**Content descriptions** + +When using icons for navigation icons, action items and other elements of bottom +app bars, you should set a content description on them so that screen readers +like TalkBack are able to announce their purpose or action, if any. \ No newline at end of file diff --git a/docs/0.18.0/components/AppBarsBottom_docs.md b/docs/0.18.0/components/AppBarsBottom_docs.md new file mode 100644 index 000000000..4566c033f --- /dev/null +++ b/docs/0.18.0/components/AppBarsBottom_docs.md @@ -0,0 +1,4 @@ +--- +layout: main +content_page: AppBarsBottom.md +--- \ No newline at end of file diff --git a/docs/0.18.0/components/AppBarsTop.md b/docs/0.18.0/components/AppBarsTop.md new file mode 100644 index 000000000..0988cc0ee --- /dev/null +++ b/docs/0.18.0/components/AppBarsTop.md @@ -0,0 +1,157 @@ +--- +layout: detail +title: "App bars: top" +description: Top app bars display information and actions relating to the current screen. +--- + +
**On this page** + +* [Specifications references](#specifications-references) +* [Accessibility](#accessibility) +* [Variants](#variants) + * [Regular top app bar](#regular-top-app-bar) + * [Jetpack Compose](#jetpack-compose) + * [OdsTopAppBar API](#odstopappbar-api) + * [Large top app bar](#large-top-app-bar) + * [Jetpack Compose](#jetpack-compose-1) + * [OdsLargeTopAppBar API](#odslargetopappbar-api) + +--- + +## Specifications references + +- [Design System Manager - App bars](https://system.design.orange.com/0c1af118d/p/23e0e6-app-bars/b/620966) +- [Material Design - App bars: top](https://material.io/components/app-bars-top/) + +## Accessibility + +Please follow [accessibility criteria for development](https://a11y-guidelines.orange.com/en/mobile/android/development/). + +`OdsTopAppBar` provides accessibility support for the navigation icon, +action items, overflow menu and more for informing the user as to what each +action performs. + +## Variants + +### Regular top app bar + +#### Jetpack Compose + +Add `OdsTopAppBar` composable to your Scaffold `topBar`. +Here is an example of use: + +```kotlin +OdsTopAppBar( + title = "Title", + navigationIcon = OdsTopAppBar.NavigationIcon( + painter = painterResource(id = R.drawable.ic_back), + contentDescription = "content description", + onClick = { doSomething() } + ), + actions = listOf( + OdsTopAppBar.ActionButton( + painter = painterResource(id = R.drawable.ic_share), + contentDescription = "content description", + onClick = { doSomething() } + ), + // ... + ), + overflowMenuItems = listOf( + OdsDropdownMenu.Item( + text = "Text", + onClick = { doSomething() } + ), + // ... + ) +) +``` + +Note: By default, the `OdsTopAppBar` is elevated but you can set `elevated` parameter to `false` if you don't want any shadow below it (for example if you want to display tabs below). + +##### OdsTopAppBar API + +Parameter | Default value | Description +-- | -- | -- +`title: String` | | Title to be displayed in the center of the top app bar +`modifier: Modifier` | `Modifier` |`Modifier` to be applied to the top app bar +`navigationIcon: OdsTopAppBar.NavigationIcon?` | `null` | Icon to be displayed at the start of the top app bar +`actions: List` | `emptyList()` | Actions to be displayed at the end of the top app bar. The default layout here is a `Row`, so icons inside will be placed horizontally. +`overflowMenuItems: List` | `emptyList()` | List of items displayed in the overflow menu. The top app bar uses `OdsDropdownMenu` to display its overflow menu. +`elevated: Boolean` | `true` | Controls the elevation of the top app bar: `true` to set an elevation to the top app bar (a shadow is displayed below), `false` otherwise +{:.table} + +### Large top app bar + +#### Jetpack Compose + +First, you have to add this line in your application `build.gradle.kts` file cause this component relies on Compose Material 3 implementation: + +```kotlin +implementation("androidx.compose.material3:material3:") +``` + +Then you can add `OdsLargeTopAppBar` composable to your Scaffold `topBar`: + +```kotlin +OdsLargeTopAppBar( + title = "Title", + navigationIcon = OdsTopAppBar.NavigationIcon( + painter = painterResource(id = R.drawable.ic_back), + contentDescription = "content description", + onClick = { doSomething() } + ), + actions = listOf( + OdsTopAppBar.ActionButton( + painter = painterResource(id = R.drawable.ic_share), + contentDescription = "content description", + onClick = { doSomething() } + ), + // ... + ), + overflowMenuItems = listOf( + OdsDropdownMenu.Item( + text = "Text", + onClick = { doSomething() } + ), + // ... + ), + scrollBehavior = null // See below to attach a scroll behavior and make the top app bar collapsible +) +``` + +If you want a collapsible large top app bar, you can follow these steps: + +1 - Define the scroll behavior to use: + +```kotlin +val scrollBehavior = TopAppBarDefaults.exitUntilCollapsedScrollBehavior(rememberTopAppBarState()) +``` + +2 - Provide this `scrollBehavior` to the `OdsLargeTopAppBar` and as a modifier of your Scaffold in order to listen to the scroll event + +```kotlin +Scaffold( + modifier = Modifier.nestedScroll(scrollBehavior.nestedScrollConnection), + topBar = { + OdsLargeTopAppBar( + //... + scrollBehavior = scrollBehavior, + ) + }, + //... +) { + // Scaffold content +} +``` + +##### OdsLargeTopAppBar API + +Parameter | Default value | Description +-- | -- | -- +`title: String` | | Title displayed in the center of the top app bar +`modifier: Modifier` | `Modifier` |`Modifier` applied to the top app bar +`navigationIcon: OdsTopAppBar.NavigationIcon?` | `null` | Icon displayed at the start of the top app bar +`actions: List` | `emptyList()` | Actions displayed at the end of the top app bar. The default layout here is a `Row`, so icons inside will be placed horizontally. +`overflowMenuItems: List` | `emptyList()` | List of items displayed in the overflow menu. The top app bar uses `OdsDropdownMenu` to display its overflow menu. +`scrollBehavior: TopAppBarScrollBehavior?` | `null` | `TopAppBarScrollBehavior` attached to the top app bar +{:.table} diff --git a/docs/0.18.0/components/AppBarsTop_docs.md b/docs/0.18.0/components/AppBarsTop_docs.md new file mode 100644 index 000000000..1afad632b --- /dev/null +++ b/docs/0.18.0/components/AppBarsTop_docs.md @@ -0,0 +1,4 @@ +--- +layout: main +content_page: AppBarsTop.md +--- \ No newline at end of file diff --git a/docs/0.18.0/components/Banners.md b/docs/0.18.0/components/Banners.md new file mode 100644 index 000000000..b8b1d9527 --- /dev/null +++ b/docs/0.18.0/components/Banners.md @@ -0,0 +1,62 @@ +--- +layout: detail +title: Banners +description: Banners displays an important message which requires an action to be dismissed. +--- + +A banner displays an important, succinct message, and provides actions for users to address (or dismiss the banner). +It requires a user action to be dismissed. + +Banners should be displayed at the top of the screen, below a top app bar. They’re persistent and nonmodal, allowing the user to either ignore them or interact with them at any time. +Only one banner should be shown at a time + +
**On this page** + +* [Specifications references](#specifications-references) +* [Accessibility](#accessibility) +* [Implementation](#implementation) + * [Jetpack Compose](#jetpack-compose) + * [OdsBanner API](#odsbanner-api) + +--- + +## Specifications references + +- [Design System Manager - Banners](https://system.design.orange.com/0c1af118d/p/19a040-banners/b/497b77) +- [Material Design - Banners](https://m2.material.io/components/banners) + +## Accessibility + +Please follow [accessibility criteria for development](https://a11y-guidelines.orange.com/en/mobile/android/development/). + +`OdsBanner` is built to support accessibility criteria and is readable by most screen readers, such as TalkBack. The use of an `OdsBanner.Image` force the developer to associate a content description to the banner image. + +## Implementation + +![Banner light](images/banner_light.png) + +![Banner dark](images/banner_dark.png) + +### Jetpack Compose + +You can use the `OdsBanner` composable like this: + +```kotlin +OdsBanner( + message = "Message displayed into the banner.", + firstButton = OdsBanner.Button("Dismiss") { doSomething() }, + secondButton = OdsBanner.Button("Detail") { doSomething() }, + image = OdsBanner.Image(painterResource(id = R.drawable.placeholder), "") +) +``` + +#### OdsBanner API + +Parameter | Default value | Description +-- | -- | -- +`message: String` | | Text displayed into the banner +`modifier: Modifier` | `Modifier` | `Modifier` applied to the banner +`image: OdsBanner.Image?` | `null` | Image displayed in the banner in a circle shape +`firstButton: OdsBanner.Button?` | `null` | Primary button displayed in the banner +`secondButton: OdsBanner.Button?` | `null` | Secondary button displayed into the banner next to the primary one +{:.table} diff --git a/docs/0.18.0/components/Banners_docs.md b/docs/0.18.0/components/Banners_docs.md new file mode 100644 index 000000000..78ed1c027 --- /dev/null +++ b/docs/0.18.0/components/Banners_docs.md @@ -0,0 +1,4 @@ +--- +layout: main +content_page: Banners.md +--- \ No newline at end of file diff --git a/docs/0.18.0/components/Buttons.md b/docs/0.18.0/components/Buttons.md new file mode 100644 index 000000000..1e5b08283 --- /dev/null +++ b/docs/0.18.0/components/Buttons.md @@ -0,0 +1,319 @@ +--- +layout: detail +title: Buttons +description: Buttons allow users to take actions, and make choices, with a single tap. +--- + +
**On this page** + +* [Specifications references](#specifications-references) +* [Accessibility](#accessibility) +* [Variants](#variants) + * [Contained button](#contained-button) + * [Jetpack Compose](#jetpack-compose) + * [OdsButton API](#odsbutton-api) + * [Text button](#text-button) + * [Jetpack Compose](#jetpack-compose-1) + * [OdsTextButton API](#odstextbutton-api) + * [Outlined button](#outlined-button) + * [Jetpack Compose](#jetpack-compose-2) + * [OdsOutlinedButton API](#odsoutlinedbutton-api) + * [Text toggle buttons group](#text-toggle-buttons-group) + * [Jetpack Compose](#jetpack-compose-3) + * [OdsTextToggleButtonsRow API](#odstexttogglebuttonsrow-api) + * [Icon button](#icon-button) + * [Jetpack Compose](#jetpack-compose-4) + * [OdsIconButton API](#odsiconbutton-api) + * [Icon toggle button](#icon-toggle-button) + * [Jetpack Compose](#jetpack-compose-5) + * [OdsIconToggleButton API](#odsicontogglebutton-api) + * [Icon toggle buttons group](#icon-toggle-buttons-group) + * [Jetpack Compose](#jetpack-compose-6) + * [OdsIconToggleButtonsRow API](#odsicontogglebuttonsrow-api) + +--- + +## Specifications references + +- [Design System Manager - Buttons](https://system.design.orange.com/0c1af118d/p/06a393-buttons/b/530521) +- [Material Design - Buttons](https://material.io/components/buttons/) + +## Accessibility + +Please follow [accessibility criteria for development](https://a11y-guidelines.orange.com/en/mobile/android/development/). + +ODS buttons support accessibility criteria and are readable by most screen readers, such as TalkBack. + +Content descriptions for icons are unnecessary in the case of buttons containing text. For other buttons types, such as `OdsIconButton`, icons content descriptions are mandatory in the APIs. + +## Variants + +### Contained button + +Contained buttons are high-emphasis, distinguished by their use of elevation and fill. They contain +actions that are primary to your app. + +![ContainedButton](images/button_contained_light.png) ![ContainedButton dark](images/button_contained_dark.png) + +Functional positive: + +![ContainedButton positive light](images/button_contained_positive_light.png) ![ContainedButton positive dark](images/button_contained_positive_dark.png) + +Functional negative: + +![ContainedButton negative light](images/button_contained_negative_light.png) ![ContainedButton negative dark](images/button_contained_negative_dark.png) + +#### Jetpack Compose + +Use the `OdsButton` composable: + +```kotlin +OdsButton( + text = "Contained button", + onClick = { doSomething() }, + enabled = true, + icon = OdsButton.Icon(painterResource(R.drawable.ic_coffee)) // Line can be removed if you don't need any icon +) +``` + +To display a primary button or a functional green/red button, you need to pass an `OdsButton.Style` +through the `style` parameter: + +```kotlin +OdsButton( + text = "Positive button", + onClick = { doSomething() }, + enabled = true, + icon = OdsButton.Icon(painterResource(R.drawable.ic_coffee)), // Line can be removed if you don't need any icon + style = OdsButton.Style.FunctionalPositive +) +``` + +##### OdsButton API + +Parameter | Default value | Description +-- | -- | -- +`text: String` | | Text displayed into the button +`onClick: () -> Unit` | | Callback invoked when the button is clicked +`modifier: Modifier` | `Modifier` | `Modifier` applied to the button +`icon: OdsButton.Icon?` | `null` | Icon displayed in the button before the text +`enabled: Boolean` | `true` | Controls the enabled state of the button. When `false`, this button will not be clickable. +`style: OdsButton.Style` | `OdsButton.Style.Default` | Style applied to the button. Set it to `OdsButton.Style.Primary` for an highlighted button style or use `OdsButton.Style.FunctionalPositive`/ `OdsButton.Style.FunctionalNegative` for a functional green/red button style. +`displaySurface: OdsDisplaySurface` | `OdsDisplaySurface.Default` | `OdsDisplaySurface` applied to the button. It allows to force the button display on light or dark surface. By default, the appearance applied is based on the system night mode value. +{:.table} + +### Text button + +Text buttons are typically used for less-pronounced actions, including those located in dialogs and +cards. In cards, text buttons help maintain an emphasis on card content. + +![TextButton](images/button_text_light.png) ![TextButton dark](images/button_text_dark.png) + +#### Jetpack Compose + +Use the `OdsTextButton` composable: + +```kotlin +OdsTextButton( + text = "Text button", + onClick = { doSomething() }, + enabled = true, + icon = OdsButton.Icon(painterResource(R.drawable.ic_coffee)), // Line can be removed if you don't need any icon + style = OdsTextButton.Style.Primary +) +``` + +##### OdsTextButton API + +Parameter | Default value | Description +-- | -- | -- +`text: String` | | Text displayed into the button +`onClick: () -> Unit` | | Callback invoked on button click +`modifier: Modifier` | `Modifier` | `Modifier` applied to the button +`icon: OdsButton.Icon?` | `null` | Icon displayed in the button before the text +`enabled: Boolean` | `true` | Controls the enabled state of the button. When `false`, this button will not be clickable. +`style: OdsTextButton.Style` | `OdsTextButton.Style.Default` | Style applied to the button. By default `onSurface` color is used for text color. Use `OdsTextButton.Style.Primary` for an highlighted text color. +`displaySurface: OdsDisplaySurface` | `OdsDisplaySurface.Default` | `OdsDisplaySurface` applied to the button. It allows to force the button display on light or dark surface. By default, the appearance applied is based on the system night mode value. +{:.table} + +### Outlined button + +Outlined buttons are medium-emphasis buttons. They contain actions that are important, but aren’t +the primary action in an app. + +![ButtonOutlined](images/button_outlined_light.png) ![ButtonOutlined dark](images/button_outlined_dark.png) + +#### Jetpack Compose + +Use the `OdsOutlinedButton` composable: + +```kotlin +OdsOutlinedButton( + text = "Outlined button", + onClick = {}, + enabled = true, + icon = OdsButton.Icon(painterResource(R.drawable.ic_coffee)) // Line can be removed if you don't need any icon +) +``` + +##### OdsOutlinedButton API + +Parameter | Default value | Description +-- | -- | -- +`text: String` | | Text displayed into the button +`onClick: () -> Unit` | | Callback invoked on button click +`modifier: Modifier` | `Modifier` | `Modifier` applied to the button +`icon: OdsButton.Icon?` | `null` | Icon displayed in the button before the text +`enabled: Boolean` | `true` | Controls the enabled state of the button. When `false`, the button is not clickable. +`displaySurface: OdsDisplaySurface` | `OdsDisplaySurface.Default` | `OdsDisplaySurface` applied to the button. It allows to force the button display on light or dark surface. By default, the appearance applied is based on the system night mode value. +{:.table} + +### Text toggle buttons group + +A group of text toggle buttons. Only one option in a group of toggle buttons can be selected and active at a time. +Selecting one option deselects any other. + +![Button text toggle group light](images/button_text_toggle_group_light.png) ![Button text toggle group dark](images/button_text_toggle_group_dark.png) + +#### Jetpack Compose + +Use the `OdsTextToggleButtonsRow` composable: + +```kotlin +OdsTextToggleButtonsRow( + textToggleButtons = listOf( + OdsTextToggleButtonsRowItem("XML", true), + OdsTextToggleButtonsRowItem("COMPOSE", true), + ), + selectedIndex = 0, + onSelectedIndexChange = { + doSomething() // Do something like changing selectedIndex to refresh composable with new selection + }, + sameItemsWeight = false +) +``` + +##### OdsTextToggleButtonsRow API + +Parameter | Default value | Description +-- | -- | -- +`textToggleButtons: List` | | Items displayed into the toggle group +`selectedIndex: Int` | | `textToggleButtons` list index of the selected button +`onSelectedIndexChange: (Int) -> Unit` | | Callback invoked on selection change +`modifier: Modifier` | `Modifier` | `Modifier` applied to the toggle buttons row +`sameItemsWeight: Boolean` | `false` | Controls the place occupied by each item. When `true`, same weight of importance will be applied to each item, they will occupy the same width. +`displaySurface: OdsDisplaySurface` | `OdsDisplaySurface.Default` | `OdsDisplaySurface` applied to the button. It allows to force the button display on light or dark surface. By default, the appearance applied is based on the system night mode value. +{:.table} + +### Icon button + +An icon button is a clickable icon, used to represent actions. This component is typically used +inside an App Bar for the navigation icon / actions. + +![OdsIconButton](images/button_icon_light.png) ![OdsIconButton dark](images/button_icon_dark.png) + +#### Jetpack Compose + +Use the `OdsIconButton` composable: + +```kotlin +OdsIconButton( + icon = OdsIconButton.Icon( + painterResource(id = R.drawable.ic_ui_light_mode), + stringResource(id = R.string.theme_changer_icon_content_description_light) + ), + onClick = { doSomething() }, +) +``` + +##### OdsIconButton API + +Parameter | Default value | Description +-- | -- | -- +`icon: OdsIconButton.Icon` | | Icon to be drawn into the button +`onClick: () -> Unit` | | Callback to be invoked when the button is clicked +`modifier: Modifier` | `Modifier` | `Modifier` to be applied to the button +`enabled: Boolean` | `true` | Controls the enabled state of the button. When `false`, this button will not be clickable. +`displaySurface: OdsDisplaySurface` | `OdsDisplaySurface.Default` | `OdsDisplaySurface` to be applied to the button. It allows to force the button display on light or dark surface. By default, the appearance applied is based on the system night mode value. +{:.table} + +### Icon toggle button + +An icon button with two states, for icons that can be toggled 'on' and 'off', such as a bookmark +icon, or a navigation icon that opens a drawer. + +![Button icon toggle light](images/button_icon_toggle_light.png) ![Button icon toggle dark](images/button_icon_toggle_dark.png) + +#### Jetpack Compose + +Use the `OdsIconToggleButton` composable: + +```kotlin +OdsIconToggleButton( + checked = false, + onCheckedChange = { doSomething() }, + uncheckedIcon = OdsIconButton.Icon( + painterResource(R.drawable.ic_heart_outlined), + "Add to favorites" + ), + checkedIcon = OdsIconButton.Icon(painterResource(R.drawable.ic_heart), "Remove from favorites") +) +``` + +##### OdsIconToggleButton API + +Parameter | Default value | Description +-- | -- | -- +`checked: Boolean` | | Controls the checked state of the button +`onCheckedChange: (Boolean) -> Unit` | | Callback invoked when the button is checked +`uncheckedIcon: OdsIconButton.Icon` | | Icon displayed when the button is unchecked +`checkedIcon: OdsIconButton.Icon` | | Icon displayed when the button is checked +`modifier: Modifier` | `Modifier` | `Modifier` applied to the button +`enabled: Boolean` | `true` | Controls the enabled state of the button. When `false`, this button will not be clickable. +`displaySurface: OdsDisplaySurface` | `OdsDisplaySurface.Default` | `OdsDisplaySurface` applied to the button. It allows to force the button display on light or dark surface. By default, the appearance applied is based on the system night mode value. +{:.table} + +### Icon toggle buttons group + +A group of toggle buttons. Only one option in a group of toggle buttons can be selected and active +at a time. +Selecting one option deselects any other. + +![Button icon toggle group light](images/button_icon_toggle_group_light.png) ![Button icon toggle group dark](images/button_icon_toggle_group_dark.png) + +#### Jetpack Compose + +Use the `OdsIconToggleButtonsRow` composable: + +```kotlin +OdsIconToggleButtonsRow( + icons = listOf( + OdsIconToggleButtonsRow.Icon(painterResource(id = R.drawable.ic_restaurant), "Restaurant"), + OdsIconToggleButtonsRow.Icon( + painterResource(id = R.drawable.ic_cooking_pot), + "Cooking pot" + ), + OdsIconToggleButtonsRow.Icon( + painterResource(id = R.drawable.ic_coffee), + "Coffee", + enabled = false + ) + ), + selectedIndex = 0, + onSelectedIndexChange = { + doSomething() // Do something like changing selectedIndex to refresh composable with new selection + }, + displaySurface = displaySurface +) +``` + +##### OdsIconToggleButtonsRow API + +Parameter | Default value | Description +-- | -- | -- +`icons: List` | | Icons to be displayed into the toggle group +`selectedIndex: Int` | | `icons` list index of the selected button +`onSelectedIndexChange: (Int) -> Unit` | | Callback invoked on selection change +`modifier: Modifier` | `Modifier` | `Modifier` applied to the toggle buttons group +`displaySurface: OdsDisplaySurface` | `OdsDisplaySurface.Default` | `OdsDisplaySurface` applied to the button. It allows to force the button display on light or dark surface. By default, the appearance applied is based on the system night mode value. +{:.table} diff --git a/docs/0.18.0/components/Buttons_docs.md b/docs/0.18.0/components/Buttons_docs.md new file mode 100644 index 000000000..2617cf23f --- /dev/null +++ b/docs/0.18.0/components/Buttons_docs.md @@ -0,0 +1,4 @@ +--- +layout: main +content_page: Buttons.md +--- \ No newline at end of file diff --git a/docs/0.18.0/components/Cards.md b/docs/0.18.0/components/Cards.md new file mode 100644 index 000000000..e45e3e248 --- /dev/null +++ b/docs/0.18.0/components/Cards.md @@ -0,0 +1,222 @@ +--- +layout: detail +title: Cards +description: Cards contain content and actions about a single subject. +--- + +
**On this page** + +* [Specifications references](#specifications-references) +* [Accessibility](#accessibility) +* [Variants](#variants) + * [Vertical image first card](#vertical-image-first-card) + * [Jetpack Compose](#jetpack-compose) + * [OdsVerticalImageFirstCard API](#odsverticalimagefirstcard-api) + * [Vertical header first card](#vertical-header-first-card) + * [Jetpack Compose](#jetpack-compose-1) + * [OdsVerticalHeaderFirstCard API](#odsverticalheaderfirstcard-api) + * [Small card](#small-card) + * [Jetpack Compose](#jetpack-compose-2) + * [OdsSmallCard API](#odssmallcard-api) + * [Horizontal card](#horizontal-card) + * [Jetpack Compose](#jetpack-compose-3) + * [OdsHorizontalCard API](#odshorizontalcard-api) + +--- + +## Specifications references + +- [Design System Manager - Cards](https://system.design.orange.com/0c1af118d/p/272739-cards/b/991690) +- [Material Design - Cards](https://material.io/components/cards/) + +## Accessibility + +Please follow [accessibility criteria for development](https://a11y-guidelines.orange.com/en/mobile/android/development/). + +The contents within a card should follow their own accessibility guidelines, such as images having content descriptions set on them. +The ODS library cards APIs forces the developers to add content descriptions on card images. + +## Variants + +The library offers several Composables for Jetpack Compose implementation. + +### Vertical image first card + +This is a full width card containing elements arranged vertically with an image as first element. + +![Vertical image first card light](images/card_vertical_image_first_light.png) ![Vertical image first card dark](images/card_vertical_image_first_dark.png) + +#### Jetpack Compose + +In your composable screen you can use `OdsVerticalImageFirstCard` composable: + +```kotlin +OdsVerticalImageFirstCard( + title = "Title", + image = OdsCard.Image( + painterResource(R.drawable.picture), + "Picture content description", + Alignment.Center, + ContentScale.Crop, + Color(0xff1b1b1b) + ), + subtitle = "Subtitle", + text = "Text", + firstButton = OdsCard.Button("First button") { doSomething() }, + secondButton = OdsCard.Button("Second button") { doSomething() }, + onClick = { doSomething() } +) +``` + +##### OdsVerticalImageFirstCard API + +Parameter | Default value | Description +-- | -- | -- +`title: String` | | Title displayed into the card +`image: OdsCard.Image` | | Image displayed into the card +`modifier: Modifier` | `Modifier` | `Modifier` applied to the layout of the card +`subtitle: String?` | `null` | Subtitle displayed into the card +`text: String?` | `null` | Text displayed into the card +`firstButton: OdsCard.Button?` | `null` | First button displayed into the card +`secondButton: OdsCard.Button?` | `null` | Second button displayed into the card +`onClick: (() -> Unit)?` | `null` | Callback invoked on card click +{:.table} + +### Vertical header first card + +This is a full width card containing elements arranged vertically with a header (thumbnail, title & subtitle) as first element. + +![Vertical header first card light](images/card_vertical_header_first_light.png) ![Vertical header first card dark](images/card_vertical_header_first_dark.png) + +#### Jetpack Compose + +In your composable screen you can use `OdsVerticalHeaderFirstCard` composable: + +```kotlin +OdsVerticalHeaderFirstCard( + title = "Title", + image = OdsCard.Image( + painterResource(R.drawable.picture), + "Picture content description", + Alignment.Center, + ContentScale.Crop, + Color(0xff1b1b1b) + ), + thumbnail = OdsCard.Thumbnail( + painterResource(R.drawable.thumbnail), + "Thumbnail content description" + ), + subtitle = "Subtitle", + text = "Text", + firstButton = OdsCard.Button("First button") { doSomething() }, + secondButton = OdsCard.Button("Second button") { doSomething() }, + onClick = { doSomething() } +) +``` + +##### OdsVerticalHeaderFirstCard API + +Parameter | Default value | Description +-- | -- | -- +`title: String` | | Title displayed into the card +`image: OdsCard.Image` | | Image displayed into the card +`modifier: Modifier` | `Modifier` | `Modifier` applied to the layout of the card +`thumbnail: OdsCard.Thumbnail?` | `null` | Thumbnail displayed into the card next to the title: avatar, logo or icon. +`subtitle: String?` | `null` | Subtitle displayed into the card +`text: String?` | `null` | Text displayed into the card +`firstButton: OdsCard.Button?` | `null` | First button displayed into the card +`secondButton: OdsCard.Button?` | `null` | Second button displayed into the card +`onClick: (() -> Unit)?` | `null` | Callback called on card click +{:.table} + +### Small card + +This is a small card which takes the half screen width. + +![CardSmall](images/card_small_light.png) ![CardSmall dark](images/card_small_dark.png) + +#### Jetpack Compose + +You can add an `OdsSmallCard` composable in your screen to add a small card: + +```kotlin +Row( + horizontalArrangement = Arrangement.spacedBy(16.dp), +) { + OdsSmallCard( + title = "Title", + image = OdsCard.Image( + painterResource(R.drawable.picture), + "Picture content description" + ), + modifier = Modifier.weight(0.5f), + onClick = { doSomething() } + ) + OdsSmallCard( + title = "Title", + image = OdsCard.Image( + painterResource(R.drawable.picture), + "Picture content description" + ), + modifier = Modifier.weight(0.5f), + onClick = { doSomething() } + ) +} +``` + +##### OdsSmallCard API + +Parameter | Default value | Description +-- | -- | -- +`title: String` | | Title displayed into the card. If the card is clickable, it will be truncated to fit on one line otherwise it will be displayed entirely for accessibility reasons. +`image: OdsCard.Image` | | Image displayed into the card +`modifier: Modifier` | `Modifier` | `Modifier` applied to the layout of the card +`subtitle: String?` | `null` | Subtitle displayed into the card. If the card is clickable, it will be truncated to fit on one line otherwise it will be displayed entirely for accessibility reasons. +`onClick: (() -> Unit)?` | `null` | Callback invoked on card click +{:.table} + +### Horizontal card + +This is a full screen width card with an image on the side. The image can be displayed on the left or on the right. + +![Horizontal card light](images/card_horizontal_light.png) ![Horizontal card dark](images/card_horizontal_dark.png) + +#### Jetpack Compose + +In your screen you can use `OdsHorizontalCard` composable: + +```kotlin +OdsHorizontalCard( + title = "Title", + image = OdsCard.Image( + painterResource(R.drawable.picture), + "Picture content description", + Alignment.Center, + ContentScale.Crop, + Color(0xff1b1b1b) + ), + subtitle = "Subtitle", + text = "Text", + firstButton = OdsCard.Button("First button") { doSomething() }, + secondButton = OdsCard.Button("Second button") { doSomething() }, + imagePosition = OdsCard.Image.Position.Start, + divider = false, + onClick = { doSomething() } +) +``` + +##### OdsHorizontalCard API + +Parameter | Default value | Description +-- | -- | -- +`title: String` | | Title displayed into the card +`image: OdsCard.Image` | | Image displayed into the card +`modifier: Modifier` | `Modifier` | `Modifier` applied to the layout of the card +`subtitle: String?` | `null` | Subtitle displayed into the card +`text: String?` | `null` | Text displayed into the card +`firstButton: OdsCard.Button?` | `null` | First button displayed into the card +`secondButton: OdsCard.Button?` | `null` | Second button displayed into the card +`imagePosition: OdsCard.Image.Position` | `OdsCard.Image.Position.Start` | Position of the image within the card, it can be set to `OdsCard.Image.Position.Start` or `OdsCard.Image.Position.End` +`divider: Boolean` | `true` | Controls the divider display. If `true`, it will be displayed between the card content and the action buttons. +`onClick: (() -> Unit)?` | `null` | Callback invoked on card click +{:.table} diff --git a/docs/0.18.0/components/Cards_docs.md b/docs/0.18.0/components/Cards_docs.md new file mode 100644 index 000000000..ac6a9375c --- /dev/null +++ b/docs/0.18.0/components/Cards_docs.md @@ -0,0 +1,4 @@ +--- +layout: main +content_page: Cards.md +--- \ No newline at end of file diff --git a/docs/0.18.0/components/Checkboxes.md b/docs/0.18.0/components/Checkboxes.md new file mode 100644 index 000000000..505d1a8e5 --- /dev/null +++ b/docs/0.18.0/components/Checkboxes.md @@ -0,0 +1,62 @@ +--- +layout: detail +title: Checkboxes +description: Checkbox selection control allows the user to select options. +--- + +Use checkboxes to: + +* Select one or more options from a list +* Present a list containing sub-selections +* Turn an item on or off in a desktop environment + +
**On this page** + +* [Specifications references](#specifications-references) +* [Accessibility](#accessibility) +* [Implementation](#implementation) + * [Jetpack Compose](#jetpack-compose) + * [OdsCheckbox API](#odscheckbox-api) + +--- + +## Specifications references + +- [Design System Manager - Selection controls](https://system.design.orange.com/0c1af118d/p/14638a-selection-controls/b/352c00) +- [Material Design - Checkboxes](https://material.io/components/checkboxes/) + +## Accessibility + +Please follow [accessibility criteria for development](https://a11y-guidelines.orange.com/en/mobile/android/development/). + +Checkboxes support content labeling for accessibility and are readable by most screen readers, such +as TalkBack. Text rendered in check boxes is automatically provided to accessibility services. +Additional content labels are usually unnecessary. + +## Implementation + +![Checkbox](images/checkbox_light.png) ![Checkbox dark](images/checkbox_dark.png) + +### Jetpack Compose + +In your composable screen you can use: + +```kotlin +var checked by remember { mutableStateOf(false) } +OdsCheckbox( + checked = checked, + onCheckedChange = { checked = it }, + enabled = true +) +``` + +#### OdsCheckbox API + +Parameter | Default value | Description +-- | -- | -- +`checked: Boolean` | | Controls checked state of the checkbox +`onCheckedChange: ((Boolean) -> Unit)?` | | Callback invoked on checkbox click. If `null`, then this is passive and relies entirely on a higher-level component to control the checked state. +`modifier: Modifier` | `Modifier` | `Modifier` applied to the checkbox +`enabled: Boolean` | `true` | Controls enabled state of the checkbox. When `false`, this checkbox will not be clickable. +{:.table} + diff --git a/docs/0.18.0/components/Checkboxes_docs.md b/docs/0.18.0/components/Checkboxes_docs.md new file mode 100644 index 000000000..6e2b8096e --- /dev/null +++ b/docs/0.18.0/components/Checkboxes_docs.md @@ -0,0 +1,4 @@ +--- +layout: main +content_page: Checkboxes.md +--- \ No newline at end of file diff --git a/docs/0.18.0/components/Chips.md b/docs/0.18.0/components/Chips.md new file mode 100644 index 000000000..240025142 --- /dev/null +++ b/docs/0.18.0/components/Chips.md @@ -0,0 +1,234 @@ +--- +layout: detail +title: Chips +description: Chips are compact elements that represent an input, attribute, or action. +--- + +
**On this page** + +* [Specifications references](#specifications-references) +* [Accessibility](#accessibility) +* [Variants](#variants) + * [Input chip](#input-chip) + * [Jetpack Compose](#jetpack-compose) + * [OdsChip API](#odschip-api) + * [Choice chip](#choice-chip) + * [Jetpack Compose](#jetpack-compose-1) + * [Filter chip](#filter-chip) + * [Jetpack Compose](#jetpack-compose-2) + * [OdsFilterChip API](#odsfilterchip-api) + * [Action chip](#action-chip) + * [Jetpack Compose](#jetpack-compose-3) +* [Extras](#extras) + * [Choice chips flow row](#choice-chips-flow-row) + * [OdsChoiceChipsFlowRow API](#odschoicechipsflowrow-api) + +--- + +## Specifications references + +- [Design System Manager](https://system.design.orange.com/0c1af118d/p/81aa91-chips/b/13c40e) +- [Material Design](https://material.io/components/chips) + +## Accessibility + +Please follow [accessibility criteria for development](https://a11y-guidelines.orange.com/en/mobile/android/development/). + +Chips support content labeling for accessibility and are readable by most screen readers, such as +TalkBack. Text rendered in chips is automatically provided to accessibility services. Additional +content labels are usually unnecessary. + +## Variants + +### Input chip + +Input chips (referred to as **entry** chips in Android) represent a complex piece of information in +compact form, such as an entity (person, place, or thing) or text. They enable user input and verify +that input by converting text into chips. + +![Light input chip](images/chips_input_light.png) ![Dark input chip](images/chips_input_dark.png) + +![Light outlined input chip](images/chips_input_outlined_light.png) ![Dark outlined input chip](images/chips_input_outlined_dark.png) + +#### Jetpack Compose + +Use the `OdsChip` composable. +Note that the chip style is outlined or filled according to your OdsTheme component configuration, +outlined by default. + +```kotlin +OdsChip( + text = "chip text", + onClick = { + doSomething() + }, + leading = OdsChip.LeadingAvatar( + painterResource(id = R.drawable.avatar), + "Avatar" + ), + enabled = true, + onCancel = { + doSomething() + } +) +``` + +##### OdsChip API + +Parameter | Default value | Description +-- | -- | -- +`text: String` | | Text to be displayed into the chip +`onClick: () -> Unit` | | Callback called on chip click +`modifier: Modifier` | `Modifier` | `Modifier` to be applied to the chip +`enabled: Boolean` | `true` | Controls the enabled state of the chip. When `false`, this chip will not respond to user input. +`selected: Boolean` | `false` | Controls the selected state of the chip. When `true`, the chip is highlighted (useful for choice chips). +`leading: OdsChip.Leading?` | `null` | The leading content to be displayed at the start of the chip, preceding the text +`onCancel: (() -> Unit)?` | `null` | Callback called on chip cancel cross click. Pass `null` for no cancel cross. +{:.table} + +### Choice chip + +Choice chips allow selection of a single chip from a set of options. + +Choice chips clearly delineate and display options in a compact area. They are a good alternative to +toggle buttons, radio buttons, and single select menus. + +**Note: To display a set of choice chips please see [Choice chips flow row](#choice-chips-flow-row) +** + +![Light choice chips](images/chips_choice_light.png) ![Dark choice chips](images/chips_choice_dark.png) + +![Light outlined choice chips](images/chips_choice_outlined_light.png) ![Dark outlined choice chips](images/chips_choice_outlined_dark.png) + +#### Jetpack Compose + +Use the `OdsChip` composable. +Note that the chip style is outlined or filled according to your OdsTheme component configuration, +outlined by default. + +```kotlin +OdsChip( + text = "chip text", + onClick = { + doSomething() + }, + enabled = true, +) +``` + +Use the [OdsChip API](#odschip-api). + +### Filter chip + +Filter chips use tags or descriptive words to filter content. + +Filter chips clearly delineate and display options in a compact area. They are a good alternative to +toggle buttons or checkboxes. + +![Light filter chips](images/chips_filter_light.png) ![Dark filter chips](images/chips_filter_dark.png) + +![Light filter chips with avatar](images/chips_filter_avatar_light.png) ![Dark filter chips with avatar](images/chips_filter_avatar_dark.png) + +#### Jetpack Compose + +Use the `OdsFilterChip` composable. +Note that the chip style is outlined or filled according to your OdsTheme component configuration, +outlined by default. + +```kotlin +OdsFilterChip( + text = "chip text", + onClick = { + doSomething() + }, + leadingAvatar = OdsChip.LeadingAvatar( + painterResource(id = R.drawable.avatar), + "" + ), // Set it to `null` for no avatar + selected = false, + enabled = true, +) +``` + +##### OdsFilterChip API + +Parameter | Default value | Description +-- | -- | -- +`text: String` | | Text to be displayed into the chip +`onClick: () -> Unit` | | Callback called on chip click +`modifier: Modifier` | `Modifier` | `Modifier` to be applied to the chip +`enabled: Boolean` | `true` | Controls the enabled state of the chip. When `false`, this chip will not respond to user input. It also appears visually disabled and is disabled to accessibility services. +`selected: Boolean` | `false` | Controls the selected state of the chip. When `true`, the chip is highlighted. +`leadingAvatar: OdsChip.LeadingAvatar?` | `null` | Avatar to be displayed in a circle shape at the start of the chip, preceding the content text +{:.table} + +### Action chip + +Action chips offer actions related to primary content. They should appear dynamically and +contextually in a UI. + +An alternative to action chips are buttons, which should appear persistently and consistently. + +![Light action chip](images/chips_action_light.png) ![Dark action chip](images/chips_action_dark.png) + +![Light outlined action chip](images/chips_action_outlined_light.png) ![Dark outlined action chip](images/chips_action_outlined_dark.png) + +#### Jetpack Compose + +Use the `OdsChip` composable. +Note that the chip style is outlined or filled according to your OdsTheme component configuration, +outlined by default. + +```kotlin +OdsChip( + text = "chip text", + onClick = { + doSomething() + }, + leading = OdsChip.LeadingIcon( + painterResource(id = R.drawable.ic_heart), + "Heart" + ), // set it to `null` for no icon + enabled = true, +) +``` + +Use the [OdsChip API](#odschip-api). + +## Extras + +The ODS library provides some chips related components to facilitate the implementation of chips groups. + +### Choice chips flow row + +This is a full width `FlowRow` containing selectable chips. It works like radio buttons, only one chip of the set can be selected. + +![Light choice chips flow row](images/chips_choice_flow_row_light.png) + +![Dark choice chips flow row](images/chips_choice_flow_row_dark.png) + +Use `OdsChoiceChipsFlowRow` composable. +Note that the chips style is outlined or filled according to your OdsTheme component configuration, +outlined by default. + +```kotlin +OdsChoiceChipsFlowRow( + chips = listOf( + OdsChoiceChip(text = "Choice chip 1", value = 1), + OdsChoiceChip(text = "Choice chip 2", value = 2) + ), + value = chipValue, + onValueChange = { value -> chipValue = value }, + modifier = Modifier.padding(horizontal = dimensionResource(id = com.orange.ods.R.dimen.spacing_m)) +) +``` + +#### OdsChoiceChipsFlowRow API + +Parameter | Default value | Description +-- | -- | -- +`chips: List>` | | Chips displayed into the flow row +`value: String` | | Initial value of the choice chips flow row +`onValueChange: (value: T) -> Unit` | | Callback invoked when the value changes. The new value is provided as parameter. +`modifier: Modifier` | `Modifier` | `Modifier` applied to the chips flow row +{:.table} diff --git a/docs/0.18.0/components/Chips_docs.md b/docs/0.18.0/components/Chips_docs.md new file mode 100644 index 000000000..c69ad1fd9 --- /dev/null +++ b/docs/0.18.0/components/Chips_docs.md @@ -0,0 +1,4 @@ +--- +layout: main +content_page: Chips.md +--- \ No newline at end of file diff --git a/docs/0.18.0/components/Dialogs.md b/docs/0.18.0/components/Dialogs.md new file mode 100644 index 000000000..b4dbca0f7 --- /dev/null +++ b/docs/0.18.0/components/Dialogs.md @@ -0,0 +1,68 @@ +--- +layout: detail +title: Dialogs +description: Dialogs inform users about a task and can contain critical information, require decisions, or involve multiple tasks. +--- + +A dialog is a type of modal window that appears in front of app content to +provide critical information or ask for a decision. Dialogs disable all app +functionality when they appear, and remain on screen until confirmed, dismissed, +or a required action has been taken. + +Dialogs are purposefully interruptive, so they should be used sparingly. + +
**On this page** + +* [Specifications references](#specifications-references) +* [Accessibility](#accessibility) +* [Variants](#variants) + * [Alert dialog](#alert-dialog) + * [Jetpack Compose](#jetpack-compose) + * [OdsAlertDialog API](#odsalertdialog-api) + +--- + +## Specifications references + +- [Design System Manager - Dialogs](https://system.design.orange.com/0c1af118d/p/02ae02-dialogs/b/81772e) +- [Material Design - Dialogs](https://material.io/components/dialogs) + +## Accessibility + +Please follow [accessibility criteria for development](https://a11y-guidelines.orange.com/en/mobile/android/development/). + +## Variants + +### Alert dialog + +Alert dialogs interrupt users with urgent information, details, or actions. + +![Alert dialog light](images/dialog_alert_light.png) ![Alert dialog dark](images/dialog_alert_dark.png) + +#### Jetpack Compose + +To display an alert dialog in your composable screen, you can use: + +```kotlin +OdsAlertDialog( + modifier = Modifier, + title = "title", + text = "content text of the dialog", + confirmButton = OdsAlertDialog.Button("confirm") { doSomething() }, + dismissButton = OdsAlertDialog.Button("dismiss") { doSomething() }, + properties = DialogProperties() +) +``` + +##### OdsAlertDialog API + +Parameter | Default value | Description +-- | -- | -- +`text: String` | | Text displayed into the dialog which presents the details regarding the Dialog's purpose +`confirmButton: OdsAlertDialog.Button` | | Button displayed into the dialog which is meant to confirm a proposed action, thus resolving what triggered the dialog +`modifier: Modifier` | `Modifier` | `Modifier` applied to the layout of the dialog +`onDismissRequest: () -> Unit` | `{}` | Callback invoked when the user tries to dismiss the dialog by clicking outside or pressing the back button. This is not called when the dismiss button is clicked. +`dismissButton: OdsAlertDialog.Button?` | `null` | Button displayed into the dialog which is meant to dismiss the dialog +`title: String?` | `null` | Title displayed into the dialog which should specify the purpose of the dialog. The title is not mandatory, because there may be sufficient information inside the `text`. +`properties: DialogProperties` | `DialogProperties()` | Typically platform specific properties to further configure the dialog +{:.table} diff --git a/docs/0.18.0/components/Dialogs_docs.md b/docs/0.18.0/components/Dialogs_docs.md new file mode 100644 index 000000000..30e1a52ad --- /dev/null +++ b/docs/0.18.0/components/Dialogs_docs.md @@ -0,0 +1,4 @@ +--- +layout: main +content_page: Dialogs.md +--- \ No newline at end of file diff --git a/docs/0.18.0/components/FloatingActionButtons.md b/docs/0.18.0/components/FloatingActionButtons.md new file mode 100644 index 000000000..02426d603 --- /dev/null +++ b/docs/0.18.0/components/FloatingActionButtons.md @@ -0,0 +1,127 @@ +--- +layout: detail +title: Floating action buttons +description: A floating action button (FAB) represents the primary action of a screen. +--- + +
**On this page** + +* [Specifications references](#specifications-references) +* [Accessibility](#accessibility) +* [Variants](#variants) + * [Regular FAB](#regular-fab) + * [Jetpack Compose](#jetpack-compose) + * [OdsFloatingActionButton API](#odsfloatingactionbutton-api) + * [Mini FAB](#mini-fab) + * [Jetpack Compose](#jetpack-compose-1) + * [Extended FAB](#extended-fab) + * [Jetpack Compose](#jetpack-compose-2) + * [OdsExtendedFloatingActionButton API](#odsextendedfloatingactionbutton-api) + +--- + +## Specifications references + +- [Design System Manager - Floating Action Button](https://system.design.orange.com/0c1af118d/p/577022-buttons-fab/b/101b2a) +- [Material Design - Buttons: floating action button](https://material.io/components/buttons-floating-action-button/) + +## Accessibility + +Please follow [accessibility criteria for development](https://a11y-guidelines.orange.com/en/mobile/android/development/). + +The `OdsFloatingActionButton.Icon` used in Floating Action Buttons APIs force the developers to set a content description to the FABs so that +screen readers like TalkBack are able to announce their purpose or action. + +Text rendered in an extended FAB is automatically provided to accessibility services, so additional content labels are usually unnecessary. +In this context you can set an empty `contentDescription`. + +## Variants + +### Regular FAB + +Regular FABs are FABs that are not expanded and are a regular size. + +![FAB light](images/fab_light.png) ![FAB dark](images/fab_dark.png) + +#### Jetpack Compose + +To display a regular Floating Action Button in your composable screen, use `OdsFloatingActionButton`: + +```kotlin +OdsFloatingActionButton( + onClick = { doSomething() }, + mini = false, + icon = OdsFloatingActionButton.Icon( + painterResource(id = R.drawable.ic_plus), + stringResource(id = R.string.add) + ), + modifier = modifier +) +``` + +##### OdsFloatingActionButton API + +Parameter | Default value | Description +-- | -- | -- +`icon: OdsFloatingActionButton.Icon` | | Icon used into the FAB +`onClick: () -> Unit` | | Callback invoked on FAB click +`modifier: Modifier` | `Modifier` | `Modifier` applied to the FAB +`mini: Boolean` | `false` | Controls the size of the FAB. If `true`, the size of the FAB will be 40dp, otherwise the default size will be used. +{:.table} + +### Mini FAB + +A mini FAB should be used on smaller screens. + +Mini FABs can also be used to create visual continuity with other screen elements. + +![FAB mini light](images/fab_mini_light.png) ![FAB mini dark](images/fab_mini_dark.png) + +#### Jetpack Compose + +To display a mini FAB in your composable screen use `OdsFloatingActionButton` + +```kotlin +OdsFloatingActionButton( + onClick = { doSomething() }, + mini = true, + icon = OdsFloatingActionButton.Icon( + painterResource(id = R.drawable.ic_plus), + stringResource(id = R.string.add) + ), + modifier = modifier +) +``` + +Use [OdsFloatingActionButton API](#odsfloatingactionbutton-api). + +### Extended FAB + +The extended FAB is wider, and it includes a text label. + +![FAB extended light](images/fab_extended_light.png) ![FAB extended dark](images/fab_extended_dark.png) + +![FAB extended full width light](images/fab_extended_full_width_light.png) ![FAB extended full width dark](images/fab_extended_full_width_dark.png) + +#### Jetpack Compose + +To display an extended FAB, use `OdsExtendedFloatingActionButton`: + +```kotlin +OdsExtendedFloatingActionButton( + onClick = { doSomething() }, + text = stringResource(id = R.string.add), + icon = OdsFloatingActionButton.Icon(painterResource(id = R.drawable.ic_plus), ""), + modifier = modifier +) +``` + +##### OdsExtendedFloatingActionButton API + +Parameter | Default value | Description +-- | -- | -- +`icon: OdsFloatingActionButton.Icon` | | Icon used into the FAB +`onClick: () -> Unit` | | Callback invoked on FAB click +`text: String` | | Text displayed into the FAB +`modifier: Modifier` | `Modifier` | `Modifier` applied to the FAB +{:.table} diff --git a/docs/0.18.0/components/FloatingActionButtons_docs.md b/docs/0.18.0/components/FloatingActionButtons_docs.md new file mode 100644 index 000000000..c1bcf38ba --- /dev/null +++ b/docs/0.18.0/components/FloatingActionButtons_docs.md @@ -0,0 +1,4 @@ +--- +layout: main +content_page: FloatingActionButtons.md +--- \ No newline at end of file diff --git a/docs/0.18.0/components/ImageItem.md b/docs/0.18.0/components/ImageItem.md new file mode 100644 index 000000000..2ba153c83 --- /dev/null +++ b/docs/0.18.0/components/ImageItem.md @@ -0,0 +1,69 @@ +--- +layout: detail +title: Image item +description: +--- + +
**On this page** + +* [Specifications references](#specifications-references) +* [Accessibility](#accessibility) +* [Implementation](#implementation) + * [Jetpack Compose](#jetpack-compose) + * [OdsImageItem API](#odsimageitem-api) + +--- + +## Specifications references + +- [Design System Manager - Image item](https://system.design.orange.com/0c1af118d/p/49434d-image-item) +- [Material Design - Image lists](https://m2.material.io/components/image-lists) + +## Accessibility + +Please follow [accessibility criteria for development](https://a11y-guidelines.orange.com/en/mobile/android/development/). + +An image in an `OdsImageItem` should always be associated to a content description. This is the reason why the `OdsImageItem.Image` forces the developer to fill a content description parameter. + +## Implementation + +#### Jetpack Compose + +You can use the `OdsImageItem` composable like this: + +```kotlin +OdsImageItem( + image = OdsImageItem.Image( + painterResource(id = R.drawable.placeholder), + "Picture content description" + ), + modifier = modifier, + legendAreaDisplayType = OdsImageItem.LegendAreaDisplayType.Below, + title = "Component Image item", + icon = OdsImageItem.IconToggleButton( + uncheckedIcon = OdsIconButton.Icon( + painterResource(id = R.drawable.ic_heart_outlined), + "Add to favourites" + ), + checkedIcon = OdsIconButton.Icon( + painterResource(id = R.drawable.ic_heart), + "Remove from favourites" + ), + checked = false, + onCheckedChange = { doSomething() }, + ), + onClick = { doSomething() } +) +``` + +##### OdsImageItem API + +Parameter | Default value | Description +-- | -- | -- +`image: OdsImageItem.Image` | | Image displayed into the item +`legendAreaDisplayType: OdsImageItem.LegendAreaDisplayType` | | Controls how the title and the icon are displayed relatively to the image. If set to `OdsImageItem.LegendAreaDisplayType.None`, no legend area will be displayed. +`modifier: Modifier` | `Modifier` | `Modifier` applied to the image item +`title: String?` | `null` | Title displayed into the image item. It is linked to the image and displayed according to the `legendAreaDisplayType` value. +`icon: OdsImageItem.IconToggleButton` | `null` | Clickable icon displayed next to the `title` +`onClick: (() -> Unit)?` | `null` | Callback invoked on image item click +{:.table} diff --git a/docs/0.18.0/components/ImageItem_docs.md b/docs/0.18.0/components/ImageItem_docs.md new file mode 100644 index 000000000..9ded86b13 --- /dev/null +++ b/docs/0.18.0/components/ImageItem_docs.md @@ -0,0 +1,4 @@ +--- +layout: main +content_page: ImageItem.md +--- \ No newline at end of file diff --git a/docs/0.18.0/components/ListItems.md b/docs/0.18.0/components/ListItems.md new file mode 100644 index 000000000..f2413f18d --- /dev/null +++ b/docs/0.18.0/components/ListItems.md @@ -0,0 +1,155 @@ +--- +layout: detail +title: List items +description: Lists are continuous, vertical indexes of text or images. +--- + +
**On this page** + +* [Specifications references](#specifications-references) +* [Accessibility](#accessibility) +* [Variants](#variants) + * [Single-line list](#single-line-list) + * [Jetpack Compose](#jetpack-compose) + * [OdsListItem API](#odslistitem-api) + * [Two-line list](#two-line-list) + * [Jetpack Compose](#jetpack-compose-1) + * [Three-line list](#three-line-list) + * [Jetpack Compose](#jetpack-compose-2) + +--- + +## Specifications references + +- [Design System Manager - Lists](https://system.design.orange.com/0c1af118d/p/09a804-lists/b/669743) +- [Material Design - Lists](https://material.io/components/lists/) + +## Accessibility + +Please follow [accessibility criteria for development](https://a11y-guidelines.orange.com/en/mobile/android/development/). + +## Variants + +### Single-line list + +There are multiple display possibilities for a single-line list, where leading can optionally be an icon, a circular, a square or a wide image. + +Here are two examples: + +- with a wide image and a checkbox + + ![Lists single-line wide image](images/lists_single_line_wide_image_light.png) ![Lists single-line wide image dark](images/lists_single_line_wide_image_dark.png) + +- with a standard icon and a checkbox + + ![Lists single-line](images/lists_single_line_light.png) ![Lists single-line dark](images/lists_single_line_dark.png) + +Please note that there is no start padding with wide images. + +#### Jetpack Compose + +The library offers the `OdsListItem` composable to display lists items. + +The `OdsListItem` composable allows you to display a leading icon using the `leadingIcon` parameter of the `OdsListItem` method, as well as a trailing element (either a checkbox, a switch, a radio button, an icon or a caption text) using the `trailing` parameter. + +```kotlin +OdsListItem( + modifier = Modifier.clickable { doSomething() }, + text = "Primary text", + leadingIcon = OdsListItem.LeadingIcon( + OdsListItem.leadingIcon.Type.Icon, + painterResource(id = R.drawable.ic_heart), + "Heart" + ), + trailing = OdsListItem.TrailingCheckbox(checked) { checked != checked }, + divider = true +) +``` + +##### OdsListItem API + +Parameter | Default value | Description +-- | -- | -- +`text: String` | | The primary text of the list item +`modifier: Modifier` | `Modifier` | Modifier to be applied to the list item +`leadingIcon: OdsListItem.LeadingIcon?` | `null` | The leading supporting visual of the list item +`secondaryText: String?` | `null` | The secondary text of the list item +`singleLineSecondaryText: Boolean` | `true` | Whether the secondary text is single line +`overlineText: String?` | `null` | The text displayed above the primary text +`trailing: OdsListItem.Trailing?` | `null` | The trailing content to display at the end of the list item +`divider: Boolean` | `false` | Whether or not a divider is displayed at the bottom of the list item +`onClick: (() -> Unit)?` | `null` | Will be called when the user clicks the list item. This parameter only has an effect if trailing is `OdsListItem.TrailingIcon` or `null`. +{:.table} + +### Two-line list + +Like single-line list, two-line list leading can optionally be an icon, a circular, a square or a wide image. + +Here are two examples: + +- with a wide image and a checkbox + + ![Lists two-line wide image](images/lists_two_line_wide_image_light.png) ![Lists two-line wide image dark](images/lists_two_line_wide_image_dark.png) + +- with a standard icon and a checkbox + + ![Lists two-line](images/lists_two_line_light.png) ![Lists two-line dark](images/lists_two_line_dark.png) + +#### Jetpack Compose + +The only difference with the single-line implementation is that the `secondaryText` property of `OdsListItem` is not null. + +```kotlin +OdsListItem( + modifier = Modifier.clickable { doSomething() }, + text = "Primary text", + secondaryText = "Secondary text", + leadingIcon = OdsListItem.LeadingIcon( + OdsListItem.LeadingIcon.Type.CircularImage, + painterResource(id = R.drawable.placeholder, "") + ), + trailing = OdsListItem.TrailingIcon( + painterResource(id = R.drawable.ic_drag_handle), + "Drag item" + ), + divider = true +) +``` + +Use [OdsListItem API](#odslistitem-api). + +### Three-line list + +Like single-line list, three-line list leading can optionally be an icon, a circular, a square or a wide image. + +Here are two examples: + +- with a wide image and a checkbox + + ![Lists three-line wide image](images/lists_three_line_wide_image_light.png) ![Lists three-line wide image dark](images/lists_three_line_wide_image_dark.png) + +- with a standard icon and a checkbox + + ![Lists three-line](images/lists_three_line_light.png) ![Lists three-line dark](images/lists_three_line_dark.png) + +#### Jetpack Compose + +The only difference with the two-line implementation is that the `singleLineSecondaryText` property of `OdsListItem` is `false`. + +```kotlin +OdsListItem( + modifier = Modifier.clickable { doSomething() }, + text = "Primary text", + secondaryText = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor.", + singleLineSecondaryText = false, + leadingIcon = OdsListItem.LeadingIcon( + OdsListItem.LeadingIcon.Type.SquareImage, + painter = painterResource(id = R.drawable.placeholder), + "" + ), + trailing = OdsListItem.TrailingCaption("Caption"), + divider = true +) +``` + +Use [OdsListItem API](#odslistitem-api). diff --git a/docs/0.18.0/components/ListItems_docs.md b/docs/0.18.0/components/ListItems_docs.md new file mode 100644 index 000000000..44e4d0a23 --- /dev/null +++ b/docs/0.18.0/components/ListItems_docs.md @@ -0,0 +1,4 @@ +--- +layout: main +content_page: ListItems.md +--- \ No newline at end of file diff --git a/docs/0.18.0/components/Menus.md b/docs/0.18.0/components/Menus.md new file mode 100644 index 000000000..2c70a242b --- /dev/null +++ b/docs/0.18.0/components/Menus.md @@ -0,0 +1,118 @@ +--- +layout: detail +title: Menus +description: Menus appear from a button, action, or other control. It contains at least 2 items that can affect the app, the view or elements within the view. +--- + +
**On this page** + +* [Specifications references](#specifications-references) +* [Accessibility](#accessibility) +* [Variants](#variants) + * [Dropdown menu](#dropdown-menu) + * [Jetpack Compose](#jetpack-compose) + * [OdsDropdownMenu API](#odsdropdownmenu-api) + * [Exposed dropdown menu](#exposed-dropdown-menu) + * [Jetpack Compose](#jetpack-compose-1) + * [OdsExposedDropdownMenu API](#odsexposeddropdownmenu-api) + +--- + +## Specifications references + +- [Design System Manager - Menus](https://system.design.orange.com/0c1af118d/p/07a69b-menus/b/862cbb) +- [Material Design - Menus](https://m2.material.io/components/menus) + +## Accessibility + +Please follow [accessibility criteria for development](https://a11y-guidelines.orange.com/en/mobile/android/development/). + +The icons which can be displayed in a dropdown menu are always associated to a text so they don't need a content description. + +## Variants + +### Dropdown menu + +A dropdown menu is a compact way of displaying multiple choices. It appears upon interaction with an element (such as an icon or button) or when users perform a specific action. + +![Dropdown menu light](images/menu_dropdown_light.png) ![Dropdown menu dark](images/menu_dropdown_dark.png) + +#### Jetpack Compose + +The library offers an `OdsDropdownMenu` container composable in which you can add `OdsDropdownMenu.Item` or `OdsDivider` as shown in the following example: + +```kotlin +var menuExpanded by remember { mutableStateOf(false) } + +OdsDropdownMenu( + expanded = menuExpanded, + onDismissRequest = { menuExpanded = false }, + offset = DpOffset(x = (-100).dp, y = (-10).dp), + items = listOf( + OdsDropdownMenu.Item( + text = "Summer salad", + icon = painterResource(id = R.drawable.ic_salad), + divider = true, // Allow to add a divider between the 2 items + onClick = { doSomething() } + ), + OdsDropdownMenu.Item( + text = "Brocoli soup", + icon = painterResource(id = R.drawable.ic_soup), + onClick = { doSomething() } + ) + ) +) +``` + +##### OdsDropdownMenu API + +Parameter | Default value | Description +-- | -- | -- +`items: List` | | Items displayed into the dropdown menu +`expanded: Boolean` | | Controls whether the menu is currently open and visible to the user +`onDismissRequest: () -> Unit` | | Callback invoked when the user requests to dismiss the menu, such as by tapping outside the menu's bounds +`modifier: Modifier` | `Modifier` | `Modifier` applied to the dropdown menu +`offset: DpOffset` | `DpOffset(0.dp, 0.dp)` | Offset added to the menu position +`properties: PopupProperties` | `PopupProperties(focusable = true)` | Properties for further customization of the popup's behavior +{:.table} + +### Exposed dropdown menu + +Exposed dropdown menus display the currently selected menu item above the menu. This is a combination of a text field and a menu. + +![Exposed dropdown menu light](images/menu_exposed_dropdown_light.png) ![Exposed dropdown menu dark](images/menu_exposed_dropdown_dark.png) + +#### Jetpack Compose + +To display an exposed dropdown menu, you can use the `OdsExposedDropdownMenu` composable. As shown below, you should provide a list of `OdsExposedDropdownMenu.Item` corresponding to the items displayed in the menu (with or without icons). + +```kotlin +val items = listOf( + OdsExposedDropdownMenu.Item("Email", android.R.drawable.ic_dialog_email), + OdsExposedDropdownMenu.Item("Map", android.R.drawable.ic_dialog_map), + OdsExposedDropdownMenu.Item("Dialer", android.R.drawable.ic_dialog_dialer), +) +val selectedItem = rememberSaveable() { mutableStateOf(items.first()) } + +OdsExposedDropdownMenu( + label = "Dropdown menu label", + items = items, + selectedItem = selectedItem, + onItemSelectionChange = { item -> + doSomething() // Do something like retrieving the selected item + }, + enabled = true +) +``` + +##### OdsExposedDropdownMenu API + +Parameter | Default value | Description +-- | -- | -- +`label: String` | | Label of the exposed menu text field +`items: List` | | Items displayed into the dropdown menu +`selectedItem: MutableState` | | Selected item displayed into the text field +`onItemSelectionChange: (OdsExposedDropdownMenu.Item) -> Unit` | | Callback invoked when a dropdown menu item is selected. It can be used to get the menu value. +`modifier: Modifier` | `Modifier` | `Modifier` applied to the dropdown menu +`enabled: Boolean` | `true` | Controls the enabled state of the dropdown menu. When `false`, the dropdown menu text field will be neither clickable nor focusable, visually it will appear in the disabled state. +{:.table} diff --git a/docs/0.18.0/components/Menus_docs.md b/docs/0.18.0/components/Menus_docs.md new file mode 100644 index 000000000..2bf37b337 --- /dev/null +++ b/docs/0.18.0/components/Menus_docs.md @@ -0,0 +1,4 @@ +--- +layout: main +content_page: Menus.md +--- \ No newline at end of file diff --git a/docs/0.18.0/components/NavigationBottom.md b/docs/0.18.0/components/NavigationBottom.md new file mode 100644 index 000000000..f5a47f86b --- /dev/null +++ b/docs/0.18.0/components/NavigationBottom.md @@ -0,0 +1,117 @@ +--- +layout: detail +title: "Navigation: bottom" +description: Bottom navigation bars allow movement between primary destinations in an app. +--- + +
**On this page** + +* [Specifications references](#specifications-references) +* [Accessibility](#accessibility) +* [Implementation](#implementation) + * [Jetpack Compose](#jetpack-compose) + * [OdsBottomNavigation API](#odsbottomnavigation-api) + * [XML](#xml) + +--- + +## Specifications references + +- [Design System Manager - Navigation: bottom](https://system.design.orange.com/0c1af118d/p/042eb8-navigation-bottom/b/30078d) +- [Material Design - Bottom navigation](https://material.io/components/bottom-navigation) + +## Accessibility + +Please follow [accessibility criteria for development](https://a11y-guidelines.orange.com/en/mobile/android/development/). + +Note that TalkBack already reads the bottom navigation items labels so the content descriptions of the `OdsBottomNavigation.Item.Icon`s can be empty. + +## Implementation + +![BottomNavigation light](images/bottom_navigation_light.png) + +![BottomNavigation dark](images/bottom_navigation_dark.png) + +### Jetpack Compose + +In your composable screen, use the `OdsBottomNavigation` composable. It should contain multiple `OdsBottomNavigation.Item`s. + +Here is an example of use: + +```kotlin + private data class NavigationItem( + @StringRes val titleResId: Int, + @DrawableRes val iconResId: Int +) + +val items = listOf( + R.string.component_bottom_navigation_coffee to R.drawable.ic_coffee, + R.string.component_bottom_navigation_cooking_pot to R.drawable.ic_cooking_pot, + R.string.component_bottom_navigation_ice_cream to R.drawable.ic_ice_cream, + R.string.component_bottom_navigation_restaurant to R.drawable.ic_restaurant, + R.string.component_bottom_navigation_favorites to R.drawable.ic_heart +) + +var selectedItemIndex by remember { mutableStateOf(0) } + +OdsBottomNavigation( + items = items.mapIndexed { index, item -> + OdsBottomNavigation.Item( + icon = OdsBottomNavigation.Item.Icon( + painter = painterResource(id = item.first), + contentDescription = "" + ), // contentDescription is empty cause TalkBack already read the item's label + label = stringResource(id = item.second), + selected = selectedItemIndex == index, + onClick = { + selectedItemIndex = index + doSomething() + } + ) + } +) +``` + +#### OdsBottomNavigation API + +Parameter | Default value | Description +-- | -- | -- +`items: List` | | Items displayed into the bottom navigation +`modifier: Modifier` | `Modifier` | `Modifier` applied to the bottom navigation +{:.table} + +### XML + +In your layout, use the `OdsBottomNavigation` view. + +```xml + + +``` + +Then using view binding, add the bottom navigation items by code: + +```kotlin +binding.odsBottomNavigation.items = listOf( + OdsBottomNavigation.Item( + icon = OdsBottomNavigation.Item.Icon( + painter = painterResource(id = R.drawable.ic_dna), + contentDescription = "" + ), + label = "Guidelines", + selected = true, + onClick = { doSomething() } + ), + OdsBottomNavigation.Item( + icon = OdsBottomNavigation.Item.Icon( + painter = painterResource(id = R.drawable.ic_atom), + contentDescription = "" + ), + label = "Components", + selected = false, + onClick = { doSomething() } + ) +) +``` \ No newline at end of file diff --git a/docs/0.18.0/components/NavigationBottom_docs.md b/docs/0.18.0/components/NavigationBottom_docs.md new file mode 100644 index 000000000..8cc980a8e --- /dev/null +++ b/docs/0.18.0/components/NavigationBottom_docs.md @@ -0,0 +1,4 @@ +--- +layout: main +content_page: NavigationBottom.md +--- \ No newline at end of file diff --git a/docs/0.18.0/components/NavigationDrawers.md b/docs/0.18.0/components/NavigationDrawers.md new file mode 100644 index 000000000..108705345 --- /dev/null +++ b/docs/0.18.0/components/NavigationDrawers.md @@ -0,0 +1,114 @@ +--- +layout: detail +title: Navigation drawers +description: The navigation drawer slides in from the left when the nav icon is tapped. The content should be concerned with identity and/or navigation.. +--- + +
**On this page** + +* [Specifications references](#specifications-references) +* [Accessibility](#accessibility) +* [Implementation](#implementation) + * [Jetpack Compose](#jetpack-compose) + * [OdsModalDrawer API](#odsmodaldrawer-api) + * [API parameter types](#api-parameter-types) + * [OdsModalDrawer.Header](#odsmodaldrawerheader) + * [OdsModalDrawer.Item](#odsmodaldraweritem) + +--- + +## Specifications references + +- [Design System Manager - Navigation drawers](https://system.design.orange.com/0c1af118d/p/92bc26-navigation-drawers/b/146f55) +- [Material Design - Navigation drawer](https://m2.material.io/components/navigation-drawer) + +## Accessibility + +Please follow [accessibility criteria for development](https://a11y-guidelines.orange.com/en/mobile/android/development/). + +## Implementation + +### Jetpack Compose + +The `OdsModalDrawer` is built using the following provided elements: + +- `header` which contains a title, an optional subtitle and an optional image displayed as header background or as an avatar (circular shaped image) above the title. +- `items` which constitute the list of elements displayed vertically below the header. This list can contain section headers, list items or simple dividers. + +You can use the `OdsModalDrawer` composable like this: + +```kotlin +OdsModalDrawer( + header = OdsModalDrawer.Header( + title = "Side navigation drawer", + image = OdsModalDrawer.Header.Avatar(painterResource(id = R.drawable.placeholder), ""), + subtitle = "Example", + ), + items = listOf( + OdsModalDrawer.ListItem( // `OdsModalDrawer.ListItem` is used to specified an item of the list + icon = R.drawable.ic_heart, + text = "label1" + ) { doSomething() }, + OdsModalDrawer.ListItem( + icon = R.drawable.ic_heart, + text = "label2" + ) { doSomething() }, + OdsModalDrawer.Divider, // `OdsModalDrawerDivider` is used to add a divider in a specific level of the list + OdsModalDrawer.SectionHeader( + label = "Label" + ), // `OdsModalDrawer.SectionHeader` is used to add a divider and the text above the divider + OdsModalDrawer.ListItem( + icon = R.drawable.ic_heart, + text = "label3" + ) { doSomething() } + ), + drawerState = rememberDrawerState(DrawerValue.Closed), // or rememberDrawerState(DrawerValue.Open) +) { + // Put here the rest of the UI content +} +``` + +#### OdsModalDrawer API + +Parameter | Default value | Description +-- | -- | -- +`header: `[OdsModalDrawer.Header](#odsmodaldrawerheader) | | Content descriptor of the drawer header +`items: List<`[OdsModalDrawer.Item](#odsmodaldraweritem)`>` | | List of `OdsModalDrawer.Item` displayed in a column inside the modal drawer +`modifier: Modifier` | `Modifier` | `Modifier` applied to the modal drawer +`state: DrawerState` | `rememberDrawerState(DrawerValue.Closed)` | State of the modal drawer +`selectedItem: OdsModalDrawer.ListItem?` | `null` | Selected `OdsModalDrawer.ListItem` that appears in selected state +`content: @Composable () -> Unit` | | Content of the rest of the UI +{:.table} + +#### API parameter types + +##### OdsModalDrawer.Header + +Parameter | Default value | Description +-- | -- | -- +`title: String` | | Title displayed in the header +`image: OdsModalDrawer.HeaderImage?` | `null` | Image displayed in the header. It should be an avatar image of `OdsModalDrawer.Header.Avatar` type or a background image of `OdsModalDrawer.Header.Background` type. +`subtitle: String?` | `null` | Subtitle displayed below the `title` in the header +{:.table} + +##### OdsModalDrawer.Item + +Here are the available types of `OdsModalDrawer.Item`: + +**OdsModalDrawer.SectionHeader** displays a divider and a section header label below + +Parameter | Default value | Description +-- | -- | -- +`label: String` | | Label of the section header +{:.table} + +**OdsModalDrawer.ListItem** displays a clickable item in the modal drawer + +Parameter | Default value | Description +-- | -- | -- +`text: String` | | Text displayed in the modal drawer list item +`leadingIcon: Painter?` | `null` | Leading icon displayed in the modal drawer list item +`onClick: (OdsModalDrawer.ListItem) -> Unit` | | Callback invoked on an `OdsModalDrawer.ListItem` click. Provides the clicked `OdsModalDrawer.ListItem`. +{:.table} + +**OdsModalDrawerDivider** displays a simple divider (no parameter needed) diff --git a/docs/0.18.0/components/NavigationDrawers_docs.md b/docs/0.18.0/components/NavigationDrawers_docs.md new file mode 100644 index 000000000..e1c08c075 --- /dev/null +++ b/docs/0.18.0/components/NavigationDrawers_docs.md @@ -0,0 +1,4 @@ +--- +layout: main +content_page: NavigationDrawers.md +--- \ No newline at end of file diff --git a/docs/0.18.0/components/ProgressIndicators.md b/docs/0.18.0/components/ProgressIndicators.md new file mode 100644 index 000000000..e90d9fc72 --- /dev/null +++ b/docs/0.18.0/components/ProgressIndicators.md @@ -0,0 +1,134 @@ +--- +layout: detail +title: Progress indicators +description: Progress indicators express an unspecified wait time or display the length of a process. +--- + +
**On this page** + +* [Specifications references](#specifications-references) +* [Accessibility](#accessibility) +* [Variants](#variants) + * [Progress bar](#progress-bar) + * [Jetpack Compose](#jetpack-compose) + * [OdsLinearProgressIndicator API](#odslinearprogressindicator-api) + * [Activity indicator](#activity-indicator) + * [Jetpack Compose](#jetpack-compose-1) + * [OdsCircularProgressIndicator API](#odscircularprogressindicator-api) + +--- + +## Specifications references + +- [Design System Manager - Progress indicators](https://system.design.orange.com/0c1af118d/p/92aec5-progress-indicators------/b/33faf7) +- [Material Design - Progress indicators](https://material.io/components/progress-indicators/) + +## Accessibility + +Please follow [accessibility criteria for development](https://a11y-guidelines.orange.com/en/mobile/android/development/). + +## Variants + +### Progress bar + +Progress bars, also called linear progress indicators, display progress by animating an indicator along the length of a fixed, +visible track. The behavior of the indicator is dependent on whether the progress of a process is +known. + +Linear progress indicators support both determinate and indeterminate operations. + +* Determinate operations display the indicator increasing in width + from 0 to 100% of the track, in sync with the process’s progress. +* Indeterminate operations display the indicator continually growing + and shrinking along the track until the process is complete. + + ![Progress bar light](images/progress_linear_light.png) + + ![Progress bar dark](images/progress_linear_dark.png) + +#### Jetpack Compose + +You can use the composable `OdsLinearProgressIndicator` like this: + +For a **determinate** linear progress indicator, provide the progress value: + +```kotlin +OdsLinearProgressIndicator( + progress = 0.9f, + label = "Downloading ...", + icon = OdsLinearProgressIndicator( + painterResource(id = R.drawable.ic_arrow_down), + "" + ), + showCurrentValue = true +) +``` + +For an **indeterminate** linear progress indicator, no need to provide a progress value: + +```kotlin +OdsLinearProgressIndicator( + label = "Downloading ...", + icon = OdsLinearProgressIndicator( + painterResource(id = R.drawable.ic_arrow_down), + "" + ) +) +``` + +##### OdsLinearProgressIndicator API + +Parameter | Default value | Description +-- | -- | -- +`modifier: Modifier` | `Modifier` | `Modifier` applied to the progress indicator +`progress: Float?` | `null` | Progress indicator value where 0.0 represents no progress and 1.0 represents full progress. Values outside of this range are coerced into the range. If set to `null`, the progress indicator is indeterminate. +`label: String?` | `null` | Label displayed above the linear progress +`icon: OdsLinearProgressIndicator.Icon?` | `null` | Icon displayed above the progress indicator +`showCurrentValue: Boolean` | `false` | Controls the progress indicator current value visibility which is displayed in percent below the progress bar +{:.table} + +### Activity indicator + +Activity indicators, also called circular progress indicators, display progress by animating an indicator along an +invisible circular track in a clockwise direction. They can be applied directly +to a surface, such as a button or card. + +Circular progress indicators support both determinate and indeterminate +processes. + +* Determinate circular indicators fill the invisible, circular track with + color, as the indicator moves from 0 to 360 degrees. +* Indeterminate circular indicators grow and shrink in size while moving along + the invisible track. + +![Activity indicator light](images/progress_circular_light.png) ![Activity indicator dark](images/progress_circular_dark.png) + +#### Jetpack Compose + +You can use the `OdsCircularProgressIndicator` composable like this: + +- For a **determinate** circular progress indicator, provide the progress value: + +```kotlin +OdsCircularProgressIndicator( + progress = 0.9f, + label = "Downloading ..." +) +``` + +- For an **indeterminate** circular progress indicator, no need to provide a progress value: + +```kotlin +OdsCircularProgressIndicator( + label = "Downloading ..." +) +``` + +##### OdsCircularProgressIndicator API + +Parameter | Default value | Description +-- | -- | -- +`modifier: Modifier` | `Modifier` | `Modifier` applied to the progress indicator +`progress: Float?` | `null` | Progress indicator value where 0.0 represents no progress and 1.0 represents full progress. Values outside of this range are coerced into the range. If set to `null`, the progress indicator is indeterminate. +`label: String?` | `null` | Label displayed below the circular progress +{:.table} diff --git a/docs/0.18.0/components/ProgressIndicators_docs.md b/docs/0.18.0/components/ProgressIndicators_docs.md new file mode 100644 index 000000000..77ee6e5b9 --- /dev/null +++ b/docs/0.18.0/components/ProgressIndicators_docs.md @@ -0,0 +1,4 @@ +--- +layout: main +content_page: ProgressIndicators.md +--- \ No newline at end of file diff --git a/docs/0.18.0/components/RadioButtons.md b/docs/0.18.0/components/RadioButtons.md new file mode 100644 index 000000000..24aac4962 --- /dev/null +++ b/docs/0.18.0/components/RadioButtons.md @@ -0,0 +1,62 @@ +--- +layout: detail +title: Radio buttons +description: Radio button selection control allows the user to select options. +--- + +Use radio buttons to: + +* Select a single option from a list +* Expose all available options +* If available options can be collapsed, consider using a dropdown menu + instead, as it uses less space. + +
**On this page** + +* [Specifications references](#specifications-references) +* [Accessibility](#accessibility) +* [Implementation](#implementation) + * [Jetpack Compose](#jetpack-compose) + * [OdsRadioButton API](#odsradiobutton-api) + +--- + +## Specifications references + +- [Design System Manager - Selection controls](https://system.design.orange.com/0c1af118d/p/14638a-selection-controls/b/352c00) +- [Material Design - Radio buttons](https://material.io/components/radio-buttons/) + +## Accessibility + +Please follow [accessibility criteria for development](https://a11y-guidelines.orange.com/en/mobile/android/development/). + +Radio buttons support content labeling for accessibility and are readable by +most screen readers, such as TalkBack. Text rendered in radio buttons is +automatically provided to accessibility services. Additional content labels are +usually unnecessary. + +## Implementation + +![RadioButton](images/radio_button_light.png) ![RadioButton dark](images/radio_button_dark.png) + +### Jetpack Compose + +In your composable screen you can use: + +```kotlin +OdsRadioButton( + selected = true, + onClick = { doSomething() }, + enabled = true +) +``` + +#### OdsRadioButton API + +Parameter | Default value | Description +-- | -- | -- +`selected: Boolean` | | Controls the selected state of the radio button +`onClick: (() -> Unit)?` | | Callback invoked on radio button click. If `null`, then the radio button will not handle input events, and only act as a visual indicator of `selected` state. +`modifier: Modifier` | `Modifier` | `Modifier` applied to the radio button +`enabled: Boolean` | `true` | Controls the enabled state of the radio button. When `false`, the button will not be selectable and appears disabled. +{:.table} diff --git a/docs/0.18.0/components/RadioButtons_docs.md b/docs/0.18.0/components/RadioButtons_docs.md new file mode 100644 index 000000000..95e949338 --- /dev/null +++ b/docs/0.18.0/components/RadioButtons_docs.md @@ -0,0 +1,4 @@ +--- +layout: main +content_page: RadioButtons.md +--- \ No newline at end of file diff --git a/docs/0.18.0/components/SheetsBottom.md b/docs/0.18.0/components/SheetsBottom.md new file mode 100644 index 000000000..bccdb8982 --- /dev/null +++ b/docs/0.18.0/components/SheetsBottom.md @@ -0,0 +1,72 @@ +--- +layout: detail +title: "Sheets: bottom" +description: Bottom Sheets are surfaces anchored to the bottom of the screen that present users supplement content. +--- + +Use Sheets bottom to: + +* Display content that complements the screen’s primary content +* Expose all complements options + +
**On this page** + +* [Specifications references](#specifications-references) +* [Accessibility](#accessibility) +* [Implementation](#implementation) + * [Jetpack Compose](#jetpack-compose) + * [OdsBottomSheetScaffold API](#odsbottomsheetscaffold-api-) + +--- + +## Specifications references + +- [Design System Manager - Sheets](https://system.design.orange.com/0c1af118d/p/81f927-sheets-bottom/b/47b99b) +- [Material Design - Sheets: bottom](https://material.io/components/sheets-bottom) + +## Accessibility + +Please follow [accessibility criteria for development](https://a11y-guidelines.orange.com/en/mobile/android/development/). + +## Implementation + +![BottomSheet light](images/sheetbottom_light.png) ![BottomSheet dark](images/sheetbottom_dark.png) + +The contents within a bottom sheet should follow their own accessibility guidelines, such as images having content descriptions set on them. + +### Jetpack Compose + +```kotlin +OdsBottomSheetScaffold( + sheetContent = { + // Put here the content of the sheet + }, + modifier = Modifier, + scaffoldState = rememberBottomSheetScaffoldState(), + topBar = null, + snackbarHost = {}, + floatingActionButton = {}, + floatingActionButtonPosition = FabPosition.End, + sheetGesturesEnabled = true, + sheetPeekHeight = 56.dp, + content = { + // Put here the screen content + } +) +``` + +#### OdsBottomSheetScaffold API [#](#odsbottomsheetscaffold-api-) + +Parameter | Default value | Description +-- | -- | -- +`sheetContent: @Composable ColumnScope.() -> Unit` | | Content of the bottom sheet +`modifier: Modifier` | `Modifier` | `Modifier` applied to the bottom sheet scaffold +`scaffoldState: BottomSheetScaffoldState` | `rememberBottomSheetScaffoldState()` | State of the scaffold +`topBar: (@Composable () -> Unit)?` | `null` | Top app bar displayed in the scaffold +`snackbarHost: @Composable (SnackbarHostState) -> Unit` | `{ SnackbarHost(it) }` | Composable hosting the snackbars shown inside the scaffold +`floatingActionButton: (@Composable () -> Unit)?` | `null` | Floating action button displayed in the scaffold +`floatingActionButtonPosition: FabPosition` | `FabPosition.End`| Position of the floating action button +`sheetGesturesEnabled: Boolean` | `true` | Whether the bottom sheet can be interacted with by gestures +`sheetPeekHeight: Dp` | `BottomSheetScaffoldDefaults.SheetPeekHeight` | Height of the bottom sheet when it is collapsed +`content: @Composable (PaddingValues) -> Unit` | | Content of the screen +{:.table} diff --git a/docs/0.18.0/components/SheetsBottom_docs.md b/docs/0.18.0/components/SheetsBottom_docs.md new file mode 100644 index 000000000..6602fd47a --- /dev/null +++ b/docs/0.18.0/components/SheetsBottom_docs.md @@ -0,0 +1,4 @@ +--- +layout: main +content_page: SheetsBottom.md +--- \ No newline at end of file diff --git a/docs/0.18.0/components/Sliders.md b/docs/0.18.0/components/Sliders.md new file mode 100644 index 000000000..95349f2ec --- /dev/null +++ b/docs/0.18.0/components/Sliders.md @@ -0,0 +1,230 @@ +--- +layout: detail +title: Sliders +description: Sliders allow users to make selections from a range of values. +--- + +
**On this page** + +* [Specifications references](#specifications-references) +* [Accessibility](#accessibility) +* [Variants](#variants) + * [Continuous slider](#continuous-slider) + * [Jetpack Compose](#jetpack-compose) + * [OdsSlider API](#odsslider-api) + * [Continuous lockups slider](#continuous-lockups-slider) + * [Jetpack Compose](#jetpack-compose-1) + * [OdsSliderLockups API](#odssliderlockups-api) + * [Discrete slider](#discrete-slider) + * [Jetpack Compose](#jetpack-compose-2) + * [Discrete lockups slider](#discrete-lockups-slider) + * [Jetpack Compose](#jetpack-compose-3) + +--- + +## Specifications references + +- [Design System Manager - Sliders](https://system.design.orange.com/0c1af118d/p/8077fc-sliders/b/673558) +- [Material Design - Sliders](https://material.io/components/sliders/) + +## Accessibility + +Please follow [accessibility criteria for development](https://a11y-guidelines.orange.com/en/mobile/android/development/). + +## Variants + +### Continuous slider + +Continuous sliders allow users to make meaningful selections that don’t require +a specific value. + +![Continuous slider](images/slider_continuous_light.png) ![Continuous slider dark](images/slider_continuous_dark.png) + +With icons: + +![Continuous slider with icons](images/slider_continuous_with_icon_light.png) ![Continuous slider with icons dark](images/slider_continuous_with_icon_dark.png) + +#### Jetpack Compose + +In your composable screen you can use: + +```kotlin +OdsSlider( + value = 20f, + steps = 9, + onValueChange = { doSomething() } +) +``` + +You can add icons to the continuous slider like this: + +```kotlin +OdsSlider( + value = 20f, + steps = 9, + onValueChange = { doSomething() }, + startIcon = OdsSlider.Icon( + painterResource(id = R.drawable.ic_volume_status_1), + stringResource(id = R.string.component_slider_low_volume) + ), + endIcon = OdsSlider.Icon( + painterResource(id = R.drawable.ic_volume_status_4), + stringResource(id = R.string.component_slider_high_volume) + ) +) +``` + +##### OdsSlider API + +Parameter | Default value | Description +-- | -- | -- +`value: Float` | | Current value of the slider. If outside of `valueRange` provided, value will be coerced to this range. +`onValueChange: (Float) -> Unit` | | Callback invoked on slider value change. `value` should be updated here. +`modifier: Modifier` | `Modifier` | `Modifier` applied to the slider +`enabled: Boolean` | `true` | Controls the enabled state of the slider. If `false`, the user cannot interact with it. +`valueRange: ClosedFloatingPointRange` | `0f..1f` | Range of values that the slider can take. Given `value` will be coerced to this range. +`steps: Int` | `0` | If greater than `0`, specifies the amounts of discrete values, evenly distributed between across the whole value range. If `0`, slider will behave as a continuous slider and allow to choose any value from the range specified. Must not be negative. +`onValueChangeFinished: (() -> Unit)?` | `null` | Callback invoked when value change has ended. This callback shouldn't be used to update the slider value (use `onValueChange` for that), but rather to know when the user has completed selecting a new value by ending a drag or a click. +`startIcon: OdsSlider.Icon?` | `null` | Icon displayed at the start of the slider +`endIcon: OdsSlider.Icon?` | `null` | Icon displayed at the end of the slider +{:.table} + +### Continuous lockups slider + +![Continuous lockups slider](images/slider_continuous_lockups_light.png) ![Continuous lockups slider dark](images/slider_continuous_lockups_light.png) + +With icons: + +![Continuous lockups slider with icons](images/slider_continuous_lockups_with_icon_light.png) ![Continuous lockups slider with icons dark](images/slider_continuous_lockups_with_icon_dark.png) + +#### Jetpack Compose + +In your composable screen you can use: + +```kotlin +OdsSliderLockups( + value = 20f, + valueRange = 0f..100f, + onValueChange = { doSomething() } +) +``` + +You can add icons to the continuous lockups slider like this: + +```kotlin +OdsSliderLockups( + value = 20f, + valueRange = 0f..100f, + onValueChange = { doSomething() }, + startIcon = OdsSlider.Icon( + painterResource(id = R.drawable.ic_volume_status_1), + stringResource(id = R.string.component_slider_low_volume) + ), + endIcon = OdsSlider.Icon( + painterResource(id = R.drawable.ic_volume_status_4), + stringResource(id = R.string.component_slider_high_volume) + ) +) +``` + +##### OdsSliderLockups API + +Parameter | Default value | Description +-- | -- | -- +`value: Float` | | Current value of the slider. If outside of `valueRange` provided, value will be coerced to this range. +`onValueChange: (Float) -> Unit` | | Callback invoked on slider value change. `value` should be updated here. +`modifier: Modifier` | `Modifier` | `Modifier` applied to the slider +`enabled: Boolean` | `true` | Controls the enabled state of the slider. If `false`, the user cannot interact with it. +`valueRange: ClosedFloatingPointRange` | `0f..1f` | Range of values that the slider can take. Given `value` will be coerced to this range. +`steps: Int` | `0` | If greater than `0`, specifies the amounts of discrete values, evenly distributed between across the whole value range. If `0`, slider will behave as a continuous slider and allow to choose any value from the range specified. Must not be negative. +`onValueChangeFinished: (() -> Unit)?` | `null` | Callback invoked when value change has ended. This callback shouldn't be used to update the slider value (use `onValueChange` for that), but rather to know when the user has completed selecting a new value by ending a drag or a click. +`startIcon: OdsSlider.Icon?` | `null` | Icon displayed at the start of the slider +`endIcon: OdsSlider.Icon?` | `null` | Icon displayed at the end of the slider +{:.table} + +### Discrete slider + +Discrete sliders display a numeric value label upon pressing the thumb, which +allows a user to input an exact value. + +![Discrete slider](images/slider_discrete_light.png) ![Discrete slider dark](images/slider_discrete_dark.png) + +With icons: + +![Discrete slider with icon](images/slider_discrete_with_icon_light.png) ![Discrete slider with icon dark](images/slider_discrete_with_icon_dark.png) + +#### Jetpack Compose + +In your composable screen you can use: + +```kotlin +OdsSlider( + value = 20f, + valueRange = 0f..100f, + steps = 10, + onValueChange = { doSomething() } +) +``` + +You can add icons to the discrete slider like this: + +```kotlin +OdsSlider( + value = 20f, + valueRange = 0f..100f, + steps = 10, + onValueChange = { doSomething() }, + startIcon = OdsSlider.Icon( + painterResource(id = R.drawable.ic_volume_status_1), + stringResource(id = R.string.component_slider_low_volume) + ), + endIcon = OdsSlider.Icon( + painterResource(id = R.drawable.ic_volume_status_4), + stringResource(id = R.string.component_slider_high_volume) + ) +) +``` + +Use [OdsSlider API](#odsslider-api). + +### Discrete lockups slider + +![Discrete lockups slider](images/slider_discrete_lockups_light.png) ![Discrete lockups slider dark](images/slider_discrete_lockups_dark.png) + +With icons: + +![Discrete lockups slider with icons](images/slider_discrete_lockups_with_icon_light.png) ![Discrete lockups slider with icons dark](images/slider_discrete_lockups_with_icon_dark.png) + +#### Jetpack Compose + +In your composable screen you can use: + +```kotlin +OdsSliderLockups( + value = 20f, + valueRange = 0f..100f, + steps = 10, + onValueChange = { doSomething() } +) +``` + +You can add icons to the continuous lockups slider like this: + +```kotlin +OdsSliderLockups( + value = 20f, + valueRange = 0f..100f, + steps = 10, + onValueChange = { doSomething() }, + startIcon = OdsSlider.Icon( + painterResource(id = R.drawable.ic_volume_status_1), + stringResource(id = R.string.component_slider_low_volume) + ), + endIcon = OdsSlider.Icon( + painterResource(id = R.drawable.ic_volume_status_4), + stringResource(id = R.string.component_slider_high_volume) + ) +) +``` + +Use [OdsSliderLockups API](#odssliderlockups-api). diff --git a/docs/0.18.0/components/Sliders_docs.md b/docs/0.18.0/components/Sliders_docs.md new file mode 100644 index 000000000..ab068de42 --- /dev/null +++ b/docs/0.18.0/components/Sliders_docs.md @@ -0,0 +1,4 @@ +--- +layout: main +content_page: Sliders.md +--- \ No newline at end of file diff --git a/docs/0.18.0/components/Snackbars.md b/docs/0.18.0/components/Snackbars.md new file mode 100644 index 000000000..3dc54a675 --- /dev/null +++ b/docs/0.18.0/components/Snackbars.md @@ -0,0 +1,94 @@ +--- +layout: detail +title: Snackbars +description: Snackbars provide brief messages about app processes at the bottom of the screen. +--- + +Snackbars inform users of a process that an app has performed or will perform. +They appear temporarily, towards the bottom of the screen. They shouldn’t +interrupt the user experience, and they don’t require user input to disappear. +They disappear either after a timeout or after a user interaction elsewhere on +the screen, but can also be swiped off the screen. + +Snackbars can also offer the ability to perform an action, such as undoing an +action that was just taken, or retrying an action that had failed. + +
**On this page** + +* [Specifications references](#specifications-references) +* [Accessibility](#accessibility) +* [Implementation](#implementation) + * [Jetpack Compose](#jetpack-compose) + * [OdsSnackbarHost API](#odssnackbarhost-api) + +--- + +## Specifications references + +- [Design System Manager - Toasts & Snackbars](https://system.design.orange.com/0c1af118d/p/887440-toast--snackbars/b/043ece) +- [Material Design - Snackbars](https://material.io/components/snackbars) + +## Accessibility + +Please follow [accessibility criteria for development](https://a11y-guidelines.orange.com/en/mobile/android/development/). + +Snackbars support content labeling for accessibility and are readable by most +screen readers, such as TalkBack. Text rendered in snackbars is automatically +provided to accessibility services. Additional content labels are usually +unnecessary. + +## Implementation + +![Snackbar light](images/snackbar_light.png) + +![Snackbar dark](images/snackbar_dark.png) + +With action button: + +![Snackbar with action light](images/snackbar_with_action_light.png) + +![Snackbar with action dark](images/snackbar_with_action_dark.png) + +### Jetpack Compose + +We advise you to use a `Scaffold` to add an `OdsSnackbarHost.Snackbar` in order to make sure everything is displayed together in the right place according to Material Design. +Then use `OdsSnackbarHost` which provides the good margins to display the snackbar and `OdsSnackbarHost.Snackbar` as follow: + +```kotlin +val scaffoldState = rememberScaffoldState() +val coroutineScope: CoroutineScope = rememberCoroutineScope() + +Scaffold( + scaffoldState = scaffoldState, + snackbarHost = { + OdsSnackbarHost(hostState = it) { data -> + OdsSnackbarHost.Snackbar(data = data, actionOnNewLine = true, onActionClick = { + doSomething() + }) + } + }) { + OdsButton( + modifier = Modifier + .padding(horizontal = dimensionResource(id = com.orange.ods.R.dimen.screen_horizontal_margin)) + .padding(top = dimensionResource(id = com.orange.ods.R.dimen.screen_vertical_margin)), + text = "Show snackbar", + onClick = { + coroutineScope.launch { + scaffoldState.snackbarHostState.showSnackbar( + message = "This is the message of the Snackbar.", + actionLabel = "Action" + ) + } + } + ) +} +``` + +#### 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) -> OdsSnackbarHost.Snackbar` | `{ OdsSnackbarHost.Snackbar(it) }` | Instance of the `OdsSnackbarHost.Snackbar` to be shown at the appropriate time with appearance based on the `SnackbarData` provided as a param +{:.table} \ No newline at end of file diff --git a/docs/0.18.0/components/Snackbars_docs.md b/docs/0.18.0/components/Snackbars_docs.md new file mode 100644 index 000000000..b1d395cc1 --- /dev/null +++ b/docs/0.18.0/components/Snackbars_docs.md @@ -0,0 +1,4 @@ +--- +layout: main +content_page: Snackbars.md +--- \ No newline at end of file diff --git a/docs/0.18.0/components/Switches.md b/docs/0.18.0/components/Switches.md new file mode 100644 index 000000000..fb43230f0 --- /dev/null +++ b/docs/0.18.0/components/Switches.md @@ -0,0 +1,59 @@ +--- +layout: detail +title: Switches +description: Switch selection control allows the user to select options. +--- + +Switches toggle the state of a single setting on or off. They are the preferred +way to adjust settings on mobile. + +
**On this page** + +* [Specifications references](#specifications-references) +* [Accessibility](#accessibility) +* [Implementation](#implementation) + * [Jetpack Compose](#jetpack-compose) + * [OdsSwitch API](#odsswitch-api) + +--- + +## Specifications references + +- [Design System Manager - Selection controls](https://system.design.orange.com/0c1af118d/p/14638a-selection-controls/b/352c00) +- [Material Design - Switches](https://material.io/components/switches) + +## Accessibility + +Please follow [accessibility criteria for development](https://a11y-guidelines.orange.com/en/mobile/android/development/). + +Switches support content labeling for accessibility and are readable by most +screen readers, such as TalkBack. Text rendered in switches is automatically +provided to accessibility services. Additional content labels are usually +unnecessary. + +## Implementation + +![Switch](images/switch_light.png) ![Switch dark](images/switch_dark.png) + +### Jetpack Compose + +In your composable screen you can use: + +```kotlin +OdsSwitch( + checked = true, + onCheckedChange = { doSomething() }, + enabled = true +) +``` + +#### OdsSwitch API + +Parameter | Default value | Description +-- | -- | -- +`checked: Boolean` | | Controls the checked state of the switch +`onCheckedChange: ((Boolean) -> Unit)?` | | Callback invoked on switch check. If `null`, then this is passive and relies entirely on a higher-level component to control the "checked" state. +`modifier: Modifier` | `Modifier` | `Modifier` applied to the switch +`enabled: Boolean` | `true` | Controls the enabled state of the switch. When `false`, the switch will not be checkable and appears disabled. +{:.table} + diff --git a/docs/0.18.0/components/Switches_docs.md b/docs/0.18.0/components/Switches_docs.md new file mode 100644 index 000000000..e8d456663 --- /dev/null +++ b/docs/0.18.0/components/Switches_docs.md @@ -0,0 +1,4 @@ +--- +layout: main +content_page: Switches.md +--- \ No newline at end of file diff --git a/docs/0.18.0/components/Tabs.md b/docs/0.18.0/components/Tabs.md new file mode 100644 index 000000000..9822860c2 --- /dev/null +++ b/docs/0.18.0/components/Tabs.md @@ -0,0 +1,119 @@ +--- +layout: detail +title: Tabs +description: Tabs organize content across different screens, data sets, and other interactions. +--- + +
**On this page** + +* [Specifications references](#specifications-references) +* [Accessibility](#accessibility) +* [Variants](#variants) + * [Fixed tabs row](#fixed-tabs-row) + * [Jetpack Compose](#jetpack-compose) + * [OdsTabRow API](#odstabrow-api) + * [Scrollable tabs row](#scrollable-tabs-row) + * [Jetpack Compose](#jetpack-compose-1) + * [OdsScrollableTabRow API](#odsscrollabletabrow-api) + +--- + +## Specifications references + +- [Design System Manager - Tabs](https://system.design.orange.com/0c1af118d/p/513d27-tabs/b/50cb71) +- [Material Design - Tabs](https://material.io/components/tabs/) + +## Accessibility + +Please follow [accessibility criteria for development](https://a11y-guidelines.orange.com/en/mobile/android/development/). + +The Android tab components support screen reader descriptions for tabs and +badges. While optional, we strongly encourage their use. + +## Variants + +### Fixed tabs row + +Fixed tabs display all tabs on one screen, with each tab at a fixed width. The +width of each tab is determined by dividing the number of tabs by the screen +width. They don’t scroll to reveal more tabs; the visible tab set represents the +only tabs available. + +#### Jetpack Compose + +To display fixed tabs, use `OdsTabRow` composable and provide a list of `OdsTabRow.Tab` representing the tabs to display. +You can change tab icon position with `tabIconPosition` parameter. + +![Fixed tabs light](images/tabs_fixed_light.png) + +![Fixed tabs dark](images/tabs_fixed_dark.png) + +```kotlin +OdsTabRow( + selectedTabIndex = 0, + tabs = listOf( + OdsTabRow.Tab( + painter = OdsTabRow.Tab.Icon(painterResource(id = R.drawable.ic_heart)), + text = "Favourites", + onClick = { doSomething() } + ), + OdsTabRow.Tab( + painter = OdsTabRow.Tab.Icon(painterResource(id = R.drawable.ic_call)), + text = "Calls", + onClick = { doSomething() } + ) + ) +) +``` + +##### OdsTabRow API + +Parameter | Default value | Description +-- | -- | -- +`selectedTabIndex: Int` | | Index of the currently selected tab +`tabs: List` | | List of the `OdsTabRow.Tab` displayed inside this tabs row +`modifier: Modifier` | `Modifier` | `Modifier` applied to the tabs row +`tabIconPosition: OdsTabRow.Tab.Icon.Position` | `OdsTabRow.Tab.Icon.Position.Top` | Controls the position of the icon in the tabs. By default, the icon is displayed above the text. +{:.table} + +### Scrollable tabs row + +Scrollable tabs are displayed without fixed widths. They are scrollable, such +that some tabs will remain off-screen until scrolled. + +![Scrollable tabs light](images/tabs_scrollable_light.png) + +![Scrollable tabs dark](images/tabs_scrollable_dark.png) + +#### Jetpack Compose + +To display scrollable tabs, use `OdsScrollableTabRow` composable. This is the only difference with fixed tabs implementation. +As for fixed tabs, you can change tab icon position with `tabIconPosition` parameter. + +```kotlin +OdsScrollableTabRow( + selectedTabIndex = 0, + tabs = listOf( + OdsTabRow.Tab( + painter = OdsTabRow.Tab.Icon(painterResource(id = R.drawable.ic_heart)), + text = "Favourites", + onClick = { doSomething() } + ), + OdsTabRow.Tab( + painter = OdsTabRow.Tab.Icon(painterResource(id = R.drawable.ic_call)), + text = "Calls", + onClick = { doSomething() } + ) + ) +) +``` + +##### OdsScrollableTabRow API + +Parameter | Default value | Description +-- | -- | -- +`selectedTabIndex: Int` | | Index of the currently selected tab +`tabs: List` | | List of the `OdsTabRow.Tab` displayed inside this tabs row +`modifier: Modifier` | `Modifier` | `Modifier` applied to the tabs row +`tabIconPosition: OdsTabRow.Tab.Icon.Position` | `OdsTabRow.Tab.Icon.Position.Top` | Controls the position of the icon in the tabs. By default, the icon is displayed above the text. +{:.table} \ No newline at end of file diff --git a/docs/0.18.0/components/Tabs_docs.md b/docs/0.18.0/components/Tabs_docs.md new file mode 100644 index 000000000..8ad98cfca --- /dev/null +++ b/docs/0.18.0/components/Tabs_docs.md @@ -0,0 +1,4 @@ +--- +layout: main +content_page: Tabs.md +--- \ No newline at end of file diff --git a/docs/0.18.0/components/TextFields.md b/docs/0.18.0/components/TextFields.md new file mode 100644 index 000000000..657a14154 --- /dev/null +++ b/docs/0.18.0/components/TextFields.md @@ -0,0 +1,223 @@ +--- +layout: detail +title: Text fields +description: Text fields let users enter and edit text. +--- + +
**On this page** + +* [Specifications references](#specifications-references) +* [Accessibility](#accessibility) +* [Variants](#variants) + * [Text field](#text-field-) + * [Jetpack Compose](#jetpack-compose) + * [OdsTextField API](#odstextfield-api-) + * [Password text field](#password-text-field-) + * [Jetpack Compose](#jetpack-compose-1) + * [OdsPasswordTextField API](#odspasswordtextfield-api-) +* [Extras](#extras) + * [Character counter](#character-counter-) + * [Jetpack Compose](#jetpack-compose-2) + * [OdsTextFieldCharacterCounter](#odstextfieldcharactercounter-) +* [Custom theme configuration](#custom-theme-configuration) + +--- + +## Specifications references + +- [Design System Manager - Text fields](https://system.design.orange.com/0c1af118d/p/483f94-text-fields/b/720e3b) +- [Material Design - Text fields](https://material.io/components/text-fields/) + +## Accessibility + +Please follow [accessibility criteria for development](https://a11y-guidelines.orange.com/en/mobile/android/development/). + +Android's text field component APIs support both label text and helper text for informing the user +as to what information is requested for a text field. + +## Variants + +### Text field [#](#text-field-) + +A text field can be filled or outlined. +The outlined version is more accessible in term of contrast. This is the reason why Orange text fields are outlined. + +![TextField outlined light](images/textfield_outlined_light.png) +![TextField outlined dark](images/textfield_outlined_dark.png) + +![TextField filled light](images/textfield_filled_light.png) +![TextField filled dark](images/textfield_filled_dark.png) + +#### Jetpack Compose + +To add a text field in your composable screen you can use the `OdsTextField` composable as follow: + +```kotlin +var text by rememberSaveable { mutableStateOf("") } +OdsTextField( + leadingIcon = OdsTextField.LeadingIcon( + painterResource(id = R.drawable.ic_heart), + "Like" + ) { doSomething() }, + trailing = OdsTextField.TrailingText(text = "units"), // It can be one of the provided `OdsTextField.Trailing`. See more information below. + enabled = true, + readOnly = false, + isError = false, + errorMessage = "Error message", + value = text, + onValueChange = { text = it }, + label = "Label", + placeholder = "Placeholder", + visualTransformation = VisualTransformation.None, + keyboardOptions = KeyboardOptions.Default, + keyboardActions = KeyboardActions(), + singleLine = false, + maxLines = Int.MAX_VALUE, + characterCounter = OdsTextFieldCharacterCounter( + characterCount = characterCount, + maxCharacterCount = 20, + enabled = true + ) +) +``` + +The library provides several `OdsTextField.Trailing` that you can use as trailing element for text field: + +- `OdsTextField.TrailingIcon`: Displays an icon as trailing element +- `OdsTextField.TrailingText`: Displays a text as trailing element + +**Note:** You will find more information about the character counter in [Extras](#extras) + +##### OdsTextField API [#](#odstextfield-api-) + +Parameter | Default value | Description +-- | -- | -- +`value: String` | | Input text to be shown in the text field +`onValueChange: (String) -> Unit` | | Callback that is triggered when the input service updates the text. An updated text comes as a parameter of the callback. +`modifier: Modifier` | `Modifier` | Modifier applied to this text field +`trailing: OdsTextField.Trailing?` | `null` | Trailing element to display at the end of the text field +`enabled: Boolean` | `true` | Controls the enabled state of the text field. When `false`, the text field will be neither editable nor focusable, the input of the text field will not be selectable, visually text field will appear in the disabled UI state. +`readOnly: Boolean` | `false` | Controls the editable state of the text field. When `true`, the text field can not be modified, however, a user can focus it and copy text from it. Read-only text fields are usually used to display pre-filled forms that user can not edit. +`label: String?` | `null` | Label to be displayed inside or outside the text field. The default text style used is `Typography.caption` when the text field is in focus and `Typography.subtitle1` when the text field is not in focus. +`placeholder: String?` | `null` | Placeholder to be displayed when the text field is in focus and the input text is empty. The default text style for internal `Text` is `Typography.subtitle1`. +`leadingIcon: OdsTextField.LeadingIcon?` | `null` | Icon displayed at the beginning of the text field container +`isError: Boolean` | `false` | Indicates if the text field's current value is in error state. If set to `true`, the text field outline and the error message will be displayed in error color. +`errorMessage: String?` | `null` | Message displayed below the text field when it is in error +`visualTransformation: VisualTransformation` | `VisualTransformation.None` | Transforms the visual representation of the input value. For example, you can use `PasswordVisualTransformation` to create a password text field. By default no visual transformation is applied. +`keyboardOptions: KeyboardOptions` | `KeyboardOptions.Default` | Software keyboard options that contains configuration such as `KeyboardType` and `ImeAction` +`keyboardActions: KeyboardActions` | `KeyboardActions()` | When the input service emits an IME action, the corresponding callback is called. Note that this IME action may be different from what you specified in `KeyboardOptions.imeAction`. +`singleLine: Boolean` | `false` | When set to `true`, this text field becomes a single horizontally scrolling text field instead of wrapping onto multiple lines. The keyboard will be informed to not show the return key as the `ImeAction`. Note that `maxLines` parameter will be ignored as the maxLines attribute will be automatically set to 1. +`maxLines: Int` | `Int.MAX_VALUE` | Maximum number of visible lines. Should be equal or greater than 1. Note that this parameter will be ignored and instead maxLines will be set to 1 if `singleLine` is set to `true`. +`characterCounter: `[OdsTextFieldCharacterCounter](#odstextfieldcharactercounter-)`?` | `null` | Character counter displayed below the text field +{:.table} + +### Password text field [#](#password-text-field-) + +Password text field is a text field implementation that includes password visual transformation and optional visualisation icon. + +![TextField outlined password light](images/textfield_outlined_password_light.png) +![TextField outlined password dark](images/textfield_outlined_password_dark.png) + +![TextField filled password light](images/textfield_filled_password_light.png) +![TextField filled password dark](images/textfield_filled_password_dark.png) + +#### Jetpack Compose + +To add a password text field in your composable screen you can use the `OdsPasswordTextField` composable as follow: + +```kotlin +var text by rememberSaveable { mutableStateOf("") } +OdsPasswordTextField( + enabled = true, + readOnly = false, + isError = false, + errorMessage = "Error message", + value = text, + onValueChange = { text = it }, + label = "Label", + placeholder = "Placeholder", + visualisationIcon = true, + keyboardOptions = KeyboardOptions.Default, + keyboardActions = KeyboardActions(), + characterCounter = OdsTextFieldCharacterCounter( + characterCount = characterCount, + maxCharacterCount = TextFieldMaxCharacterCount, + enabled = enabled + ) +) +``` + +**Note:** This composable relies on `OdsTextField` in order to keep homogeneity in each application. +Its appearance (outlined or filled) is inherited from text fields style configuration. +See [text field section](#text-field) if you want to change it in your custom theme. + +##### OdsPasswordTextField API [#](#odspasswordtextfield-api-) + +Parameter | Default value | Description +-- | -- | -- +`value: String` | | Input text to be shown in the text field +`onValueChange: (String) -> Unit` | | Callback that is triggered when the input service updates the text. An updated text comes as a parameter of the callback. +`modifier: Modifier` | `Modifier` | Modifier applied to this text field +`enabled: Boolean` | `true` | Controls the enabled state of the text field. When `false`, the text field will be neither editable nor focusable, the input of the text field will not be selectable, visually text field will appear in the disabled UI state. +`readOnly: Boolean` | `false` | Controls the editable state of the text field. When `true`, the text field can not be modified, however, a user can focus it and copy text from it. Read-only text fields are usually used to display pre-filled forms that user can not edit. +`label: String?` | `null` | Label to be displayed inside or outside the text field. The default text style used is `Typography.caption` when the text field is in focus and `Typography.subtitle1` when the text field is not in focus. +`placeholder: String?` | `null` | Placeholder to be displayed when the text field is in focus and the input text is empty. The default text style for internal `Text` is `Typography.subtitle1`. +`visualisationIcon: Boolean` | `true` | Controls the display of the eye icon to allow showing/hiding password +`isError: Boolean` | `false` | Indicates if the text field's current value is in error state. If set to `true`, the text field outline and the error message will be displayed in error color. +`errorMessage: String?` | `null` | Message displayed below the text field when it is in error +`keyboardOptions: KeyboardOptions` | `KeyboardOptions.Default` | Software keyboard options that contains configuration such as `KeyboardType` and `ImeAction` +`keyboardActions: KeyboardActions` | `KeyboardActions()` | When the input service emits an IME action, the corresponding callback is called. Note that this IME action may be different from what you specified in `KeyboardOptions.imeAction`. +`characterCounter: `[OdsTextFieldCharacterCounter](#odstextfieldcharactercounter-)`?` | `null` | Character counter displayed below the text field +{:.table} + +## Extras + +### Character counter [#](#character-counter-) + +![TextField character counter light](images/textfield_character_counter_light.png) +![TextField character counter dark](images/textfield_character_counter_dark.png) + +#### Jetpack Compose + +In each TextField component, you can use the `characterCounter` parameter to add a character counter if there is a restriction on the number of characters in a field. +It will be placed properly below the text field, end aligned. + +Use the `OdsTextFieldCharacterCounter` class for this behavior as shown below: + +```kotlin +OdsTextFieldCharacterCounter( + modifier = Modifier.align(Alignment.End), + characterCount = characterCount, + maxCharacterCount = 20, + enabled = true +) +``` + +Be careful, the limitation behavior should be managed by yourself in the `onValueChange` method of the text field: + +```kotlin +if (text.length <= TextFieldMaxCharacterCount) { + value = text +} +``` + +##### OdsTextFieldCharacterCounter [#](#odstextfieldcharactercounter-) + +Parameter | Default value | Description +-- | -- | -- +`characterCount: Int` | | Text field current characters count. +`maxCharacterCount: Int` | | Maximum number of characters to display in the counter. Note: the limitation behavior should be managed by yourself in the `onValueChange` method of the text field. +`enabled: Boolean` | `true` | Controls the enable state of the counter. If set to `false` the text will be displayed in disabled color. +{:.table} + +## Custom theme configuration + +You can override the default display of text fields in your custom theme by overriding the `textFieldStyle` attribute as below: + +```kotlin +override val components: OdsComponentsConfiguration + get() = object : OdsComponentsConfiguration() { + override val textFieldStyle: ComponentStyle + get() = ComponentStyle.Filled + } +``` diff --git a/docs/0.18.0/components/TextFields_docs.md b/docs/0.18.0/components/TextFields_docs.md new file mode 100644 index 000000000..f9039ae91 --- /dev/null +++ b/docs/0.18.0/components/TextFields_docs.md @@ -0,0 +1,4 @@ +--- +layout: main +content_page: TextFields.md +--- \ No newline at end of file diff --git a/docs/0.18.0/components/images/app_bar_top_overflow_menu_dark.png b/docs/0.18.0/components/images/app_bar_top_overflow_menu_dark.png new file mode 100644 index 000000000..60322543e Binary files /dev/null and b/docs/0.18.0/components/images/app_bar_top_overflow_menu_dark.png differ diff --git a/docs/0.18.0/components/images/app_bar_top_overflow_menu_light.png b/docs/0.18.0/components/images/app_bar_top_overflow_menu_light.png new file mode 100644 index 000000000..2e3bd9056 Binary files /dev/null and b/docs/0.18.0/components/images/app_bar_top_overflow_menu_light.png differ diff --git a/docs/0.18.0/components/images/banner_dark.png b/docs/0.18.0/components/images/banner_dark.png new file mode 100644 index 000000000..60803f207 Binary files /dev/null and b/docs/0.18.0/components/images/banner_dark.png differ diff --git a/docs/0.18.0/components/images/banner_light.png b/docs/0.18.0/components/images/banner_light.png new file mode 100644 index 000000000..4d174146a Binary files /dev/null and b/docs/0.18.0/components/images/banner_light.png differ diff --git a/docs/0.18.0/components/images/bottom_navigation_dark.png b/docs/0.18.0/components/images/bottom_navigation_dark.png new file mode 100644 index 000000000..4f4bd9087 Binary files /dev/null and b/docs/0.18.0/components/images/bottom_navigation_dark.png differ diff --git a/docs/0.18.0/components/images/bottom_navigation_light.png b/docs/0.18.0/components/images/bottom_navigation_light.png new file mode 100644 index 000000000..dafd1f3b2 Binary files /dev/null and b/docs/0.18.0/components/images/bottom_navigation_light.png differ diff --git a/docs/0.18.0/components/images/button_contained_dark.png b/docs/0.18.0/components/images/button_contained_dark.png new file mode 100644 index 000000000..17180098e Binary files /dev/null and b/docs/0.18.0/components/images/button_contained_dark.png differ diff --git a/docs/0.18.0/components/images/button_contained_light.png b/docs/0.18.0/components/images/button_contained_light.png new file mode 100644 index 000000000..ad4d8dc6d Binary files /dev/null and b/docs/0.18.0/components/images/button_contained_light.png differ diff --git a/docs/0.18.0/components/images/button_contained_negative_dark.png b/docs/0.18.0/components/images/button_contained_negative_dark.png new file mode 100644 index 000000000..d19e6ccf7 Binary files /dev/null and b/docs/0.18.0/components/images/button_contained_negative_dark.png differ diff --git a/docs/0.18.0/components/images/button_contained_negative_light.png b/docs/0.18.0/components/images/button_contained_negative_light.png new file mode 100644 index 000000000..a242cd7ee Binary files /dev/null and b/docs/0.18.0/components/images/button_contained_negative_light.png differ diff --git a/docs/0.18.0/components/images/button_contained_positive_dark.png b/docs/0.18.0/components/images/button_contained_positive_dark.png new file mode 100644 index 000000000..ae3a73886 Binary files /dev/null and b/docs/0.18.0/components/images/button_contained_positive_dark.png differ diff --git a/docs/0.18.0/components/images/button_contained_positive_light.png b/docs/0.18.0/components/images/button_contained_positive_light.png new file mode 100644 index 000000000..730194c7b Binary files /dev/null and b/docs/0.18.0/components/images/button_contained_positive_light.png differ diff --git a/docs/0.18.0/components/images/button_icon_dark.png b/docs/0.18.0/components/images/button_icon_dark.png new file mode 100644 index 000000000..551ce30a0 Binary files /dev/null and b/docs/0.18.0/components/images/button_icon_dark.png differ diff --git a/docs/0.18.0/components/images/button_icon_light.png b/docs/0.18.0/components/images/button_icon_light.png new file mode 100644 index 000000000..b11c9dd5b Binary files /dev/null and b/docs/0.18.0/components/images/button_icon_light.png differ diff --git a/docs/0.18.0/components/images/button_icon_toggle_dark.png b/docs/0.18.0/components/images/button_icon_toggle_dark.png new file mode 100644 index 000000000..d2702c6e4 Binary files /dev/null and b/docs/0.18.0/components/images/button_icon_toggle_dark.png differ diff --git a/docs/0.18.0/components/images/button_icon_toggle_group_dark.png b/docs/0.18.0/components/images/button_icon_toggle_group_dark.png new file mode 100644 index 000000000..1f3fdc9a8 Binary files /dev/null and b/docs/0.18.0/components/images/button_icon_toggle_group_dark.png differ diff --git a/docs/0.18.0/components/images/button_icon_toggle_group_light.png b/docs/0.18.0/components/images/button_icon_toggle_group_light.png new file mode 100644 index 000000000..4f32291c9 Binary files /dev/null and b/docs/0.18.0/components/images/button_icon_toggle_group_light.png differ diff --git a/docs/0.18.0/components/images/button_icon_toggle_light.png b/docs/0.18.0/components/images/button_icon_toggle_light.png new file mode 100644 index 000000000..8256c3953 Binary files /dev/null and b/docs/0.18.0/components/images/button_icon_toggle_light.png differ diff --git a/docs/0.18.0/components/images/button_outlined_dark.png b/docs/0.18.0/components/images/button_outlined_dark.png new file mode 100644 index 000000000..094925f21 Binary files /dev/null and b/docs/0.18.0/components/images/button_outlined_dark.png differ diff --git a/docs/0.18.0/components/images/button_outlined_light.png b/docs/0.18.0/components/images/button_outlined_light.png new file mode 100644 index 000000000..9e308f16b Binary files /dev/null and b/docs/0.18.0/components/images/button_outlined_light.png differ diff --git a/docs/0.18.0/components/images/button_text_dark.png b/docs/0.18.0/components/images/button_text_dark.png new file mode 100644 index 000000000..9e4800910 Binary files /dev/null and b/docs/0.18.0/components/images/button_text_dark.png differ diff --git a/docs/0.18.0/components/images/button_text_light.png b/docs/0.18.0/components/images/button_text_light.png new file mode 100644 index 000000000..9b70e404f Binary files /dev/null and b/docs/0.18.0/components/images/button_text_light.png differ diff --git a/docs/0.18.0/components/images/button_text_toggle_group_dark.png b/docs/0.18.0/components/images/button_text_toggle_group_dark.png new file mode 100644 index 000000000..b8aab9b36 Binary files /dev/null and b/docs/0.18.0/components/images/button_text_toggle_group_dark.png differ diff --git a/docs/0.18.0/components/images/button_text_toggle_group_light.png b/docs/0.18.0/components/images/button_text_toggle_group_light.png new file mode 100644 index 000000000..7c594ce45 Binary files /dev/null and b/docs/0.18.0/components/images/button_text_toggle_group_light.png differ diff --git a/docs/0.18.0/components/images/button_toggle_dark.png b/docs/0.18.0/components/images/button_toggle_dark.png new file mode 100644 index 000000000..20faac6fc Binary files /dev/null and b/docs/0.18.0/components/images/button_toggle_dark.png differ diff --git a/docs/0.18.0/components/images/button_toggle_light.png b/docs/0.18.0/components/images/button_toggle_light.png new file mode 100644 index 000000000..70554b9a7 Binary files /dev/null and b/docs/0.18.0/components/images/button_toggle_light.png differ diff --git a/docs/0.18.0/components/images/card_horizontal_dark.png b/docs/0.18.0/components/images/card_horizontal_dark.png new file mode 100644 index 000000000..7ea820dc7 Binary files /dev/null and b/docs/0.18.0/components/images/card_horizontal_dark.png differ diff --git a/docs/0.18.0/components/images/card_horizontal_light.png b/docs/0.18.0/components/images/card_horizontal_light.png new file mode 100644 index 000000000..e2068ee89 Binary files /dev/null and b/docs/0.18.0/components/images/card_horizontal_light.png differ diff --git a/docs/0.18.0/components/images/card_small_dark.png b/docs/0.18.0/components/images/card_small_dark.png new file mode 100644 index 000000000..9a4097c8c Binary files /dev/null and b/docs/0.18.0/components/images/card_small_dark.png differ diff --git a/docs/0.18.0/components/images/card_small_light.png b/docs/0.18.0/components/images/card_small_light.png new file mode 100644 index 000000000..4b9420763 Binary files /dev/null and b/docs/0.18.0/components/images/card_small_light.png differ diff --git a/docs/0.18.0/components/images/card_vertical_header_first_dark.png b/docs/0.18.0/components/images/card_vertical_header_first_dark.png new file mode 100644 index 000000000..1626639cc Binary files /dev/null and b/docs/0.18.0/components/images/card_vertical_header_first_dark.png differ diff --git a/docs/0.18.0/components/images/card_vertical_header_first_light.png b/docs/0.18.0/components/images/card_vertical_header_first_light.png new file mode 100644 index 000000000..31e9d39cd Binary files /dev/null and b/docs/0.18.0/components/images/card_vertical_header_first_light.png differ diff --git a/docs/0.18.0/components/images/card_vertical_image_first_dark.png b/docs/0.18.0/components/images/card_vertical_image_first_dark.png new file mode 100644 index 000000000..090ce5269 Binary files /dev/null and b/docs/0.18.0/components/images/card_vertical_image_first_dark.png differ diff --git a/docs/0.18.0/components/images/card_vertical_image_first_light.png b/docs/0.18.0/components/images/card_vertical_image_first_light.png new file mode 100644 index 000000000..9dd3ed2dd Binary files /dev/null and b/docs/0.18.0/components/images/card_vertical_image_first_light.png differ diff --git a/docs/0.18.0/components/images/checkbox_dark.png b/docs/0.18.0/components/images/checkbox_dark.png new file mode 100644 index 000000000..ebd5321ed Binary files /dev/null and b/docs/0.18.0/components/images/checkbox_dark.png differ diff --git a/docs/0.18.0/components/images/checkbox_light.png b/docs/0.18.0/components/images/checkbox_light.png new file mode 100644 index 000000000..5650e8b3f Binary files /dev/null and b/docs/0.18.0/components/images/checkbox_light.png differ diff --git a/docs/0.18.0/components/images/chips_action_dark.png b/docs/0.18.0/components/images/chips_action_dark.png new file mode 100644 index 000000000..c9bebe9b6 Binary files /dev/null and b/docs/0.18.0/components/images/chips_action_dark.png differ diff --git a/docs/0.18.0/components/images/chips_action_light.png b/docs/0.18.0/components/images/chips_action_light.png new file mode 100644 index 000000000..2b19d6222 Binary files /dev/null and b/docs/0.18.0/components/images/chips_action_light.png differ diff --git a/docs/0.18.0/components/images/chips_action_outlined_dark.png b/docs/0.18.0/components/images/chips_action_outlined_dark.png new file mode 100644 index 000000000..d88b7e0fc Binary files /dev/null and b/docs/0.18.0/components/images/chips_action_outlined_dark.png differ diff --git a/docs/0.18.0/components/images/chips_action_outlined_light.png b/docs/0.18.0/components/images/chips_action_outlined_light.png new file mode 100644 index 000000000..10bddc302 Binary files /dev/null and b/docs/0.18.0/components/images/chips_action_outlined_light.png differ diff --git a/docs/0.18.0/components/images/chips_choice_dark.png b/docs/0.18.0/components/images/chips_choice_dark.png new file mode 100644 index 000000000..338f76f72 Binary files /dev/null and b/docs/0.18.0/components/images/chips_choice_dark.png differ diff --git a/docs/0.18.0/components/images/chips_choice_flow_row_dark.png b/docs/0.18.0/components/images/chips_choice_flow_row_dark.png new file mode 100644 index 000000000..18a7c58ca Binary files /dev/null and b/docs/0.18.0/components/images/chips_choice_flow_row_dark.png differ diff --git a/docs/0.18.0/components/images/chips_choice_flow_row_light.png b/docs/0.18.0/components/images/chips_choice_flow_row_light.png new file mode 100644 index 000000000..d80a00356 Binary files /dev/null and b/docs/0.18.0/components/images/chips_choice_flow_row_light.png differ diff --git a/docs/0.18.0/components/images/chips_choice_light.png b/docs/0.18.0/components/images/chips_choice_light.png new file mode 100644 index 000000000..f9b38d549 Binary files /dev/null and b/docs/0.18.0/components/images/chips_choice_light.png differ diff --git a/docs/0.18.0/components/images/chips_choice_outlined_dark.png b/docs/0.18.0/components/images/chips_choice_outlined_dark.png new file mode 100644 index 000000000..1b4329284 Binary files /dev/null and b/docs/0.18.0/components/images/chips_choice_outlined_dark.png differ diff --git a/docs/0.18.0/components/images/chips_choice_outlined_light.png b/docs/0.18.0/components/images/chips_choice_outlined_light.png new file mode 100644 index 000000000..2eaba4744 Binary files /dev/null and b/docs/0.18.0/components/images/chips_choice_outlined_light.png differ diff --git a/docs/0.18.0/components/images/chips_filter_avatar_dark.png b/docs/0.18.0/components/images/chips_filter_avatar_dark.png new file mode 100644 index 000000000..9158aeb7a Binary files /dev/null and b/docs/0.18.0/components/images/chips_filter_avatar_dark.png differ diff --git a/docs/0.18.0/components/images/chips_filter_avatar_light.png b/docs/0.18.0/components/images/chips_filter_avatar_light.png new file mode 100644 index 000000000..1914df0da Binary files /dev/null and b/docs/0.18.0/components/images/chips_filter_avatar_light.png differ diff --git a/docs/0.18.0/components/images/chips_filter_dark.png b/docs/0.18.0/components/images/chips_filter_dark.png new file mode 100644 index 000000000..6a79f17b6 Binary files /dev/null and b/docs/0.18.0/components/images/chips_filter_dark.png differ diff --git a/docs/0.18.0/components/images/chips_filter_light.png b/docs/0.18.0/components/images/chips_filter_light.png new file mode 100644 index 000000000..d39968cd5 Binary files /dev/null and b/docs/0.18.0/components/images/chips_filter_light.png differ diff --git a/docs/0.18.0/components/images/chips_input_dark.png b/docs/0.18.0/components/images/chips_input_dark.png new file mode 100644 index 000000000..d76828f0d Binary files /dev/null and b/docs/0.18.0/components/images/chips_input_dark.png differ diff --git a/docs/0.18.0/components/images/chips_input_light.png b/docs/0.18.0/components/images/chips_input_light.png new file mode 100644 index 000000000..436f48b73 Binary files /dev/null and b/docs/0.18.0/components/images/chips_input_light.png differ diff --git a/docs/0.18.0/components/images/chips_input_outlined_dark.png b/docs/0.18.0/components/images/chips_input_outlined_dark.png new file mode 100644 index 000000000..841191acf Binary files /dev/null and b/docs/0.18.0/components/images/chips_input_outlined_dark.png differ diff --git a/docs/0.18.0/components/images/chips_input_outlined_light.png b/docs/0.18.0/components/images/chips_input_outlined_light.png new file mode 100644 index 000000000..91e8196de Binary files /dev/null and b/docs/0.18.0/components/images/chips_input_outlined_light.png differ diff --git a/docs/0.18.0/components/images/dialog_alert_dark.png b/docs/0.18.0/components/images/dialog_alert_dark.png new file mode 100644 index 000000000..9521ceb28 Binary files /dev/null and b/docs/0.18.0/components/images/dialog_alert_dark.png differ diff --git a/docs/0.18.0/components/images/dialog_alert_light.png b/docs/0.18.0/components/images/dialog_alert_light.png new file mode 100644 index 000000000..03ba441d5 Binary files /dev/null and b/docs/0.18.0/components/images/dialog_alert_light.png differ diff --git a/docs/0.18.0/components/images/fab_dark.png b/docs/0.18.0/components/images/fab_dark.png new file mode 100644 index 000000000..416210dd3 Binary files /dev/null and b/docs/0.18.0/components/images/fab_dark.png differ diff --git a/docs/0.18.0/components/images/fab_extended_dark.png b/docs/0.18.0/components/images/fab_extended_dark.png new file mode 100644 index 000000000..62f560ae2 Binary files /dev/null and b/docs/0.18.0/components/images/fab_extended_dark.png differ diff --git a/docs/0.18.0/components/images/fab_extended_full_width_dark.png b/docs/0.18.0/components/images/fab_extended_full_width_dark.png new file mode 100644 index 000000000..e85c907e0 Binary files /dev/null and b/docs/0.18.0/components/images/fab_extended_full_width_dark.png differ diff --git a/docs/0.18.0/components/images/fab_extended_full_width_light.png b/docs/0.18.0/components/images/fab_extended_full_width_light.png new file mode 100644 index 000000000..71a00d02b Binary files /dev/null and b/docs/0.18.0/components/images/fab_extended_full_width_light.png differ diff --git a/docs/0.18.0/components/images/fab_extended_light.png b/docs/0.18.0/components/images/fab_extended_light.png new file mode 100644 index 000000000..32da1d57b Binary files /dev/null and b/docs/0.18.0/components/images/fab_extended_light.png differ diff --git a/docs/0.18.0/components/images/fab_light.png b/docs/0.18.0/components/images/fab_light.png new file mode 100644 index 000000000..3b2f977d7 Binary files /dev/null and b/docs/0.18.0/components/images/fab_light.png differ diff --git a/docs/0.18.0/components/images/fab_mini_dark.png b/docs/0.18.0/components/images/fab_mini_dark.png new file mode 100644 index 000000000..062d6a74a Binary files /dev/null and b/docs/0.18.0/components/images/fab_mini_dark.png differ diff --git a/docs/0.18.0/components/images/fab_mini_light.png b/docs/0.18.0/components/images/fab_mini_light.png new file mode 100644 index 000000000..d34e524c6 Binary files /dev/null and b/docs/0.18.0/components/images/fab_mini_light.png differ diff --git a/docs/0.18.0/components/images/lists_single_line_dark.png b/docs/0.18.0/components/images/lists_single_line_dark.png new file mode 100644 index 000000000..d46eca2dc Binary files /dev/null and b/docs/0.18.0/components/images/lists_single_line_dark.png differ diff --git a/docs/0.18.0/components/images/lists_single_line_light.png b/docs/0.18.0/components/images/lists_single_line_light.png new file mode 100644 index 000000000..3bda5190e Binary files /dev/null and b/docs/0.18.0/components/images/lists_single_line_light.png differ diff --git a/docs/0.18.0/components/images/lists_single_line_wide_image_dark.png b/docs/0.18.0/components/images/lists_single_line_wide_image_dark.png new file mode 100644 index 000000000..c00f21923 Binary files /dev/null and b/docs/0.18.0/components/images/lists_single_line_wide_image_dark.png differ diff --git a/docs/0.18.0/components/images/lists_single_line_wide_image_light.png b/docs/0.18.0/components/images/lists_single_line_wide_image_light.png new file mode 100644 index 000000000..d839b5cc6 Binary files /dev/null and b/docs/0.18.0/components/images/lists_single_line_wide_image_light.png differ diff --git a/docs/0.18.0/components/images/lists_three_line_dark.png b/docs/0.18.0/components/images/lists_three_line_dark.png new file mode 100644 index 000000000..15e350f3c Binary files /dev/null and b/docs/0.18.0/components/images/lists_three_line_dark.png differ diff --git a/docs/0.18.0/components/images/lists_three_line_light.png b/docs/0.18.0/components/images/lists_three_line_light.png new file mode 100644 index 000000000..f3dabd4e8 Binary files /dev/null and b/docs/0.18.0/components/images/lists_three_line_light.png differ diff --git a/docs/0.18.0/components/images/lists_three_line_wide_image_dark.png b/docs/0.18.0/components/images/lists_three_line_wide_image_dark.png new file mode 100644 index 000000000..2d44de0c3 Binary files /dev/null and b/docs/0.18.0/components/images/lists_three_line_wide_image_dark.png differ diff --git a/docs/0.18.0/components/images/lists_three_line_wide_image_light.png b/docs/0.18.0/components/images/lists_three_line_wide_image_light.png new file mode 100644 index 000000000..b6eaa4363 Binary files /dev/null and b/docs/0.18.0/components/images/lists_three_line_wide_image_light.png differ diff --git a/docs/0.18.0/components/images/lists_two_line_dark.png b/docs/0.18.0/components/images/lists_two_line_dark.png new file mode 100644 index 000000000..7e130d9fa Binary files /dev/null and b/docs/0.18.0/components/images/lists_two_line_dark.png differ diff --git a/docs/0.18.0/components/images/lists_two_line_light.png b/docs/0.18.0/components/images/lists_two_line_light.png new file mode 100644 index 000000000..ea4e52cb9 Binary files /dev/null and b/docs/0.18.0/components/images/lists_two_line_light.png differ diff --git a/docs/0.18.0/components/images/lists_two_line_wide_image_dark.png b/docs/0.18.0/components/images/lists_two_line_wide_image_dark.png new file mode 100644 index 000000000..0ea681e85 Binary files /dev/null and b/docs/0.18.0/components/images/lists_two_line_wide_image_dark.png differ diff --git a/docs/0.18.0/components/images/lists_two_line_wide_image_light.png b/docs/0.18.0/components/images/lists_two_line_wide_image_light.png new file mode 100644 index 000000000..0c214c277 Binary files /dev/null and b/docs/0.18.0/components/images/lists_two_line_wide_image_light.png differ diff --git a/docs/0.18.0/components/images/menu_dropdown_dark.png b/docs/0.18.0/components/images/menu_dropdown_dark.png new file mode 100644 index 000000000..b47bccfe6 Binary files /dev/null and b/docs/0.18.0/components/images/menu_dropdown_dark.png differ diff --git a/docs/0.18.0/components/images/menu_dropdown_light.png b/docs/0.18.0/components/images/menu_dropdown_light.png new file mode 100644 index 000000000..5af3fb658 Binary files /dev/null and b/docs/0.18.0/components/images/menu_dropdown_light.png differ diff --git a/docs/0.18.0/components/images/menu_exposed_dropdown_dark.png b/docs/0.18.0/components/images/menu_exposed_dropdown_dark.png new file mode 100644 index 000000000..029fb349f Binary files /dev/null and b/docs/0.18.0/components/images/menu_exposed_dropdown_dark.png differ diff --git a/docs/0.18.0/components/images/menu_exposed_dropdown_light.png b/docs/0.18.0/components/images/menu_exposed_dropdown_light.png new file mode 100644 index 000000000..202aa7db9 Binary files /dev/null and b/docs/0.18.0/components/images/menu_exposed_dropdown_light.png differ diff --git a/docs/0.18.0/components/images/progress_circular_dark.png b/docs/0.18.0/components/images/progress_circular_dark.png new file mode 100644 index 000000000..69b07e8ce Binary files /dev/null and b/docs/0.18.0/components/images/progress_circular_dark.png differ diff --git a/docs/0.18.0/components/images/progress_circular_light.png b/docs/0.18.0/components/images/progress_circular_light.png new file mode 100644 index 000000000..b183a1d7d Binary files /dev/null and b/docs/0.18.0/components/images/progress_circular_light.png differ diff --git a/docs/0.18.0/components/images/progress_linear_dark.png b/docs/0.18.0/components/images/progress_linear_dark.png new file mode 100644 index 000000000..e4e3e843c Binary files /dev/null and b/docs/0.18.0/components/images/progress_linear_dark.png differ diff --git a/docs/0.18.0/components/images/progress_linear_light.png b/docs/0.18.0/components/images/progress_linear_light.png new file mode 100644 index 000000000..f56e57735 Binary files /dev/null and b/docs/0.18.0/components/images/progress_linear_light.png differ diff --git a/docs/0.18.0/components/images/radio_button_dark.png b/docs/0.18.0/components/images/radio_button_dark.png new file mode 100644 index 000000000..e7d12ea2f Binary files /dev/null and b/docs/0.18.0/components/images/radio_button_dark.png differ diff --git a/docs/0.18.0/components/images/radio_button_light.png b/docs/0.18.0/components/images/radio_button_light.png new file mode 100644 index 000000000..6de7c0510 Binary files /dev/null and b/docs/0.18.0/components/images/radio_button_light.png differ diff --git a/docs/0.18.0/components/images/sheetbottom_dark.png b/docs/0.18.0/components/images/sheetbottom_dark.png new file mode 100644 index 000000000..92919efce Binary files /dev/null and b/docs/0.18.0/components/images/sheetbottom_dark.png differ diff --git a/docs/0.18.0/components/images/sheetbottom_light.png b/docs/0.18.0/components/images/sheetbottom_light.png new file mode 100644 index 000000000..add8e3f0b Binary files /dev/null and b/docs/0.18.0/components/images/sheetbottom_light.png differ diff --git a/docs/0.18.0/components/images/slider_continuous_dark.png b/docs/0.18.0/components/images/slider_continuous_dark.png new file mode 100644 index 000000000..d51cceb18 Binary files /dev/null and b/docs/0.18.0/components/images/slider_continuous_dark.png differ diff --git a/docs/0.18.0/components/images/slider_continuous_light.png b/docs/0.18.0/components/images/slider_continuous_light.png new file mode 100644 index 000000000..79534c544 Binary files /dev/null and b/docs/0.18.0/components/images/slider_continuous_light.png differ diff --git a/docs/0.18.0/components/images/slider_continuous_lockups_dark.png b/docs/0.18.0/components/images/slider_continuous_lockups_dark.png new file mode 100644 index 000000000..6611a0239 Binary files /dev/null and b/docs/0.18.0/components/images/slider_continuous_lockups_dark.png differ diff --git a/docs/0.18.0/components/images/slider_continuous_lockups_light.png b/docs/0.18.0/components/images/slider_continuous_lockups_light.png new file mode 100644 index 000000000..32983ce8d Binary files /dev/null and b/docs/0.18.0/components/images/slider_continuous_lockups_light.png differ diff --git a/docs/0.18.0/components/images/slider_continuous_lockups_with_icon_dark.png b/docs/0.18.0/components/images/slider_continuous_lockups_with_icon_dark.png new file mode 100644 index 000000000..05224484e Binary files /dev/null and b/docs/0.18.0/components/images/slider_continuous_lockups_with_icon_dark.png differ diff --git a/docs/0.18.0/components/images/slider_continuous_lockups_with_icon_light.png b/docs/0.18.0/components/images/slider_continuous_lockups_with_icon_light.png new file mode 100644 index 000000000..6684b95d1 Binary files /dev/null and b/docs/0.18.0/components/images/slider_continuous_lockups_with_icon_light.png differ diff --git a/docs/0.18.0/components/images/slider_continuous_with_icon_dark.png b/docs/0.18.0/components/images/slider_continuous_with_icon_dark.png new file mode 100644 index 000000000..c26eb6ea1 Binary files /dev/null and b/docs/0.18.0/components/images/slider_continuous_with_icon_dark.png differ diff --git a/docs/0.18.0/components/images/slider_continuous_with_icon_light.png b/docs/0.18.0/components/images/slider_continuous_with_icon_light.png new file mode 100644 index 000000000..aa2313001 Binary files /dev/null and b/docs/0.18.0/components/images/slider_continuous_with_icon_light.png differ diff --git a/docs/0.18.0/components/images/slider_discrete_dark.png b/docs/0.18.0/components/images/slider_discrete_dark.png new file mode 100644 index 000000000..bb77c044b Binary files /dev/null and b/docs/0.18.0/components/images/slider_discrete_dark.png differ diff --git a/docs/0.18.0/components/images/slider_discrete_light.png b/docs/0.18.0/components/images/slider_discrete_light.png new file mode 100644 index 000000000..778ae3b6a Binary files /dev/null and b/docs/0.18.0/components/images/slider_discrete_light.png differ diff --git a/docs/0.18.0/components/images/slider_discrete_lockups_dark.png b/docs/0.18.0/components/images/slider_discrete_lockups_dark.png new file mode 100644 index 000000000..b2b16047e Binary files /dev/null and b/docs/0.18.0/components/images/slider_discrete_lockups_dark.png differ diff --git a/docs/0.18.0/components/images/slider_discrete_lockups_light.png b/docs/0.18.0/components/images/slider_discrete_lockups_light.png new file mode 100644 index 000000000..078f7d80e Binary files /dev/null and b/docs/0.18.0/components/images/slider_discrete_lockups_light.png differ diff --git a/docs/0.18.0/components/images/slider_discrete_lockups_with_icon_dark.png b/docs/0.18.0/components/images/slider_discrete_lockups_with_icon_dark.png new file mode 100644 index 000000000..5dac0f3dc Binary files /dev/null and b/docs/0.18.0/components/images/slider_discrete_lockups_with_icon_dark.png differ diff --git a/docs/0.18.0/components/images/slider_discrete_lockups_with_icon_light.png b/docs/0.18.0/components/images/slider_discrete_lockups_with_icon_light.png new file mode 100644 index 000000000..b455cbcf5 Binary files /dev/null and b/docs/0.18.0/components/images/slider_discrete_lockups_with_icon_light.png differ diff --git a/docs/0.18.0/components/images/slider_discrete_with_icon_dark.png b/docs/0.18.0/components/images/slider_discrete_with_icon_dark.png new file mode 100644 index 000000000..cfa833cc0 Binary files /dev/null and b/docs/0.18.0/components/images/slider_discrete_with_icon_dark.png differ diff --git a/docs/0.18.0/components/images/slider_discrete_with_icon_light.png b/docs/0.18.0/components/images/slider_discrete_with_icon_light.png new file mode 100644 index 000000000..300f59ad9 Binary files /dev/null and b/docs/0.18.0/components/images/slider_discrete_with_icon_light.png differ diff --git a/docs/0.18.0/components/images/snackbar_dark.png b/docs/0.18.0/components/images/snackbar_dark.png new file mode 100644 index 000000000..975974543 Binary files /dev/null and b/docs/0.18.0/components/images/snackbar_dark.png differ diff --git a/docs/0.18.0/components/images/snackbar_light.png b/docs/0.18.0/components/images/snackbar_light.png new file mode 100644 index 000000000..581e307cf Binary files /dev/null and b/docs/0.18.0/components/images/snackbar_light.png differ diff --git a/docs/0.18.0/components/images/snackbar_with_action_dark.png b/docs/0.18.0/components/images/snackbar_with_action_dark.png new file mode 100644 index 000000000..0b1db7fea Binary files /dev/null and b/docs/0.18.0/components/images/snackbar_with_action_dark.png differ diff --git a/docs/0.18.0/components/images/snackbar_with_action_light.png b/docs/0.18.0/components/images/snackbar_with_action_light.png new file mode 100644 index 000000000..8590dcf57 Binary files /dev/null and b/docs/0.18.0/components/images/snackbar_with_action_light.png differ diff --git a/docs/0.18.0/components/images/switch_dark.png b/docs/0.18.0/components/images/switch_dark.png new file mode 100644 index 000000000..88e383385 Binary files /dev/null and b/docs/0.18.0/components/images/switch_dark.png differ diff --git a/docs/0.18.0/components/images/switch_light.png b/docs/0.18.0/components/images/switch_light.png new file mode 100644 index 000000000..3e7c48822 Binary files /dev/null and b/docs/0.18.0/components/images/switch_light.png differ diff --git a/docs/0.18.0/components/images/tabs_fixed_dark.png b/docs/0.18.0/components/images/tabs_fixed_dark.png new file mode 100644 index 000000000..1c529c768 Binary files /dev/null and b/docs/0.18.0/components/images/tabs_fixed_dark.png differ diff --git a/docs/0.18.0/components/images/tabs_fixed_light.png b/docs/0.18.0/components/images/tabs_fixed_light.png new file mode 100644 index 000000000..8ceda3637 Binary files /dev/null and b/docs/0.18.0/components/images/tabs_fixed_light.png differ diff --git a/docs/0.18.0/components/images/tabs_scrollable_dark.png b/docs/0.18.0/components/images/tabs_scrollable_dark.png new file mode 100644 index 000000000..e99f89125 Binary files /dev/null and b/docs/0.18.0/components/images/tabs_scrollable_dark.png differ diff --git a/docs/0.18.0/components/images/tabs_scrollable_light.png b/docs/0.18.0/components/images/tabs_scrollable_light.png new file mode 100644 index 000000000..c6496d8db Binary files /dev/null and b/docs/0.18.0/components/images/tabs_scrollable_light.png differ diff --git a/docs/0.18.0/components/images/textfield_character_counter_dark.png b/docs/0.18.0/components/images/textfield_character_counter_dark.png new file mode 100644 index 000000000..9b52ae51b Binary files /dev/null and b/docs/0.18.0/components/images/textfield_character_counter_dark.png differ diff --git a/docs/0.18.0/components/images/textfield_character_counter_light.png b/docs/0.18.0/components/images/textfield_character_counter_light.png new file mode 100644 index 000000000..482d4c207 Binary files /dev/null and b/docs/0.18.0/components/images/textfield_character_counter_light.png differ diff --git a/docs/0.18.0/components/images/textfield_filled_dark.png b/docs/0.18.0/components/images/textfield_filled_dark.png new file mode 100644 index 000000000..38424f0f4 Binary files /dev/null and b/docs/0.18.0/components/images/textfield_filled_dark.png differ diff --git a/docs/0.18.0/components/images/textfield_filled_light.png b/docs/0.18.0/components/images/textfield_filled_light.png new file mode 100644 index 000000000..881386b2a Binary files /dev/null and b/docs/0.18.0/components/images/textfield_filled_light.png differ diff --git a/docs/0.18.0/components/images/textfield_filled_password_dark.png b/docs/0.18.0/components/images/textfield_filled_password_dark.png new file mode 100644 index 000000000..aaffb22ff Binary files /dev/null and b/docs/0.18.0/components/images/textfield_filled_password_dark.png differ diff --git a/docs/0.18.0/components/images/textfield_filled_password_light.png b/docs/0.18.0/components/images/textfield_filled_password_light.png new file mode 100644 index 000000000..8e9b23d4b Binary files /dev/null and b/docs/0.18.0/components/images/textfield_filled_password_light.png differ diff --git a/docs/0.18.0/components/images/textfield_outlined_dark.png b/docs/0.18.0/components/images/textfield_outlined_dark.png new file mode 100644 index 000000000..18ab3afdd Binary files /dev/null and b/docs/0.18.0/components/images/textfield_outlined_dark.png differ diff --git a/docs/0.18.0/components/images/textfield_outlined_light.png b/docs/0.18.0/components/images/textfield_outlined_light.png new file mode 100644 index 000000000..0f971aa24 Binary files /dev/null and b/docs/0.18.0/components/images/textfield_outlined_light.png differ diff --git a/docs/0.18.0/components/images/textfield_outlined_password_dark.png b/docs/0.18.0/components/images/textfield_outlined_password_dark.png new file mode 100644 index 000000000..6f33c5418 Binary files /dev/null and b/docs/0.18.0/components/images/textfield_outlined_password_dark.png differ diff --git a/docs/0.18.0/components/images/textfield_outlined_password_light.png b/docs/0.18.0/components/images/textfield_outlined_password_light.png new file mode 100644 index 000000000..7a6292a76 Binary files /dev/null and b/docs/0.18.0/components/images/textfield_outlined_password_light.png differ diff --git a/docs/0.18.0/guidelines/Colors.md b/docs/0.18.0/guidelines/Colors.md new file mode 100644 index 000000000..f389de153 --- /dev/null +++ b/docs/0.18.0/guidelines/Colors.md @@ -0,0 +1,55 @@ +--- +layout: detail +title: Colors +--- + +--- + +**Page Summary** + +* [Specifications references](#specifications-references) +* [Implementation in Jetpack Compose](#implementation-in-jetpack-compose) + * [Theme colors](#theme-colors) + * [Functional colors](#functional-colors) + * [Other colors from Orange Design System](#other-colors-from-orange-design-system) + +--- + + +## Specifications references + +- [Design System Manager - Colour](https://system.design.orange.com/0c1af118d/p/623630-colour/b/041102) +- [Material Design - The color system](https://material.io/design/color/the-color-system.html#color-usage-and-palettes) + +## Implementation in Jetpack Compose + +### Theme colors + +ODS library provides MaterialTheme colors. You can use these colors by using `MaterialTheme.colors`: + +```kotlin +Text( + text = "Hello world", + color = MaterialTheme.colors.primary +) +``` + +### Functional colors + +Functional colors have been added and can also be used as above: +- `MaterialTheme.colors.functionalPositive` +- `MaterialTheme.colors.functionalInfo` +- `MaterialTheme.colors.functionalAlert` + +Note: These colors will be different depending on whether they are displayed in light or in dark mode. + +### Other colors from Orange Design System + +All the other colors defined in the library can be used directly through their names: + +```kotlin +Text( + text = "Hello world", + color = Pink100 +) +``` diff --git a/docs/0.18.0/guidelines/Colors_docs.md b/docs/0.18.0/guidelines/Colors_docs.md new file mode 100644 index 000000000..1818ea806 --- /dev/null +++ b/docs/0.18.0/guidelines/Colors_docs.md @@ -0,0 +1,4 @@ +--- +layout: main +content_page: Colors.md +--- \ No newline at end of file diff --git a/docs/0.18.0/guidelines/Typography.md b/docs/0.18.0/guidelines/Typography.md new file mode 100644 index 000000000..615c0a64f --- /dev/null +++ b/docs/0.18.0/guidelines/Typography.md @@ -0,0 +1,49 @@ +--- +layout: detail +title: Typography +--- + +--- + +**Page Summary** + +* [Specifications references](#specifications-references) +* [Implementation in Jetpack Compose](#implementation-in-jetpack-compose) + * [TextStyles](#textstyles) + * [OdsText composables](#odstext-composables) + +--- + +## Specifications references + +- [Design System Manager - Typography](https://system.design.orange.com/0c1af118d/p/90d1e5-typography) +- [Material Design - The type system](https://material.io/design/typography/the-type-system.html#type-scale) + +## Implementation in Jetpack Compose + +### TextStyles + +ODS library uses the Material type system. +TextStyles are accessed via `MaterialTheme.typography`. Retrieve the TextStyles like so: + +```kotlin +Text( + text = "Subtitle2 styled", + style = MaterialTheme.typography.subtitle2 +) +``` + +### OdsText composables + +ODS library also provides `OdsText` composables already using specific styles. They are here to simplify the code you write. + +For example, to display a text styled with subtitle2 typo, you can write: + +```kotlin +OdsTextSubtitle2(text = "Subtitle2 styled") +``` + +Optional parameters are: +- a `Modifier` +- an `OdsDisplaySurface` which allow to force elements appearance to be displayed on light or dark surface. + diff --git a/docs/0.18.0/guidelines/Typography_docs.md b/docs/0.18.0/guidelines/Typography_docs.md new file mode 100644 index 000000000..5ff7b782c --- /dev/null +++ b/docs/0.18.0/guidelines/Typography_docs.md @@ -0,0 +1,4 @@ +--- +layout: main +content_page: Typography.md +--- \ No newline at end of file diff --git a/docs/0.18.0/home_content.md b/docs/0.18.0/home_content.md new file mode 100644 index 000000000..155f91bf8 --- /dev/null +++ b/docs/0.18.0/home_content.md @@ -0,0 +1,105 @@ +## Introduction + +Orange is providing a full Design System to build Orange Mobile Application. The objective of the [Orange Design System](https://system.design.orange.com/0c1af118d/p/019ecc-android/) (ODS) is to propose a set of guidelines on how to apply the Orange Brand on mobile applications. The Orange design System also provides a series of components and modules that show in details how to use this in the Orange apps. + +The Orange Design System has been implemented in a code library that provides: +- a Jetpack Compose code library +- a demo app that can be launched to show the components and modules +- this demo app also shows how to use the lib or style existing components + +Using these resources will allow you to create Orange branded applications faster and will inherit all the work that was done to make sure that all presented codes are fully tested with regard to the brand and the accessibility compliance. + +The ODS library is compatible with **Android 5.0 (API level 21) and higher**. + +## Instructions + +### 1. Depend on our library + +Orange Design System for Android is available through [Maven Central Repository](https://mvnrepository.com/artifact/com.orange.ods.android). To use it: + +1. Open the `build.gradle` file for your application. +2. Make sure that the `repositories` section includes Maven Central. For example: + + ```groovy + allprojects { + repositories { + google() + mavenCentral() + } + } + ``` + +3. Add the library to the `dependencies` section: + + ```groovy + dependencies { + // ... + implementation 'com.orange.ods.android:ods-lib:0.18.0' + // ... + } + ``` + +4. (Optional) Add an `OdsThemeConfiguration` implementation library to the `dependencies` section: + + You have the possibility to use the ODS library with another theme than the Orange theme. + + ```groovy + dependencies { + // ... + implementation(project(":theme-innovation-cup")) + // ... + } + ``` + +### 2. Compile your app with Android 11 + +Orange Design System library depends on Material Design library from Google. For this reason, you +will have to install Android Studio 4.0 or higher to build with Android 11, and update your +app's `compileSdkVersion` to `31`. + +### 3. Ensure you are using `AppCompatActivity` + +Using `AppCompatActivity` will ensure that all the components work correctly. If you are unable to +extend from `AppCompatActivity`, update your activities to use +`AppCompatDelegate`. This will enable the `AppCompat` versions of components to be inflated among +other important things. + +### 4. Change your app theme to inherit from a Orange Design theme + +Note that Orange theme supports both light and dark mode. + +#### In Jetpack Compose app + +In the `Manifest.xml` file, add `Theme.Orange.NoActionBar` to your application: +```xml + + + +``` + +Use the `OdsTheme` in your screens which is a Material theme extension for Jetpack Compose applications. +Cause ODS support multi-theme, you should pass the `OrangeThemeConfiguration` as theme configuration to use the Orange theme. +```kotlin +OdsTheme(themeConfiguration = OrangeThemeConfiguration()) { + //... +} +``` + +Note: Use another provided `OdsThemeConfigurationContract` implementation if you want to use a custom theme. For example `InnovationCupThemeConfiguration`. + +#### In XML app + +Update your app theme to inherit from Orange theme, e.g.: +```xml + +``` + +This theme will use the default `Toolbar`. If you want to provide your own `Toolbar` please use: +```xml + +``` diff --git a/docs/0.18.0/index.md b/docs/0.18.0/index.md new file mode 100644 index 000000000..2993026ed --- /dev/null +++ b/docs/0.18.0/index.md @@ -0,0 +1,6 @@ +--- +layout: main +title: Getting started with Orange Design System for Android +--- + +{% include_relative home_content.md %} \ No newline at end of file diff --git a/docs/0.18.0/index_content.md b/docs/0.18.0/index_content.md new file mode 100644 index 000000000..e5908590b --- /dev/null +++ b/docs/0.18.0/index_content.md @@ -0,0 +1,6 @@ +--- +layout: detail +title: Getting started with Orange Design System for Android +--- + +{% include_relative home_content.md %} \ No newline at end of file diff --git a/docs/0.18.0/modules/About.md b/docs/0.18.0/modules/About.md new file mode 100644 index 000000000..6cb3e7127 --- /dev/null +++ b/docs/0.18.0/modules/About.md @@ -0,0 +1,147 @@ +--- +layout: detail +title: About +description: An about screen should be displayed in all Orange applications to display the application name, software version as well as all legal data protection, privacy, and terms of service compliance information. +--- + +The ODS About module displays the following mandatory menu items: *Privacy policy* and *Terms of service*. +It also allows you to add optional predefined menu items: *App news*, *Legal information* and *Rate the app*. +Moreover you can add your own menu items linked to a local file or an URL. + +Share and feedback functionalities are optional but can be added and configured. + +
**On this page** + +* [Specifications references](#specifications-references) +* [Accessibility](#accessibility) +* [Integration](#integration) + * [Jetpack Compose](#jetpack-compose) +* [Configuration](#configuration) + * [OdsAboutConfiguration API](#odsaboutconfiguration-api) + * [App news](#app-news) + +--- + +## Specifications references + +- [Design System Manager - About](https://system.design.orange.com/0c1af118d/p/80ec10-about/b/31ce28) + +## Accessibility + +Please follow [accessibility criteria for development](https://a11y-guidelines.orange.com/en/mobile/android/development/). + +The ODS About module is built to support accessibility criteria and is readable by most screen readers, such as TalkBack. + +## Integration + +![About light](images/about_light.png) + +![About dark](images/about_dark.png) + +### Jetpack Compose + +Follow these steps in order to integrate an ODS About into your app: + +1) Add ODS About graph to your app navigation graph and provide the app `NavController` instance as well as a lambda that returns a configuration for the module (see [Configuration chapter](#configuration)). + +```kotlin +NavHost( + navController = navController, + startDestination = StartRoute, + modifier = Modifier.padding(innerPadding) +) { + //... + odsAboutGraph(navController) { + OdsAboutConfiguration( + appName = "App name", + privacyPolicyMenuItemFile = OdsAboutFileMenuItem.File(R.raw.about_privacy_policy, OdsAboutFileMenuItem.File.Format.Html), + termsOfServiceMenuItemFile = OdsAboutFileMenuItem.File(R.raw.about_terms_of_service, OdsAboutFileMenuItem.File.Format.Html), + ) + } + //... +} +``` + +2) Use the `NavController.navigateToOdsAbout()` extension method when you need to display the previously configured ODS About. + +```kotlin +navController.navigateToOdsAbout() +``` + +## Configuration + +In order to configure the ODS About Module, you need to provide an `OdsAboutConfiguration`. The properties of this class are explained below. + +### OdsAboutConfiguration API + +Property | Default value | Description +-- | -- | -- +`appName: String` | | The name of the application displayed on the main screen of the About module +`privacyPolicyMenuItemFile: OdsAboutFileMenuItem.File` | | The privacy policy menu item file. Note that this menu item is mandatory and you MUST provide the corresponding file in the raw directory to display the privacy policy of your app. +`termsOfServiceMenuItemFile: OdsAboutFileMenuItem.File` | | The terms of service menu item file. Note that this menu item is mandatory and you MUST provide the corresponding file in the raw directory to display the terms of service for your app. +`appIllustrationRes: OdsBanner.Image?` | `R.drawable.il_about` | The illustration resource id. It should be a SVG or PNG resource file, placed in res/drawable directory. It allows to customize the displayed image on the main screen of the About module. If not provided, the default Orange illustration will be displayed. +`appVersion: String?` | `null` | The application version displayed on the main screen of the About module. If null, no version will be displayed. Note that you can use the provided `OdsAboutVersionHelper` to display a version using your package information. +`appDescription: String?` | `null` | The application description displayed on the main screen of the About module. If null, no description will be displayed. +`shareData: OdsAboutShareData?` | `null` | The data to be used to share the app on share button click. If null, no share button will be displayed. +`onFeedbackButtonClick: (() -> Unit)?` | `null ` | The action to be launched on feedback button click. If null, no feedback button will be displayed. +`topAppBarActions: List` | `emptyList()` | The optional actions displayed at the end of the About module TopAppBar. +`topAppBarOverflowMenuActions: List` | `emptyList()` | The optional actions displayed in the overflow menu of the About module TopAppBar. If the list is empty, the overflow menu icon will not be displayed. +`appNewsMenuItemFileRes: Int?` | `null` | App news menu item JSON file resource. Provide it to display an App news menu item linked to this file. Be careful to respect the [App news JSON format](#app-news). +`legalInformationMenuItemFile: OdsAboutFileMenuItem.File?` | `null` | Legal information menu item file. Provide it to display a Legal information menu item linked to this file. +`rateTheAppUrl: String?` | `null` | Rate the app URL. Provide it to display a Rate the app menu item linked to this URL. +`customMenuItems: List` | `emptyList()` | The custom menu items to be displayed on the about main screen. Note that mandatory items will be added to the provided list: Privacy policy (position = 100), Term of services (position = 101), Accessibility (position = 102). +`onScreenChange: ((title: String) -> Unit)?` | `null` | Callback invoked on about module screen change. It can help you managing top app bar title update if necessary. +{:.table} + +### App news + +To add the *App news* functionality in your about screen, you need to provide a JSON file which MUST respect the following schema: + +```json +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "title": "Release set", + "type": "array", + "items": { + "title": "Release", + "type": "object", + "properties": { + "version": { + "description": "The release version", + "type": "string" + }, + "date": { + "description": "The date of the release", + "type": "string" + }, + "news": { + "description": "The release description with the notable elements", + "type": "string" + } + }, + "required": [ + "version", + "date", + "news" + ] + } +} +``` + +Here is an example of a valid *App news* JSON file: + +```json +[ + { + "version": "0.17.0", + "date": "2023-11-08", + "news": "- Several API changes: Bottom navigation, choice chips, sliders, list items and snackbars\n- Include ODS composables parameters description in the documentation" + }, + { + "version": "0.16.0", + "date": "2023-10-11", + "news": "- Several API changes: Cards ans sliders" + } +] +``` + diff --git a/docs/0.18.0/modules/About_docs.md b/docs/0.18.0/modules/About_docs.md new file mode 100644 index 000000000..fd5e7a027 --- /dev/null +++ b/docs/0.18.0/modules/About_docs.md @@ -0,0 +1,4 @@ +--- +layout: main +content_page: About.md +--- \ No newline at end of file diff --git a/docs/0.18.0/modules/images/about_dark.png b/docs/0.18.0/modules/images/about_dark.png new file mode 100644 index 000000000..0102039d3 Binary files /dev/null and b/docs/0.18.0/modules/images/about_dark.png differ diff --git a/docs/0.18.0/modules/images/about_light.png b/docs/0.18.0/modules/images/about_light.png new file mode 100644 index 000000000..dda497b77 Binary files /dev/null and b/docs/0.18.0/modules/images/about_light.png differ diff --git a/docs/_config.yml b/docs/_config.yml index d30dabe82..385abbca2 100644 --- a/docs/_config.yml +++ b/docs/_config.yml @@ -51,3 +51,7 @@ defaults: path: "0.17.0" values: version: "0.17.0" + - scope: + path: "0.18.0" + values: + version: "0.18.0" diff --git a/docs/_config_netlify.yml b/docs/_config_netlify.yml index c9d2fd802..595d7b0a7 100644 --- a/docs/_config_netlify.yml +++ b/docs/_config_netlify.yml @@ -50,3 +50,7 @@ defaults: path: "0.17.0" values: version: "0.17.0" + - scope: + path: "0.18.0" + values: + version: "0.18.0" diff --git a/docs/home_content.md b/docs/home_content.md index b2fd9c785..155f91bf8 100644 --- a/docs/home_content.md +++ b/docs/home_content.md @@ -34,7 +34,7 @@ Orange Design System for Android is available through [Maven Central Repository] ```groovy dependencies { // ... - implementation 'com.orange.ods.android:ods-lib:0.17.0' + implementation 'com.orange.ods.android:ods-lib:0.18.0' // ... } ``` diff --git a/gradle.properties b/gradle.properties index 3cc5faa9f..c866b1238 100644 --- a/gradle.properties +++ b/gradle.properties @@ -29,4 +29,4 @@ android.enableJetifier=true # Kotlin code style for this project: "official" or "obsolete": kotlin.code.style=official kapt.incremental.apt=true -version=0.17.0 \ No newline at end of file +version=0.18.0 \ No newline at end of file