Skip to content

Commit

Permalink
[iOS] Add elevation support to container color of Bottom Sheet and Da…
Browse files Browse the repository at this point in the history
…te Picker
  • Loading branch information
MohamedRejeb committed Aug 28, 2024
1 parent e1f0c55 commit 568ea6b
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 17 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,14 @@ import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.material3.DatePickerColors
import androidx.compose.material3.DatePickerFormatter
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.LocalAbsoluteTonalElevation
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.interop.UIKitView
import com.mohamedrejeb.calf.core.InternalCalfApi
import com.mohamedrejeb.calf.ui.utils.surfaceColorAtElevation
import kotlinx.cinterop.ExperimentalForeignApi
import platform.UIKit.UIDatePicker

Expand All @@ -33,7 +35,6 @@ actual fun AdaptiveDatePicker(
val datePickerManager = remember {
DatePickerManager(
initialSelectedDateMillis = state.selectedDateMillis,
colors = colors,
datePicker = datePicker,
displayMode = state.initialUIKitDisplayMode,
onSelectionChanged = { dateMillis ->
Expand All @@ -42,8 +43,20 @@ actual fun AdaptiveDatePicker(
)
}

LaunchedEffect(colors) {
datePickerManager.applyColors(colors)
val absoluteElevation = LocalAbsoluteTonalElevation.current

val containerColorAtElevation =
surfaceColorAtElevation(
color = colors.containerColor,
elevation = absoluteElevation
)

LaunchedEffect(colors, containerColorAtElevation) {
datePickerManager.applyColors(
containerColor = containerColorAtElevation,
dayContentColor = colors.dayContentColor,
selectedDayContainerColor = colors.selectedDayContainerColor,
)
}

Box(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
package com.mohamedrejeb.calf.ui.datepicker

import androidx.compose.material3.DatePickerColors
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableFloatStateOf
import androidx.compose.runtime.setValue
import androidx.compose.ui.graphics.Color
import com.mohamedrejeb.calf.core.InternalCalfApi
import com.mohamedrejeb.calf.ui.utils.applyTheme
import com.mohamedrejeb.calf.ui.utils.datetime.KotlinxDatetimeCalendarModel
Expand All @@ -16,18 +15,21 @@ import kotlinx.cinterop.ObjCAction
import kotlinx.cinterop.useContents
import kotlinx.datetime.TimeZone
import kotlinx.datetime.toNSTimeZone
import platform.Foundation.*
import platform.UIKit.*
import platform.Foundation.NSDate
import platform.Foundation.dateWithTimeIntervalSince1970
import platform.Foundation.timeIntervalSince1970
import platform.UIKit.UIControlEventValueChanged
import platform.UIKit.UIDatePicker
import platform.UIKit.UIDatePickerMode
import platform.UIKit.UIDatePickerStyle
import platform.objc.sel_registerName

@OptIn(
ExperimentalForeignApi::class,
ExperimentalMaterial3Api::class
)
@InternalCalfApi
class DatePickerManager @OptIn(ExperimentalMaterial3Api::class) internal constructor(
class DatePickerManager internal constructor(
initialSelectedDateMillis: Long?,
colors: DatePickerColors,
private val datePicker: UIDatePicker,
displayMode: UIKitDisplayMode,
private val onSelectionChanged: (dateMillis: Long?) -> Unit,
Expand Down Expand Up @@ -83,13 +85,16 @@ class DatePickerManager @OptIn(ExperimentalMaterial3Api::class) internal constru
datePicker.frame.useContents {
aspectRatio = this.size.width.toFloat() / this.size.height.toFloat()
}
applyColors(colors)
}

internal fun applyColors(colors: DatePickerColors) {
applyTheme(isDark = !isDark(colors.dayContentColor))
datePicker.tintColor = colors.selectedDayContainerColor.toUIColor()
datePicker.backgroundColor = colors.containerColor.toUIColor()
internal fun applyColors(
containerColor: Color,
dayContentColor: Color,
selectedDayContainerColor: Color,
) {
applyTheme(isDark = !isDark(dayContentColor))
datePicker.tintColor = selectedDayContainerColor.toUIColor()
datePicker.backgroundColor = containerColor.toUIColor()
}

internal fun applyTheme(isDark: Boolean) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import androidx.compose.foundation.layout.ColumnScope
import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.LocalAbsoluteTonalElevation
import androidx.compose.material3.SheetValue
import androidx.compose.material3.Surface
import androidx.compose.runtime.Composable
Expand All @@ -24,6 +25,7 @@ import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.Shape
import androidx.compose.ui.interop.LocalUIViewController
import androidx.compose.ui.unit.Dp
import com.mohamedrejeb.calf.ui.utils.surfaceColorAtElevation

@OptIn(ExperimentalMaterial3Api::class)
@Composable
Expand Down Expand Up @@ -53,6 +55,14 @@ actual fun AdaptiveBottomSheet(

val isDark = isSystemInDarkTheme()

val absoluteElevation = LocalAbsoluteTonalElevation.current + tonalElevation

val containerColorAtElevation =
surfaceColorAtElevation(
color = containerColor,
elevation = absoluteElevation
)

val sheetManager = remember(currentUIViewController) {
BottomSheetManager(
parentUIViewController = currentUIViewController,
Expand Down Expand Up @@ -108,8 +118,8 @@ actual fun AdaptiveBottomSheet(
sheetManager.applyTheme(isDark)
}

LaunchedEffect(containerColor) {
sheetManager.applyContainerColor(containerColor)
LaunchedEffect(containerColorAtElevation) {
sheetManager.applyContainerColor(containerColorAtElevation)
}

LaunchedEffect(adaptiveSheetState.sheetValue) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
package com.mohamedrejeb.calf.ui.utils

import androidx.compose.material3.ColorScheme
import androidx.compose.material3.LocalTonalElevationEnabled
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.surfaceColorAtElevation
import androidx.compose.runtime.Composable
import androidx.compose.runtime.ReadOnlyComposable
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.Dp
import platform.UIKit.UIColor

fun Color.toUIColor(): UIColor {
Expand All @@ -10,4 +17,19 @@ fun Color.toUIColor(): UIColor {
blue = this.blue.toDouble(),
alpha = this.alpha.toDouble(),
)
}

@Composable
internal fun surfaceColorAtElevation(color: Color, elevation: Dp): Color =
MaterialTheme.colorScheme.applyTonalElevation(color, elevation)

@Composable
@ReadOnlyComposable
internal fun ColorScheme.applyTonalElevation(backgroundColor: Color, elevation: Dp): Color {
val tonalElevationEnabled = LocalTonalElevationEnabled.current
return if (backgroundColor == surface && tonalElevationEnabled) {
surfaceColorAtElevation(elevation)
} else {
backgroundColor
}
}

0 comments on commit 568ea6b

Please sign in to comment.