Skip to content

Commit 16926aa

Browse files
committed
library: TopAppBar: Set windowInsetsPadding in layout
1 parent 7191d4d commit 16926aa

File tree

1 file changed

+79
-56
lines changed
  • miuix/src/commonMain/kotlin/top/yukonga/miuix/kmp/basic

1 file changed

+79
-56
lines changed

miuix/src/commonMain/kotlin/top/yukonga/miuix/kmp/basic/TopAppBar.kt

Lines changed: 79 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -70,10 +70,12 @@ import kotlin.math.abs
7070
import kotlin.math.roundToInt
7171

7272
/**
73-
* A [TopAppBar] that can collapse and expand based on the scroll position of the content below it.
73+
* A [TopAppBar] with Miuix style that can collapse and expand based on the
74+
* scroll position of the content below it.
7475
*
75-
* The [TopAppBar] can be configured with a title, a navigation icon, and action icons. The large
76-
* title will collapse when the content is scrolled up and expand when the content is scrolled down.
76+
* The [TopAppBar] can be configured with a title, a navigation icon, and action icons.
77+
* The large title will collapse when the content is scrolled up and expand when
78+
* the content is scrolled down.
7779
*
7880
* @param title The title of the [TopAppBar].
7981
* @param modifier The modifier to be applied to the [TopAppBar].
@@ -83,7 +85,7 @@ import kotlin.math.roundToInt
8385
* @param actions The [Composable] content that represents the action icons.
8486
* @param scrollBehavior The [ScrollBehavior] that controls the behavior of the [TopAppBar].
8587
* @param defaultWindowInsetsPadding Whether to apply default window insets padding to the [TopAppBar].
86-
* @param horizontalPadding The horizontal padding of the [TopAppBar].
88+
* @param horizontalPadding The horizontal padding of the [TopAppBar]'s title & large title.
8789
*/
8890
@Composable
8991
fun TopAppBar(
@@ -122,45 +124,42 @@ fun TopAppBar(
122124
)
123125
}
124126

125-
val dragConsumerModifier = remember { Modifier.pointerInput(Unit) { detectVerticalDragGestures { _, _ -> } } }
126-
127-
val displayCutoutInsets = WindowInsets.displayCutout
128-
val navigationBarsInsets = WindowInsets.navigationBars
129-
130-
val windowInsetsModifier = remember(defaultWindowInsetsPadding, displayCutoutInsets, navigationBarsInsets) {
131-
if (defaultWindowInsetsPadding) {
132-
Modifier
133-
.windowInsetsPadding(displayCutoutInsets.only(WindowInsetsSides.Horizontal))
134-
.windowInsetsPadding(navigationBarsInsets.only(WindowInsetsSides.Horizontal))
135-
} else Modifier
136-
}
137-
val surfaceModifier = remember(modifier, dragConsumerModifier, windowInsetsModifier) {
138-
modifier
139-
.then(dragConsumerModifier)
140-
.then(windowInsetsModifier)
141-
}
142-
143127
// Compose a Surface with a TopAppBarLayout content.
144128
// The surface's background color is animated as specified above.
145129
// The height of the app bar is determined by subtracting the bar's height offset from the
146130
// app bar's defined constant height value (i.e. the ContainerHeight token).
147131
Surface(
148-
color = color,
149-
modifier = surfaceModifier
132+
color = color
150133
) {
151134
TopAppBarLayout(
135+
modifier = modifier,
152136
title = title,
153137
largeTitle = largeTitle ?: title,
154138
navigationIcon = navigationIcon,
155139
actions = actionsRow,
156140
scrolledOffset = { scrollBehavior?.state?.heightOffset ?: 0f },
157141
expandedHeightPx = expandedHeightPx,
158142
horizontalPadding = horizontalPadding,
159-
largeTitleHeight = largeTitleHeight
143+
largeTitleHeight = largeTitleHeight,
144+
defaultWindowInsetsPadding = defaultWindowInsetsPadding
160145
)
161146
}
162147
}
163148

