From e58a36a4e08ba7187b596c3f370c4a6e07ba595b Mon Sep 17 00:00:00 2001 From: yuta-ikeoku Date: Fri, 21 Jun 2024 00:54:57 +0900 Subject: [PATCH] responsive and refactor styles --- torisetsu/src/jsMain/kotlin/App.kt | 40 +++++++ torisetsu/src/jsMain/kotlin/Main.kt | 43 +------- .../jsMain/kotlin/components/base/Button.kt | 25 +---- .../kotlin/components/base/ButtonStyle.kt | 47 ++++++++ .../src/jsMain/kotlin/components/base/Card.kt | 13 +-- .../kotlin/components/base/CardStyle.kt | 18 +++ .../kotlin/components/base/PageLayout.kt | 51 ++------- .../kotlin/components/base/PageLayoutStyle.kt | 35 ++++++ .../kotlin/components/base/XShareButton.kt | 30 +---- .../components/base/XShareButtonStyle.kt | 29 +++++ .../jsMain/kotlin/components/pages/TopPage.kt | 103 ++++-------------- .../kotlin/components/pages/TopPageStyle.kt | 83 ++++++++++++++ .../src/jsMain/kotlin/style/GlobalStyle.kt | 31 ++++++ torisetsu/src/jsMain/kotlin/style/Utils.kt | 36 ++++++ torisetsu/src/jsMain/resources/index.html | 3 +- torisetsu/src/jsMain/resources/reset.css | 22 ---- 16 files changed, 362 insertions(+), 247 deletions(-) create mode 100644 torisetsu/src/jsMain/kotlin/App.kt create mode 100644 torisetsu/src/jsMain/kotlin/components/base/ButtonStyle.kt create mode 100644 torisetsu/src/jsMain/kotlin/components/base/CardStyle.kt create mode 100644 torisetsu/src/jsMain/kotlin/components/base/PageLayoutStyle.kt create mode 100644 torisetsu/src/jsMain/kotlin/components/base/XShareButtonStyle.kt create mode 100644 torisetsu/src/jsMain/kotlin/components/pages/TopPageStyle.kt create mode 100644 torisetsu/src/jsMain/kotlin/style/GlobalStyle.kt create mode 100644 torisetsu/src/jsMain/kotlin/style/Utils.kt delete mode 100644 torisetsu/src/jsMain/resources/reset.css diff --git a/torisetsu/src/jsMain/kotlin/App.kt b/torisetsu/src/jsMain/kotlin/App.kt new file mode 100644 index 0000000..6f21079 --- /dev/null +++ b/torisetsu/src/jsMain/kotlin/App.kt @@ -0,0 +1,40 @@ +import androidx.compose.runtime.* +import components.pages.QuizPage +import components.pages.ResultPage +import components.pages.TopPage +import core.ComposeQuiz +import core.ComposeResult +import core.Quiz +import core.Result + +@Composable +fun App() { + var resultId by remember { mutableStateOf(0) } + var currentPage by remember { mutableStateOf(Page.RESULT) } + val quiz: Quiz by remember { mutableStateOf(ComposeQuiz()) } + val result: Result by remember { mutableStateOf(ComposeResult()) } + + + when (currentPage) { + Page.TOP -> TopPage( + onClickStart = { currentPage = Page.QUIZ } + ) + + Page.QUIZ -> QuizPage( + quiz = quiz, + onClickFinish = { nextId: Int -> + resultId = nextId + currentPage = Page.RESULT + } + ) + + Page.RESULT -> ResultPage( + diagnosis = result.getDiagnosis(resultId), + onClickBack = { + quiz.reset() + resultId = 0 + currentPage = Page.TOP + } + ) + } +} \ No newline at end of file diff --git a/torisetsu/src/jsMain/kotlin/Main.kt b/torisetsu/src/jsMain/kotlin/Main.kt index 2120a57..86f4b9f 100644 --- a/torisetsu/src/jsMain/kotlin/Main.kt +++ b/torisetsu/src/jsMain/kotlin/Main.kt @@ -1,15 +1,6 @@ -import androidx.compose.runtime.getValue -import androidx.compose.runtime.mutableStateOf -import androidx.compose.runtime.remember -import androidx.compose.runtime.setValue -import components.pages.QuizPage -import components.pages.ResultPage -import components.pages.TopPage -import core.ComposeQuiz -import core.ComposeResult -import core.Quiz -import core.Result +import org.jetbrains.compose.web.css.Style import org.jetbrains.compose.web.renderComposable +import style.GlobalStyle enum class Page { TOP, @@ -19,33 +10,7 @@ enum class Page { fun main() { renderComposable(rootElementId = "root") { - var resultId by remember { mutableStateOf(0) } - var currentPage by remember { mutableStateOf(Page.TOP) } - val quiz: Quiz by remember { mutableStateOf(ComposeQuiz()) } - val result: Result by remember { mutableStateOf(ComposeResult()) } - - when (currentPage) { - Page.TOP -> TopPage( - onClickStart = { currentPage = Page.QUIZ } - ) - - Page.QUIZ -> QuizPage( - quiz = quiz, - onClickFinish = { nextId: Int -> - resultId = nextId - currentPage = Page.RESULT - } - ) - - Page.RESULT -> ResultPage( - diagnosis = result.getDiagnosis(resultId), - onClickBack = { - quiz.reset() - resultId = 0 - currentPage = Page.TOP - } - ) - } - + Style(GlobalStyle) + App() } } \ No newline at end of file diff --git a/torisetsu/src/jsMain/kotlin/components/base/Button.kt b/torisetsu/src/jsMain/kotlin/components/base/Button.kt index 539a826..d2c804b 100644 --- a/torisetsu/src/jsMain/kotlin/components/base/Button.kt +++ b/torisetsu/src/jsMain/kotlin/components/base/Button.kt @@ -1,7 +1,6 @@ package components.base import androidx.compose.runtime.Composable -import org.jetbrains.compose.web.css.* import org.jetbrains.compose.web.dom.Button enum class ButtonSize { @@ -17,29 +16,9 @@ fun Button( ) { Button( attrs = { - style { - when (size) { - ButtonSize.NORMAL -> { - padding(16.px, 36.px) - borderRadius(16.px) - fontSize(32.px) - } - - ButtonSize.LARGE -> { - padding(40.px, 100.px) - borderRadius(40.px) - fontSize(60.px) - } - } - backgroundImage("linear-gradient(#5772FF, #0054DD)") - color(Color.white) - fontWeight(700) - property( - "box-shadow", - "0px 5.13px 5.13px 0px #F9F7F340 inset, 0px -5.13px 5.13px 0px #00000040 inset" - ) - } + classes(ButtonStyle.rootElm) onClick { onClick() } + attr("data-size", size.name.lowercase()) } ) { content() diff --git a/torisetsu/src/jsMain/kotlin/components/base/ButtonStyle.kt b/torisetsu/src/jsMain/kotlin/components/base/ButtonStyle.kt new file mode 100644 index 0000000..030daf3 --- /dev/null +++ b/torisetsu/src/jsMain/kotlin/components/base/ButtonStyle.kt @@ -0,0 +1,47 @@ +package components.base + +import org.jetbrains.compose.web.css.* +import style.GlobalStyle +import style.data +import style.forMobile + +object ButtonStyle : StyleSheet(GlobalStyle) { + val rootElm by style { + data("size", "normal") { + padding(16.px, 36.px) + borderRadius(16.px) + fontSize(32.px) + } + + + data("size", "large") { + padding(40.px, 100.px) + borderRadius(40.px) + fontSize(60.px) + } + + forMobile { + data("size", "normal") { + padding(16.px, 36.px) + borderRadius(12.px) + fontSize(24.px) + } + + data("size", "large") { + padding(20.px, 50.px) + borderRadius(20.px) + fontSize(32.px) + } + } + + + + backgroundImage("linear-gradient(#5772FF, #0054DD)") + color(Color.white) + fontWeight(700) + property( + "box-shadow", + "0px 5.13px 5.13px 0px #F9F7F340 inset, 0px -5.13px 5.13px 0px #00000040 inset" + ) + } +} \ No newline at end of file diff --git a/torisetsu/src/jsMain/kotlin/components/base/Card.kt b/torisetsu/src/jsMain/kotlin/components/base/Card.kt index 4d14bdd..0a95979 100644 --- a/torisetsu/src/jsMain/kotlin/components/base/Card.kt +++ b/torisetsu/src/jsMain/kotlin/components/base/Card.kt @@ -1,24 +1,13 @@ package components.base import androidx.compose.runtime.Composable -import org.jetbrains.compose.web.css.* import org.jetbrains.compose.web.dom.Div @Composable fun Card( content: @Composable() () -> Unit ) { - Div( - attrs = { - style { - padding(32.px) - backgroundColor(rgb(255, 255, 255)) - borderRadius(16.px) - property("box-shadow", "0px 4px 4px rgba(0, 0, 0, 0.25), 0px 8px 6px rgba(0, 0, 0, 0.10)") - - } - } - ) { + Div(attrs = { classes(CardStyle.rootElm) }) { content() } } \ No newline at end of file diff --git a/torisetsu/src/jsMain/kotlin/components/base/CardStyle.kt b/torisetsu/src/jsMain/kotlin/components/base/CardStyle.kt new file mode 100644 index 0000000..a2f7215 --- /dev/null +++ b/torisetsu/src/jsMain/kotlin/components/base/CardStyle.kt @@ -0,0 +1,18 @@ +package components.base + +import org.jetbrains.compose.web.css.* +import style.GlobalStyle +import style.forMobile + +object CardStyle : StyleSheet(GlobalStyle) { + val rootElm by style { + padding(32.px) + backgroundColor(rgb(255, 255, 255)) + borderRadius(16.px) + property("box-shadow", "0px 4px 4px rgba(0, 0, 0, 0.25), 0px 8px 6px rgba(0, 0, 0, 0.10)") + + forMobile { + padding(24.px) + } + } +} \ No newline at end of file diff --git a/torisetsu/src/jsMain/kotlin/components/base/PageLayout.kt b/torisetsu/src/jsMain/kotlin/components/base/PageLayout.kt index 8d3d614..095432c 100644 --- a/torisetsu/src/jsMain/kotlin/components/base/PageLayout.kt +++ b/torisetsu/src/jsMain/kotlin/components/base/PageLayout.kt @@ -1,69 +1,36 @@ package components.base import androidx.compose.runtime.Composable -import org.jetbrains.compose.web.css.* import org.jetbrains.compose.web.dom.Div import org.jetbrains.compose.web.dom.Img +import org.jetbrains.compose.web.dom.Main @Composable fun PageLayout( content: @Composable() () -> Unit ) { return Div( - attrs = { - style { - padding(32.px, 12.px) - display(DisplayStyle.Flex) - flexDirection(FlexDirection.Column) - alignItems(AlignItems.Center) - } - } + attrs = { classes(PageLayoutStyle.rootElm) } ) { Div( - attrs = { - style { - width(649.px) - maxWidth(100.percent) - display(DisplayStyle.Flex) - alignItems(AlignItems.Center) - flexDirection(FlexDirection.Column) - } - } + attrs = { classes(PageLayoutStyle.wrapper) } ) { Div( - attrs = { - style { - display(DisplayStyle.Flex) - flexDirection(FlexDirection.Row) - gap(60.px) - } - } + attrs = { classes(PageLayoutStyle.header) } ) { Img( src = "./images/service_logo.svg", alt = "エンジニア トリ診断", - attrs = { - style { - width(150.px) - } - } + attrs = { classes(PageLayoutStyle.titleLogo) } ) Img( src = "./images/m3_logo_en.svg", alt = "M3 Inc.", - attrs = { - style { - width(160.px) - } - }) + attrs = { classes(PageLayoutStyle.m3Logo) } + ) } - Div( - attrs = { - style { - marginTop(40.px) - width(100.percent) - } - } + Main( + attrs = { classes(PageLayoutStyle.main) } ) { content() } diff --git a/torisetsu/src/jsMain/kotlin/components/base/PageLayoutStyle.kt b/torisetsu/src/jsMain/kotlin/components/base/PageLayoutStyle.kt new file mode 100644 index 0000000..c0ea3b9 --- /dev/null +++ b/torisetsu/src/jsMain/kotlin/components/base/PageLayoutStyle.kt @@ -0,0 +1,35 @@ +package components.base + +import org.jetbrains.compose.web.css.* +import style.GlobalStyle + +object PageLayoutStyle : StyleSheet(GlobalStyle) { + val rootElm by style { + padding(32.px, 24.px) + display(DisplayStyle.Flex) + flexDirection(FlexDirection.Column) + alignItems(AlignItems.Center) + } + val wrapper by style { + width(649.px) + maxWidth(100.percent) + display(DisplayStyle.Flex) + alignItems(AlignItems.Center) + flexDirection(FlexDirection.Column) + } + val header by style { + display(DisplayStyle.Flex) + flexDirection(FlexDirection.Row) + gap(60.px) + } + val titleLogo by style { + width(150.px) + } + val m3Logo by style { + width(160.px) + } + val main by style { + marginTop(40.px) + width(100.percent) + } +} \ No newline at end of file diff --git a/torisetsu/src/jsMain/kotlin/components/base/XShareButton.kt b/torisetsu/src/jsMain/kotlin/components/base/XShareButton.kt index 117a6e7..6f6223c 100644 --- a/torisetsu/src/jsMain/kotlin/components/base/XShareButton.kt +++ b/torisetsu/src/jsMain/kotlin/components/base/XShareButton.kt @@ -3,7 +3,6 @@ package components.base import androidx.compose.runtime.Composable import org.jetbrains.compose.web.attributes.ATarget import org.jetbrains.compose.web.attributes.target -import org.jetbrains.compose.web.css.* import org.jetbrains.compose.web.dom.A import org.jetbrains.compose.web.dom.Div import org.jetbrains.compose.web.dom.Img @@ -15,38 +14,15 @@ fun XShareButton() { href = "https://twitter.com/intent/tweet?text=私のトリタイプはハシビロコウです!&url=https://example.com&hashtags=トリタイプ診断", attrs = { target(ATarget.Blank) - style { - backgroundColor(rgb(0, 0, 0)) - color(Color.white) - padding(20.px, 32.px) - borderRadius(999.px) - textDecoration("none") - width(160.px) - display(DisplayStyle.Flex) - alignItems(AlignItems.Center) - gap(10.px) - justifyContent(JustifyContent.Center) - } + classes(XShareButtonStyle.rootElm) } - ) { Img( src = "/icons/x_icon.svg", - attrs = { - style { - width(20.px) - flexShrink(0) - property("aspect-ratio", "1") - } - } - + attrs = { classes(XShareButtonStyle.icon) } ) Div( - attrs = { - style { - flexShrink(0) - } - } + attrs = { classes(XShareButtonStyle.text) } ) { Text("Xでシェア") } diff --git a/torisetsu/src/jsMain/kotlin/components/base/XShareButtonStyle.kt b/torisetsu/src/jsMain/kotlin/components/base/XShareButtonStyle.kt new file mode 100644 index 0000000..165e5b3 --- /dev/null +++ b/torisetsu/src/jsMain/kotlin/components/base/XShareButtonStyle.kt @@ -0,0 +1,29 @@ +package components.base + +import org.jetbrains.compose.web.css.* +import style.GlobalStyle + +object XShareButtonStyle : StyleSheet(GlobalStyle) { + val rootElm by style { + backgroundColor(rgb(0, 0, 0)) + color(Color.white) + padding(20.px, 32.px) + borderRadius(999.px) + textDecoration("none") + width(160.px) + display(DisplayStyle.Flex) + alignItems(AlignItems.Center) + gap(10.px) + justifyContent(JustifyContent.Center) + } + + val icon by style { + width(20.px) + flexShrink(0) + property("aspect-ratio", "1") + } + + val text by style { + flexShrink(0) + } +} \ No newline at end of file diff --git a/torisetsu/src/jsMain/kotlin/components/pages/TopPage.kt b/torisetsu/src/jsMain/kotlin/components/pages/TopPage.kt index 0fd32cf..a449afa 100644 --- a/torisetsu/src/jsMain/kotlin/components/pages/TopPage.kt +++ b/torisetsu/src/jsMain/kotlin/components/pages/TopPage.kt @@ -1,77 +1,52 @@ package components.pages import androidx.compose.runtime.Composable -import components.base.ButtonSize import components.base.Button -import org.jetbrains.compose.web.css.* +import components.base.ButtonSize +import org.jetbrains.compose.web.css.marginTop +import org.jetbrains.compose.web.css.px import org.jetbrains.compose.web.dom.* @Composable fun TopPage( onClickStart: () -> Unit ) { - Div( - attrs = { - style { - display(DisplayStyle.Flex) - flexDirection(FlexDirection.Column) - alignItems(AlignItems.Center) - width(100.percent) - height(100.percent) - padding(100.px, 32.px) - } - } - ) { + Div(attrs = { classes(TopPageStyle.rootElm) }) { Div( attrs = { - style { - display(DisplayStyle.Flex) - flexDirection(FlexDirection.Column) - alignItems(AlignItems.Center) - justifyContent(JustifyContent.Center) - gap(30.px) - width(700.px) - maxWidth(90.percent) - } + classes(TopPageStyle.heroSection) } - ) { H1 { Img( src = "./images/service_logo.svg", attrs = { - style { - width(700.px) - maxWidth(100.percent) - } + classes(TopPageStyle.heroImage) } ) } Div { P( attrs = { - style { - fontSize(20.px) - color(Color.white) - fontWeight(700) - display(DisplayStyle.Flex) - alignItems(AlignItems.Center) - justifyContent(JustifyContent.SpaceBetween) - gap(32.px) - } + classes(TopPageStyle.catchphraseSection) } - ) { - Span { + Div({ classes(TopPageStyle.catchphraseText) }) { Text("トリあえず、やってみればーどうでしょう??") } - Span { - Text("by") + Div( + attrs = { + classes(TopPageStyle.by_m3) + } + ) { + Div { + Text("by") + } + Img( + src = "images/m3_logo_en.svg", + alt = "M3 Inc.", + ) } - Img( - src = "images/m3_logo_en.svg", - alt = "M3 Inc.", - ) } } @@ -88,43 +63,11 @@ fun TopPage( onClick = { onClickStart() }, size = ButtonSize.LARGE ) { - Span( - attrs = { - style { - fontSize(60.px) - fontWeight(700) - } - } - ) { - - Text("診断を始める") - } + Text("診断を始める") } } - Div( - attrs = { - style { - position(Position.Fixed) - bottom(0.px) - left(0.px) - right(0.px) - background("#0F0069") - height(68.px) - display(DisplayStyle.Flex) - alignItems(AlignItems.Center) - justifyContent(JustifyContent.Center) - property("z-index", -1) - } - } - ) { - P( - attrs = { - style { - color(Color.white) - fontSize(12.px) - } - } - ) { + Div(attrs = { classes(TopPageStyle.footer) }) { + P(attrs = { classes(TopPageStyle.footerText) }) { Text("@M3, Inc") } } diff --git a/torisetsu/src/jsMain/kotlin/components/pages/TopPageStyle.kt b/torisetsu/src/jsMain/kotlin/components/pages/TopPageStyle.kt new file mode 100644 index 0000000..f598887 --- /dev/null +++ b/torisetsu/src/jsMain/kotlin/components/pages/TopPageStyle.kt @@ -0,0 +1,83 @@ +package components.pages + +import org.jetbrains.compose.web.css.* +import style.GlobalStyle +import style.forMobile + +object TopPageStyle : StyleSheet(GlobalStyle) { + val rootElm by style { + display(DisplayStyle.Flex) + flexDirection(FlexDirection.Column) + alignItems(AlignItems.Center) + width(100.percent) + height(100.percent) + padding(100.px, 32.px) + + forMobile { + padding(64.px, 16.px) + } + } + + val heroSection by style { + display(DisplayStyle.Flex) + flexDirection(FlexDirection.Column) + alignItems(AlignItems.Center) + justifyContent(JustifyContent.Center) + gap(30.px) + width(700.px) + maxWidth(90.percent) + } + + val heroImage by style { + width(700.px) + maxWidth(100.percent) + } + + val catchphraseSection by style { + fontSize(20.px) + color(Color.white) + fontWeight(700) + display(DisplayStyle.Flex) + alignItems(AlignItems.Center) + justifyContent(JustifyContent.SpaceBetween) + gap(32.px) + + forMobile { + fontSize(16.px) + flexDirection(FlexDirection.Column) + } + } + + val by_m3 by style { + display(DisplayStyle.Flex) + alignItems(AlignItems.Center) + justifyContent(JustifyContent.Center) + gap(16.px) + } + + val catchphraseText by style { + flexGrow(1) + } + + val footer by style { + position(Position.Fixed) + bottom(0.px) + left(0.px) + right(0.px) + background("#0F0069") + height(68.px) + display(DisplayStyle.Flex) + alignItems(AlignItems.Center) + justifyContent(JustifyContent.Center) + property("z-index", -1) + } + + val footerText by style { + color(Color.white) + fontSize(16.px) + + forMobile { + fontSize(12.px) + } + } +} \ No newline at end of file diff --git a/torisetsu/src/jsMain/kotlin/style/GlobalStyle.kt b/torisetsu/src/jsMain/kotlin/style/GlobalStyle.kt new file mode 100644 index 0000000..75d5ee5 --- /dev/null +++ b/torisetsu/src/jsMain/kotlin/style/GlobalStyle.kt @@ -0,0 +1,31 @@ +package style + +import org.jetbrains.compose.web.css.* + +object GlobalStyle : StyleSheet() { + init { + universal style { + boxSizing("border-box") + } + + "body" style { + margin(0.px) + backgroundSize("auto auto") + backgroundColor(rgb(12, 31, 204)) + backgroundImage("repeating-linear-gradient(-45deg, rgb(12, 31, 204), rgb(12, 31, 204) 10px, rgba(10, 0, 146, 1) 10px, rgba(10, 0, 146, 1) 12px)") + minHeight(100.vh) + fontFamily("\"Noto Sans JP\", sans-serif") + property("font-optical-sizing", "auto") + } + + "h1, h2, h3, h4, h5, h6, p" style { + margin(0.px) + } + + "button" style { + backgroundColor(Color.transparent) + border(0.px) + cursor("pointer") + } + } +} \ No newline at end of file diff --git a/torisetsu/src/jsMain/kotlin/style/Utils.kt b/torisetsu/src/jsMain/kotlin/style/Utils.kt new file mode 100644 index 0000000..c7f666c --- /dev/null +++ b/torisetsu/src/jsMain/kotlin/style/Utils.kt @@ -0,0 +1,36 @@ +package style + +import org.jetbrains.compose.web.css.* +import org.jetbrains.compose.web.css.selectors.CSSSelector + +fun GenericStyleSheetBuilder.mobile( + cssSelector: CSSSelector, + rulesBuild: TBuilder.() -> Unit +) { + media(mediaMaxWidth(640.px)) { + cssSelector style rulesBuild + } +} + +fun CSSBuilder.forMobile(builder: CSSBuilder.() -> Unit) { + mobile(self, builder) +} + + +fun GenericStyleSheetBuilder.dataAttr( + selector: String, + value: String, + cssSelector: CSSSelector, + rulesBuild: TBuilder.() -> Unit +) { + (cssSelector + attrEquals("data-$selector", value, true)) style { + rulesBuild() + } +} + +fun CSSBuilder.data(selector: String, value: String, builder: CSSBuilder.() -> Unit) { +// (self + attrEquals(selector, value, true)) style { +// builder() +// } + dataAttr(selector, value, self, builder) +} \ No newline at end of file diff --git a/torisetsu/src/jsMain/resources/index.html b/torisetsu/src/jsMain/resources/index.html index e284245..3527e6f 100644 --- a/torisetsu/src/jsMain/resources/index.html +++ b/torisetsu/src/jsMain/resources/index.html @@ -1,5 +1,5 @@ - + エンジニア トリ診断 @@ -7,7 +7,6 @@ -
diff --git a/torisetsu/src/jsMain/resources/reset.css b/torisetsu/src/jsMain/resources/reset.css deleted file mode 100644 index 0183dc4..0000000 --- a/torisetsu/src/jsMain/resources/reset.css +++ /dev/null @@ -1,22 +0,0 @@ -body { - margin: 0; - background-size: auto auto; - background-image: repeating-linear-gradient(-45deg, rgb(12, 31, 204), rgb(12, 31, 204) 10px, rgba(10, 0, 146, 1) 10px, rgba(10, 0, 146, 1) 12px); - min-height: 100dvh; - font-family: "Noto Sans JP", sans-serif; - font-optical-sizing: auto; -} - -h1, h2, h3, h4, h5, h6, p { - margin: 0; -} - -button { - background-color: transparent; - border: none; - cursor: pointer; -} - -* { - box-sizing: border-box; -} \ No newline at end of file