From ea8b0bc19219f6f931e3be757c25743c2c828b2e Mon Sep 17 00:00:00 2001 From: Volpeon Date: Sun, 6 Feb 2022 10:28:10 +0100 Subject: Added checkbox and switch --- src/index.scss | 2 + src/objects/_button.scss | 11 +-- src/objects/_checkbox.scss | 238 +++++++++++++++++++++++++++++++++++++++++++++ src/objects/_radio.scss | 56 +++++++---- src/objects/_switch.scss | 217 +++++++++++++++++++++++++++++++++++++++++ 5 files changed, 496 insertions(+), 28 deletions(-) create mode 100644 src/objects/_checkbox.scss create mode 100644 src/objects/_switch.scss (limited to 'src') diff --git a/src/index.scss b/src/index.scss index faa053e..c945321 100644 --- a/src/index.scss +++ b/src/index.scss @@ -13,6 +13,8 @@ @import 'objects/text-field'; @import 'objects/field-label'; @import 'objects/radio'; +@import 'objects/checkbox'; +@import 'objects/switch'; :root { @include iro.props-assign; diff --git a/src/objects/_button.scss b/src/objects/_button.scss index 5da1fbd..3932575 100644 --- a/src/objects/_button.scss +++ b/src/objects/_button.scss @@ -55,7 +55,7 @@ --accent: ( --bg: iro.props-get(--colors --accent --primary, $global: true), --label: iro.props-get(--colors --accent --primary-fg, $global: true), - --outline-label: iro.props-get(--colors --accent --primary-lo2, $global: true), + --outline-label: iro.props-get(--colors --accent --primary-lo, $global: true), --shadow: 0 0 0 0 transparent, --hover: ( @@ -130,12 +130,9 @@ @include button-variant('secondary'); - @each $mod in ('accent' 'primary' 'secondary') { - @if $mod != 'secondary' { - @include iro.bem-modifier($mod) { - // sass-lint:disable-block function-name-format - @include button-variant($mod); - } + @each $mod in ('accent' 'primary') { + @include iro.bem-modifier($mod) { + @include button-variant($mod); } } diff --git a/src/objects/_checkbox.scss b/src/objects/_checkbox.scss new file mode 100644 index 0000000..606b717 --- /dev/null +++ b/src/objects/_checkbox.scss @@ -0,0 +1,238 @@ +@use 'iro-sass/src/index' as iro; + +@include iro.props-namespace('checkbox') { + @include iro.props-store(( + --dims: ( + --size: iro.fn-px-to-rem(14px), + --label-gap: .6rem, + --border-width: iro.props-get(--dims --border-width --medium, $global: true), + --padding-x: .3rem, + --padding-y: .3rem, + --margin-right: iro.props-get(--dims --spacing --x --md, $global: true), + ), + --colors: ( + --box-border: iro.props-get(--colors --fg-hi, $global: true), + --box-bg: iro.props-get(--colors --bg-hi, $global: true), + + --hover: ( + --label: iro.props-get(--colors --fg-lo, $global: true), + --box-border: iro.props-get(--colors --fg, $global: true), + ), + --accent: ( + --box-border: iro.props-get(--colors --accent --primary, $global: true), + + --hover: ( + --box-border: iro.props-get(--colors --accent --primary-lo, $global: true), + ), + ), + --key-focus: ( + --label: iro.props-get(--colors --focus --text, $global: true), + --box-border: iro.props-get(--colors --focus --fill, $global: true), + --shadow: iro.props-get(--colors --focus --shadow, $global: true), + ), + --disabled: ( + --label: iro.props-get(--colors --fg-hi3, $global: true), + --box-border: iro.props-get(--colors --obj-lo, $global: true), + --box-bg: iro.props-get(--colors --bg-hi, $global: true), + ) + ), + )); + + @include iro.bem-object(iro.props-namespace()) { + display: inline-flex; + position: relative; + align-items: flex-start; + margin-right: calc(-1 * #{iro.props-get(--dims --padding-x)} + #{iro.props-get(--dims --margin-right)}); + margin-left: calc(-1 * #{iro.props-get(--dims --padding-x)}); + padding: iro.props-get(--dims --padding-y) iro.props-get(--dims --padding-x); // sass-lint:disable-line shorthand-values + + @include iro.bem-elem('box') { + display: block; + position: relative; + flex: 0 0 auto; + width: iro.props-get(--dims --size); + height: iro.props-get(--dims --size); + margin-top: calc(.5 * (#{$line-height * 1em} - #{iro.props-get(--dims --size)})); + border-radius: iro.props-get(--dims --border-width); + background-color: iro.props-get(--colors --box-border); + + &::before, + &::after { + content: ''; + display: block; + position: absolute; + } + + &::before { + z-index: 2; + top: iro.props-get(--dims --border-width); + left: iro.props-get(--dims --border-width); + width: calc(iro.props-get(--dims --size) - 2 * iro.props-get(--dims --border-width)); + height: calc(iro.props-get(--dims --size) - 2 * iro.props-get(--dims --border-width)); + transition: transform .2s ease; + background-color: iro.props-get(--colors --box-bg); + } + + &::after { + z-index: 3; + top: calc(.5 * #{iro.props-get(--dims --size)} - 1px); + left: calc(1.5 * #{iro.props-get(--dims --border-width)}); + box-sizing: border-box; + width: calc(iro.props-get(--dims --size) - 3 * iro.props-get(--dims --border-width)); + height: 0; + transform: scale(0); + transition: transform .2s ease; + border-width: 0 2px 2px 0; + border-style: solid; + border-radius: 2px; + border-color: iro.props-get(--colors --box-bg); + } + } + + @include iro.bem-elem('check-icon') { + display: block; + position: absolute; + z-index: 2; + top: calc(1 * iro.props-get(--dims --border-width)); + left: calc(1 * iro.props-get(--dims --border-width)); + width: calc(100% - 2 * iro.props-get(--dims --border-width)); + height: calc(100% - 2 * iro.props-get(--dims --border-width)); + transform: scale(0); + transform-origin: 40% 90%; + transition: transform .2s ease; + stroke-width: iro.fn-px-to-rem(3px); + color: iro.props-get(--colors --box-bg); + } + + @include iro.bem-elem('label') { + margin-left: iro.props-get(--dims --label-gap); + } + + @include iro.bem-elem('native') { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + margin: 0; + padding: 0; + overflow: hidden; + opacity: .0001; + + &:hover { + @include iro.bem-sibling-elem('label') { + color: iro.props-get(--colors --hover --label); + } + + @include iro.bem-sibling-elem('box') { + background-color: iro.props-get(--colors --hover --box-border); + } + } + + &:checked { + @include iro.bem-sibling-elem('box') { + &::before { + transform: scale(0); + } + + @include iro.bem-elem('check-icon') { + transform: scale(1); + } + } + } + + &:indeterminate { + @include iro.bem-sibling-elem('box') { + &::before { + transform: scale(0); + } + + &::after { + transform: scale(1); + } + + @include iro.bem-elem('check-icon') { + transform: scale(0); + } + } + } + + &:disabled { + @include iro.bem-sibling-elem('label') { + color: iro.props-get(--colors --disabled --label); + } + + @include iro.bem-sibling-elem('box') { + background-color: iro.props-get(--colors --disabled --box-border); + + &::before { + background-color: iro.props-get(--colors --disabled --box-bg); + } + } + } + + @include iro.bem-at-theme('keyboard') { + &:focus { + @include iro.bem-sibling-elem('label') { + color: iro.props-get(--colors --key-focus --label); + } + + @include iro.bem-sibling-elem('box') { + background-color: iro.props-get(--colors --key-focus --box-border); + box-shadow: iro.props-get(--colors --key-focus --shadow); + } + } + } + } + + @include iro.bem-modifier('accent') { + @include iro.bem-elem('native') { + &:checked { + @include iro.bem-sibling-elem('box') { + background-color: iro.props-get(--colors --accent --box-border); + } + + &:hover { + @include iro.bem-sibling-elem('box') { + background-color: iro.props-get(--colors --accent --hover --box-border); + } + } + } + + &:indeterminate { + @include iro.bem-sibling-elem('box') { + background-color: iro.props-get(--colors --accent --box-border); + } + + &:hover { + @include iro.bem-sibling-elem('box') { + background-color: iro.props-get(--colors --accent --hover --box-border); + } + } + } + + &:disabled { + @include iro.bem-sibling-elem('box') { + background-color: iro.props-get(--colors --disabled --box-border); + + &::before { + background-color: iro.props-get(--colors --disabled --box-bg); + } + } + + &:checked { + @include iro.bem-sibling-elem('box') { + background-color: iro.props-get(--colors --disabled --box-border); + } + } + + &:indeterminate { + @include iro.bem-sibling-elem('box') { + background-color: iro.props-get(--colors --disabled --box-border); + } + } + } + } + } + } +} diff --git a/src/objects/_radio.scss b/src/objects/_radio.scss index 635a260..bb32cdf 100644 --- a/src/objects/_radio.scss +++ b/src/objects/_radio.scss @@ -11,14 +11,14 @@ --margin-right: iro.props-get(--dims --spacing --x --md, $global: true), ), --colors: ( - --circle-border: iro.props-get(--colors --fg-hi2, $global: true), + --circle-border: iro.props-get(--colors --fg-hi, $global: true), --circle-bg: iro.props-get(--colors --bg-hi, $global: true), --hover: ( --label: iro.props-get(--colors --fg-lo, $global: true), - --circle-border: iro.props-get(--colors --fg-hi, $global: true), + --circle-border: iro.props-get(--colors --fg, $global: true), ), - --active: ( + --accent: ( --circle-border: iro.props-get(--colors --accent --primary, $global: true), --hover: ( @@ -34,10 +34,6 @@ --label: iro.props-get(--colors --fg-hi3, $global: true), --circle-border: iro.props-get(--colors --obj-lo, $global: true), --circle-bg: iro.props-get(--colors --bg-hi, $global: true), - - --active: ( - --circle-border: iro.props-get(--colors --obj-lo, $global: true), - ), ) ), )); @@ -104,18 +100,10 @@ &:checked { @include iro.bem-sibling-elem('circle') { - background-color: iro.props-get(--colors --active --circle-border); - &::after { transform: translateY(-50%) scale(.44); } } - - &:hover { - @include iro.bem-sibling-elem('circle') { - background-color: iro.props-get(--colors --active --hover --circle-border); - } - } } &:disabled { @@ -130,12 +118,6 @@ background-color: iro.props-get(--colors --disabled --circle-bg); } } - - &:checked { - @include iro.bem-sibling-elem('circle') { - background-color: iro.props-get(--colors --disabled --active --circle-border); - } - } } @include iro.bem-at-theme('keyboard') { @@ -151,5 +133,37 @@ } } } + + @include iro.bem-modifier('accent') { + @include iro.bem-elem('native') { + &:checked { + @include iro.bem-sibling-elem('circle') { + background-color: iro.props-get(--colors --accent --circle-border); + } + + &:hover { + @include iro.bem-sibling-elem('circle') { + background-color: iro.props-get(--colors --accent --hover --circle-border); + } + } + } + + &:disabled { + @include iro.bem-sibling-elem('circle') { + background-color: iro.props-get(--colors --disabled --circle-border); + + &::after { + background-color: iro.props-get(--colors --disabled --circle-bg); + } + } + + &:checked { + @include iro.bem-sibling-elem('circle') { + background-color: iro.props-get(--colors --disabled --circle-border); + } + } + } + } + } } } diff --git a/src/objects/_switch.scss b/src/objects/_switch.scss new file mode 100644 index 0000000..25125da --- /dev/null +++ b/src/objects/_switch.scss @@ -0,0 +1,217 @@ +@use 'iro-sass/src/index' as iro; + +@include iro.props-namespace('switch') { + @include iro.props-store(( + --dims: ( + --width: iro.fn-px-to-rem(26px), + --height: iro.fn-px-to-rem(15px), + --label-gap: .6rem, + --border-width: iro.props-get(--dims --border-width --medium, $global: true), + --padding-x: .3rem, + --padding-y: .3rem, + --margin-right: iro.props-get(--dims --spacing --x --md, $global: true), + ), + --colors: ( + --track-bg: iro.props-get(--colors --obj, $global: true), + --handle-border: iro.props-get(--colors --fg-hi, $global: true), + --handle-bg: iro.props-get(--colors --bg-hi, $global: true), + + --hover: ( + --label: iro.props-get(--colors --fg-lo, $global: true), + --handle-border: iro.props-get(--colors --fg, $global: true), + ), + --accent: ( + --handle-border: iro.props-get(--colors --accent --primary, $global: true), + + --hover: ( + --handle-border: iro.props-get(--colors --accent --primary-lo, $global: true), + ), + ), + --key-focus: ( + --label: iro.props-get(--colors --focus --text, $global: true), + --track-bg: iro.props-get(--colors --focus --fill, $global: true), + --handle-border: iro.props-get(--colors --focus --fill, $global: true), + --shadow: iro.props-get(--colors --focus --shadow, $global: true), + ), + --disabled: ( + --label: iro.props-get(--colors --fg-hi3, $global: true), + --track-bg: iro.props-get(--colors --obj, $global: true), + --handle-border: iro.props-get(--colors --obj-lo, $global: true), + --handle-bg: iro.props-get(--colors --bg-hi, $global: true), + ) + ), + )); + + @include iro.bem-object(iro.props-namespace()) { + display: inline-flex; + position: relative; + align-items: flex-start; + margin-right: calc(-1 * iro.props-get(--dims --padding-x) + iro.props-get(--dims --margin-right)); + margin-left: calc(-1 * iro.props-get(--dims --padding-x)); + padding: iro.props-get(--dims --padding-y) iro.props-get(--dims --padding-x); // sass-lint:disable-line shorthand-values + + @include iro.bem-elem('indicator') { + display: block; + position: relative; + box-sizing: border-box; + flex: 0 0 auto; + width: iro.props-get(--dims --width); + height: iro.props-get(--dims --height); + margin-top: calc(.5 * ($line-height * 1em - iro.props-get(--dims --height))); + transition: background-color .2s ease; + border-radius: 2em; + background-color: iro.props-get(--colors --track-bg); + + &::after { + content: ''; + display: block; + position: absolute; + z-index: 10; + top: 50%; + left: 0; + width: calc(iro.props-get(--dims --height) - 2 * iro.props-get(--dims --border-width)); + height: calc(iro.props-get(--dims --height) - 2 * iro.props-get(--dims --border-width)); + transform: translateY(-50%); + transition: left .2s ease; + border: iro.props-get(--dims --border-width) solid iro.props-get(--colors --handle-border); + border-radius: iro.props-get(--dims --width); + background-color: iro.props-get(--colors --handle-bg); + } + } + + @include iro.bem-elem('label') { + margin-left: iro.props-get(--dims --label-gap); + } + + @include iro.bem-elem('native') { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + margin: 0; + padding: 0; + overflow: hidden; + opacity: .0001; + + &:hover { + @include iro.bem-sibling-elem('label') { + color: iro.props-get(--colors --hover --label); + } + + @include iro.bem-sibling-elem('indicator') { + &::after { + border-color: iro.props-get(--colors --hover --handle-border); + } + } + } + + &:checked { + @include iro.bem-sibling-elem('indicator') { + background-color: iro.props-get(--colors --handle-border); + + &::after { + left: calc(#{iro.props-get(--dims --width)} - #{iro.props-get(--dims --height)} + .5px); + border-color: iro.props-get(--colors --handle-border); + } + } + + &:hover { + @include iro.bem-sibling-elem('indicator') { + background-color: iro.props-get(--colors --hover --handle-border); + + &::after { + border-color: iro.props-get(--colors --hover --handle-border); + } + } + } + } + + &:disabled { + @include iro.bem-sibling-elem('label') { + color: iro.props-get(--colors --disabled --label); + } + + @include iro.bem-sibling-elem('indicator') { + background-color: iro.props-get(--colors --disabled --track-bg); + + &::after { + border-color: iro.props-get(--colors --disabled --handle-border); + background-color: iro.props-get(--colors --disabled --handle-bg); + } + } + + &:checked { + @include iro.bem-sibling-elem('indicator') { + background-color: iro.props-get(--colors --disabled --handle-border); + + &::after { + border-color: iro.props-get(--colors --disabled --handle-border); + } + } + } + } + + @include iro.bem-at-theme('keyboard') { + &:focus { + @include iro.bem-sibling-elem('label') { + color: iro.props-get(--colors --key-focus --label); + } + + @include iro.bem-sibling-elem('indicator') { + &::after { + border-color: iro.props-get(--colors --key-focus --handle-border); + box-shadow: iro.props-get(--colors --key-focus --shadow); + } + } + + &:checked { + @include iro.bem-sibling-elem('indicator') { + background-color: iro.props-get(--colors --key-focus --track-bg); + } + } + } + } + } + + @include iro.bem-modifier('accent') { + @include iro.bem-elem('native') { + &:checked { + @include iro.bem-sibling-elem('indicator') { + background-color: iro.props-get(--colors --accent --handle-border); + + &::after { + border-color: iro.props-get(--colors --accent --handle-border); + } + } + + &:hover { + @include iro.bem-sibling-elem('indicator') { + background-color: iro.props-get(--colors --accent --hover --handle-border); + + &::after { + border-color: iro.props-get(--colors --accent --hover --handle-border); + } + } + } + } + + &:disabled { + @include iro.bem-sibling-elem('label') { + color: iro.props-get(--colors --disabled --label); + } + + &:checked { + @include iro.bem-sibling-elem('indicator') { + background-color: iro.props-get(--colors --disabled --handle-border); + + &::after { + border-color: iro.props-get(--colors --disabled --handle-border); + } + } + } + } + } + } + } +} -- cgit v1.2.3-70-g09d2