Skip to content

Commit 84107d6

Browse files
authored
Merge pull request #14903 from woocommerce/woomob-1645-woo-postech-debt-create-wooposshimmertext-component-that
[WOOMOB-1645] Add WooPosShimmerText component with automatic text measurement
2 parents ad23678 + b04a159 commit 84107d6

File tree

6 files changed

+185
-126
lines changed

6 files changed

+185
-126
lines changed
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
package com.woocommerce.android.ui.woopos.common.composeui.component
2+
3+
import androidx.compose.foundation.layout.Column
4+
import androidx.compose.foundation.layout.height
5+
import androidx.compose.foundation.layout.padding
6+
import androidx.compose.foundation.layout.width
7+
import androidx.compose.foundation.shape.RoundedCornerShape
8+
import androidx.compose.runtime.Composable
9+
import androidx.compose.ui.Modifier
10+
import androidx.compose.ui.draw.clip
11+
import androidx.compose.ui.platform.LocalDensity
12+
import androidx.compose.ui.text.TextStyle
13+
import androidx.compose.ui.text.font.FontWeight
14+
import androidx.compose.ui.text.rememberTextMeasurer
15+
import androidx.compose.ui.tooling.preview.Preview
16+
import androidx.compose.ui.unit.Dp
17+
import androidx.compose.ui.unit.dp
18+
import com.woocommerce.android.ui.woopos.common.composeui.WooPosPreview
19+
import com.woocommerce.android.ui.woopos.common.composeui.designsystem.WooPosCornerRadius
20+
import com.woocommerce.android.ui.woopos.common.composeui.designsystem.WooPosSpacing
21+
import com.woocommerce.android.ui.woopos.common.composeui.designsystem.WooPosTheme
22+
import com.woocommerce.android.ui.woopos.common.composeui.designsystem.WooPosTypography
23+
24+
@Composable
25+
fun WooPosShimmerText(
26+
modifier: Modifier = Modifier,
27+
text: String,
28+
style: TextStyle,
29+
fontWeight: FontWeight? = null,
30+
cornerRadius: WooPosCornerRadius? = null
31+
) {
32+
val textMeasurer = rememberTextMeasurer()
33+
val density = LocalDensity.current
34+
35+
val measuredText = textMeasurer.measure(
36+
text = text,
37+
style = style.copy(fontWeight = fontWeight)
38+
)
39+
40+
val width = with(density) { measuredText.size.width.toDp() }
41+
val height = with(density) { measuredText.size.height.toDp() }
42+
43+
val calculatedCornerRadius = cornerRadius ?: height.toCornerRadius()
44+
45+
WooPosShimmerBox(
46+
modifier = modifier
47+
.width(width)
48+
.height(height)
49+
.clip(RoundedCornerShape(calculatedCornerRadius.value))
50+
)
51+
}
52+
53+
private fun Dp.toCornerRadius(): WooPosCornerRadius = when {
54+
this <= 20.dp -> WooPosCornerRadius.XSmall
55+
this <= 36.dp -> WooPosCornerRadius.Small
56+
this <= 54.dp -> WooPosCornerRadius.Medium
57+
this <= 80.dp -> WooPosCornerRadius.Large
58+
else -> WooPosCornerRadius.XLarge
59+
}
60+
61+
@WooPosPreview
62+
@Preview
63+
@Composable
64+
private fun WooPosShimmerTextPreview() {
65+
WooPosTheme {
66+
Column(
67+
modifier = Modifier.padding(WooPosSpacing.Medium.value)
68+
) {
69+
WooPosShimmerText(
70+
text = "Loading heading text...",
71+
style = WooPosTypography.Heading.style,
72+
modifier = Modifier.padding(bottom = WooPosSpacing.Small.value)
73+
)
74+
75+
WooPosShimmerText(
76+
text = "Loading body large bold text",
77+
style = WooPosTypography.BodyLarge.style,
78+
fontWeight = FontWeight.Bold,
79+
modifier = Modifier.padding(bottom = WooPosSpacing.Small.value)
80+
)
81+
82+
WooPosShimmerText(
83+
text = "Loading body medium text",
84+
style = WooPosTypography.BodyMedium.style,
85+
modifier = Modifier.padding(bottom = WooPosSpacing.Small.value)
86+
)
87+
88+
WooPosShimmerText(
89+
text = "Loading caption",
90+
style = WooPosTypography.Caption.style,
91+
modifier = Modifier.padding(bottom = WooPosSpacing.Small.value)
92+
)
93+
94+
WooPosShimmerText(
95+
text = "Custom corner radius",
96+
style = WooPosTypography.BodyLarge.style,
97+
cornerRadius = WooPosCornerRadius.None,
98+
modifier = Modifier.padding(bottom = WooPosSpacing.Small.value)
99+
)
100+
}
101+
}
102+
}

WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/home/cart/WooPosCartScreen.kt

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,6 @@ import androidx.compose.runtime.setValue
5656
import androidx.compose.ui.Alignment
5757
import androidx.compose.ui.Modifier
5858
import androidx.compose.ui.draw.alpha
59-
import androidx.compose.ui.draw.clip
6059
import androidx.compose.ui.graphics.ColorFilter
6160
import androidx.compose.ui.layout.ContentScale
6261
import androidx.compose.ui.platform.LocalContext
@@ -89,6 +88,7 @@ import com.woocommerce.android.ui.woopos.common.composeui.component.WooPosCard
8988
import com.woocommerce.android.ui.woopos.common.composeui.component.WooPosIconButton
9089
import com.woocommerce.android.ui.woopos.common.composeui.component.WooPosLazyColumn
9190
import com.woocommerce.android.ui.woopos.common.composeui.component.WooPosShimmerBox
91+
import com.woocommerce.android.ui.woopos.common.composeui.component.WooPosShimmerText
9292
import com.woocommerce.android.ui.woopos.common.composeui.component.WooPosText
9393
import com.woocommerce.android.ui.woopos.common.composeui.designsystem.WooPosCornerRadius
9494
import com.woocommerce.android.ui.woopos.common.composeui.designsystem.WooPosElevation
@@ -785,20 +785,17 @@ private fun LoadingItem(
785785
.weight(1f)
786786
.padding(end = WooPosSpacing.Medium.value.toAdaptivePadding())
787787
) {
788-
WooPosShimmerBox(
789-
modifier = Modifier
790-
.height(22.dp)
791-
.fillMaxWidth(0.95f)
792-
.clip(RoundedCornerShape(WooPosCornerRadius.Medium.value))
788+
WooPosShimmerText(
789+
text = item.name,
790+
style = WooPosTypography.BodySmall.style,
791+
fontWeight = FontWeight.Bold
793792
)
794793

795794
Spacer(modifier = Modifier.height(WooPosSpacing.XSmall.value.toAdaptivePadding()))
796795

797-
WooPosShimmerBox(
798-
modifier = Modifier
799-
.height(22.dp)
800-
.fillMaxWidth(0.25f)
801-
.clip(RoundedCornerShape(WooPosCornerRadius.Medium.value))
796+
WooPosShimmerText(
797+
text = "$10.00",
798+
style = WooPosTypography.BodySmall.style
802799
)
803800
}
804801

WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/home/items/WooPosItemsList.kt

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@ import androidx.compose.runtime.remember
3333
import androidx.compose.runtime.snapshotFlow
3434
import androidx.compose.ui.Alignment
3535
import androidx.compose.ui.Modifier
36-
import androidx.compose.ui.draw.clip
3736
import androidx.compose.ui.graphics.ColorFilter
3837
import androidx.compose.ui.layout.ContentScale
3938
import androidx.compose.ui.platform.LocalContext
@@ -50,7 +49,7 @@ import com.woocommerce.android.ui.woopos.common.composeui.WooPosPreview
5049
import com.woocommerce.android.ui.woopos.common.composeui.component.ShadowType
5150
import com.woocommerce.android.ui.woopos.common.composeui.component.WooPosCard
5251
import com.woocommerce.android.ui.woopos.common.composeui.component.WooPosLazyColumn
53-
import com.woocommerce.android.ui.woopos.common.composeui.component.WooPosShimmerBox
52+
import com.woocommerce.android.ui.woopos.common.composeui.component.WooPosShimmerText
5453
import com.woocommerce.android.ui.woopos.common.composeui.component.WooPosText
5554
import com.woocommerce.android.ui.woopos.common.composeui.designsystem.WooPosCornerRadius
5655
import com.woocommerce.android.ui.woopos.common.composeui.designsystem.WooPosElevation
@@ -504,20 +503,17 @@ private fun ItemsLoadingItem() {
504503
.weight(1f),
505504
verticalArrangement = Arrangement.Center,
506505
) {
507-
WooPosShimmerBox(
508-
modifier = Modifier
509-
.fillMaxWidth()
510-
.height(32.dp)
511-
.clip(RoundedCornerShape(WooPosCornerRadius.Medium.value))
506+
WooPosShimmerText(
507+
text = "Product Name",
508+
style = WooPosTypography.BodyLarge.style,
509+
fontWeight = FontWeight.Bold
512510
)
513511

514512
Spacer(modifier = Modifier.size(WooPosSpacing.XSmall.value))
515513

516-
WooPosShimmerBox(
517-
modifier = Modifier
518-
.height(32.dp)
519-
.width(57.dp)
520-
.clip(RoundedCornerShape(WooPosCornerRadius.Medium.value))
514+
WooPosShimmerText(
515+
text = "$10.00",
516+
style = WooPosTypography.BodyLarge.style
521517
)
522518
}
523519

WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/orders/WooPosOrdersLoadingState.kt

Lines changed: 53 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ import com.woocommerce.android.ui.woopos.common.composeui.WooPosPreview
3131
import com.woocommerce.android.ui.woopos.common.composeui.component.ShadowType
3232
import com.woocommerce.android.ui.woopos.common.composeui.component.WooPosCard
3333
import com.woocommerce.android.ui.woopos.common.composeui.component.WooPosShimmerBox
34+
import com.woocommerce.android.ui.woopos.common.composeui.component.WooPosShimmerText
3435
import com.woocommerce.android.ui.woopos.common.composeui.component.WooPosText
3536
import com.woocommerce.android.ui.woopos.common.composeui.designsystem.WooPosCornerRadius
3637
import com.woocommerce.android.ui.woopos.common.composeui.designsystem.WooPosElevation
@@ -76,23 +77,18 @@ fun WooPosOrdersOrderLoadingRow() {
7677
verticalAlignment = Alignment.Top
7778
) {
7879
Column(verticalArrangement = Arrangement.spacedBy(WooPosSpacing.XSmall.value)) {
79-
WooPosShimmerBox(
80-
modifier = Modifier
81-
.fillMaxWidth(0.2f)
82-
.height(18.dp)
83-
.clip(RoundedCornerShape(WooPosCornerRadius.Small.value))
80+
WooPosShimmerText(
81+
text = "Order #123",
82+
style = WooPosTypography.BodySmall.style,
83+
fontWeight = FontWeight.Bold
8484
)
85-
WooPosShimmerBox(
86-
modifier = Modifier
87-
.fillMaxWidth(0.35f)
88-
.height(14.dp)
89-
.clip(RoundedCornerShape(WooPosCornerRadius.Small.value))
85+
WooPosShimmerText(
86+
text = "January 1, 2024 at 12:00 PM",
87+
style = WooPosTypography.BodySmall.style
9088
)
91-
WooPosShimmerBox(
92-
modifier = Modifier
93-
.fillMaxWidth(0.25f)
94-
.height(14.dp)
95-
.clip(RoundedCornerShape(WooPosCornerRadius.Small.value))
89+
WooPosShimmerText(
90+
91+
style = WooPosTypography.BodySmall.style
9692
)
9793
Spacer(Modifier.height(WooPosSpacing.XSmall.value))
9894
WooPosShimmerBox(
@@ -105,12 +101,9 @@ fun WooPosOrdersOrderLoadingRow() {
105101

106102
Spacer(Modifier.weight(1f))
107103

108-
WooPosShimmerBox(
109-
modifier = Modifier
110-
.width(48.dp)
111-
.height(18.dp)
112-
.alignByBaseline()
113-
.clip(RoundedCornerShape(WooPosCornerRadius.Small.value))
104+
WooPosShimmerText(
105+
text = "$100.00",
106+
style = WooPosTypography.BodySmall.style
114107
)
115108
}
116109
}
@@ -142,29 +135,24 @@ private fun OrderDetailsLoadingPane(modifier: Modifier = Modifier) {
142135
horizontalArrangement = Arrangement.SpaceBetween
143136
) {
144137
Column {
145-
WooPosShimmerBox(
146-
modifier = Modifier
147-
.width(96.dp)
148-
.height(28.dp)
149-
.clip(RoundedCornerShape(WooPosCornerRadius.Small.value))
138+
WooPosShimmerText(
139+
text = "Order #123",
140+
style = WooPosTypography.Heading.style,
141+
fontWeight = FontWeight.Bold
150142
)
151143

152144
Spacer(modifier = Modifier.height(WooPosSpacing.Medium.value))
153145

154-
WooPosShimmerBox(
155-
modifier = Modifier
156-
.width(120.dp)
157-
.height(18.dp)
158-
.clip(RoundedCornerShape(WooPosCornerRadius.Small.value))
146+
WooPosShimmerText(
147+
text = "Jul 28, 2025 at 10:31 PM",
148+
style = WooPosTypography.BodyMedium.style
159149
)
160150

161-
Spacer(modifier = Modifier.height(WooPosSpacing.XSmall.value))
151+
Spacer(modifier = Modifier.height(WooPosSpacing.Small.value))
162152

163-
WooPosShimmerBox(
164-
modifier = Modifier
165-
.width(80.dp)
166-
.height(18.dp)
167-
.clip(RoundedCornerShape(WooPosCornerRadius.Small.value))
153+
WooPosShimmerText(
154+
text = "Completed",
155+
style = WooPosTypography.BodyLarge.style
168156
)
169157
}
170158

@@ -261,37 +249,32 @@ private fun ProductLoadingItem() {
261249
}
262250
)
263251

264-
WooPosShimmerBox(
265-
modifier = Modifier
266-
.width(120.dp)
267-
.height(22.dp)
268-
.clip(RoundedCornerShape(WooPosCornerRadius.Small.value))
269-
.constrainAs(nameShimmer) {
270-
top.linkTo(image.top)
271-
start.linkTo(image.end, margin = WooPosSpacing.Medium.value)
272-
}
252+
WooPosShimmerText(
253+
text = "Product Name",
254+
style = WooPosTypography.BodyLarge.style,
255+
fontWeight = FontWeight.Bold,
256+
modifier = Modifier.constrainAs(nameShimmer) {
257+
top.linkTo(image.top)
258+
start.linkTo(image.end, margin = WooPosSpacing.Medium.value)
259+
}
273260
)
274261

275-
WooPosShimmerBox(
276-
modifier = Modifier
277-
.width(80.dp)
278-
.height(18.dp)
279-
.clip(RoundedCornerShape(WooPosCornerRadius.Small.value))
280-
.constrainAs(qtyShimmer) {
281-
bottom.linkTo(image.bottom)
282-
start.linkTo(nameShimmer.start)
283-
}
262+
WooPosShimmerText(
263+
text = "2 x $10.00",
264+
style = WooPosTypography.BodyMedium.style,
265+
modifier = Modifier.constrainAs(qtyShimmer) {
266+
bottom.linkTo(image.bottom)
267+
start.linkTo(nameShimmer.start)
268+
}
284269
)
285270

286-
WooPosShimmerBox(
287-
modifier = Modifier
288-
.width(60.dp)
289-
.height(18.dp)
290-
.clip(RoundedCornerShape(WooPosCornerRadius.Small.value))
291-
.constrainAs(totalShimmer) {
292-
top.linkTo(nameShimmer.top)
293-
end.linkTo(parent.end)
294-
}
271+
WooPosShimmerText(
272+
text = "$20.00",
273+
style = WooPosTypography.BodyMedium.style,
274+
modifier = Modifier.constrainAs(totalShimmer) {
275+
top.linkTo(nameShimmer.top)
276+
end.linkTo(parent.end)
277+
}
295278
)
296279
}
297280
}
@@ -302,18 +285,14 @@ private fun TotalLoadingItem() {
302285
modifier = Modifier.fillMaxWidth(),
303286
horizontalArrangement = Arrangement.SpaceBetween
304287
) {
305-
WooPosShimmerBox(
306-
modifier = Modifier
307-
.fillMaxWidth(0.3f)
308-
.height(16.dp)
309-
.clip(RoundedCornerShape(WooPosCornerRadius.Small.value))
288+
WooPosShimmerText(
289+
text = "Subtotal",
290+
style = WooPosTypography.BodyMedium.style
310291
)
311292

312-
WooPosShimmerBox(
313-
modifier = Modifier
314-
.width(60.dp)
315-
.height(18.dp)
316-
.clip(RoundedCornerShape(WooPosCornerRadius.Small.value))
293+
WooPosShimmerText(
294+
text = "$100.00",
295+
style = WooPosTypography.BodyMedium.style
317296
)
318297
}
319298
}

0 commit comments

Comments
 (0)