From 1c1a00c12c1be4989e28d6c3bf19b9139396250f Mon Sep 17 00:00:00 2001 From: Volpeon Date: Sat, 26 Oct 2024 18:13:16 +0200 Subject: Move lightbox thumbnail to own object --- src/_iro-design.scss | 3 +- src/layouts/_card-view.scss | 18 +++++++ src/layouts/_media-view.scss | 18 ------- src/objects/_lightbox.scss | 88 --------------------------------- src/objects/_thumbnail.scss | 102 +++++++++++++++++++++++++++++++++++++++ src/objects/_thumbnail.vars.scss | 51 ++++++++++++++++++++ src_demo/index.scss | 1 + tpl/objects/lightbox.pug | 21 +++++--- 8 files changed, 188 insertions(+), 114 deletions(-) create mode 100644 src/layouts/_card-view.scss delete mode 100644 src/layouts/_media-view.scss create mode 100644 src/objects/_thumbnail.scss create mode 100644 src/objects/_thumbnail.vars.scss diff --git a/src/_iro-design.scss b/src/_iro-design.scss index 7f726da..6698d76 100644 --- a/src/_iro-design.scss +++ b/src/_iro-design.scss @@ -32,7 +32,7 @@ $breakpoints: ( @forward 'layouts/media' as l-media--*; @forward 'layouts/overflow' as l-overflow--*; @forward 'layouts/split-view' as l-split-view--*; -@forward 'layouts/media-view' as l-media-view--*; +@forward 'layouts/card-view' as l-card-view--*; @forward 'scopes/implicit' as s-implicit--*; @forward 'scopes/blockquotes' as s-blockquotes--*; @@ -65,6 +65,7 @@ $breakpoints: ( @forward 'objects/switch' as o-switch--*; @forward 'objects/table' as o-table--*; @forward 'objects/text-field' as o-text-field--*; +@forward 'objects/thumbnail' as o-thumbnail--*; @forward 'utils' as utils--*; diff --git a/src/layouts/_card-view.scss b/src/layouts/_card-view.scss new file mode 100644 index 0000000..f6e0ef1 --- /dev/null +++ b/src/layouts/_card-view.scss @@ -0,0 +1,18 @@ +@use 'sass:meta'; +@use 'iro-sass/src/bem'; +@use 'iro-sass/src/props'; +@use '../props' as *; + +@mixin styles { + @include bem.layout('card-view') { + display: flex; + flex-direction: column; + min-block-size: 100%; + + @include bem.elem('footer') { + position: sticky; + inset-block-end: 0; + margin-block-start: auto; + } + } +} diff --git a/src/layouts/_media-view.scss b/src/layouts/_media-view.scss deleted file mode 100644 index 2c53db6..0000000 --- a/src/layouts/_media-view.scss +++ /dev/null @@ -1,18 +0,0 @@ -@use 'sass:meta'; -@use 'iro-sass/src/bem'; -@use 'iro-sass/src/props'; -@use '../props' as *; - -@mixin styles { - @include bem.layout('media-view') { - display: flex; - flex-direction: column; - min-block-size: 100%; - - @include bem.elem('footer') { - position: sticky; - inset-block-end: 0; - margin-block-start: auto; - } - } -} diff --git a/src/objects/_lightbox.scss b/src/objects/_lightbox.scss index 0ce62ff..4964b81 100644 --- a/src/objects/_lightbox.scss +++ b/src/objects/_lightbox.scss @@ -45,69 +45,6 @@ overflow: auto; } - @include bem.elem('thumbnail') { - position: relative; - flex: 0 0 auto; - inline-size: props.get(vars.$thumbnail--size); - block-size: props.get(vars.$thumbnail--size); - overflow: hidden; - border-radius: props.get(vars.$thumbnail--rounding); - outline: props.get(vars.$thumbnail--border-color) solid props.get(vars.$thumbnail--border-width); - outline-offset: calc(-1 * props.get(vars.$thumbnail--border-width)); - opacity: .75; - - &:hover, - &:active, - &:focus-visible { - outline-color: props.get(vars.$thumbnail--hover--border-color); - opacity: 1; - } - - @include bem.is('selected') { - $focus-border-offset: calc(-1 * props.get(vars.$thumbnail--selected--border-width)); - - margin: $focus-border-offset; - border: props.get(vars.$thumbnail--selected--border-width) solid props.get(vars.$thumbnail--selected--border-color); - border-radius: calc(props.get(vars.$thumbnail--rounding) - $focus-border-offset); - outline: none; - opacity: 1; - } - - &:focus-visible { - $focus-border-offset: calc(-1 * props.get(vars.$thumbnail--key-focus--border-offset)); - - margin: $focus-border-offset; - border: props.get(vars.$thumbnail--key-focus--border-offset) solid transparent; - border-radius: calc(props.get(vars.$thumbnail--rounding) - $focus-border-offset); - outline: props.get(vars.$thumbnail--key-focus--border-color) solid props.get(vars.$thumbnail--key-focus--border-width); - outline-offset: 0; - box-shadow: - 0 - 0 - 0 - calc(props.get(vars.$thumbnail--key-focus--outline-width) + props.get(vars.$thumbnail--key-focus--border-width)) - props.get(vars.$thumbnail--key-focus--outline-color); - } - } - - @include bem.elem('thumbnail-img') { - position: absolute; - inset-block-start: 0; - inset-inline-start: 0; - display: block; - inline-size: 100%; - block-size: 100%; - object-fit: cover; - object-position: center center; - } - - @include bem.elem('thumbnail-icon') { - position: absolute; - inset-block-start: 50%; - inset-inline-start: 50%; - transform: translate(-50%, -50%); - } - @include bem.elem('close-btn') { display: none; flex: 0 0 auto; @@ -187,31 +124,6 @@ @each $theme in map.keys(props.get(vars.$static-themes)) { @include bem.modifier(string.slice($theme, 3)) { color: props.get(vars.$static-themes, $theme, --text); - - @include bem.elem('thumbnail') { - outline-color: props.get(vars.$static-themes, $theme, --thumbnail, --border); - - &:hover, - &:active, - &:focus-visible { - outline-color: props.get(vars.$static-themes, $theme, --thumbnail, --hover, --border); - } - - @include bem.is('selected') { - border-color: props.get(vars.$static-themes, $theme, --thumbnail, --selected, --border); - } - - &:focus-visible { - border-color: transparent; - outline-color: props.get(vars.$static-themes, $theme, --thumbnail, --key-focus, --border); - box-shadow: - 0 - 0 - 0 - calc(props.get(vars.$thumbnail--key-focus--outline-width) + props.get(vars.$thumbnail--key-focus--border-width)) - props.get(vars.$static-themes, $theme, --thumbnail, --key-focus, --outline); - } - } } } } diff --git a/src/objects/_thumbnail.scss b/src/objects/_thumbnail.scss new file mode 100644 index 0000000..8702fbe --- /dev/null +++ b/src/objects/_thumbnail.scss @@ -0,0 +1,102 @@ +@use 'sass:map'; +@use 'sass:meta'; +@use 'sass:string'; +@use 'iro-sass/src/bem'; +@use 'iro-sass/src/props'; +@use '../props' as *; + +@forward 'thumbnail.vars'; +@use 'thumbnail.vars' as vars; + +@mixin styles { + @include materialize-at-root(meta.module-variables('vars')); + + @include bem.object('thumbnail') { + position: relative; + inline-size: props.get(vars.$size); + block-size: props.get(vars.$size); + overflow: hidden; + border-radius: props.get(vars.$rounding); + outline: props.get(vars.$border-color) solid props.get(vars.$border-width); + outline-offset: calc(-1 * props.get(vars.$border-width)); + opacity: .75; + + &:hover, + &:active, + &:focus-visible { + outline-color: props.get(vars.$hover--border-color); + opacity: 1; + } + + @include bem.is('selected') { + $focus-border-offset: calc(-1 * props.get(vars.$selected--border-width)); + + margin: $focus-border-offset; + border: props.get(vars.$selected--border-width) solid props.get(vars.$selected--border-color); + border-radius: calc(props.get(vars.$rounding) - $focus-border-offset); + outline: none; + opacity: 1; + } + + @include bem.elem('image') { + position: absolute; + inset-block-start: 0; + inset-inline-start: 0; + display: block; + inline-size: 100%; + block-size: 100%; + object-fit: cover; + object-position: center center; + } + + @include bem.elem('icon') { + position: absolute; + inset-block-start: 50%; + inset-inline-start: 50%; + transform: translate(-50%, -50%); + } + + &:focus-visible { + $focus-border-offset: calc(-1 * props.get(vars.$key-focus--border-offset)); + + margin: $focus-border-offset; + border: props.get(vars.$key-focus--border-offset) solid transparent; + border-radius: calc(props.get(vars.$rounding) - $focus-border-offset); + outline: props.get(vars.$key-focus--border-color) solid props.get(vars.$key-focus--border-width); + outline-offset: 0; + box-shadow: + 0 + 0 + 0 + calc(props.get(vars.$key-focus--outline-width) + props.get(vars.$key-focus--border-width)) + props.get(vars.$key-focus--outline-color); + } + + @each $theme in map.keys(props.get(vars.$static-themes)) { + @include bem.modifier(string.slice($theme, 3)) { + outline-color: props.get(vars.$static-themes, $theme, --border); + + &:hover, + &:active, + &:focus-visible { + outline-color: props.get(vars.$static-themes, $theme, --hover, --border); + } + + @include bem.is('selected') { + border-color: props.get(vars.$static-themes, $theme, --selected, --border); + } + + &:focus-visible { + border-color: transparent; + outline-color: props.get(vars.$static-themes, $theme, --key-focus, --border); + box-shadow: + 0 + 0 + 0 + calc(props.get(vars.$key-focus--outline-width) + props.get(vars.$key-focus--border-width)) + props.get(vars.$static-themes, $theme, --key-focus, --outline); + } + } + } + } +} diff --git a/src/objects/_thumbnail.vars.scss b/src/objects/_thumbnail.vars.scss new file mode 100644 index 0000000..ba8cebe --- /dev/null +++ b/src/objects/_thumbnail.vars.scss @@ -0,0 +1,51 @@ +@use 'sass:map'; +@use 'sass:string'; +@use 'iro-sass/src/props'; +@use '../core.vars' as core; + +$size: props.def(--o-thumbnail--size, props.get(core.$size--700)) !default; +$rounding: props.def(--o-thumbnail--rounding, props.get(core.$rounding)) !default; +$spacing: props.def(--o-thumbnail--spacing, props.get(core.$size--100)) !default; +$border-width: props.def(--o-thumbnail--border-width, props.get(core.$border-width--thin)) !default; + +$selected--border-width: props.def(--o-thumbnail--selected--border-width, props.get(core.$border-width--medium)) !default; + +$key-focus--border-width: props.def(--o-thumbnail--key-focus--border-width, props.get(core.$key-focus--border-width)) !default; +$key-focus--border-offset: props.def(--o-thumbnail--key-focus--border-offset, props.get(core.$key-focus--border-offset)) !default; +$key-focus--outline-width: props.def(--o-thumbnail--key-focus--outline-width, props.get(core.$key-focus--outline-width)) !default; + +$border-color: props.def(--o-thumbnail--border-color, props.get(core.$theme, --border-strong), 'color') !default; + +$hover--border-color: props.def(--o-thumbnail--hover--border-color, props.get(core.$theme, --text-mute-more), 'color') !default; + +$selected--border-color: props.def(--o-thumbnail--selected--border-color, props.get(core.$theme, --heading), 'color') !default; + +$key-focus--border-color: props.def(--o-thumbnail--key-focus--border-color, props.get(core.$theme, --focus, --border), 'color') !default; +$key-focus--outline-color: props.def(--o-thumbnail--key-focus--outline-color, props.get(core.$theme, --focus, --outline), 'color') !default; + +$size--md: props.def(--o-thumbnail--size, props.get(core.$size--600), 'md') !default; + +$static-themes: props.def(--o-thumbnail, (), 'color'); + +@each $theme in map.keys(props.get(core.$transparent-colors)) { + $thumbnail-theme: --static-#{string.slice($theme, 3)}; + + $static-themes: props.merge($static-themes, ( + $thumbnail-theme: ( + --border: props.get(core.$transparent-colors, $theme, --400), + + --hover: ( + --border: props.get(core.$transparent-colors, $theme, --500), + ), + + --selected: ( + --border: props.get(core.$transparent-colors, $theme, --900), + ), + + --key-focus: ( + --border: props.get(core.$transparent-colors, $theme, --900), + --outline: props.get(core.$transparent-colors, $theme, --300), + ), + ) + )); +} diff --git a/src_demo/index.scss b/src_demo/index.scss index 3611d71..085a60b 100644 --- a/src_demo/index.scss +++ b/src_demo/index.scss @@ -41,6 +41,7 @@ @include iro.o-switch--styles; @include iro.o-table--styles; @include iro.o-text-field--styles; +@include iro.o-thumbnail--styles; @include iro.utils--styles; diff --git a/tpl/objects/lightbox.pug b/tpl/objects/lightbox.pug index 85c468f..842d44a 100644 --- a/tpl/objects/lightbox.pug +++ b/tpl/objects/lightbox.pug @@ -9,10 +9,14 @@ mixin lightbox(images) let linksClasses = { 's-links': true, } + let thumbnailClasses = { + 'o-thumbnail': true, + } if (attributes.theme) { classes[`o-lightbox--${attributes.theme}`] = true; linksClasses[`s-links--${attributes.theme}`] = true; + thumbnailClasses[`o-thumbnail--${attributes.theme}`] = true; } div(class=classes) @@ -30,10 +34,13 @@ mixin lightbox(images) .o-lightbox__thumbnails each img, i in images - - classes = i === 0 ? 'is-selected' : '' - a.o-lightbox__thumbnail(class=classes href='#image-' + i) - img.o-lightbox__thumbnail-img(src=img) - button.o-lightbox__thumbnail - +icon('volume-2')(class='o-lightbox__thumbnail-icon') - button.o-lightbox__thumbnail - +icon('video')(class='o-lightbox__thumbnail-icon') + - + let classes = { 'is-selected': i === 0 } + Object.assign(classes, thumbnailClasses) + + a.o-thumbnail(class=classes href='#image-' + i) + img.o-thumbnail__image(src=img) + button(class=thumbnailClasses) + +icon('volume-2')(class='o-thumbnail__icon') + button(class=thumbnailClasses) + +icon('video')(class='o-thumbnail__icon') -- cgit v1.2.3-70-g09d2