From 8f49d0cba610e4829e183e81e4126aba136dfccc Mon Sep 17 00:00:00 2001 From: Volpeon Date: Mon, 7 Feb 2022 18:37:09 +0100 Subject: Added action-menu --- src/index.scss | 1 + src/layouts/_card.scss | 8 ++-- src/objects/_action-menu.scss | 94 ++++++++++++++++++++++++++++++++++++++++ tpl/index.pug | 15 +++++++ tpl/objects/action-button.pug | 37 ++++++++-------- tpl/objects/action-menu.pug | 25 +++++++++++ tpl/objects/icon.pug | 15 ++++--- tpl/objects/status-indicator.pug | 5 ++- 8 files changed, 173 insertions(+), 27 deletions(-) create mode 100644 src/objects/_action-menu.scss create mode 100644 tpl/objects/action-menu.pug diff --git a/src/index.scss b/src/index.scss index 24b8d72..5ceb11f 100644 --- a/src/index.scss +++ b/src/index.scss @@ -19,6 +19,7 @@ @use 'objects/action-button'; @use 'objects/status-indicator'; @use 'objects/avatar'; +@use 'objects/action-menu'; @use 'layouts/form'; diff --git a/src/layouts/_card.scss b/src/layouts/_card.scss index a5b9028..a2d201f 100644 --- a/src/layouts/_card.scss +++ b/src/layouts/_card.scss @@ -17,13 +17,13 @@ @include iro.bem-layout(iro.props-namespace()) { display: flex; align-items: center; - padding: prop(--dims --pad-y) prop(--dims --pad-x); - gap: prop(--dims --pad-x); + padding: fn.dim(--pad-y) fn.dim(--pad-x); + gap: fn.dim(--pad-x); line-height: 1.4; @include iro.bem-modifier('lg') { - padding: prop(--dims --lg --pad-y) prop(--dims --lg --pad-x); - gap: prop(--dims --lg --pad-x); + padding: fn.dim(--lg --pad-y) fn.dim(--lg --pad-x); + gap: fn.dim(--lg --pad-x); } @include iro.bem-modifier('flush') { diff --git a/src/objects/_action-menu.scss b/src/objects/_action-menu.scss new file mode 100644 index 0000000..35d23b8 --- /dev/null +++ b/src/objects/_action-menu.scss @@ -0,0 +1,94 @@ +@use 'iro-sass/src/index' as iro; +@use '../functions' as fn; + +@include iro.props-namespace('action-menu') { + @include iro.props-store(( + --dims: ( + --x: 0, + --y: 0, + --pad-x: 0, + --pad-y: .3rem, + --separator: .3rem, + --rounding: 3px, + --item: ( + --pad-x: .8rem, + --pad-y: .4rem, + ), + ), + ), 'dims'); + + @include iro.props-store(( + --colors: ( + --shadow: 0 .2em .5em rgba(#000, .3), + --separator: fn.global-color(--obj), + --icon: fn.global-color(--fg-hi), + --item: ( + --hover: ( + --bg: fn.global-color(--obj-hi), + --fg: fn.global-color(--fg-lo), + ), + ), + ), + ), 'colors'); + + @include iro.bem-object(iro.props-namespace()) { + @include iro.bem-composed-of('action-button' 'object'); + + position: absolute; + z-index: 10000; + top: fn.dim(--y); + left: fn.dim(--x); + padding: fn.dim(--pad-y) fn.dim(--pad-x); + border-radius: fn.dim(--rounding); + background-color: fn.global-color(--bg); + box-shadow: fn.color(--shadow); + color: fn.global-color(--fg); + + @include iro.bem-modifier('static') { + position: static; + } + + @include iro.bem-modifier('up-left') { + transform: translate(0, -100%); + } + + @include iro.bem-modifier('up-right') { + transform: translate(-100%, -100%); + } + + @include iro.bem-modifier('down-right') { + transform: translate(-100%, 0); + } + + @include iro.bem-elem('separator') { + height: 1px; + margin: fn.dim(--separator) 0; + background-color: fn.color(--separator); + } + + @include iro.bem-elem('item') { + display: block; + box-sizing: border-box; + width: 100%; + padding: fn.dim(--item --pad-y) fn.dim(--item --pad-x); + + @include iro.bem-multi('&:link, &:visited', 'modifier' 'native') { + &:hover, + &:active { + background-color: fn.color(--item --hover --bg); + color: fn.color(--item --hover --fg); + } + } + } + + @include iro.bem-elem('icon-slot') { + display: flex; + justify-content: center; + width: 1em; + } + + @include iro.bem-elem('icon') { + color: fn.color(--icon); + } + } +} diff --git a/tpl/index.pug b/tpl/index.pug index 206e40b..a59526e 100644 --- a/tpl/index.pug +++ b/tpl/index.pug @@ -15,6 +15,7 @@ include objects/form.pug include objects/action-button.pug include objects/status-indicator.pug include objects/avatar.pug +include objects/action-menu.pug mixin box +container(padX=true padY=true inPage=true theme="raised") @@ -435,3 +436,17 @@ html +avatar(circle=true size='xs' hue=225) = 'o' +avatar(circle=true size='xs' src='avatar.png') + + //----------------------------------------- + + +h1-heading(level='xl')= 'Action menu' + +rule(level='medium') + + +box + +action-menu + +action-menu-item(icon='trash')= 'Item 1' + +action-menu-item= 'Item 2' + +action-menu-item= 'Item 3' + +action-menu-separator + +action-menu-item= 'Item 4' + diff --git a/tpl/objects/action-button.pug b/tpl/objects/action-button.pug index 0afe1ea..eb524a2 100644 --- a/tpl/objects/action-button.pug +++ b/tpl/objects/action-button.pug @@ -1,21 +1,24 @@ include icon.pug mixin action-button - - - let classes = { - 'o-action-button': true, - 'o-action-button--block': attributes.block, - 'o-action-button--quiet': attributes.quiet, - 'is-disabled': attributes.disabled, - 'is-selected': attributes.selected - } - - let href = attributes.disabled ? null : '#'; + - + let classes = { + 'o-action-button': true, + 'o-action-button--block': attributes.block, + 'o-action-button--quiet': attributes.quiet, + 'is-disabled': attributes.disabled, + 'is-selected': attributes.selected + } + if (attributes.class) { + classes[attributes.class] = true; + } - a(class=classes href=href) - if attributes.icon - +icon(attributes.icon) - = ' ' - if block - span.o-action-button__label - block + let href = attributes.disabled ? null : '#'; + + a(class=classes href=href) + if attributes.icon + +icon(attributes.icon) + = ' ' + if block + span.o-action-button__label + block diff --git a/tpl/objects/action-menu.pug b/tpl/objects/action-menu.pug new file mode 100644 index 0000000..85f93bf --- /dev/null +++ b/tpl/objects/action-menu.pug @@ -0,0 +1,25 @@ +include ../objects/action-button.pug +include icon.pug + +mixin action-menu + - + let classes = { + 'o-action-menu': true, + 'o-action-menu--static': true, + 't-raised': true + } + + div(class=classes) + block + +mixin action-menu-item + button.o-action-menu__item.o-action-menu__item--native + .l-card.l-card--flush + .l-card__block.o-action-menu__icon-slot + if attributes.icon + +icon(attributes.icon) + .l-card__block.l-card__block--main + block + +mixin action-menu-separator + .o-action-menu__separator diff --git a/tpl/objects/icon.pug b/tpl/objects/icon.pug index 0e444f9..494abf6 100644 --- a/tpl/objects/icon.pug +++ b/tpl/objects/icon.pug @@ -1,7 +1,12 @@ mixin icon(id) - - - let href = 'icons.svg#' + id - let classes = attributes.class ? attributes.class : '' + - + let href = 'icons.svg#' + id + let classes = { + 'o-icon': true + } + if (attributes.class) { + classes[attributes.class] = true; + } - svg(class=['o-icon', classes] width='1em' height='1em') - use(href=href) + svg(class=classes width='1em' height='1em') + use(href=href) diff --git a/tpl/objects/status-indicator.pug b/tpl/objects/status-indicator.pug index 9b240e1..7ecb08a 100644 --- a/tpl/objects/status-indicator.pug +++ b/tpl/objects/status-indicator.pug @@ -4,5 +4,8 @@ mixin status-indicator(status) 'o-status-indicator': true, } classes['is-' + status] = true + if (attributes.class) { + classes[attributes.class] = true; + } - div(class=classes)&attributes(attributes) + div(class=classes) -- cgit v1.2.3-70-g09d2