Skip to content

Commit

Permalink
(All) Fix setup for buttons and allow other data types #25
Browse files Browse the repository at this point in the history
  • Loading branch information
maxkeppeler committed Feb 7, 2023
1 parent ba31077 commit e0a5b3c
Show file tree
Hide file tree
Showing 15 changed files with 171 additions and 81 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ package com.maxkeppeler.sheets.calendar.models
import android.util.Range
import com.maxkeppeker.sheets.core.models.base.BaseSelection
import com.maxkeppeker.sheets.core.models.base.SelectionButton
import com.maxkeppeker.sheets.core.utils.BaseConstants
import java.time.LocalDate

/**
Expand All @@ -42,9 +43,9 @@ sealed class CalendarSelection : BaseSelection() {
override val withButtonView: Boolean = true,
override val extraButton: SelectionButton? = null,
override val onExtraButtonClick: (() -> Unit)? = null,
override val negativeButton: SelectionButton? = null,
override val negativeButton: SelectionButton? = BaseConstants.DEFAULT_NEGATIVE_BUTTON,
override val onNegativeClick: (() -> Unit)? = null,
override val positiveButton: SelectionButton? = null,
override val positiveButton: SelectionButton = BaseConstants.DEFAULT_POSITIVE_BUTTON,
val selectedDate: LocalDate? = null,
val onSelectDate: (date: LocalDate) -> Unit
) : CalendarSelection()
Expand All @@ -62,9 +63,9 @@ sealed class CalendarSelection : BaseSelection() {
class Dates(
override val extraButton: SelectionButton? = null,
override val onExtraButtonClick: (() -> Unit)? = null,
override val negativeButton: SelectionButton? = null,
override val negativeButton: SelectionButton? = BaseConstants.DEFAULT_NEGATIVE_BUTTON,
override val onNegativeClick: (() -> Unit)? = null,
override val positiveButton: SelectionButton? = null,
override val positiveButton: SelectionButton = BaseConstants.DEFAULT_POSITIVE_BUTTON,
val selectedDates: List<LocalDate>? = null,
val onSelectDates: (dates: List<LocalDate>) -> Unit
) : CalendarSelection()
Expand All @@ -84,9 +85,9 @@ sealed class CalendarSelection : BaseSelection() {
override val withButtonView: Boolean = true,
override val extraButton: SelectionButton? = null,
override val onExtraButtonClick: (() -> Unit)? = null,
override val negativeButton: SelectionButton? = null,
override val negativeButton: SelectionButton? = BaseConstants.DEFAULT_NEGATIVE_BUTTON,
override val onNegativeClick: (() -> Unit)? = null,
override val positiveButton: SelectionButton? = null,
override val positiveButton: SelectionButton = BaseConstants.DEFAULT_POSITIVE_BUTTON,
val selectedRange: Range<LocalDate>? = null,
val onSelectRange: (startDate: LocalDate, endDate: LocalDate) -> Unit
) : CalendarSelection()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ package com.maxkeppeler.sheets.clock.models

import com.maxkeppeker.sheets.core.models.base.BaseSelection
import com.maxkeppeker.sheets.core.models.base.SelectionButton
import com.maxkeppeker.sheets.core.utils.BaseConstants

/**
* The selection configuration for the clock dialog.
Expand All @@ -39,9 +40,9 @@ sealed class ClockSelection : BaseSelection() {
override val withButtonView: Boolean = false,
override val extraButton: SelectionButton? = null,
override val onExtraButtonClick: (() -> Unit)? = null,
override val negativeButton: SelectionButton? = null,
override val negativeButton: SelectionButton? = BaseConstants.DEFAULT_NEGATIVE_BUTTON,
override val onNegativeClick: (() -> Unit)? = null,
override val positiveButton: SelectionButton? = null,
override val positiveButton: SelectionButton = BaseConstants.DEFAULT_POSITIVE_BUTTON,
val onPositiveClick: (hours: Int, minutes: Int) -> Unit,
) : ClockSelection()

Expand All @@ -59,9 +60,9 @@ sealed class ClockSelection : BaseSelection() {
override val withButtonView: Boolean = false,
override val extraButton: SelectionButton? = null,
override val onExtraButtonClick: (() -> Unit)? = null,
override val negativeButton: SelectionButton? = null,
override val negativeButton: SelectionButton? = BaseConstants.DEFAULT_NEGATIVE_BUTTON,
override val onNegativeClick: (() -> Unit)? = null,
override val positiveButton: SelectionButton? = null,
override val positiveButton: SelectionButton = BaseConstants.DEFAULT_POSITIVE_BUTTON,
val onPositiveClick: (hours: Int, minutes: Int, seconds: Int) -> Unit,
) : ClockSelection()
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,9 @@

package com.maxkeppeler.sheets.color.models

import com.maxkeppeker.sheets.core.models.base.SelectionButton
import com.maxkeppeker.sheets.core.models.base.BaseSelection
import com.maxkeppeker.sheets.core.models.base.SelectionButton
import com.maxkeppeker.sheets.core.utils.BaseConstants

/**
* The selection configuration for the color dialog.
Expand All @@ -36,9 +37,9 @@ data class ColorSelection(
override val withButtonView: Boolean = true,
override val extraButton: SelectionButton? = null,
override val onExtraButtonClick: (() -> Unit)? = null,
override val negativeButton: SelectionButton? = null,
override val negativeButton: SelectionButton? = BaseConstants.DEFAULT_NEGATIVE_BUTTON,
override val onNegativeClick: (() -> Unit)? = null,
override val positiveButton: SelectionButton? = null,
override val positiveButton: SelectionButton = BaseConstants.DEFAULT_POSITIVE_BUTTON,
val onSelectNone: (() -> Unit)? = null,
val onSelectColor: (color: Int) -> Unit,
) : BaseSelection()
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ package com.maxkeppeker.sheets.core.models

import com.maxkeppeker.sheets.core.models.base.BaseSelection
import com.maxkeppeker.sheets.core.models.base.SelectionButton
import com.maxkeppeker.sheets.core.utils.BaseConstants

/**
* The selection configuration for the core dialog.
Expand All @@ -27,8 +28,8 @@ class CoreSelection(
override val withButtonView: Boolean = true,
override val extraButton: SelectionButton? = null,
override val onExtraButtonClick: (() -> Unit)? = null,
override val negativeButton: SelectionButton? = null,
override val negativeButton: SelectionButton? = BaseConstants.DEFAULT_NEGATIVE_BUTTON,
override val onNegativeClick: (() -> Unit)? = null,
override val positiveButton: SelectionButton? = null,
override val positiveButton: SelectionButton = BaseConstants.DEFAULT_POSITIVE_BUTTON,
val onPositiveClick: (() -> Unit)? = null,
) : BaseSelection()
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,16 @@
*/
package com.maxkeppeker.sheets.core.models.base

