From 1cb77f7c4cb27e40e368656b6536bb208d96aef9 Mon Sep 17 00:00:00 2001 From: Volpeon Date: Sat, 5 Feb 2022 18:32:31 +0100 Subject: Added text field --- src/_general.scss | 30 +++++--- src/_vars.scss | 38 ++++++---- src/index.scss | 12 ++- src/objects/_icon.scss | 40 ++++++++++ src/objects/_rule.scss | 2 - src/objects/_text-field.scss | 169 +++++++++++++++++++++++++++++++++++++++++++ tpl/index.pug | 32 +++++++- tpl/objects/icon.pug | 7 ++ tpl/objects/text-field.pug | 13 ++++ 9 files changed, 310 insertions(+), 33 deletions(-) create mode 100644 src/objects/_icon.scss create mode 100644 src/objects/_text-field.scss create mode 100644 tpl/objects/icon.pug create mode 100644 tpl/objects/text-field.pug diff --git a/src/_general.scss b/src/_general.scss index 82b9467..e03d0b3 100644 --- a/src/_general.scss +++ b/src/_general.scss @@ -52,18 +52,24 @@ ol { text-decoration: none; } -button { - box-sizing: content-box; - margin: 0; - padding: 0; - border: 0; - background-color: transparent; - color: currentColor; - font: inherit; - letter-spacing: inherit; - text-align: left; - text-transform: inherit; - appearance: none; + +button, +input, +textarea { + box-sizing: content-box; + margin: 0; + padding: 0; + border: 0; + background: none; + color: currentColor; + font-family: inherit; + font-size: 1em; + font-style: inherit; + font-weight: inherit; + line-height: inherit; + text-align: inherit; + text-transform: inherit; + appearance: none; &::-moz-focus-inner { border: 0; diff --git a/src/_vars.scss b/src/_vars.scss index d2bdf38..c315438 100644 --- a/src/_vars.scss +++ b/src/_vars.scss @@ -90,18 +90,6 @@ $line-height: map-get($font--main, line-height); ), --colors: ( - --gray1: hsl(210, 0%, 100%), // 1.11 - --gray2: hsl(210, 0%, 98%), // 1.07 - --gray3: hsl(210, 0%, 95%), // 1 - --gray4: hsl(210, 0%, 90%), // 1.11 - --gray5: hsl(210, 0%, 87%), // 1.2 - --gray6: hsl(210, 0%, 78%), // 1.51 - --gray7: hsl(210, 0%, 69%), // 1.93 - --gray8: hsl(210, 0%, 55%), // 3 - --gray9: hsl(210, 0%, 38%), // 5.53 - --gray10: hsl(210, 0%, 19%), // 11.78 - --gray11: hsl(210, 0%, 0%), // 18.75 - --bg-hi2: iro.props-get(--colors --gray1, null), // Lightest background --bg-hi: iro.props-get(--colors --gray2, null), // Lighter background --bg: iro.props-get(--colors --gray3, null), // Background @@ -167,6 +155,22 @@ $line-height: map-get($font--main, line-height); ), )); + @include iro.props-store(( + --colors: ( + --gray1: hsl(210, 0%, 100%), // 1.11 + --gray2: hsl(210, 0%, 98%), // 1.07 + --gray3: hsl(210, 0%, 95%), // 1 + --gray4: hsl(210, 0%, 90%), // 1.11 + --gray5: hsl(210, 0%, 87%), // 1.2 + --gray6: hsl(210, 0%, 78%), // 1.51 + --gray7: hsl(210, 0%, 69%), // 1.93 + --gray8: hsl(210, 0%, 55%), // 3 + --gray9: hsl(210, 0%, 38%), // 5.53 + --gray10: hsl(210, 0%, 19%), // 11.78 + --gray11: hsl(210, 0%, 0%), // 18.75 + ) + ), 'light-palette'); + @include iro.props-store(( --colors: ( --gray1: hsl(210, 0%, 100%), // 1 @@ -181,7 +185,7 @@ $line-height: map-get($font--main, line-height); --gray10: hsl(210, 0%, 22%), // 11.72 --gray11: hsl(210, 0%, 0%), // 21 ) - ), 'light-raised'); + ), 'light-raised-palette'); } // @@ -192,11 +196,17 @@ $line-height: map-get($font--main, line-height); --colors: () ), 'dark'); } + + @include iro.fn-execute { + @include iro.props-store(( + --colors: () + ), 'dark-palette'); + } @include iro.fn-execute { @include iro.props-store(( --colors: () - ), 'dark-raised'); + ), 'dark-raised-palette'); } } diff --git a/src/index.scss b/src/index.scss index 1d21d45..5a6a94c 100644 --- a/src/index.scss +++ b/src/index.scss @@ -6,12 +6,15 @@ @import 'layouts/container'; +@import 'objects/icon'; @import 'objects/heading'; @import 'objects/rule'; @import 'objects/button'; +@import 'objects/text-field'; :root { @include iro.props-assign; + @include iro.props-assign('light-palette'); @each $breakpoint in map-keys(media.$breakpoints) { @include media.media('<=#{$breakpoint}') { @@ -25,8 +28,8 @@ } @include iro.bem-theme('raised') { - @include iro.props-assign($root: --colors, $prefix: --colors); - @include iro.props-assign('light-raised'); + @include iro.props-assign('light-raised-palette'); + @include iro.props-assign; @include iro.bem-multi('at-theme' 'grayscale', 'theme' 'grayscale') { @include iro.props-assign($root: --colors --grayscale-accent, $prefix: --colors --accent); @@ -35,14 +38,15 @@ /*@media (prefers-color-scheme: dark) { @include iro.props-assign('dark'); + @include iro.props-assign('dark-palette'); @include iro.bem-theme('grayscale') { @include iro.props-assign('dark', $root: --colors --grayscale-accent, $prefix: --colors --accent); } @include iro.bem-theme('raised') { - @include iro.props-assign('dark', $root: --colors, $prefix: --colors); - @include iro.props-assign('dark-raised'); + @include iro.props-assign('dark-raised-palette'); + @include iro.props-assign('dark'); @include iro.bem-multi('at-theme' 'grayscale', 'theme' 'grayscale') { @include iro.props-assign('dark', $root: --colors --grayscale-accent, $prefix: --colors --accent); diff --git a/src/objects/_icon.scss b/src/objects/_icon.scss new file mode 100644 index 0000000..b9e3c0d --- /dev/null +++ b/src/objects/_icon.scss @@ -0,0 +1,40 @@ +@use 'iro-sass/src/index' as iro; + +@include iro.props-namespace('icon') { + @include iro.bem-object(iro.props-namespace()) { + display: inline-block; + width: 1em; + height: 1em; + stroke-width: var(--icon-stroke-width, 1.5px); + stroke-linecap: round; + stroke-linejoin: round; + vertical-align: -.1em; + + @include iro.bem-modifier('block') { + display: block; + } + } + + @keyframes rotate { + 100% { + transform: rotate(360deg); + } + } + + @keyframes dash { + 0% { + stroke-dasharray: 1, 200; + stroke-dashoffset: 0; + } + + 50% { + stroke-dasharray: 89, 200; + stroke-dashoffset: -35px; + } + + 100% { + stroke-dasharray: 89, 200; + stroke-dashoffset: -124px; + } + } +} diff --git a/src/objects/_rule.scss b/src/objects/_rule.scss index 74987da..bfd1240 100644 --- a/src/objects/_rule.scss +++ b/src/objects/_rule.scss @@ -1,6 +1,4 @@ @use 'iro-sass/src/index' as iro; -@use '../vars'; -@use '../mixins/typography'; @include iro.props-namespace('rule') { @include iro.props-store(( diff --git a/src/objects/_text-field.scss b/src/objects/_text-field.scss new file mode 100644 index 0000000..f2c3678 --- /dev/null +++ b/src/objects/_text-field.scss @@ -0,0 +1,169 @@ +@use 'iro-sass/src/index' as iro; +@use '../vars'; +@use '../mixins/typography'; + +@include iro.props-namespace('text-field') { + @include iro.props-store(( + --dims: ( + --padding-x: .6rem, + --padding-y: .5rem, + --border-width: iro.props-get(--dims --border-width --thin, $global: true), + --border-radius: 2px, + + --focus: ( + --border-width: iro.props-get(--dims --border-width --medium, $global: true), + ) + ), + --colors: ( + --bg: iro.props-get(--colors --bg-hi2, $global: true), + --placeholder: iro.props-get(--colors --fg-hi2, $global: true), + --text: iro.props-get(--colors --fg, $global: true), + --border: iro.props-get(--colors --obj-lo, $global: true), + --shadow: 0 0 0 0 transparent, + + --hover: ( + --border: iro.props-get(--colors --fg-hi2, $global: true), + --shadow: 0 0 0 0 transparent, + ), + --focus: ( + --border: iro.props-get(--colors --accent --primary, $global: true), + --shadow: 0 0 0 0 transparent, + ), + --key-focus: ( + --border: iro.props-get(--colors --focus --fill, $global: true), + --shadow: iro.props-get(--colors --focus --shadow, $global: true), + ), + --error: ( + --border: iro.props-get(--colors --accent --error-hi, $global: true), + --shadow: 0 0 0 0 transparent, + + --hover: ( + --border: iro.props-get(--colors --accent --error, $global: true), + --shadow: iro.props-get(--colors --text-input --error --shadow, null), + ), + --focus: ( + --border: iro.props-get(--colors --accent --error, $global: true), + --shadow: iro.props-get(--colors --text-input --error --shadow, null), + ), + ), + --disabled: ( + --bg: iro.props-get(--colors --obj-hi, $global: true), + --placeholder: iro.props-get(--colors --fg-hi3, $global: true), + --text: iro.props-get(--colors --fg-hi3, $global: true), + --border: iro.props-get(--colors --obj-hi, $global: true), + --shadow: 0 0 0 0 transparent, + ), + ), + )); + + @include iro.bem-object(iro.props-namespace()) { + position: relative; + min-width: 0; + padding: iro.props-get(--dims --padding-y) iro.props-get(--dims --padding-x); + background-color: iro.props-get(--colors --bg); + + @include iro.bem-elem('bg') { + display: block; + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + border: iro.props-get(--dims --border-width) solid iro.props-get(--colors --border); + border-radius: iro.props-get(--dims --border-radius); + box-shadow: iro.props-get(--colors --shadow); + pointer-events: none; + } + + @include iro.bem-elem('input') { + @include typography.set-font(vars.$font--main, (size: 1em, line-height: vars.$line-height)); + + display: block; + color: iro.props-get(--colors --text); + resize: none; + + &::placeholder { + opacity: 1; + color: iro.props-get(--colors --placeholder); + font-style: italic; + } + + &:hover { + @include iro.bem-sibling-elem('bg') { + border-color: iro.props-get(--colors --hover --border); + box-shadow: iro.props-get(--colors --hover --shadow); + } + } + + &:focus { + outline: 0; + + @include iro.bem-sibling-elem('bg') { + $offset: calc(iro.props-get(--dims --border-width) - iro.props-get(--dims --focus --border-width)); + + top: $offset; + right: $offset; + bottom: $offset; + left: $offset; + border: iro.props-get(--dims --focus --border-width) solid iro.props-get(--colors --focus --border); + border-radius: calc(iro.props-get(--dims --border-radius) - $offset); + box-shadow: iro.props-get(--colors --focus --shadow); + } + } + + &:invalid { + @include iro.bem-sibling-elem('bg') { + border-color: iro.props-get(--colors --error --border); + box-shadow: iro.props-get(--colors --error --shadow); + } + + &:hover { + @include iro.bem-sibling-elem('bg') { + border-color: iro.props-get(--colors --error --hover --border); + box-shadow: iro.props-get(--colors --error --hover --shadow); + } + } + + &:focus { + @include iro.bem-sibling-elem('bg') { + border-color: iro.props-get(--colors --error --focus --border); + box-shadow: iro.props-get(--colors --error --focus --shadow); + } + } + } + + @include iro.bem-at-theme('keyboard') { + &:focus { + @include iro.bem-sibling-elem('bg') { + border-color: iro.props-get(--colors --key-focus --border); + box-shadow: iro.props-get(--colors --key-focus --shadow); + } + } + } + } + + @include iro.bem-modifier('fill') { + padding: 0; + + @include iro.bem-elem('input') { + padding: iro.props-get(--dims --padding-y) iro.props-get(--dims --padding-x); + } + } + + @include iro.bem-is('disabled') { + background-color: iro.props-get(--colors --disabled --bg); + + @include iro.bem-elem('input') { + color: iro.props-get(--colors --disabled --text); + + &::placeholder { + color: iro.props-get(--colors --disabled --placeholder); + } + } + + @include iro.bem-elem('bg') { + border-color: iro.props-get(--colors --disabled --border); + } + } + } +} diff --git a/tpl/index.pug b/tpl/index.pug index 47dbc55..7dab86f 100644 --- a/tpl/index.pug +++ b/tpl/index.pug @@ -6,6 +6,7 @@ include layouts/container.pug include objects/heading.pug include objects/rule.pug include objects/button.pug +include objects/text-field.pug mixin box +container(padX=true padY=true inPage=true theme="raised") @@ -21,7 +22,7 @@ html link(rel="stylesheet" href="style.css") script(src="script.js") - body(class='t-lighter') + body +container(padX=true padY=true narrow=true) +h1-heading(level='xl')= 'Heading' @@ -91,3 +92,32 @@ html +a-button(variant='secondary' outline=true)= 'Button' = ' ' +a-button(variant='secondary' outline=true disabled=true)= 'Button' + + //----------------------------------------- + + +h1-heading(level='xl')= 'Text field' + +rule(level='medium') + + +box + +text-field(placeholder='Placeholder') + br + br + +text-field(value='Just landed in L.A.') + br + br + +text-field(value='Readonly' readonly=true) + br + br + +text-field(value='Incorrect input' pattern='a+' required=true) + br + br + +text-field(placeholder='Placeholder' disabled=true) + br + br + +text-field(value='Just landed in L.A.' disabled=true) + br + br + +text-field(value='Readonly' readonly=true disabled=true) + br + br + +text-field(value='Incorrect input' pattern='a+' required=true disabled=true) diff --git a/tpl/objects/icon.pug b/tpl/objects/icon.pug new file mode 100644 index 0000000..a77a3ed --- /dev/null +++ b/tpl/objects/icon.pug @@ -0,0 +1,7 @@ +mixin icon(id) + - + let href = '../node_modules/iro-icons/src/icons/' + id + '.svg' + let classes = attributes.class ? attributes.class : '' + + svg(class=['o-icon', 'o-icon--iro', 'o-icon--iro-' + id, classes] width='1em' height='1em') + use(xlink:href=href) diff --git a/tpl/objects/text-field.pug b/tpl/objects/text-field.pug new file mode 100644 index 0000000..9bbe0a1 --- /dev/null +++ b/tpl/objects/text-field.pug @@ -0,0 +1,13 @@ +include icon.pug + +mixin text-field + - + let classes = { + 'o-text-field': true, + 'is-invalid': attributes.invalid, + 'is-disabled': attributes.disabled, + } + + div(class=classes) + input(class='o-text-field__input')&attributes(attributes) + .o-text-field__bg -- cgit v1.2.3-70-g09d2