Skip to content

Commit dd7237d

Browse files
committed
Theme and styles refactoring. Make Button component
1 parent 0224d46 commit dd7237d

File tree

7 files changed

+182
-92
lines changed

7 files changed

+182
-92
lines changed

build.gradle.kts

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import org.jetbrains.kotlin.gradle.ExperimentalKotlinGradlePluginApi
2+
13
plugins {
24
alias(libs.plugins.kotlin.multiplatform)
35
alias(libs.plugins.kotlinx.serialization)
@@ -19,6 +21,7 @@ kotlin {
1921
binaries.executable()
2022
}
2123

24+
@OptIn(ExperimentalKotlinGradlePluginApi::class)
2225
compilerOptions {
2326
freeCompilerArgs.add(
2427
"-Xcontext-receivers",
@@ -28,9 +31,7 @@ kotlin {
2831
sourceSets {
2932
jsMain.dependencies {
3033
implementation(libs.kotlin.coroutines)
31-
implementation(libs.kotlin.css)
3234
implementation(libs.kotlin.extensions)
33-
implementation(libs.kotlinx.html)
3435
implementation(libs.kotlinx.serialization.core)
3536
implementation(libs.kotlinx.serialization.json)
3637
implementation(compose.runtime)

src/jsMain/kotlin/Application.kt

+16-27
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@ import androidx.compose.runtime.getValue
22
import androidx.compose.runtime.mutableStateOf
33
import androidx.compose.runtime.remember
44
import androidx.compose.runtime.setValue
5+
import common.BaseStyles
6+
import common.Theme
7+
import common.ThemeProvider
8+
import common.ThemeVariables
59
import components.Layout
610
import components.PageContent
711
import components.PageFooter
@@ -11,23 +15,21 @@ import org.jetbrains.compose.web.css.Style
1115
import org.jetbrains.compose.web.dom.*
1216
import org.jetbrains.compose.web.renderComposableInBody
1317

14-
enum class Theme { Dark, Light }
15-
1618
fun main() {
1719
renderComposableInBody {
18-
var theme by remember { mutableStateOf(Theme.Light) }
1920
Style {
2021
root {
21-
when (theme) {
22+
when (ThemeProvider.theme) {
2223
Theme.Light -> {
23-
ThemeVariables.mainColor(Color("#333"))
24-
ThemeVariables.accentColor(Color("#6200ea"))
25-
ThemeVariables.backgroundColor(Color("#f0f0f0"))
24+
ThemeVariables.mainColor(Color("#201e1f"))
25+
ThemeVariables.accentColor(Color("#1d7874"))
26+
ThemeVariables.backgroundColor(Color("#F8F4E3"))
2627
}
28+
2729
Theme.Dark -> {
28-
ThemeVariables.mainColor(Color("#f0f0f0"))
29-
ThemeVariables.accentColor(Color("#6200ea"))
30-
ThemeVariables.backgroundColor(Color("#333"))
30+
ThemeVariables.mainColor(Color("#F8F4E3"))
31+
ThemeVariables.accentColor(Color("#1d7874"))
32+
ThemeVariables.backgroundColor(Color("#201e1f"))
3133
}
3234
}
3335
}
@@ -39,15 +41,8 @@ fun main() {
3941
PageHeader {
4042
H1 { Text("My delicious site") }
4143
Div {
42-
Button(attrs = {
43-
onClick {
44-
theme = when (theme) {
45-
Theme.Light -> Theme.Dark
46-
Theme.Dark -> Theme.Light
47-
}
48-
}
49-
}) {
50-
Text("Switch theme")
44+
components.Button("Switch theme") {
45+
ThemeProvider.theme = ThemeProvider.theme.opposite
5146
}
5247
}
5348
}
@@ -58,14 +53,8 @@ fun main() {
5853
}
5954
Div {
6055
Span {
61-
Button(
62-
attrs = {
63-
onClick {
64-
counter++
65-
}
66-
},
67-
) {
68-
Text("Increment")
56+
components.Button("Increment") {
57+
counter++
6958
}
7059
}
7160
}

src/jsMain/kotlin/Styles.kt

-62
This file was deleted.

src/jsMain/kotlin/common/Styles.kt

+66
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
package common
2+
3+
import org.jetbrains.compose.web.css.*
4+
5+
object ThemeVariables {
6+
val backgroundColor by variable<CSSColorValue>()
7+
val mainColor by variable<CSSColorValue>()
8+
val accentColor by variable<CSSColorValue>()
9+
}
10+
11+
object BaseStyles : StyleSheet() {
12+
init {
13+
"#root" style {
14+
display(DisplayStyle.Flex)
15+
flexDirection(FlexDirection.Column)
16+
minHeight(100.vh)
17+
color(ThemeVariables.mainColor.value())
18+
backgroundColor(ThemeVariables.backgroundColor.value())
19+
}
20+
}
21+
22+
val header by style {
23+
backgroundColor(ThemeVariables.accentColor.value())
24+
color(ThemeVariables.backgroundColor.value())
25+
flex(0, 0, 60.px)
26+
display(DisplayStyle.Flex)
27+
alignItems(AlignItems.Center)
28+
justifyContent(JustifyContent.SpaceBetween)
29+
fontSize(1.5.cssRem)
30+
padding(10.px)
31+
maxWidth(80.cssRem)
32+
}
33+
34+
val main by style {
35+
flex(1)
36+
display(DisplayStyle.Flex)
37+
alignItems(AlignItems.Center)
38+
justifyContent(JustifyContent.Center)
39+
padding(20.px)
40+
backgroundColor(ThemeVariables.backgroundColor.value())
41+
}
42+
43+
val footer by style {
44+
flex(0, 0, 40.px)
45+
display(DisplayStyle.Flex)
46+
alignItems(AlignItems.Center)
47+
justifyContent(JustifyContent.Center)
48+
fontSize(1.cssRem)
49+
property("border-top", "2px solid")
50+
property("border-left", "none")
51+
property("border-right", "none")
52+
property("border-bottom", "none")
53+
}
54+
55+
val container by style {
56+
backgroundColor(ThemeVariables.backgroundColor.value())
57+
display(DisplayStyle.Flex)
58+
flexDirection(FlexDirection.Column)
59+
flexGrow(1)
60+
justifyContent(JustifyContent.Center)
61+
alignItems(AlignItems.Center)
62+
maxWidth(800.px)
63+
width(100.percent)
64+
padding(20.px)
65+
}
66+
}

src/jsMain/kotlin/common/Theme.kt

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package common
2+
3+
import androidx.compose.runtime.getValue
4+
import androidx.compose.runtime.mutableStateOf
5+
import androidx.compose.runtime.setValue
6+
7+
enum class Theme {
8+
Dark,
9+
Light,
10+
;
11+
12+
val opposite
13+
get() =
14+
when (this) {
15+
Light -> Dark
16+
Dark -> Light
17+
}
18+
}
19+
20+
object ThemeProvider {
21+
var theme by mutableStateOf(Theme.Light)
22+
}

src/jsMain/kotlin/components/AppLayout.kt

+4-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
package components
22

3-
import BaseStyles
3+
import common.BaseStyles
44
import androidx.compose.runtime.Composable
55
import org.jetbrains.compose.web.dom.*
66
import org.w3c.dom.HTMLElement
@@ -21,6 +21,7 @@ fun PageHeader(
2121
content: @Composable ElementScope<HTMLElement>.() -> Unit,
2222
) {
2323
Header({
24+
classes(BaseStyles.header)
2425
attrs?.invoke(this)
2526
}) {
2627
content()
@@ -34,6 +35,7 @@ fun AppLayoutContext.PageContent(
3435
content: @Composable ElementScope<HTMLElement>.() -> Unit,
3536
) {
3637
Main({
38+
classes(BaseStyles.main)
3739
attrs?.invoke(this)
3840
}) {
3941
Div({
@@ -51,6 +53,7 @@ fun AppLayoutContext.PageFooter(
5153
content: @Composable ElementScope<HTMLElement>.() -> Unit,
5254
) {
5355
Footer({
56+
classes(BaseStyles.footer)
5457
attrs?.invoke(this)
5558
}) {
5659
content()
+71
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
package components
2+
3+
import androidx.compose.runtime.Composable
4+
import common.ThemeVariables
5+
import org.jetbrains.compose.web.ExperimentalComposeWebApi
6+
import org.jetbrains.compose.web.css.*
7+
import org.jetbrains.compose.web.dom.ElementScope
8+
import org.jetbrains.compose.web.dom.Text
9+
import org.w3c.dom.HTMLElement
10+
11+
object ButtonStyles : StyleSheet() {
12+
@OptIn(ExperimentalComposeWebApi::class)
13+
val button by style {
14+
display(DisplayStyle.InlineBlock)
15+
padding(10.px, 20.px)
16+
fontSize(16.px)
17+
fontWeight("bold")
18+
color(ThemeVariables.mainColor.value())
19+
backgroundColor(ThemeVariables.backgroundColor.value())
20+
border { style = LineStyle.None }
21+
borderRadius(8.px)
22+
property("box-shadow", "0 4px 8px rgba(0, 0, 0, 0.2)")
23+
cursor("pointer")
24+
transitions {
25+
"transform" { duration = 0.2.s }
26+
"box-shadow" { duration = 0.2.s }
27+
}
28+
textAlign("center")
29+
textDecoration("none")
30+
31+
self + hover style {
32+
transform {
33+
translateY((-2).px)
34+
}
35+
property("box-shadow", "0 6px 12px rgba(0, 0, 0, 0.3)")
36+
}
37+
38+
self + active style {
39+
transform {
40+
translateY(0.px)
41+
}
42+
property("box-shadow", "0 2px 4px rgba(0, 0, 0, 0.2)")
43+
}
44+
}
45+
}
46+
47+
@Composable
48+
fun Button(
49+
text: String,
50+
onClick: () -> Unit,
51+
) {
52+
Button(onClick) { Text(text) }
53+
}
54+
55+
@Composable
56+
fun Button(
57+
onClick: () -> Unit,
58+
content: @Composable ElementScope<HTMLElement>.() -> Unit,
59+
) {
60+
Style(ButtonStyles)
61+
org.jetbrains.compose.web.dom.Button(
62+
attrs = {
63+
classes(ButtonStyles.button)
64+
onClick {
65+
onClick.invoke()
66+
}
67+
},
68+
) {
69+
content()
70+
}
71+
}

0 commit comments

Comments
 (0)