diff --git a/demo/src/main/java/com/orange/ods/demo/ui/components/lists/ComponentList.kt b/demo/src/main/java/com/orange/ods/demo/ui/components/lists/ComponentList.kt index 9d9ce561e..424229288 100644 --- a/demo/src/main/java/com/orange/ods/demo/ui/components/lists/ComponentList.kt +++ b/demo/src/main/java/com/orange/ods/demo/ui/components/lists/ComponentList.kt @@ -10,20 +10,36 @@ package com.orange.ods.demo.ui.components.lists +import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.padding import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.verticalScroll +import androidx.compose.material.Divider import androidx.compose.material.ExperimentalMaterialApi import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier +import androidx.compose.ui.res.dimensionResource +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.res.stringResource +import com.orange.ods.compose.component.list.OdsListItem +import com.orange.ods.compose.component.list.OdsListItemIcon +import com.orange.ods.compose.component.list.OdsListItemWideThumbnail +import com.orange.ods.compose.component.list.OdsListSquaredThumbnail +import com.orange.ods.compose.component.utilities.OdsImageCircleShape +import com.orange.ods.demo.R import com.orange.ods.demo.ui.components.Variant +enum class ListIconType { + None, Default, Avatar, SmallImage, WideImage +} + @ExperimentalMaterialApi @Composable fun ComponentList(variant: Variant) { Column( - modifier = Modifier - .verticalScroll(rememberScrollState()) + modifier = Modifier.verticalScroll(rememberScrollState()) ) { VariantListContent(variant) } @@ -38,4 +54,56 @@ private fun VariantListContent(variant: Variant) { Variant.ListsThreeLines -> ListThreeLinesContent() else -> {} } -} \ No newline at end of file +} + +@ExperimentalMaterialApi +@Composable +fun List( + size: Int, + text: String? = stringResource(id = R.string.component_element_title), + secondaryText: String? = null, + singleLineSecondaryText: Boolean = true, + iconType: ListIconType = ListIconType.None, + trailing: (Int) -> (@Composable () -> Unit)? +) { + Spacer(modifier = Modifier.padding(top = dimensionResource(R.dimen.spacing_s))) + + val modifier = Modifier.clickable {} + repeat(size) { index -> + if (iconType == ListIconType.WideImage) { + OdsListItemWideThumbnail( + modifier = modifier, + text = text.orEmpty(), + secondaryText = secondaryText, + singleLineSecondaryText = singleLineSecondaryText, + thumbnail = painterResource(id = R.drawable.placeholder), + trailing = trailing(index) + ) + } else { + val icon: @Composable (() -> Unit)? = when (iconType) { + ListIconType.None -> null + ListIconType.Default -> { -> OdsListItemIcon(painter = painterResource(id = R.drawable.ic_address_book)) } + ListIconType.Avatar -> { -> OdsImageCircleShape(painter = painterResource(id = R.drawable.placeholder)) } + ListIconType.SmallImage -> { -> OdsListSquaredThumbnail(painter = painterResource(id = R.drawable.placeholder)) } + ListIconType.WideImage -> { -> OdsListSquaredThumbnail(painter = painterResource(id = R.drawable.placeholder)) } + } + OdsListItem( + modifier = modifier, + text = text.orEmpty(), + secondaryText = secondaryText, + singleLineSecondaryText = singleLineSecondaryText, + icon = icon, + trailing = trailing(index) + ) + } + + val startIndent = when (iconType) { + ListIconType.None -> dimensionResource(id = R.dimen.spacing_m) + ListIconType.Default, + ListIconType.Avatar -> dimensionResource(id = R.dimen.avatar_size) + dimensionResource(id = R.dimen.spacing_m).times(2) + ListIconType.SmallImage -> dimensionResource(id = R.dimen.list_squared_thumbnail_size) + dimensionResource(id = R.dimen.spacing_m).times(2) + ListIconType.WideImage -> dimensionResource(id = R.dimen.list_wide_thumbnail_width) + dimensionResource(id = R.dimen.spacing_m) + } + Divider(startIndent = startIndent) + } +} diff --git a/demo/src/main/java/com/orange/ods/demo/ui/components/lists/VariantListOneLine.kt b/demo/src/main/java/com/orange/ods/demo/ui/components/lists/VariantListOneLine.kt index 49693ab45..2a7ba162d 100644 --- a/demo/src/main/java/com/orange/ods/demo/ui/components/lists/VariantListOneLine.kt +++ b/demo/src/main/java/com/orange/ods/demo/ui/components/lists/VariantListOneLine.kt @@ -10,68 +10,67 @@ package com.orange.ods.demo.ui.components.lists -import androidx.compose.foundation.clickable -import androidx.compose.material.Divider +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.padding import androidx.compose.material.ExperimentalMaterialApi +import androidx.compose.material.Icon import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier +import androidx.compose.ui.res.dimensionResource import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource import com.orange.ods.compose.component.control.OdsCheckbox -import com.orange.ods.compose.component.list.OdsListItem -import com.orange.ods.compose.component.list.OdsListItemIcon -import com.orange.ods.compose.component.list.OdsListItemWideThumbnail -import com.orange.ods.compose.component.list.OdsListSquaredThumbnail -import com.orange.ods.compose.component.utilities.OdsImageCircleShape +import com.orange.ods.compose.component.control.OdsSwitch import com.orange.ods.demo.R +import com.orange.ods.demo.ui.utilities.composable.Title @ExperimentalMaterialApi @Composable fun ListOneLineContent() { - var item1Checked by remember { mutableStateOf(false) } - var item2Checked by remember { mutableStateOf(false) } - var item3Checked by remember { mutableStateOf(false) } + Title(textRes = R.string.component_lists_with_label_text, withHorizontalPadding = true) + SingleLineList(text = null, secondaryText = stringResource(id = R.string.component_element_label)) - OdsListItem( - modifier = Modifier.clickable { }, - text = stringResource(id = R.string.component_element_text) - ) - Divider() - OdsListItem( - modifier = Modifier.clickable { }, - text = stringResource(id = R.string.component_element_text), - trailing = { OdsCheckbox(checked = item1Checked, onCheckedChange = { item1Checked = it }) } - ) - Divider() - OdsListItem( - modifier = Modifier.clickable { }, - text = stringResource(id = R.string.component_element_text), - icon = { OdsListItemIcon(painter = painterResource(id = R.drawable.ic_heart)) }, - trailing = { OdsCheckbox(checked = item2Checked, onCheckedChange = { item2Checked = it }) } - ) - Divider() - OdsListItem( - modifier = Modifier.clickable { }, - text = stringResource(id = R.string.component_element_text), - icon = { OdsImageCircleShape(painter = painterResource(id = R.drawable.placeholder)) } - ) - Divider() - OdsListItem( - modifier = Modifier.clickable { }, - text = stringResource(id = R.string.component_element_text), - icon = { OdsListSquaredThumbnail(painter = painterResource(id = R.drawable.placeholder)) }, - isThumbnailIcon = true - ) - Divider() - OdsListItemWideThumbnail( - modifier = Modifier.clickable { }, - text = stringResource(id = R.string.component_element_text), - thumbnail = painterResource(id = R.drawable.placeholder), - trailing = { OdsCheckbox(checked = item3Checked, onCheckedChange = { item3Checked = it }) } - ) - Divider() -} \ No newline at end of file + Title(textRes = R.string.component_lists_with_normal_text, withHorizontalPadding = true) + SingleLineList() + + Title(textRes = R.string.component_lists_with_icon_to_the_left, withHorizontalPadding = true) + SingleLineList(iconType = ListIconType.Default) + + Title(textRes = R.string.component_lists_with_avatar, withHorizontalPadding = true) + SingleLineList(iconType = ListIconType.Avatar) + + Title(textRes = R.string.component_lists_with_small_image, withHorizontalPadding = true) + SingleLineList(iconType = ListIconType.SmallImage) + + Title(textRes = R.string.component_lists_with_larger_image, withHorizontalPadding = true) + SingleLineList(iconType = ListIconType.WideImage) + + Spacer(modifier = Modifier.padding(bottom = dimensionResource(id = R.dimen.ods_screen_vertical_margin))) +} + +@ExperimentalMaterialApi +@Composable +private fun SingleLineList( + text: String? = stringResource(id = R.string.component_element_title), + secondaryText: String? = null, + iconType: ListIconType = ListIconType.None, +) { + List(size = 4, text = text, secondaryText = secondaryText, iconType = iconType) { index -> + if (index > 0) { + @Composable { + var checked by remember { mutableStateOf(true) } + when (index) { + 1 -> OdsCheckbox(checked = checked, onCheckedChange = { checked = it }) + 2 -> OdsSwitch(checked = checked, onCheckedChange = { checked = it }) + 3 -> Icon(painter = painterResource(id = R.drawable.ic_info), contentDescription = null) + } + } + } else { + null + } + } +} diff --git a/demo/src/main/java/com/orange/ods/demo/ui/components/lists/VariantListThreeLines.kt b/demo/src/main/java/com/orange/ods/demo/ui/components/lists/VariantListThreeLines.kt index bea04b71e..ecf5a6e79 100644 --- a/demo/src/main/java/com/orange/ods/demo/ui/components/lists/VariantListThreeLines.kt +++ b/demo/src/main/java/com/orange/ods/demo/ui/components/lists/VariantListThreeLines.kt @@ -10,72 +10,51 @@ package com.orange.ods.demo.ui.components.lists -import androidx.compose.foundation.clickable -import androidx.compose.material.Divider +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.padding import androidx.compose.material.ExperimentalMaterialApi -import androidx.compose.material.Icon +import androidx.compose.material.MaterialTheme import androidx.compose.material.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier -import androidx.compose.ui.res.painterResource +import androidx.compose.ui.res.dimensionResource import androidx.compose.ui.res.stringResource -import com.orange.ods.compose.component.list.OdsListItem -import com.orange.ods.compose.component.list.OdsListItemWideThumbnail -import com.orange.ods.compose.component.list.OdsListSquaredThumbnail -import com.orange.ods.compose.component.utilities.OdsImageCircleShape import com.orange.ods.demo.R +import com.orange.ods.demo.ui.utilities.composable.Title @ExperimentalMaterialApi @Composable fun ListThreeLinesContent() { + Title(textRes = R.string.component_lists_without_icon, withHorizontalPadding = true) + ThreeLineList() - OdsListItem( - modifier = Modifier.clickable { }, - text = stringResource(id = R.string.component_element_text), - secondaryText = stringResource(id = R.string.component_element_secondary_text_value), - singleLineSecondaryText = false, - trailing = { Text(stringResource(id = R.string.component_element_caption)) } - ) - Divider() - OdsListItem( - modifier = Modifier.clickable { }, - text = stringResource(id = R.string.component_element_text), - overlineText = stringResource(id = R.string.component_element_overline), - secondaryText = stringResource(id = R.string.component_element_secondary_text_value) - ) - Divider() - OdsListItem( - modifier = Modifier.clickable { }, - text = stringResource(id = R.string.component_element_text), - secondaryText = stringResource(id = R.string.component_element_secondary_text_value), - singleLineSecondaryText = false, - icon = { Icon(painter = painterResource(id = R.drawable.ic_heart), contentDescription = null) } - ) - Divider() - OdsListItem( - modifier = Modifier.clickable { }, - text = stringResource(id = R.string.component_element_text), - secondaryText = stringResource(id = R.string.component_element_secondary_text_value), - singleLineSecondaryText = false, - icon = { OdsImageCircleShape(painter = painterResource(id = R.drawable.placeholder), contentDescription = null) }, - trailing = { Text(text = stringResource(id = R.string.component_element_caption)) } - ) - Divider() - OdsListItem( - modifier = Modifier.clickable { }, - text = stringResource(id = R.string.component_element_text), - secondaryText = stringResource(id = R.string.component_element_secondary_text_value), - singleLineSecondaryText = false, - icon = { OdsListSquaredThumbnail(painter = painterResource(id = R.drawable.placeholder)) } - ) - Divider() - OdsListItemWideThumbnail( - modifier = Modifier.clickable { }, - text = stringResource(id = R.string.component_element_text), - secondaryText = stringResource(id = R.string.component_element_secondary_text_value), - singleLineSecondaryText = false, - thumbnail = painterResource(id = R.drawable.placeholder), - trailing = { Text(text = stringResource(id = R.string.component_element_caption)) } - ) - Divider() -} \ No newline at end of file + Title(textRes = R.string.component_lists_with_icon_to_the_left, withHorizontalPadding = true) + ThreeLineList(iconType = ListIconType.Default) + + Title(textRes = R.string.component_lists_with_avatar, withHorizontalPadding = true) + ThreeLineList(iconType = ListIconType.Avatar) + + Title(textRes = R.string.component_lists_with_small_image, withHorizontalPadding = true) + ThreeLineList(iconType = ListIconType.SmallImage) + + Title(textRes = R.string.component_lists_with_larger_image, withHorizontalPadding = true) + ThreeLineList(iconType = ListIconType.WideImage) + + Spacer(modifier = Modifier.padding(bottom = dimensionResource(id = R.dimen.ods_screen_vertical_margin))) +} + +@ExperimentalMaterialApi +@Composable +private fun ThreeLineList(iconType: ListIconType = ListIconType.None) { + val text = stringResource(id = R.string.component_element_title) + val secondaryText = stringResource(id = R.string.component_element_secondary_text_value) + List(size = 2, text = text, secondaryText = secondaryText, singleLineSecondaryText = false, iconType = iconType) { index -> + if (index == 0) { + @Composable { + Text(text = stringResource(id = R.string.component_element_caption), style = MaterialTheme.typography.caption) + } + } else { + null + } + } +} diff --git a/demo/src/main/java/com/orange/ods/demo/ui/components/lists/VariantListTwoLines.kt b/demo/src/main/java/com/orange/ods/demo/ui/components/lists/VariantListTwoLines.kt index c5780e758..706043512 100644 --- a/demo/src/main/java/com/orange/ods/demo/ui/components/lists/VariantListTwoLines.kt +++ b/demo/src/main/java/com/orange/ods/demo/ui/components/lists/VariantListTwoLines.kt @@ -10,68 +10,62 @@ package com.orange.ods.demo.ui.components.lists -import androidx.compose.foundation.clickable -import androidx.compose.material.Divider +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.padding import androidx.compose.material.ExperimentalMaterialApi import androidx.compose.material.Icon import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier +import androidx.compose.ui.res.dimensionResource import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource -import com.orange.ods.compose.component.list.OdsListItem -import com.orange.ods.compose.component.list.OdsListItemIcon -import com.orange.ods.compose.component.list.OdsListItemWideThumbnail -import com.orange.ods.compose.component.utilities.OdsImageCircleShape +import com.orange.ods.compose.component.control.OdsCheckbox +import com.orange.ods.compose.component.control.OdsSwitch import com.orange.ods.demo.R +import com.orange.ods.demo.ui.utilities.composable.Title @ExperimentalMaterialApi @Composable fun ListTwoLinesContent() { + Title(textRes = R.string.component_lists_without_icon, withHorizontalPadding = true) + TwoLineList() - OdsListItem( - modifier = Modifier.clickable { }, - text = stringResource(id = R.string.component_element_text), - overlineText = stringResource(id = R.string.component_element_overline) - ) - Divider() - OdsListItem( - modifier = Modifier.clickable { }, - text = stringResource(id = R.string.component_element_text), - secondaryText = stringResource(id = R.string.component_element_secondary_text), - trailing = { ListItemTrailingIcon() }) - Divider() - OdsListItem( - modifier = Modifier.clickable { }, - text = stringResource(id = R.string.component_element_text), - secondaryText = stringResource(id = R.string.component_element_secondary_text), - icon = { Icon(painter = painterResource(id = R.drawable.ic_heart), contentDescription = "") }, - trailing = { ListItemTrailingIcon() }) - Divider() - OdsListItem( - modifier = Modifier.clickable { }, - text = stringResource(id = R.string.component_element_text), - secondaryText = stringResource(id = R.string.component_element_secondary_text), - icon = { OdsListItemIcon(painter = painterResource(id = R.drawable.ic_heart)) }, - trailing = { ListItemTrailingIcon() }) - Divider() - OdsListItem( - modifier = Modifier.clickable { }, - text = stringResource(id = R.string.component_element_text), - secondaryText = stringResource(id = R.string.component_element_secondary_text), - icon = { OdsImageCircleShape(painter = painterResource(id = R.drawable.placeholder)) }, - trailing = { ListItemTrailingIcon() }) - Divider() - OdsListItemWideThumbnail( - modifier = Modifier.clickable { }, - text = stringResource(id = R.string.component_element_text), - secondaryText = stringResource(id = R.string.component_element_secondary_text), - thumbnail = painterResource(id = R.drawable.placeholder), - trailing = { ListItemTrailingIcon() } - ) - Divider() + Title(textRes = R.string.component_lists_with_icon_to_the_left, withHorizontalPadding = true) + TwoLineList(iconType = ListIconType.Default) + + Title(textRes = R.string.component_lists_with_avatar, withHorizontalPadding = true) + TwoLineList(iconType = ListIconType.Avatar) + + Title(textRes = R.string.component_lists_with_small_image, withHorizontalPadding = true) + TwoLineList(iconType = ListIconType.SmallImage) + + Title(textRes = R.string.component_lists_with_larger_image, withHorizontalPadding = true) + TwoLineList(iconType = ListIconType.WideImage) + + Spacer(modifier = Modifier.padding(bottom = dimensionResource(id = R.dimen.ods_screen_vertical_margin))) } +@ExperimentalMaterialApi @Composable -private fun ListItemTrailingIcon() { - Icon(painter = painterResource(id = R.drawable.ic_drag_handle), contentDescription = "Drag item") -} \ No newline at end of file +private fun TwoLineList(iconType: ListIconType = ListIconType.None) { + val text = stringResource(id = R.string.component_element_title) + val secondaryText = stringResource(id = R.string.component_element_subtitle) + List(size = 4, text = text, secondaryText = secondaryText, iconType = iconType) { index -> + if (index > 0) { + @Composable { + var checked by remember { mutableStateOf(true) } + when (index) { + 1 -> OdsCheckbox(checked = checked, onCheckedChange = { checked = it }) + 2 -> OdsSwitch(checked = checked, onCheckedChange = { checked = it }) + 3 -> Icon(painter = painterResource(id = R.drawable.ic_info), contentDescription = null) + } + } + } else { + null + } + } +} diff --git a/demo/src/main/res/drawable/ic_address_book.xml b/demo/src/main/res/drawable/ic_address_book.xml new file mode 100644 index 000000000..b64489fa8 --- /dev/null +++ b/demo/src/main/res/drawable/ic_address_book.xml @@ -0,0 +1,4 @@ + + + diff --git a/demo/src/main/res/drawable/ic_drag_handle.xml b/demo/src/main/res/drawable/ic_drag_handle.xml deleted file mode 100644 index 7f4a946bc..000000000 --- a/demo/src/main/res/drawable/ic_drag_handle.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/demo/src/main/res/values/strings.xml b/demo/src/main/res/values/strings.xml index 39a8e494a..1f9dc8939 100644 --- a/demo/src/main/res/values/strings.xml +++ b/demo/src/main/res/values/strings.xml @@ -167,6 +167,13 @@ One-line list Two-line list Three-line list + With label text + With normal text + No icon/image + With icon to the left + With avatar + With small image + With larger image Text fields diff --git a/lib/build.gradle.kts b/lib/build.gradle.kts index 0cd8469d0..c75261958 100644 --- a/lib/build.gradle.kts +++ b/lib/build.gradle.kts @@ -43,7 +43,11 @@ android { targetCompatibility = JavaVersion.VERSION_11 } - kotlinOptions.jvmTarget = "11" + kotlinOptions { + jvmTarget = "11" + allWarningsAsErrors = true + freeCompilerArgs = freeCompilerArgs + "-opt-in=kotlin.RequiresOptIn" + } buildFeatures { compose = true diff --git a/lib/src/main/java/com/orange/ods/compose/component/list/OdsListItem.kt b/lib/src/main/java/com/orange/ods/compose/component/list/OdsListItem.kt index afe83afef..db5de8832 100644 --- a/lib/src/main/java/com/orange/ods/compose/component/list/OdsListItem.kt +++ b/lib/src/main/java/com/orange/ods/compose/component/list/OdsListItem.kt @@ -36,6 +36,7 @@ import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.Dp import com.orange.ods.R import com.orange.ods.compose.text.OdsTextSubtitle1 +import com.orange.ods.utilities.extension.isNotNullOrBlank /** * ODS Lists. @@ -78,8 +79,9 @@ fun OdsListItem( val requiredHeight = computeRequiredHeight( hasIcon = icon != null, isThumbnailIcon = isThumbnailIcon, - hasOverline = overlineText != null, - hasSecondaryText = secondaryText != null, + hasOverline = overlineText.isNotNullOrBlank(), + hasText = text.isNotBlank(), + hasSecondaryText = secondaryText.isNotNullOrBlank(), singleLineSecondaryText = singleLineSecondaryText ) val secondaryTextLinesNumber = if (singleLineSecondaryText || (overlineText != null && secondaryText != null)) 1 else 2 @@ -88,16 +90,18 @@ fun OdsListItem( .fillMaxWidth() .requiredHeight(requiredHeight), icon = icon, - secondaryText = if (secondaryText != null) { + secondaryText = if (secondaryText.isNotNullOrBlank()) { { Text(text = secondaryText, style = MaterialTheme.typography.body2, maxLines = secondaryTextLinesNumber, overflow = TextOverflow.Ellipsis) } } else null, singleLineSecondaryText = singleLineSecondaryText, - overlineText = if (overlineText != null) { + overlineText = if (overlineText.isNotNullOrBlank()) { { Text(text = overlineText, style = MaterialTheme.typography.overline, color = MaterialTheme.colors.onSurface.copy(alpha = 0.6f)) } } else null, trailing = trailing, text = { - OdsTextSubtitle1(text = text) + if (text.isNotBlank()) { + OdsTextSubtitle1(text = text) + } } ) } @@ -196,10 +200,17 @@ fun OdsListSquaredThumbnail(painter: Painter, contentDescription: String? = null * It allows to be able to center vertically elements in the item. */ @Composable -internal fun computeRequiredHeight(hasIcon: Boolean, isThumbnailIcon: Boolean, hasOverline: Boolean, hasSecondaryText: Boolean, singleLineSecondaryText: Boolean): Dp { +internal fun computeRequiredHeight( + hasIcon: Boolean, + isThumbnailIcon: Boolean, + hasOverline: Boolean, + hasText: Boolean, + hasSecondaryText: Boolean, + singleLineSecondaryText: Boolean +): Dp { val heightRes = when { // single-line - !hasOverline && !hasSecondaryText -> when { + !hasOverline && (!hasSecondaryText || !hasText) -> when { hasIcon && !isThumbnailIcon -> R.dimen.list_single_line_with_icon_item_height isThumbnailIcon -> R.dimen.list_single_line_with_thumbnail_item_height else -> R.dimen.list_single_line_item_height diff --git a/lib/src/main/java/com/orange/ods/utilities/extension/StringExt.kt b/lib/src/main/java/com/orange/ods/utilities/extension/StringExt.kt new file mode 100644 index 000000000..4a79584dc --- /dev/null +++ b/lib/src/main/java/com/orange/ods/utilities/extension/StringExt.kt @@ -0,0 +1,23 @@ +/* + * + * Copyright 2021 Orange + * + * Use of this source code is governed by an MIT-style + * license that can be found in the LICENSE file or at + * https://opensource.org/licenses/MIT. + * / + */ + +package com.orange.ods.utilities.extension + +import kotlin.contracts.ExperimentalContracts +import kotlin.contracts.contract + +@OptIn(ExperimentalContracts::class) +fun CharSequence?.isNotNullOrBlank(): Boolean { + contract { + returns(true) implies (this@isNotNullOrBlank != null) + } + + return !isNullOrBlank() +}