Skip to content

Commit 075bf1a

Browse files
FDELAHA24GerardPaligot
authored andcommitted
feat: Create skeleton component
1 parent 3dc8788 commit 075bf1a

File tree

19 files changed

+534
-2
lines changed

19 files changed

+534
-2
lines changed

CONVENTIONS.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,9 @@ project.
3636

3737
For colors and sizes, functions for each variant shouldn't contains `Colors` and `Sizes` keywords.
3838
e.g. `Vitamin<Component>Colors.primary()` for colors and `Vitamin<Component>Sizes.medium()` for
39-
sizes.
39+
sizes. Functions arguments should be suffixed with `Color`, e.g. `backgroundColor`
40+
41+
4042

4143
## Composable variants
4244

buildSrc/src/main/kotlin/Libs.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ object Libs {
44

55
const val compose_ui = "androidx.compose.ui:ui:_"
66

7+
const val compose_ui_util = "androidx.compose.ui:ui-util:_"
8+
79
const val core = "androidx.core:core-ktx:_"
810
const val savedstate = "androidx.savedstate:savedstate-ktx:_"
911
const val lifecycle_runtime = "androidx.lifecycle:lifecycle-runtime-ktx:_"

buildSrc/src/main/kotlin/com/decathlon/vitamin/compose/VitaminComposeLibraryPlugin.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ class VitaminComposeLibraryPlugin : Plugin<Project> {
3030
add("debugImplementation", Libs.lifecycle_runtime)
3131
add("debugImplementation", Libs.savedstate)
3232
add("debugImplementation", Libs.core)
33+
add("debugImplementation", Libs.compose_ui)
34+
add("debugImplementation", Libs.compose_ui_util)
3335
add("debugImplementation", Libs.poolingcontainer)
3436

3537
add("androidTestImplementation", Libs.junit)

gradle/wrapper/gradle-wrapper.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME
22
distributionPath=wrapper/dists
33
distributionUrl=https\://services.gradle.org/distributions/gradle-7.4.2-bin.zip
44
zipStoreBase=GRADLE_USER_HOME
5-
zipStorePath=wrapper/dists
5+
zipStorePath=wrapper/dists

sample/build.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ dependencies {
6161
implementation(project(":appbars"))
6262
implementation(project(":dividers"))
6363
implementation(project(":tabs"))
64+
implementation(project(":skeletons"))
6465
implementation(project(":tags"))
6566
implementation(project(":ratings"))
6667
implementation(project(":prices"))

sample/src/main/java/com/decathlon/compose/sample/MainActivity.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import com.decathlon.compose.sample.screens.Prices
1919
import com.decathlon.compose.sample.screens.Progress
2020
import com.decathlon.compose.sample.screens.RadioButtons
2121
import com.decathlon.compose.sample.screens.Ratings
22+
import com.decathlon.compose.sample.screens.Skeletons
2223
import com.decathlon.compose.sample.screens.Switches
2324
import com.decathlon.compose.sample.screens.Tabs
2425
import com.decathlon.compose.sample.screens.Tags
@@ -55,6 +56,7 @@ class MainActivity : AppCompatActivity() {
5556
Progress,
5657
RadioButtons,
5758
AppBars,
59+
Skeletons,
5860
Tabs,
5961
Tags,
6062
Ratings,
Lines changed: 214 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,214 @@
1+
package com.decathlon.compose.sample.screens
2+
3+
import androidx.compose.foundation.ScrollState
4+
import androidx.compose.foundation.layout.Arrangement
5+
import androidx.compose.foundation.layout.Box
6+
import androidx.compose.foundation.layout.Column
7+
import androidx.compose.foundation.layout.Row
8+
import androidx.compose.foundation.layout.Spacer
9+
import androidx.compose.foundation.layout.fillMaxWidth
10+
import androidx.compose.foundation.layout.height
11+
import androidx.compose.foundation.layout.padding
12+
import androidx.compose.foundation.layout.size
13+
import androidx.compose.foundation.verticalScroll
14+
import androidx.compose.material.Text
15+
import androidx.compose.runtime.Composable
16+
import androidx.compose.ui.Modifier
17+
import androidx.compose.ui.tooling.preview.Preview
18+
import androidx.compose.ui.unit.dp
19+
import com.decathlon.compose.sample.components.SampleScaffold
20+
import com.decathlon.vitamin.compose.foundation.VitaminTheme
21+
import com.decathlon.vitamin.compose.foundation.vtmnTypography
22+
import com.decathlon.vitamin.compose.skeletons.VitaminSkeletons
23+
import com.decathlon.vitamin.compose.skeletons.vtmnSkeleton
24+
25+
object Skeletons : Screen {
26+
27+
override val name: String
28+
get() = "Skeletons"
29+
30+
override val navigationKey: String
31+
get() = "skeletons"
32+
33+
private const val smallWeight: Float = 1f
34+
private const val mediumWeight: Float = 2f
35+
private const val bigWeight: Float = 8f
36+
37+
@SuppressWarnings("LongMethod")
38+
@Composable
39+
override fun Screen() {
40+
SampleScaffold(title = name) {
41+
Column(
42+
modifier = Modifier
43+
.padding(top = 16.dp, start = 16.dp, end = 16.dp)
44+
.verticalScroll(
45+
ScrollState(initial = 0)
46+
)
47+
) {
48+
Text(
49+
text = "Classic list examples",
50+
style = vtmnTypography.h6,
51+
modifier = Modifier.padding(bottom = 16.dp)
52+
)
53+
54+
repeat((0..2).count()) {
55+
Row(Modifier.padding(top = 16.dp)) {
56+
VitaminSkeletons.Rounded(
57+
modifier = Modifier.size(80.dp, 80.dp)
58+
)
59+
SkeletonTextLines(modifier = Modifier.weight(1f))
60+
}
61+
}
62+
63+
Spacer(modifier = Modifier.height(32.dp))
64+
65+
repeat((0..2).count()) {
66+
Row(Modifier.padding(top = 16.dp)) {
67+
VitaminSkeletons.Rectangular(
68+
modifier = Modifier.size(80.dp, 80.dp),
69+
cornerRadius = 4.dp
70+
)
71+
72+
SkeletonTextLines(modifier = Modifier.weight(1f))
73+
}
74+
}
75+
76+
Text(
77+
text = "Other shape examples",
78+
style = vtmnTypography.h6,
79+
modifier = Modifier.padding(top = 32.dp)
80+
)
81+
82+
Row {
83+
VitaminSkeletons.Rectangular(
84+
modifier = Modifier
85+
.padding(top = 32.dp)
86+
.height(60.dp)
87+
.weight(smallWeight)
88+
)
89+
Spacer(modifier = Modifier.weight(1f))
90+
}
91+
92+
Row {
93+
VitaminSkeletons.Rectangular(
94+
modifier = Modifier
95+
.padding(top = 16.dp)
96+
.size(80.dp, 60.dp)
97+
.weight(mediumWeight),
98+
cornerRadius = 8.dp
99+
)
100+
Spacer(modifier = Modifier.weight(1f))
101+
}
102+
103+
Row {
104+
VitaminSkeletons.Rectangular(
105+
modifier = Modifier
106+
.padding(top = 16.dp)
107+
.size(80.dp, 60.dp)
108+
.weight(bigWeight),
109+
cornerRadius = 30.dp
110+
)
111+
Spacer(modifier = Modifier.weight(1f))
112+
}
113+
Row {
114+
VitaminSkeletons.Rounded(
115+
modifier = Modifier
116+
.padding(top = 16.dp)
117+
.size(50.dp, 50.dp)
118+
)
119+
120+
VitaminSkeletons.Rounded(
121+
modifier = Modifier
122+
.padding(top = 16.dp, start = 16.dp)
123+
.size(20.dp, 50.dp)
124+
)
125+
126+
Column {
127+
VitaminSkeletons.Rounded(
128+
modifier = Modifier
129+
.padding(top = 16.dp, start = 16.dp)
130+
.size(50.dp, 20.dp)
131+
)
132+
133+
Row {
134+
VitaminSkeletons.Rounded(
135+
modifier = Modifier
136+
.padding(top = 8.dp, start = 16.dp)
137+
.size(25.dp, 25.dp)
138+
)
139+
VitaminSkeletons.Rounded(
140+
modifier = Modifier
141+
.padding(top = 8.dp, start = 8.dp)
142+
.size(15.dp, 15.dp)
143+
)
144+
}
145+
}
146+
147+
VitaminSkeletons.Rectangular(
148+
modifier = Modifier
149+
.padding(top = 16.dp, start = 16.dp)
150+
.size(50.dp, 50.dp)
151+
)
152+
153+
VitaminSkeletons.Rectangular(
154+
modifier = Modifier
155+
.padding(top = 16.dp, start = 16.dp)
156+
.size(50.dp, 50.dp),
157+
cornerRadius = 4.dp
158+
)
159+
160+
VitaminSkeletons.Rectangular(
161+
modifier = Modifier
162+
.padding(top = 16.dp, start = 16.dp)
163+
.size(50.dp, 50.dp),
164+
cornerRadius = 10.dp
165+
)
166+
}
167+
168+
Box(
169+
modifier = Modifier
170+
.padding(top = 16.dp)
171+
.height(200.dp)
172+
.fillMaxWidth()
173+
.vtmnSkeleton()
174+
)
175+
}
176+
}
177+
}
178+
}
179+
180+
@Composable
181+
fun SkeletonTextLines(modifier: Modifier) {
182+
Column(
183+
modifier
184+
.padding(start = 16.dp)
185+
.height(80.dp),
186+
verticalArrangement = Arrangement.Center
187+
) {
188+
VitaminSkeletons.Rectangular(
189+
modifier = Modifier
190+
.height(20.dp)
191+
.fillMaxWidth(),
192+
cornerRadius = 4.dp
193+
)
194+
Row {
195+
VitaminSkeletons.Rectangular(
196+
modifier = Modifier
197+
.padding(top = 8.dp)
198+
.height(20.dp)
199+
.fillMaxWidth()
200+
.weight(1f),
201+
cornerRadius = 4.dp
202+
)
203+
Spacer(modifier = Modifier.weight(1f))
204+
}
205+
}
206+
}
207+
208+
@Preview(showBackground = true)
209+
@Composable
210+
fun SkeletonPreview() {
211+
VitaminTheme {
212+
Skeletons.Screen()
213+
}
214+
}

settings.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ include(":ratings")
2727
include(":modals")
2828
include(":sample")
2929
include(":dividers")
30+
include(":skeletons")
3031
include(":tabs")
3132
include(":tags")
3233
include(":prices")

skeletons/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
/build

skeletons/README.md

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
# Skeleton components
2+
3+
## Skeleton design specs
4+
5+
You can find the design specs on [decathlon.design](https://www.decathlon.design/).
6+
7+
## Usage
8+
9+
If you want to use components of this module in your android mobile application, you should
10+
first add the Gradle dependency in your Gradle file:
11+
12+
```kotlin
13+
implementation("com.decathlon.vitamin.compose:skeletons:<versions>")
14+
```
15+
16+
### Rectangular
17+
18+
19+
```kotlin
20+
object VitaminSkeleton {
21+
@Composable
22+
fun Rectangular(
23+
modifier: Modifier = Modifier,
24+
colors: SkeletonColors = VitaminSkeletonColors.primary(),
25+
cornerRadius: Dp = 0.dp
26+
)
27+
}
28+
```
29+
30+
This component draw a rectangle. You can add a modifier, but you can also customize the colors and the corner radius of the shape.
31+
32+
```kotlin
33+
VitaminSkeleton.Rectangular()
34+
```
35+
36+
Parameters | Descriptions
37+
-- | --
38+
`modifier: Modifier = Modifier` | The `Modifier` to be applied to the component
39+
`colors: SkeletonColors = VitaminSkeletonColors.primary()` | The colors of the background and the highlight effect
40+
`cornerRadius: Dp = 0.dp` | size of the rectangle shape corner radius, no radius by default
41+
42+
### Rounded
43+
44+
```kotlin
45+
object VitaminSkeleton {
46+
@Composable
47+
fun Rounded(
48+
modifier: Modifier = Modifier,
49+
colors: SkeletonColors = VitaminSkeletonColors.primary(),
50+
)
51+
}
52+
```
53+
54+
This component draw a round. You can add a modifier, but you can also customize the colors.
55+
56+
```kotlin
57+
VitaminSkeleton.Rounded()
58+
```
59+
60+
Parameters | Descriptions
61+
-- | --
62+
`modifier: Modifier = Modifier` | The `Modifier` to be applied to the component
63+
`colors: SkeletonColors = VitaminSkeletonColors.primary()` | The colors of the background and the highlight effect
64+
65+
### Modifier extension
66+
67+
```kotlin
68+
fun Modifier.vtmnSkeleton(
69+
visible: Boolean = true,
70+
colors: SkeletonColors = VitaminSkeletonColors.primary(),
71+
shape: Shape = RectangleShape
72+
): Modifier
73+
```
74+
75+
This Modifier extension allow to apply the shimmer effect on any @Composable
76+
77+
```kotlin
78+
Box(
79+
modifier = Modifier
80+
.vtmnSkeleton()
81+
)
82+
```
83+
84+
Parameters | Descriptions
85+
-- | --
86+
`visible: Boolean = true` | visibility state of the shimmer effect
87+
`colors: SkeletonColors = VitaminSkeletonColors.primary()` | The colors of the background and the highlight effect
88+
`shape: Shape = RectangleShape` | shape of the skeleton

0 commit comments

Comments
 (0)