From 4ef7ba48a68980c126b89bf5ba5a9ddac804f88f Mon Sep 17 00:00:00 2001 From: Volpeon Date: Sun, 17 Nov 2024 15:51:24 +0100 Subject: Add navbar --- src/_iro-design.scss | 1 + src/objects/_action-button.vars.scss | 8 +- src/objects/_navbar.scss | 165 +++++++++++++++++++++++++++++++++++ src/objects/_navbar.vars.scss | 83 ++++++++++++++++++ src_demo/index.scss | 1 + tpl/index.pug | 3 + tpl/objects/navbar.pug | 30 +++++++ tpl/views/navbar.pug | 13 +++ 8 files changed, 300 insertions(+), 4 deletions(-) create mode 100644 src/objects/_navbar.scss create mode 100644 src/objects/_navbar.vars.scss create mode 100644 tpl/objects/navbar.pug create mode 100644 tpl/views/navbar.pug diff --git a/src/_iro-design.scss b/src/_iro-design.scss index ac07846..6088344 100644 --- a/src/_iro-design.scss +++ b/src/_iro-design.scss @@ -56,6 +56,7 @@ $breakpoints: ( @forward 'objects/icon' as o-icon--*; @forward 'objects/lightbox' as o-lightbox--*; @forward 'objects/menu' as o-menu--*; +@forward 'objects/navbar' as o-navbar--*; @forward 'objects/palette' as o-palette--*; @forward 'objects/popover' as o-popover--*; @forward 'objects/radio' as o-radio--*; diff --git a/src/objects/_action-button.vars.scss b/src/objects/_action-button.vars.scss index 9de985a..8c3d510 100644 --- a/src/objects/_action-button.vars.scss +++ b/src/objects/_action-button.vars.scss @@ -5,7 +5,7 @@ $line-height: props.def(--o-action-button--line-height, 1.4) !default; $pad-i: props.def(--o-action-button--pad-i, props.get(core.$size--150)) !default; -$pad-i-label: props.def(--o-button--pad-i-label, props.get(core.$size--50)) !default; +$pad-i-label: props.def(--o-action-button--pad-i-label, props.get(core.$size--50)) !default; $pad-i-pill: props.def(--o-action-button--pad-i-pill, props.get(core.$size--200)) !default; $pad-b: props.def(--o-action-button--pad-b, props.get(core.$size--85)) !default; $border-width: props.def(--o-action-button--border-width, props.get(core.$border-width--thin)) !default; @@ -13,19 +13,19 @@ $rounding: props.def(--o-action-button--rounding, props.get(core.$rounding)) $font-size: props.def(--o-action-button--font-size, props.get(core.$font-size--100)) !default; $pad-i--sm: props.def(--o-action-button--sm--pad-i, props.get(core.$size--100)) !default; -$pad-i-label--sm: props.def(--o-button--sm--pad-i-label, props.get(core.$size--25)) !default; +$pad-i-label--sm: props.def(--o-action-button--sm--pad-i-label, props.get(core.$size--25)) !default; $pad-i-pill--sm: props.def(--o-action-button--sm--pad-i-pill, props.get(core.$size--150)) !default; $pad-b--sm: props.def(--o-action-button--sm--pad-b, props.get(core.$size--40)) !default; $font-size--sm: props.def(--o-action-button--sm--font-size, props.get(core.$font-size--75)) !default; $pad-i--lg: props.def(--o-action-button--lg--pad-i, props.get(core.$size--175)) !default; -$pad-i-label--lg: props.def(--o-button--lg--pad-i-label, props.get(core.$size--100)) !default; +$pad-i-label--lg: props.def(--o-action-button--lg--pad-i-label, props.get(core.$size--100)) !default; $pad-i-pill--lg: props.def(--o-action-button--lg--pad-i-pill, props.get(core.$size--250)) !default; $pad-b--lg: props.def(--o-action-button--lg--pad-b, props.get(core.$size--115)) !default; $font-size--lg: props.def(--o-action-button--lg--font-size, props.get(core.$font-size--150)) !default; $pad-i--xl: props.def(--o-action-button--xl--pad-i, props.get(core.$size--225)) !default; -$pad-i-label--xl: props.def(--o-button--xl--pad-i-label, props.get(core.$size--150)) !default; +$pad-i-label--xl: props.def(--o-action-button--xl--pad-i-label, props.get(core.$size--150)) !default; $pad-i-pill--xl: props.def(--o-action-button--xl--pad-i-pill, props.get(core.$size--300)) !default; $pad-b--xl: props.def(--o-action-button--xl--pad-b, props.get(core.$size--150)) !default; $font-size--xl: props.def(--o-action-button--xl--font-size, props.get(core.$font-size--200)) !default; diff --git a/src/objects/_navbar.scss b/src/objects/_navbar.scss new file mode 100644 index 0000000..16cf804 --- /dev/null +++ b/src/objects/_navbar.scss @@ -0,0 +1,165 @@ +@use 'sass:map'; +@use 'sass:meta'; +@use 'sass:string'; +@use 'iro-sass/src/bem'; +@use 'iro-sass/src/props'; +@use '../props' as *; + +@forward 'navbar.vars'; +@use 'navbar.vars' as vars; + +@mixin styles { + @include materialize-at-root(meta.module-variables('vars')); + + @include bem.object('navbar') { + display: flex; + block-size: props.get(vars.$block-size); + + @include bem.modifier('adapt') { + block-size: 100%; + } + + @include bem.elem('item-label') { + position: relative; + padding-block: props.get(vars.$item--pad-b); + padding-inline: props.get(vars.$item--pad-i); + font-size: props.get(vars.$item--font-size); + color: currentColor; + border-radius: 100em; + + &::after { + position: absolute; + inset: calc(-1 * props.get(vars.$key-focus--border-offset)); + z-index: 1; + display: none; + pointer-events: none; + content: ''; + border-radius: 100em; + outline: props.get(vars.$default-theme, --key-focus, --border) solid props.get(vars.$key-focus--border-width); + box-shadow: + 0 + 0 + 0 + calc(props.get(vars.$key-focus--border-width) + props.get(vars.$key-focus--outline-width)) + props.get(vars.$default-theme, --key-focus, --outline); + } + } + + @include bem.elem('item') { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + inline-size: 100%; + padding-inline: calc(.5 * props.get(vars.$spacing)); + font-weight: 500; + color: props.get(vars.$default-theme, --disabled, --label-color); + + &:link, + &:visited, + &:enabled { + color: props.get(vars.$default-theme, --label-color); + + &:hover, + &:focus-visible { + color: props.get(vars.$default-theme, --hover, --label-color); + + @include bem.elem('item-label') { + background-color: props.get(vars.$default-theme, --hover, --bg-color); + } + } + + &:focus-visible { + @include bem.elem('item-label') { + &::after { + display: block; + } + } + } + + &:active { + color: props.get(vars.$default-theme, --active, --label-color); + + @include bem.elem('item-label') { + background-color: props.get(vars.$default-theme, --active, --bg-color); + } + } + } + + @include bem.is('selected') { + font-weight: bold; + color: props.get(vars.$default-theme, --selected, --disabled, --label-color); + + @include bem.elem('item-label') { + background-color: props.get(vars.$default-theme, --selected, --disabled, --bg-color); + } + + &:link, + &:visited, + &:enabled { + color: props.get(vars.$default-theme, --selected, --label-color); + + @include bem.elem('item-label') { + background-color: props.get(vars.$default-theme, --selected, --bg-color); + } + + &:hover, + &:focus-visible { + color: props.get(vars.$default-theme, --selected, --hover, --label-color); + + @include bem.elem('item-label') { + background-color: props.get(vars.$default-theme, --selected, --hover, --bg-color); + } + } + + &:active { + color: props.get(vars.$default-theme, --selected, --active, --label-color); + + @include bem.elem('item-label') { + background-color: props.get(vars.$default-theme, --selected, --active, --bg-color); + } + } + } + } + } + + @include bem.modifier('quiet') { + @include bem.elem('item') { + @include bem.is('selected') { + color: props.get(vars.$default-theme, --quiet, --selected, --disabled, --label-color); + + @include bem.elem('item-label') { + background-color: props.get(vars.$default-theme, --quiet, --selected, --disabled, --bg-color); + } + + &:link, + &:visited, + &:enabled { + color: props.get(vars.$default-theme, --quiet, --selected, --label-color); + + @include bem.elem('item-label') { + background-color: props.get(vars.$default-theme, --quiet, --selected, --bg-color); + } + + &:hover, + &:focus-visible { + color: props.get(vars.$default-theme, --quiet, --selected, --hover, --label-color); + + @include bem.elem('item-label') { + background-color: props.get(vars.$default-theme, --quiet, --selected, --hover, --bg-color); + } + } + + &:active { + color: props.get(vars.$default-theme, --quiet, --selected, --active, --label-color); + + @include bem.elem('item-label') { + background-color: props.get(vars.$default-theme, --quiet, --selected, --active, --bg-color); + } + } + } + } + } + } + } +} diff --git a/src/objects/_navbar.vars.scss b/src/objects/_navbar.vars.scss new file mode 100644 index 0000000..dfd683a --- /dev/null +++ b/src/objects/_navbar.vars.scss @@ -0,0 +1,83 @@ +@use 'sass:map'; +@use 'sass:string'; +@use 'iro-sass/src/props'; +@use '../core.vars' as core; + +$block-size: props.def(--o-navbar--block-size, props.get(core.$size--700)) !default; +$spacing: props.def(--o-tabs--spacing, props.get(core.$size--400)) !default; + +$item--pad-i: props.def(--o-navbar--item--pad-i, props.get(core.$size--175)) !default; +$item--pad-b: props.def(--o-navbar--item--pad-b, props.get(core.$size--40)) !default; +$item--font-size: props.def(--o-navbar--item--font-size, props.get(core.$font-size--75)) !default; + +$key-focus--border-width: props.def(--o-navbar--key-focus--border-width, props.get(core.$key-focus--border-width)) !default; +$key-focus--border-offset: props.def(--o-navbar--key-focus--border-offset, props.get(core.$key-focus--border-offset)) !default; +$key-focus--outline-width: props.def(--o-navbar--key-focus--outline-width, props.get(core.$key-focus--outline-width)) !default; + +$default-theme-override: () !default; +$default-theme: map.deep-merge(( + --label-color: props.get(core.$theme, --text), + + --hover: ( + --bg-color: props.get(core.$theme, --border-mute), + --label-color: props.get(core.$theme, --heading), + ), + + --active: ( + --bg-color: props.get(core.$theme, --border), + --label-color: props.get(core.$theme, --heading), + ), + + --disabled: ( + --label-color: props.get(core.$theme, --border-strong), + ), + + --key-focus: ( + --label: props.get(core.$theme, --focus, --text), + --border: props.get(core.$theme, --focus, --border), + --outline: props.get(core.$theme, --focus, --outline), + ), + + --selected: ( + --bg-color: props.get(core.$theme, --heading), + --label-color: props.get(core.$theme, --base, --50), + + --hover: ( + --bg-color: props.get(core.$theme, --text), + --label-color: props.get(core.$theme, --base, --50), + ), + + --active: ( + --bg-color: props.get(core.$theme, --text-mute), + --label-color: props.get(core.$theme, --base, --50), + ), + + --disabled: ( + --bg-color: props.get(core.$theme, --border-mute), + --label-color: props.get(core.$theme, --border-strong), + ), + ), + + --quiet: ( + --selected: ( + --bg-color: props.get(core.$theme, --accent, --200), + --label-color: props.get(core.$theme, --accent, --1100), + + --hover: ( + --bg-color: props.get(core.$theme, --accent, --300), + --label-color: props.get(core.$theme, --accent, --1200), + ), + + --active: ( + --bg-color: props.get(core.$theme, --accent, --400), + --label-color: props.get(core.$theme, --accent, --1300), + ), + + --disabled: ( + --bg-color: props.get(core.$theme, --accent, --200), + --label-color: props.get(core.$theme, --accent, --800), + ), + ) + ) +), $default-theme-override) !default; +$default-theme: props.def(--o-navbar, $default-theme, 'color'); diff --git a/src_demo/index.scss b/src_demo/index.scss index 4b345dd..d9994e4 100644 --- a/src_demo/index.scss +++ b/src_demo/index.scss @@ -34,6 +34,7 @@ @include iro.o-heading--styles; @include iro.o-lightbox--styles; @include iro.o-menu--styles; +@include iro.o-navbar--styles; @include iro.o-palette--styles; @include iro.o-popover--styles; @include iro.o-radio--styles; diff --git a/tpl/index.pug b/tpl/index.pug index cccfb2a..7d73c75 100644 --- a/tpl/index.pug +++ b/tpl/index.pug @@ -24,6 +24,7 @@ include objects/avatar.pug include objects/card.pug include objects/popover.pug include objects/menu.pug +include objects/navbar.pug include objects/side-nav.pug include objects/icon-nav.pug include objects/emoji.pug @@ -76,6 +77,7 @@ include views/avatar.pug include views/card.pug include views/popover.pug include views/menu.pug +include views/navbar.pug include views/side-nav.pug include views/icon-nav.pug include views/backdrop.pug @@ -124,6 +126,7 @@ html +view-side-nav +view-popover +view-menu + +view-navbar //+view-icon-nav +view-backdrop //+view-dialog diff --git a/tpl/objects/navbar.pug b/tpl/objects/navbar.pug new file mode 100644 index 0000000..bca8c90 --- /dev/null +++ b/tpl/objects/navbar.pug @@ -0,0 +1,30 @@ +include icon.pug +include status-indicator.pug +include action-button.pug + +mixin navbar + - + let classes = { + 'o-navbar': true, + 'o-navbar--quiet': attributes.quiet, + } + if (attributes.class) { + classes[attributes.class] = true; + } + + div(class=classes)&attributes(attributes) + block + +mixin navbar-item + - + let classes = { + 'o-navbar__item': true, + 'is-selected': attributes.selected, + } + if (attributes.class) { + classes[attributes.class] = true; + } + + #{!!attributes.tag ? attributes.tag : 'button'}(class=classes)&attributes(attributes) + .o-navbar__item-label + block diff --git a/tpl/views/navbar.pug b/tpl/views/navbar.pug new file mode 100644 index 0000000..03f1591 --- /dev/null +++ b/tpl/views/navbar.pug @@ -0,0 +1,13 @@ +mixin view-navbar + +view('navbar', 'Navbar') + .c-box + +navbar + +navbar-item= 'Home' + +navbar-item(selected=true)= 'Art' + +navbar-item= 'Emojis' + + .c-box + +navbar(quiet=true) + +navbar-item= 'Home' + +navbar-item(selected=true)= 'Art' + +navbar-item= 'Emojis' -- cgit v1.2.3-70-g09d2