From 6c83cc06d524364777cfe431fe4d0b7199598a26 Mon Sep 17 00:00:00 2001 From: codecalm Date: Sat, 7 Nov 2020 01:34:08 +0100 Subject: [PATCH] switch icon component --- src/js/tabler.js | 10 ++ src/pages/_data/docs.yml | 6 + src/pages/_docs/icons.md | 44 +++++ src/pages/_docs/switch-icon.md | 25 +++ src/pages/_includes/example.html | 7 +- src/pages/_includes/ui/switch-icon.html | 12 ++ src/scss/_tabler-core.scss | 3 +- src/scss/_variables.scss | 1 + src/scss/ui/_buttons.scss | 4 +- src/scss/ui/_dropdowns.scss | 4 +- src/scss/ui/_nav.scss | 4 +- src/scss/ui/_switch-icon.scss | 210 ++++++++++++++++++++++++ 12 files changed, 322 insertions(+), 8 deletions(-) create mode 100644 src/pages/_docs/icons.md create mode 100644 src/pages/_docs/switch-icon.md create mode 100644 src/pages/_includes/ui/switch-icon.html create mode 100644 src/scss/ui/_switch-icon.scss diff --git a/src/js/tabler.js b/src/js/tabler.js index 8f6eeae31..626e2c1a6 100644 --- a/src/js/tabler.js +++ b/src/js/tabler.js @@ -34,4 +34,14 @@ import './dropdown'; return new bootstrap.Dropdown(dropdownTriggerEl); }); + + let switchesTriggerList = [].slice.call(document.querySelectorAll('[data-toggle="switch-icon"]')); + switchesTriggerList.map(function (switchTriggerEl) { + switchTriggerEl.addEventListener('click', (e) => { + e.stopPropagation(); + + switchTriggerEl.classList.toggle('active'); + }); + }); + })(); \ No newline at end of file diff --git a/src/pages/_data/docs.yml b/src/pages/_data/docs.yml index 6ac949247..515ccaf0a 100644 --- a/src/pages/_data/docs.yml +++ b/src/pages/_data/docs.yml @@ -11,6 +11,9 @@ base: typography: title: Typography url: docs/typography.html + icons: + title: Icons + url: docs/icons.html components: title: Components @@ -76,6 +79,9 @@ components: steps: title: Steps url: docs/steps.html + switch-icon: + title: Switch icon + url: docs/switch-icon.html tables: title: Tables url: docs/tables.html diff --git a/src/pages/_docs/icons.md b/src/pages/_docs/icons.md new file mode 100644 index 000000000..d2afbfe24 --- /dev/null +++ b/src/pages/_docs/icons.md @@ -0,0 +1,44 @@ +--- +title: Icons +menu: docs.base.icons +--- + +## Base icon + +{% capture code %} + {% include ui/icon.html icon="heart" %} + {% include ui/icon.html icon="ghost" %} + {% include ui/icon.html icon="star" %} + {% include ui/icon.html icon="bike" %} +{% endcapture %} +{% include example.html code=code %} + +## Filled icons + +{% capture code %} + {% include ui/icon.html icon="heart" class="icon-filled" %} + {% include ui/icon.html icon="circle" class="icon-filled" %} + {% include ui/icon.html icon="star" class="icon-filled" %} + {% include ui/icon.html icon="square" class="icon-filled" %} +{% endcapture %} +{% include example.html code=code %} + +## Icon colors + +{% capture code %} + + {% include ui/icon.html icon="heart" class="icon-filled" %} + + + {% include ui/icon.html icon="star" class="icon-filled" %} + + + {% include ui/icon.html icon="circle" %} + + + {% include ui/icon.html icon="square" %} + +{% endcapture %} +{% include example.html code=code %} + + diff --git a/src/pages/_docs/switch-icon.md b/src/pages/_docs/switch-icon.md new file mode 100644 index 000000000..f1ef93737 --- /dev/null +++ b/src/pages/_docs/switch-icon.md @@ -0,0 +1,25 @@ +--- +title: Switch icon +menu: docs.components.switch-icon +--- + +## Default markup + +{% capture code %} +{% include ui/switch-icon.html icon="circle" icon-b-class="icon-filled" icon-b-color="blue" %} +{% endcapture %} +{% include example.html code=code wrapper="d-flex space-x-2" %} + +## Switch animations + +{% capture code %} +{% include ui/switch-icon.html icon="circle" icon-b-class="icon-filled" icon-b-color="blue" %} +{% include ui/switch-icon.html variant="fade" icon-b-class="icon-filled" %} +{% include ui/switch-icon.html variant="scale" icon="star" icon-b-class="icon-filled" icon-b-color="yellow" %} +{% include ui/switch-icon.html variant="flip" icon="thumb-up" icon-b-color="facebook" %} +{% include ui/switch-icon.html variant="slide-up" icon="brand-twitter" icon-b-color="twitter" %} +{% include ui/switch-icon.html variant="slide-left" icon="check" icon-b="x" icon-b-color="red" %} +{% include ui/switch-icon.html variant="slide-down" icon="arrow-down" icon-b="arrow-up" icon-a-color="muted" icon-b-color="muted" %} +{% include ui/switch-icon.html variant="slide-right" icon="car" icon-b="scooter" icon-b-color="muted" %} +{% endcapture %} +{% include example.html code=code wrapper="d-flex space-x-2" %} \ No newline at end of file diff --git a/src/pages/_includes/example.html b/src/pages/_includes/example.html index f949acaaa..d7d44575b 100644 --- a/src/pages/_includes/example.html +++ b/src/pages/_includes/example.html @@ -23,7 +23,12 @@ {% capture new_line %} {% endcapture %} {% assign code = code | replace_regex: "\n\n+", new_line %} -{% assign code = code | replace_regex: ']*>.*?<\/svg>', '' %} + +{% unless include.show-svg %} + {% assign code = code | replace_regex: ']*class="icon ([^"]+)"[^>]*>.*?<\/svg>', '' %} + {% assign code = code | replace_regex: ']*>.*?<\/svg>', '' %} +{% endunless %} + {% assign code = code | replace_regex: 'url\(([^\)]+)\)', 'url(...)' %} {% assign code = code | replace_regex: 'src="([^"]+)"', 'src="..."' %} {% assign code = code | replace_regex: 'href="([^#][^"]+)"', 'href="#"' %} diff --git a/src/pages/_includes/ui/switch-icon.html b/src/pages/_includes/ui/switch-icon.html new file mode 100644 index 000000000..5b6594d00 --- /dev/null +++ b/src/pages/_includes/ui/switch-icon.html @@ -0,0 +1,12 @@ +{% assign icon = include.icon | default: 'heart' %} +{% assign icon-b = include.icon-b | default: icon | default: 'heart' %} +{% assign icon-a-color = include.icon-a-color | default: 'muted' %} +{% assign icon-b-color = include.icon-b-color | default: 'red' %} + \ No newline at end of file diff --git a/src/scss/_tabler-core.scss b/src/scss/_tabler-core.scss index 1d3c17916..949bcd0d8 100644 --- a/src/scss/_tabler-core.scss +++ b/src/scss/_tabler-core.scss @@ -39,13 +39,14 @@ @import "ui/popovers"; @import "ui/progress"; @import "ui/ribbons"; +@import "ui/markdown"; @import "ui/skeleton"; @import "ui/steps"; +@import "ui/switch-icon"; @import "ui/tables"; @import "ui/toasts"; @import "ui/toolbar"; @import "ui/type"; -@import "ui/markdown"; @import "ui/charts"; @import "utils/background"; diff --git a/src/scss/_variables.scss b/src/scss/_variables.scss index be81c2cc3..602824fdf 100644 --- a/src/scss/_variables.scss +++ b/src/scss/_variables.scss @@ -24,6 +24,7 @@ $icon-fonts: () !default; //Icons $icon-stroke-width: 1.5 !default; +$icon-size: 1.25rem !default; //Fonts $font-size-base: .875rem !default; diff --git a/src/scss/ui/_buttons.scss b/src/scss/ui/_buttons.scss index 7816345ee..f96f06231 100644 --- a/src/scss/ui/_buttons.scss +++ b/src/scss/ui/_buttons.scss @@ -23,8 +23,8 @@ } svg { - width: 1.25rem; - height: 1.25rem; + width: $icon-size; + height: $icon-size; margin: 0 .25rem 0; margin-inline-start: -.5rem; vertical-align: bottom; diff --git a/src/scss/ui/_dropdowns.scss b/src/scss/ui/_dropdowns.scss index 9a5bc9860..61a21aecd 100644 --- a/src/scss/ui/_dropdowns.scss +++ b/src/scss/ui/_dropdowns.scss @@ -23,8 +23,8 @@ } .dropdown-item-icon { - width: 1.25rem !important; - font-size: 1.25rem !important; + width: $icon-size !important; + height: $icon-size !important; margin-right: .5rem; color: $text-muted; opacity: $text-muted-opacity; diff --git a/src/scss/ui/_nav.scss b/src/scss/ui/_nav.scss index 281c3cad9..4e53eb1a9 100644 --- a/src/scss/ui/_nav.scss +++ b/src/scss/ui/_nav.scss @@ -90,8 +90,8 @@ } .nav-link-icon { - width: 1.25rem; - height: 1.25rem; + width: $icon-size; + height: $icon-size; margin-inline-end: .5rem; opacity: $text-muted-opacity; diff --git a/src/scss/ui/_switch-icon.scss b/src/scss/ui/_switch-icon.scss new file mode 100644 index 000000000..aec3d7fb8 --- /dev/null +++ b/src/scss/ui/_switch-icon.scss @@ -0,0 +1,210 @@ +.switch-icon { + display: inline-block; + line-height: 1; + border: 0; + padding: 0; + background: transparent; + width: $icon-size; + height: $icon-size; + position: relative; + cursor: pointer; + + &.disabled { + pointer-events: none; + opacity: $btn-disabled-opacity; + } + + &:focus { + outline: none; + } + + svg { + display: block; + width: 100%; + height: 100%; + } + + .switch-icon-a, + .switch-icon-b { + display: block; + width: 100%; + height: 100%; + } + + .switch-icon-a { + opacity: 1; + } + + .switch-icon-b { + position: absolute; + top: 0; + left: 0; + opacity: 0; + } + + &.active { + .switch-icon-a { + opacity: 0; + } + + .switch-icon-b { + opacity: 1; + } + } +} + +// Fade variant +.switch-icon-fade { + .switch-icon-a, + .switch-icon-b { + transition: opacity .5s; + } +} + +// Scale variant +.switch-icon-scale { + .switch-icon-a, + .switch-icon-b { + transition: opacity .5s, transform .0s .5s; + } + + .switch-icon-b { + transform: scale(1.5); + } + + &.active { + .switch-icon-a, + .switch-icon-b { + transition: opacity .0s, transform .5s; + } + + .switch-icon-b { + transform: scale(1); + } + } +} + +// Flip variant +.switch-icon-flip { + perspective: 10em; + + .switch-icon-a, + .switch-icon-b { + backface-visibility: hidden; + transform-style: preserve-3d; + transition: opacity 0s .2s, transform .4s ease-in-out; + } + + .switch-icon-a { + opacity: 1; + transform: rotateY(0deg); + } + + .switch-icon-b { + opacity: 1; + transform: rotateY(-180deg); + } + + &.active { + .switch-icon-a { + opacity: 1; + transform: rotateY(180deg); + } + + .switch-icon-b { + opacity: 1; + transform: rotateY(0deg); + } + } +} + +// Slide variant +.switch-icon-slide-up, +.switch-icon-slide-left, +.switch-icon-slide-right, +.switch-icon-slide-down { + overflow: hidden; + + .switch-icon-a, + .switch-icon-b { + transition: opacity .3s, transform .3s; + } + + .switch-icon-a { + transform: translateY(0); + } + + .switch-icon-b { + transform: translateY(100%); + } + + &.active { + .switch-icon-a { + transform: translateY(-100%); + } + + .switch-icon-b { + transform: translateY(0); + } + } +} + +.switch-icon-slide-left { + .switch-icon-a { + transform: translateX(0); + } + + .switch-icon-b { + transform: translateX(100%); + } + + &.active { + .switch-icon-a { + transform: translateX(-100%); + } + + .switch-icon-b { + transform: translateX(0); + } + } +} + +.switch-icon-slide-right { + .switch-icon-a { + transform: translateX(0); + } + + .switch-icon-b { + transform: translateX(-100%); + } + + &.active { + .switch-icon-a { + transform: translateX(100%); + } + + .switch-icon-b { + transform: translateX(0); + } + } +} + +.switch-icon-slide-down { + .switch-icon-a { + transform: translateY(0); + } + + .switch-icon-b { + transform: translateY(-100%); + } + + &.active { + .switch-icon-a { + transform: translateY(100%); + } + + .switch-icon-b { + transform: translateY(0); + } + } +} \ No newline at end of file