import com.maxkeppeker.sheets.core.utils.BaseConstants

/**
* Base selection for dialog-specific selections.
*/
abstract class BaseSelection {
open val withButtonView: Boolean = true
open val extraButton: SelectionButton? = null
open val onExtraButtonClick: (() -> Unit)? = null
open val negativeButton: SelectionButton? = null
open val negativeButton: SelectionButton? = BaseConstants.DEFAULT_NEGATIVE_BUTTON
open val onNegativeClick: (() -> Unit)? = null
open val positiveButton: SelectionButton? = null
open val positiveButton: SelectionButton = BaseConstants.DEFAULT_POSITIVE_BUTTON
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,77 @@
*/
package com.maxkeppeker.sheets.core.models.base

import androidx.annotation.StringRes
import androidx.compose.ui.text.AnnotatedString

/**
* An icon from various sources alongside an optional contentDescription and tint.
* @param text Text used for the button
* @param icon Icon used for the button, or none if null
* @param type Style used for the button
* Represents a button with text and an optional icon.
*/
data class SelectionButton(
val text: String,
val icon: IconSource? = null,
val type: ButtonStyle = ButtonStyle.TEXT
)
open class SelectionButton {

internal val text: String?
@StringRes
internal val textRes: Int?
val annotatedString: AnnotatedString?
internal val icon: IconSource?
internal val type: ButtonStyle

/**
* Creates a new instance of `SelectionButton` with the given text, icon and type.
*
* @param text The text to be displayed on the button.
* @param icon The icon to be displayed on the button. Can be `null`.
* @param type The style of the button. Default value is `ButtonStyle.TEXT`.
*/
constructor(
text: String,
icon: IconSource? = null,
type: ButtonStyle = ButtonStyle.TEXT
) {
this.text = text
this.textRes = null
this.annotatedString = null
this.icon = icon
this.type = type
}

/**
* Creates a new instance of `SelectionButton` with the given string resource identifier, icon and type.
*
* @param textRes The string resource identifier to be displayed on the button.
* @param icon The icon to be displayed on the button. Can be `null`.
* @param type The style of the button. Default value is `ButtonStyle.TEXT`.
*/
constructor(
@StringRes textRes: Int,
icon: IconSource? = null,
type: ButtonStyle = ButtonStyle.TEXT
) {
this.textRes = textRes
this.text = null
this.annotatedString = null
this.icon = icon
this.type = type
}

/**
* Creates a new instance of `SelectionButton` with the given `AnnotatedString`, icon and type.
*
* @param annotatedString The annotated string to be displayed on the button.
* @param icon The icon to be displayed on the button. Can be `null`.
* @param type The style of the button. Default value is `ButtonStyle.TEXT`.
*/
constructor(
annotatedString: AnnotatedString,
icon: IconSource? = null,
type: ButtonStyle = ButtonStyle.TEXT
) {
this.annotatedString = annotatedString
this.textRes = null
this.text = null
this.icon = icon
this.type = type
}
}


Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@ package com.maxkeppeker.sheets.core.utils

import androidx.compose.ui.unit.dp
import com.maxkeppeker.sheets.core.icons.LibIcons
import com.maxkeppeker.sheets.core.models.base.ButtonStyle
import com.maxkeppeker.sheets.core.models.base.LibOrientation
import com.maxkeppeker.sheets.core.models.base.SelectionButton

/**
* Defines module-wide constants.
Expand All @@ -35,4 +37,15 @@ object BaseConstants {
const val KEYBOARD_RATIO = 0.8f

val DYNAMIC_SIZE_MAX = 200.dp

val DEFAULT_NEGATIVE_BUTTON = SelectionButton(
textRes = android.R.string.cancel,
type = ButtonStyle.TEXT
)

val DEFAULT_POSITIVE_BUTTON =
SelectionButton(
textRes = android.R.string.ok,
type = ButtonStyle.TEXT
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -55,59 +55,58 @@ fun ButtonsComponent(
horizontalArrangement = Arrangement.End
) {

selection.extraButton?.let {
selection.extraButton?.let { extraButton ->
SelectionButtonComponent(
modifier = Modifier
.wrapContentWidth(),
button = selection.extraButton,
button = extraButton,
onClick = { selection.onExtraButtonClick?.invoke() },
testTag = TestTags.BUTTON_EXTRA,
)
Spacer(modifier = Modifier.weight(1f))
}

SelectionButtonComponent(
modifier = Modifier
.wrapContentWidth()
.padding(horizontal = dimensionResource(id = R.dimen.scd_normal_100)),
button = selection.negativeButton,
onClick = { onNegative(); onClose() },
defaultText = stringResource(id = R.string.cancel),
testTag = TestTags.BUTTON_NEGATIVE,
)
Spacer(modifier = Modifier.weight(1f))

selection.negativeButton?.let { negativeButton ->
SelectionButtonComponent(
modifier = Modifier
.wrapContentWidth()
.padding(horizontal = dimensionResource(id = R.dimen.scd_normal_100)),
button = negativeButton,
onClick = { onNegative(); onClose() },
testTag = TestTags.BUTTON_NEGATIVE,
)
}

SelectionButtonComponent(
modifier = Modifier
.wrapContentWidth(),
button = selection.positiveButton,
onClick = { onPositive(); onClose() },
enabled = onPositiveValid,
defaultText = stringResource(id = R.string.ok),
testTag = TestTags.BUTTON_POSITIVE,
)
}
}

/**
* A helper component to setup the right button.
* A helper component to setup a button.
* @param modifier The modifier that is applied to the button.
* @param button The data that is used to build this button.
* @param onClick Listener that is invoked when the button is clicked.
* @param enabled Controls the enabled state of this button. When false, this component will not respond to user input, and it will appear visually disabled and disabled to accessibility services.
* @param defaultText The text that is used by default in the button data does not contain a text.
* @param testTag The text that is used for the test tag.
*/
@Composable
private fun SelectionButtonComponent(
modifier: Modifier,
button: SelectionButton?,
button: SelectionButton,
onClick: () -> Unit,
enabled: Boolean = true,
defaultText: String = "",
testTag: String
) {
val buttonContent: @Composable RowScope.() -> Unit = {
button?.icon?.let { icon ->
button.icon?.let { icon ->
IconComponent(
modifier = Modifier
.testTags(testTag, TestTags.BUTTON_ICON)
Expand All @@ -116,42 +115,44 @@ private fun SelectionButtonComponent(
)
Spacer(modifier = Modifier.width(dimensionResource(id = R.dimen.scd_small_100)))
}
Text(text = button?.text ?: defaultText)

when {
button.text != null -> Text(text = button.text)
button.textRes != null -> Text(text = stringResource(button.textRes))
button.annotatedString != null -> Text(text = button.annotatedString)
else -> throw IllegalStateException("Please correct your setup. The text is missing for a button.")
}
}

when {
button == null || button.type == ButtonStyle.TEXT -> {
when (button.type) {
ButtonStyle.TEXT ->
TextButton(
modifier = modifier.testTag(testTag),
onClick = onClick,
enabled = enabled,
content = buttonContent
)
}
button.type == ButtonStyle.FILLED -> {
ButtonStyle.FILLED ->
Button(
modifier = modifier.testTag(testTag),
onClick = onClick,
enabled = enabled,
content = buttonContent
)
}
button.type == ButtonStyle.ELEVATED -> {
ButtonStyle.ELEVATED ->
ElevatedButton(
modifier = modifier.testTag(testTag),
onClick = onClick,
enabled = enabled,
content = buttonContent
)
}
button.type == ButtonStyle.OUTLINED -> {
ButtonStyle.OUTLINED ->
OutlinedButton(
modifier = modifier.testTag(testTag),
onClick = onClick,
enabled = enabled,
content = buttonContent
)
}
}

}
Loading

0 comments on commit e0a5b3c

Please sign in to comment.