149+
/**
150+
* A [SmallTopAppBar] with Miuix style.
151+
*
152+
* The [SmallTopAppBar] can be configured with a title, a navigation icon, and action icons.
153+
*
154+
* @param title The title of the [SmallTopAppBar].
155+
* @param modifier The modifier to be applied to the [SmallTopAppBar].
156+
* @param color The background color of the [SmallTopAppBar].
157+
* @param navigationIcon The [Composable] content that represents the navigation icon.
158+
* @param actions The [Composable] content that represents the action icons.
159+
* @param scrollBehavior The [ScrollBehavior] that controls the behavior of the [SmallTopAppBar].
160+
* @param defaultWindowInsetsPadding Whether to apply default window insets padding to the [SmallTopAppBar].
161+
* @param horizontalPadding The horizontal padding of the [SmallTopAppBar]'s title.
162+
*/
164163
@Composable
165164
fun SmallTopAppBar(
166165
title: String,
@@ -188,37 +187,20 @@ fun SmallTopAppBar(
188187
)
189188
}
190189

191-
val dragConsumerModifier = remember { Modifier.pointerInput(Unit) { detectVerticalDragGestures { _, _ -> } } }
192-
193-
val displayCutoutInsets = WindowInsets.displayCutout
194-
val navigationBarsInsets = WindowInsets.navigationBars
195-
196-
val windowInsetsModifier = remember(defaultWindowInsetsPadding, displayCutoutInsets, navigationBarsInsets) {
197-
if (defaultWindowInsetsPadding) {
198-
Modifier
199-
.windowInsetsPadding(displayCutoutInsets.only(WindowInsetsSides.Horizontal))
200-
.windowInsetsPadding(navigationBarsInsets.only(WindowInsetsSides.Horizontal))
201-
} else Modifier
202-
}
203-
val surfaceModifier = remember(modifier, dragConsumerModifier, windowInsetsModifier) {
204-
modifier
205-
.then(dragConsumerModifier)
206-
.then(windowInsetsModifier)
207-
}
208-
209190
// Compose a Surface with a SmallTopAppBarLayout content.
210191
// The surface's background color is animated as specified above.
211192
// The height of the app bar is determined by subtracting the bar's height offset from the
212193
// app bar's defined constant height value (i.e. the ContainerHeight token).
213194
Surface(
214-
color = color,
215-
modifier = surfaceModifier
195+
color = color
216196
) {
217197
SmallTopAppBarLayout(
198+
modifier = modifier,
218199
title = title,
219200
navigationIcon = navigationIcon,
220201
actions = actionsRow,
221-
horizontalPadding = horizontalPadding
202+
horizontalPadding = horizontalPadding,
203+
defaultWindowInsetsPadding = defaultWindowInsetsPadding
222204
)
223205
}
224206
}
@@ -557,25 +539,28 @@ private fun interface ScrolledOffset {
557539
* (leading icon), a title (header), and action icons (trailing icons). Note that the navigation and
558540
* the actions are optional.
559541
*
542+
* @param modifier the modifier to be applied to the [TopAppBar].
560543
* @param title the top app bar title (header).
561544
* @param largeTitle the large title of the top app bar, if not specified, it will be the same as title.
562545
* @param navigationIcon a navigation icon [Composable].
563546
* @param actions actions [Composable].
564547
* @param scrolledOffset a function that provides the scroll offset of the top app bar.
565548
* @param expandedHeightPx the expanded height of the top app bar in pixels.
566-
* @param horizontalPadding the horizontal padding of the [TopAppBar].
549+
* @param horizontalPadding the horizontal padding of the [TopAppBar]'s title & large title.
567550
* @param largeTitleHeight a mutable state that holds the height of the large title.
568551
*/
569552
@Composable
570553
private fun TopAppBarLayout(
554+
modifier: Modifier = Modifier,
571555
title: String,
572556
largeTitle: String,
573557
navigationIcon: @Composable () -> Unit,
574558
actions: @Composable () -> Unit,
575559
scrolledOffset: ScrolledOffset,
576560
expandedHeightPx: Float,
577561
horizontalPadding: Dp,
578-
largeTitleHeight: MutableState<Int>
562+
largeTitleHeight: MutableState<Int>,
563+
defaultWindowInsetsPadding: Boolean
579564
) {
580565
// Subtract the scrolledOffset from the maxHeight. The scrolledOffset is expected to be
581566
// equal or smaller than zero.
@@ -620,6 +605,24 @@ private fun TopAppBarLayout(
620605
Modifier.offset { IntOffset(0, heightOffset) }
621606
}
622607

608+
val statusBarsInsets = WindowInsets.statusBars
609+
val captionBarInsets = WindowInsets.captionBar
610+
val displayCutoutInsets = WindowInsets.displayCutout
611+
val navigationBarsInsets = WindowInsets.navigationBars
612+
613+
val layoutModifier = remember(defaultWindowInsetsPadding, statusBarsInsets, captionBarInsets) {
614+
modifier
615+
.windowInsetsPadding(statusBarsInsets.only(WindowInsetsSides.Top))
616+
.windowInsetsPadding(captionBarInsets.only(WindowInsetsSides.Top))
617+
.then(
618+
if (defaultWindowInsetsPadding) {
619+
Modifier
620+
.windowInsetsPadding(displayCutoutInsets.only(WindowInsetsSides.Horizontal))
621+
.windowInsetsPadding(navigationBarsInsets.only(WindowInsetsSides.Horizontal))
622+
} else modifier
623+
)
624+
}
625+
623626
Layout(
624627
{
625628
Box(
@@ -663,10 +666,9 @@ private fun TopAppBarLayout(
663666
}
664667
}
665668
},
666-
modifier = Modifier
667-
.windowInsetsPadding(WindowInsets.statusBars.only(WindowInsetsSides.Top))
668-
.windowInsetsPadding(WindowInsets.captionBar.only(WindowInsetsSides.Top))
669+
modifier = layoutModifier
669670
.clipToBounds()
671+
.pointerInput(Unit) { detectVerticalDragGestures { _, _ -> } }
670672
) { measurables, constraints ->
671673
val navigationIconPlaceable =
672674
measurables
@@ -753,24 +755,46 @@ private fun TopAppBarLayout(
753755
* (leading icon), a title (header), and action icons (trailing icons). Note that the navigation and
754756
* the actions are optional.
755757
*
758+
* @param modifier the modifier to be applied to the [SmallTopAppBar].
756759
* @param title the top app bar title (header).
757760
* @param navigationIcon a navigation icon [Composable].
758761
* @param actions actions [Composable].
759-
* @param horizontalPadding the horizontal padding of the [SmallTopAppBar].
762+
* @param horizontalPadding the horizontal padding of the [SmallTopAppBar]'s title.
763+
* @param defaultWindowInsetsPadding whether to apply default window insets padding to the [SmallTopAppBar].
760764
*/
761765
@Composable
762766
private fun SmallTopAppBarLayout(
767+
modifier: Modifier,
763768
title: String,
764769
navigationIcon: @Composable () -> Unit,
765770
actions: @Composable () -> Unit,
766-
horizontalPadding: Dp
771+
horizontalPadding: Dp,
772+
defaultWindowInsetsPadding: Boolean
767773
) {
768774
val titleModifier = remember(horizontalPadding) {
769775
Modifier
770776
.layoutId("title")
771777
.padding(horizontal = horizontalPadding)
772778
}
773779

780+
val statusBarsInsets = WindowInsets.statusBars
781+
val captionBarInsets = WindowInsets.captionBar
782+
val displayCutoutInsets = WindowInsets.displayCutout
783+
val navigationBarsInsets = WindowInsets.navigationBars
784+
785+
val layoutModifier = remember(defaultWindowInsetsPadding, statusBarsInsets, captionBarInsets) {
786+
modifier
787+
.windowInsetsPadding(statusBarsInsets.only(WindowInsetsSides.Top))
788+
.windowInsetsPadding(captionBarInsets.only(WindowInsetsSides.Top))
789+
.then(
790+
if (defaultWindowInsetsPadding) {
791+
Modifier
792+
.windowInsetsPadding(displayCutoutInsets.only(WindowInsetsSides.Horizontal))
793+
.windowInsetsPadding(navigationBarsInsets.only(WindowInsetsSides.Horizontal))
794+
} else modifier
795+
)
796+
}
797+
774798
Layout(
775799
{
776800
Box(
@@ -796,10 +820,9 @@ private fun SmallTopAppBarLayout(
796820
actions()
797821
}
798822
},
799-
modifier = Modifier
800-
.windowInsetsPadding(WindowInsets.statusBars.only(WindowInsetsSides.Top))
801-
.windowInsetsPadding(WindowInsets.captionBar.only(WindowInsetsSides.Top))
823+
modifier = layoutModifier
802824
.heightIn(max = 56.dp)
825+
.pointerInput(Unit) { detectVerticalDragGestures { _, _ -> } }
803826
) { measurables, constraints ->
804827
val navigationIconPlaceable =
805828
measurables

0 commit comments

Comments
 (0)