From e69be49666aa60a36b1b9f2c76ef887a729d6cd3 Mon Sep 17 00:00:00 2001 From: Ethosa Date: Sun, 12 May 2024 23:33:45 +0700 Subject: [PATCH] implement Switcher --- README.md | 2 +- src/happyx_ui/input.nim | 100 ++++++++++++++++++++++++++++++++++++---- tests/test.nim | 7 +++ 3 files changed, 100 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 07ea95f..7dee199 100644 --- a/README.md +++ b/README.md @@ -28,7 +28,7 @@ This library was inspired by Jetpack Compose. It contains components that allow - [ ] `Stepper` (number changer); - [ ] `Tag` (for content); - [ ] `Tooltip`; -- [ ] `Switcher`; +- [x] `Switcher`; - [x] `ChildModifier` (applies modifier to all children (not recursive)); ### Complex Components diff --git a/src/happyx_ui/input.nim b/src/happyx_ui/input.nim index b417e3b..b072b73 100644 --- a/src/happyx_ui/input.nim +++ b/src/happyx_ui/input.nim @@ -48,7 +48,7 @@ proc Input*(onInput: OnInput = defOnInput, onFocus: OnFocus = defOnFocus, background-color: transparent; color: ; font-size: 18px; - padding: 0 .5rem; + padding: .1rem .5rem; } input.hpx-input-:hover { border-bottom-color: ; @@ -63,7 +63,7 @@ proc Input*(onInput: OnInput = defOnInput, onFocus: OnFocus = defOnFocus, opacity: .7; pointer-events: none; font-size: 16px; - padding: 0 .5rem; + padding: .1rem .5rem; } input.hpx-input-:focus + label.hpx-input-placeholder- { transform: scale(75%) translateX(-15%) translateY(-150%); @@ -117,7 +117,7 @@ proc OutlineInput*(onInput: OnInput = defOnInput, onFocus: OnFocus = defOnFocus, border-radius: .5rem; color: ; font-size: 18px; - padding: 0 .5rem; + padding: .1rem .5rem; } input.hpx-input-outline-:hover { border-color: ; @@ -132,7 +132,7 @@ proc OutlineInput*(onInput: OnInput = defOnInput, onFocus: OnFocus = defOnFocus, opacity: .7; pointer-events: none; font-size: 16px; - padding: 0 .5rem; + padding: .1rem .5rem; } input.hpx-input-outline-:focus + label.hpx-input-outline-placeholder- { transform: scale(75%) translateX(-15%) translateY(-150%); @@ -147,8 +147,7 @@ proc OutlineInput*(onInput: OnInput = defOnInput, onFocus: OnFocus = defOnFocus, proc Checkbox*(onToggle: OnToggle = defOnToggle, state: State[bool] = nil, modifier: Modifier = initModifier(), class: string = "", - id = "", - stmt: TagRef): TagRef = + id = "", stmt: TagRef): TagRef = let i = uid() buildHtml: tDiv(class = fmt"hpx-checkbox-container-{i} {class}"): @@ -158,8 +157,8 @@ proc Checkbox*(onToggle: OnToggle = defOnToggle, state: State[bool] = nil, tPath(d="M4 12.6111L8.92308 17.5L20 6.5", stroke=BACKGROUND_COLOR, "stroke-linecap"="round", "stroke-linejoin"="round", "stroke-width"="2") else: tDiv(class = fmt"hpx-checkbox-off-{i}") - tLabel(class = fmt"hpx-checkbox-label-{i}"): - if not stmt.isNil: + if not stmt.isNil: + tLabel(class = fmt"hpx-checkbox-label-{i}"): stmt @click: if not state.isNil and state.val: @@ -217,3 +216,88 @@ proc Checkbox*(onToggle: OnToggle = defOnToggle, state: State[bool] = nil, cursor: pointer; } """, '<', '>')} + + +proc Switcher*(onToggle: OnToggle = defOnToggle, state: State[bool] = nil, + modifier: Modifier = initModifier(), class: string = "", + id = "", stmt: TagRef): TagRef = + let + i = uid() + switchControlClass = + if not state.isNil and state.val: + fmt"hpx-switch-control-on-{i}" + else: + fmt"hpx-switch-control-off-{i}" + switchClass = + if not state.isNil and state.val: + fmt"hpx-switch-on-{i}" + else: + fmt"hpx-switch-off-{i}" + buildHtml: + tDiv(class = fmt"hpx-switch-container-{i} {class}"): + tDiv(class = fmt"hpx-switch-{i} {switchClass}"): + tDiv(class = fmt"hpx-switch-control-{i} {switchControlClass}") + if not stmt.isNil: + tLabel(class = fmt"hpx-switch-label-{i}"): + stmt + @click: + if not state.isNil and state.val: + onToggle(false) + if not state.isNil: + state.set(false) + else: + onToggle(true) + if not state.isNil: + state.set(true) + tStyle: {fmt(""" + div.hpx-switch-container- { + display: flex; + gap: .3rem; + align-items: center; + cursor: pointer; + } + + div.hpx-switch- { + border-radius: 2rem; + width: 48px; + height: 24px; + transition: all; + transition-duration: .3s; + position: relative; + align-items: center; + display: flex; + } + + div.hpx-switch-off- { + background-color: ; + } + + div.hpx-switch-on- { + background-color: ; + } + + div.hpx-switch-control- { + border-radius: 1rem; + position: absolute; + transition: all; + transition-duration: .3s; + width: 16px; + height: 16px; + } + + div.hpx-switch-control-off- { + right: 4px; + background-color: ; + } + + div.hpx-switch-control-on- { + left: 4px; + background-color: ; + } + + label.hpx-checkbox-label- { + font-size: 18px; + user-select: none; + cursor: pointer; + } + """, '<', '>')} diff --git a/tests/test.nim b/tests/test.nim index fb9f983..2bcf7ce 100644 --- a/tests/test.nim +++ b/tests/test.nim @@ -46,7 +46,14 @@ appRoutes "app": Text("There are checkboxes") Checkbox(state = isMale): "Are you male?" + Text("Progress bar 👀") Progress(state = amount) + Card(): + Column(1.rem): + Title("Other Inputs") + Text("switchers") + Switcher(state = isMale): + "Are you male?" Title("Containers 👀") Row(2.rem): Column():