From 344eedfde5cdca687a366ac45ac28720044d55ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pau=20Ferrer=20Oca=C3=B1a?= Date: Wed, 3 Feb 2021 10:30:07 +0100 Subject: [PATCH] MOBILE-3631 theme: Reorganize theme files --- angular.json | 2 +- .../features/grades/pages/course/course.scss | 2 +- src/theme/breakpoints.scss | 13 - src/theme/custom.scss | 4 - src/theme/format-text.scss | 2 - src/theme/globals.custom.scss | 5 + src/theme/globals.mixins.ionic.scss | 520 +++++++++++++ src/theme/globals.mixins.scss | 187 +++++ src/theme/globals.scss | 10 + src/theme/globals.variables.scss | 66 ++ src/theme/mixins.scss | 697 ------------------ src/theme/{app.scss => theme.base.scss} | 40 +- src/theme/theme.custom.scss | 21 + src/theme/theme.dark.scss | 87 +++ .../{variables.scss => theme.light.scss} | 163 ++-- src/theme/{global.scss => theme.scss} | 12 +- 16 files changed, 972 insertions(+), 859 deletions(-) delete mode 100644 src/theme/breakpoints.scss delete mode 100644 src/theme/custom.scss create mode 100644 src/theme/globals.custom.scss create mode 100644 src/theme/globals.mixins.ionic.scss create mode 100644 src/theme/globals.mixins.scss create mode 100644 src/theme/globals.scss create mode 100644 src/theme/globals.variables.scss delete mode 100644 src/theme/mixins.scss rename src/theme/{app.scss => theme.base.scss} (94%) create mode 100644 src/theme/theme.custom.scss create mode 100644 src/theme/theme.dark.scss rename src/theme/{variables.scss => theme.light.scss} (66%) rename src/theme/{global.scss => theme.scss} (83%) diff --git a/angular.json b/angular.json index 7caa291e1..bccd90c01 100644 --- a/angular.json +++ b/angular.json @@ -33,7 +33,7 @@ ], "styles": [ { - "input": "src/theme/global.scss" + "input": "src/theme/theme.scss" } ], "scripts": [], diff --git a/src/core/features/grades/pages/course/course.scss b/src/core/features/grades/pages/course/course.scss index fdad1dc2b..107b3972b 100644 --- a/src/core/features/grades/pages/course/course.scss +++ b/src/core/features/grades/pages/course/course.scss @@ -1,4 +1,4 @@ -@import "~theme/breakpoints"; +@import "~theme/globals"; // @todo darkmode // @todo RTL layout diff --git a/src/theme/breakpoints.scss b/src/theme/breakpoints.scss deleted file mode 100644 index 48953000f..000000000 --- a/src/theme/breakpoints.scss +++ /dev/null @@ -1,13 +0,0 @@ -/* - * Layout Breakpoints - * - * https://ionicframework.com/docs/layout/grid#default-breakpoints - */ - - $breakpoint-xs: 0px; - $breakpoint-sm: 576px; - $breakpoint-md: 768px; - $breakpoint-lg: 992px; - $breakpoint-xl: 1200px; - - $breakpoint-tablet: $breakpoint-lg; diff --git a/src/theme/custom.scss b/src/theme/custom.scss deleted file mode 100644 index 38d41d5e4..000000000 --- a/src/theme/custom.scss +++ /dev/null @@ -1,4 +0,0 @@ -// Place here custom styles. -:root { - -} diff --git a/src/theme/format-text.scss b/src/theme/format-text.scss index 149e2e807..d8a8c498a 100644 --- a/src/theme/format-text.scss +++ b/src/theme/format-text.scss @@ -1,5 +1,3 @@ -@import "./mixins.scss"; - /** Format Text - Show more styles. */ /** Styles of elements inside the directive should be placed in format-text.scss */ core-format-text { diff --git a/src/theme/globals.custom.scss b/src/theme/globals.custom.scss new file mode 100644 index 000000000..5724c1a73 --- /dev/null +++ b/src/theme/globals.custom.scss @@ -0,0 +1,5 @@ +/* + * App Custom App variables SCSS + * ---------------------------------------------------------------------------- + * Place here all custom app variables. + */ diff --git a/src/theme/globals.mixins.ionic.scss b/src/theme/globals.mixins.ionic.scss new file mode 100644 index 000000000..73678af2a --- /dev/null +++ b/src/theme/globals.mixins.ionic.scss @@ -0,0 +1,520 @@ +/* + * Imported ionic mixins for SCSS + * ---------------------------------------------------------------------------- + * Place here our custom mixins. + * Extracted from ionic.mixins.scss + * https://github.com/ionic-team/ionic-framework/blob/master/core/src/themes/ionic.mixins.scss + */ + +@mixin input-cover() { + @include position(0, null, null, 0); + @include margin(0); + + position: absolute; + + width: 100%; + height: 100%; + + border: 0; + background: transparent; + cursor: pointer; + + appearance: none; + outline: none; + + &::-moz-focus-inner { + border: 0; + } +} + +@mixin text-inherit() { + font-family: inherit; + font-size: inherit; + font-style: inherit; + font-weight: inherit; + letter-spacing: inherit; + text-decoration: inherit; + text-indent: inherit; + text-overflow: inherit; + text-transform: inherit; + text-align: inherit; + white-space: inherit; + color: inherit; +} + +@mixin button-state() { + @include position(0, 0, 0, 0); + + position: absolute; + + content: ""; + + opacity: 0; +} + +// Font smoothing +// -------------------------------------------------- + +@mixin font-smoothing() { + -moz-osx-font-smoothing: grayscale; + -webkit-font-smoothing: antialiased; +} + +// Get the key from a map based on the index +@function index-to-key($map, $index) { + $keys: map-keys($map); + + @return nth($keys, $index); +} + + +// Breakpoint Mixins +// --------------------------------------------------------------------------------- + +// Breakpoint viewport sizes and media queries. +// +// Breakpoints are defined as a map of (name: minimum width), order from small to large: +// +// (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px) +// +// The map defined in the `$screen-breakpoints` global variable is used as the `$breakpoints` argument by default. + +// --------------------------------------------------------------------------------- + +// Minimum breakpoint width. Null for the smallest (first) breakpoint. +// +// >> breakpoint-min(sm, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px)) +// 576px +@function breakpoint-min($name, $breakpoints: $screen-breakpoints) { + $min: map-get($breakpoints, $name); + + @return if($name != index-to-key($breakpoints, 1), $min, null); +} + +// Returns a blank string if smallest breakpoint, otherwise returns the name with a dash infront. +// Useful for making responsive utilities. +// +// >> breakpoint-infix(xs, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px)) +// "" (Returns a blank string) +// >> breakpoint-infix(sm, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px)) +// "-sm" +@function breakpoint-infix($name, $breakpoints: $screen-breakpoints) { + @return if(breakpoint-min($name, $breakpoints) == null, "", "-#{$name}"); +} + +// Media of at least the minimum breakpoint width. No query for the smallest breakpoint. +// Makes the @content apply to the given breakpoint and wider. +@mixin media-breakpoint-up($name, $breakpoints: $screen-breakpoints) { + $min: breakpoint-min($name, $breakpoints); + @if $min { + @media (min-width: $min) { + @content; + } + } @else { + @content; + } +} + +// Name of the next breakpoint, or null for the last breakpoint. +// +// >> breakpoint-next(sm) +// md +// >> breakpoint-next(sm, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px)) +// md +// >> breakpoint-next(sm, $breakpoint-names: (xs sm md lg xl)) +// md +@function breakpoint-next($name, $breakpoints: $screen-breakpoints, $breakpoint-names: map-keys($breakpoints)) { + $n: index($breakpoint-names, $name); + @return if($n < length($breakpoint-names), nth($breakpoint-names, $n + 1), null); +} + +// Maximum breakpoint width. Null for the smallest (first) breakpoint. +// The maximum value is reduced by 0.02px to work around the limitations of +// `min-` and `max-` prefixes and viewports with fractional widths. +// +// See https://www.w3.org/TR/mediaqueries-4/#mq-min-max +// Uses 0.02px rather than 0.01px to work around a current rounding bug in Safari. // Uses 0.02px rather than 0.01px to work around a current rounding bug in Safari. +// See https://bugs.webkit.org/show_bug.cgi?id=178261 // See https://bugs.webkit.org/show_bug.cgi?id=178261 +// +// >> breakpoint-max(md, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px)) +// 767.98px +@function breakpoint-max($name, $breakpoints: $screen-breakpoints) { + $max: map-get($breakpoints, $name); + @return if($max and $max > 0, $max - .02, null); +} + +// Media of at most the maximum breakpoint width. No query for the largest breakpoint. +// Makes the @content apply to the given breakpoint and narrower. +@mixin media-breakpoint-down($name, $breakpoints: $screen-breakpoints) { + $max: breakpoint-max($name, $breakpoints); + @if $max { + @media (max-width: $max) { + @content; + } + } @else { + @content; + } +} + + +// Text Direction - ltr / rtl +// +// CSS defaults to use the ltr css, and adds [dir=rtl] selectors +// to override ltr defaults. +// ---------------------------------------------------------- + +@mixin multi-dir() { + @content; + + // $root: #{&}; + // @at-root [dir] { + // #{$root} { + // @content; + // } + // } + } + + @mixin rtl() { + $root: #{&}; + + @at-root [dir=rtl] { + #{$root} { + @content; + } + } + } + + @mixin ltr() { + @content; + } + + + // SVG Background Image Mixin + // @param {string} $svg + // ---------------------------------------------------------- + @mixin svg-background-image($svg, $flip-rtl: false) { + $url: url-encode($svg); + $viewBox: str-split(str-extract($svg, "viewBox='", "'"), " "); + + @if $flip-rtl != true or $viewBox == null { + @include multi-dir() { + background-image: url("data:image/svg+xml;charset=utf-8,#{$url}"); + } + } @else { + $transform: "transform='translate(#{nth($viewBox, 3)}, 0) scale(-1, 1)'"; + $flipped-url: $svg; + $flipped-url: str-replace($flipped-url, ""; + @if $flip-rtl != true { + @include multi-dir() { + background-image: url("data:image/svg+xml;charset=utf-8,#{$svg}"); + } + } @else { + $flipped-svg: ""; + + @include ltr () { + background-image: url("data:image/svg+xml;charset=utf-8,#{$svg}"); + } + @include rtl() { + background-image: url("data:image/svg+xml;charset=utf-8,#{$flipped-svg}"); + } + } +} + +@mixin border-start($px, $type, $color) { + @include ltr() { + border-left: $px $type $color; + } + + @include rtl() { + border-right: $px $type $color; + } +} + + +@mixin border-end($px, $type, $color) { + @include ltr() { + border-right: $px $type $color; + } + + @include rtl() { + border-left: $px $type $color; + } +} + +@mixin safe-area-border-start($px, $type, $color) { + $safe-area-position: calc(constant(safe-area-inset-left) + #{$px}); + $safe-area-position-env: calc(env(safe-area-inset-left) + #{$px}); + + @include border-start($px, $type, $color); + @media screen and (orientation: landscape) { + @include border-start($safe-area-position, $type, $color); + @include border-start($safe-area-position-env, $type, $color); + } +} + +@mixin safe-area-border-end($px, $type, $color) { + $safe-area-position: calc(constant(safe-area-inset-right) + #{$px}); + $safe-area-position-env: calc(env(safe-area-inset-right) + #{$px}); + + @include border-end($px, $type, $color); + @media screen and (orientation: landscape) { + @include border-end($safe-area-position, $type, $color); + @include border-end($safe-area-position-env, $type, $color); + } +} + +@mixin safe-area-margin-horizontal($start, $end: $start) { + $safe-area-end: null; + $safe-area-start: null; + $safe-area-start-env: null; + $safe-area-end-env: null; + + @if ($end) { + $safe-area-end: calc(constant(safe-area-inset-right) + #{$end}); + $safe-area-end-env: calc(env(safe-area-inset-right) + #{$end}); + } + @if ($start) { + $safe-area-start: calc(constant(safe-area-inset-left) + #{$start}); + $safe-area-start-env: calc(env(safe-area-inset-left) + #{$start}); + } + + @include margin-horizontal($start, $end); + + @media screen and (orientation: landscape) { + @include margin-horizontal($safe-area-start, $safe-area-end); + @include margin-horizontal($safe-area-start-env, $safe-area-end-env); + } +} + +@mixin safe-area-padding-start($start, $end) { + $safe-area-start: calc(constant(safe-area-inset-left) + #{$start}); + $safe-area-start-env: calc(env(safe-area-inset-left) + #{$start}); + + @include padding-horizontal($start, $end); + + @media screen and (orientation: landscape) { + @include padding-horizontal($safe-area-start, $end); + @include padding-horizontal($safe-area-start-env, $end); + } +} + +@mixin safe-area-padding-end($start, $end) { + $safe-area-end: calc(constant(safe-area-inset-right) + #{$end}); + $safe-area-end-env: calc(env(safe-area-inset-right) + #{$end}); + + @include padding-horizontal($start, $end); + + @media screen and (orientation: landscape) { + @include padding-horizontal($start, $safe-area-end); + @include padding-horizontal($start, $safe-area-end-env); + } +} + +@mixin safe-area-position($top: null, $end: null, $bottom: null, $start: null) { + @include position-horizontal($start, $end); + @include safe-position-horizontal($start, $end); + top: $top; + bottom: $bottom; +} + +@mixin core-headings() { + h1 { + font-size: 3rem; + } + h2 { + font-size: 2.8rem; + } + h3 { + font-size: 2.6rem; + } + h4 { + font-size: 2.2rem; + } + h5 { + font-size: 1.8rem; + } + h6 { + font-size: 1.4rem; + } +} + +@mixin core-as-items() { + .item-md.item-block > .item-inner { + border-bottom: 1px solid $list-md-border-color; + } + + .item-ios.item-block > .item-inner { + border-bottom: $hairlines-width solid $list-ios-border-color; + } + + &:last-child .item > .item-inner { + border-bottom: 0; + } +} + +@mixin core-items() { + &.item-md.item-block > .item-inner { + border-bottom: 1px solid $list-md-border-color; + } + + &.item-ios.item-block > .item-inner { + border-bottom: $hairlines-width solid $list-ios-border-color; + } + + &.item-block:last-child > .item-inner { + border-bottom: 0; + } +} + +@mixin darkmode() { + $root: #{&}; + + @at-root body.dark { + #{$root} { + @content; + } + } +} diff --git a/src/theme/globals.scss b/src/theme/globals.scss new file mode 100644 index 000000000..4d3cba282 --- /dev/null +++ b/src/theme/globals.scss @@ -0,0 +1,10 @@ +/* + * App Global variables SCSS + * ---------------------------------------------------------------------------- + * Place here the different files you should import to use global variables. + */ + +@import "./globals.custom.scss"; +@import "./globals.variables.scss"; +@import "./globals.mixins.scss"; +@import "./globals.mixins.ionic.scss"; diff --git a/src/theme/globals.variables.scss b/src/theme/globals.variables.scss new file mode 100644 index 000000000..0ecc0f2cd --- /dev/null +++ b/src/theme/globals.variables.scss @@ -0,0 +1,66 @@ +/* + * App Global variables SCSS + * ---------------------------------------------------------------------------- + * Place here all global variables. + */ + +/* + * App colors + */ +$black: #3a3a3a !default; // Headings, standard text. +$gray-darker: #626262 !default; // Text (emphasis-detail), placeholder, background. +$gray-dark: #9e9e9e !default; // Borders (never text). +$gray: #dddddd !default; +$gray-light: #e9e9e9 !default; // Background. +$gray-lighter: #f5f5f5 !default; +$white: #ffffff !default; // Background, reversed text. + +$blue: #0064d2 !default; // Link, background. +$turquoise: #007982 !default; // Accent. +$green: #5e8100 !default; // Accent. +$red: #cb3d4d !default; +$orange: #f98012 !default; // Accent (never text). +$yellow: #fbad1a !default; // Accent (never text). +$purple: #8e24aa !default; // Accent (never text). + +$blue-light: mix($blue, white, 20%) !default; // Background. +$blue-dark: darken($blue, 10%) !default; + +$turquoise-light: mix($turquoise, white, 20%) !default; // Background. +$turquoise-dark: darken($turquoise, 10%) !default; + +$green-light: mix($green, white, 20%) !default; +$green-dark: darken($green, 10%) !default; + +$red-light: mix($red, white, 20%) !default; +$red-dark: darken($red, 10%) !default; + +$orange-light: lighten($orange, 10%) !default; + +$yellow-light: mix($yellow, white, 20%) !default; +$yellow-dark: mix($yellow, black, 40%) !default; + +$core-color: $orange !default; +$core-color-light: lighten($core-color, 10%) !default; +$core-color-dark: darken($core-color, 10%) !default; + +$text-color: $black !default; +$link-color: $blue !default; +$background-color: $gray-light !default; +$subdued-text-color: $gray-darker !default; + +$core-online-color: #5cb85c !default; + +/* + * Layout Breakpoints + * + * https://ionicframework.com/docs/layout/grid#default-breakpoints + */ + +$breakpoint-xs: 0px !default; +$breakpoint-sm: 576px !default; +$breakpoint-md: 768px !default; +$breakpoint-lg: 992px !default; +$breakpoint-xl: 1200px !default; + +$breakpoint-tablet: $breakpoint-lg !default; diff --git a/src/theme/mixins.scss b/src/theme/mixins.scss deleted file mode 100644 index 93c952668..000000000 --- a/src/theme/mixins.scss +++ /dev/null @@ -1,697 +0,0 @@ -// Place here our custom mixins. -@mixin core-transition($where: all, $time: 500ms) { - -webkit-transition: $where $time ease-in-out; - -moz-transition: $where $time ease-in-out; - -ms-transition: $where $time ease-in-out; - -o-transition: $where $time ease-in-out; - transition: $where $time ease-in-out; -} - -@mixin push-arrow-color($color: dedede, $flip-rtl: false) { - $svg: ""; - @if $flip-rtl != true { - @include multi-dir() { - background-image: url("data:image/svg+xml;charset=utf-8,#{$svg}"); - } - } @else { - $flipped-svg: ""; - - @include ltr () { - background-image: url("data:image/svg+xml;charset=utf-8,#{$svg}"); - } - @include rtl() { - background-image: url("data:image/svg+xml;charset=utf-8,#{$flipped-svg}"); - } - } -} - -@mixin border-start($px, $type, $color) { - @include ltr() { - border-left: $px $type $color; - } - - @include rtl() { - border-right: $px $type $color; - } -} - - -@mixin border-end($px, $type, $color) { - @include ltr() { - border-right: $px $type $color; - } - - @include rtl() { - border-left: $px $type $color; - } -} - -@mixin safe-area-border-start($px, $type, $color) { - $safe-area-position: calc(constant(safe-area-inset-left) + #{$px}); - $safe-area-position-env: calc(env(safe-area-inset-left) + #{$px}); - - @include border-start($px, $type, $color); - @media screen and (orientation: landscape) { - @include border-start($safe-area-position, $type, $color); - @include border-start($safe-area-position-env, $type, $color); - } -} - -@mixin safe-area-border-end($px, $type, $color) { - $safe-area-position: calc(constant(safe-area-inset-right) + #{$px}); - $safe-area-position-env: calc(env(safe-area-inset-right) + #{$px}); - - @include border-end($px, $type, $color); - @media screen and (orientation: landscape) { - @include border-end($safe-area-position, $type, $color); - @include border-end($safe-area-position-env, $type, $color); - } -} - -@mixin safe-area-margin-horizontal($start, $end: $start) { - $safe-area-end: null; - $safe-area-start: null; - $safe-area-start-env: null; - $safe-area-end-env: null; - - @if ($end) { - $safe-area-end: calc(constant(safe-area-inset-right) + #{$end}); - $safe-area-end-env: calc(env(safe-area-inset-right) + #{$end}); - } - @if ($start) { - $safe-area-start: calc(constant(safe-area-inset-left) + #{$start}); - $safe-area-start-env: calc(env(safe-area-inset-left) + #{$start}); - } - - @include margin-horizontal($start, $end); - - @media screen and (orientation: landscape) { - @include margin-horizontal($safe-area-start, $safe-area-end); - @include margin-horizontal($safe-area-start-env, $safe-area-end-env); - } -} - -@mixin safe-area-padding-start($start, $end) { - $safe-area-start: calc(constant(safe-area-inset-left) + #{$start}); - $safe-area-start-env: calc(env(safe-area-inset-left) + #{$start}); - - @include padding-horizontal($start, $end); - - @media screen and (orientation: landscape) { - @include padding-horizontal($safe-area-start, $end); - @include padding-horizontal($safe-area-start-env, $end); - } -} - -@mixin safe-area-padding-end($start, $end) { - $safe-area-end: calc(constant(safe-area-inset-right) + #{$end}); - $safe-area-end-env: calc(env(safe-area-inset-right) + #{$end}); - - @include padding-horizontal($start, $end); - - @media screen and (orientation: landscape) { - @include padding-horizontal($start, $safe-area-end); - @include padding-horizontal($start, $safe-area-end-env); - } -} - -@mixin safe-area-position($top: null, $end: null, $bottom: null, $start: null) { - @include position-horizontal($start, $end); - @include safe-position-horizontal($start, $end); - top: $top; - bottom: $bottom; -} - -@mixin core-headings() { - h1 { - font-size: 3rem; - } - h2 { - font-size: 2.8rem; - } - h3 { - font-size: 2.6rem; - } - h4 { - font-size: 2.2rem; - } - h5 { - font-size: 1.8rem; - } - h6 { - font-size: 1.4rem; - } -} - -@mixin core-as-items() { - .item-md.item-block > .item-inner { - border-bottom: 1px solid $list-md-border-color; - } - - .item-ios.item-block > .item-inner { - border-bottom: $hairlines-width solid $list-ios-border-color; - } - - &:last-child .item > .item-inner { - border-bottom: 0; - } -} - -@mixin core-items() { - &.item-md.item-block > .item-inner { - border-bottom: 1px solid $list-md-border-color; - } - - &.item-ios.item-block > .item-inner { - border-bottom: $hairlines-width solid $list-ios-border-color; - } - - &.item-block:last-child > .item-inner { - border-bottom: 0; - } -} - -@mixin darkmode() { - $root: #{&}; - - @at-root body.dark { - #{$root} { - @content; - } - } -} - -// Extracted from ionic.mixins.scss -// https://github.com/ionic-team/ionic-framework/blob/master/core/src/themes/ionic.mixins.scss -@mixin input-cover() { - @include position(0, null, null, 0); - @include margin(0); - - position: absolute; - - width: 100%; - height: 100%; - - border: 0; - background: transparent; - cursor: pointer; - - appearance: none; - outline: none; - - &::-moz-focus-inner { - border: 0; - } -} - -@mixin text-inherit() { - font-family: inherit; - font-size: inherit; - font-style: inherit; - font-weight: inherit; - letter-spacing: inherit; - text-decoration: inherit; - text-indent: inherit; - text-overflow: inherit; - text-transform: inherit; - text-align: inherit; - white-space: inherit; - color: inherit; -} - -@mixin button-state() { - @include position(0, 0, 0, 0); - - position: absolute; - - content: ""; - - opacity: 0; -} - -// Font smoothing -// -------------------------------------------------- - -@mixin font-smoothing() { - -moz-osx-font-smoothing: grayscale; - -webkit-font-smoothing: antialiased; -} - -// Get the key from a map based on the index -@function index-to-key($map, $index) { - $keys: map-keys($map); - - @return nth($keys, $index); -} - - -// Breakpoint Mixins -// --------------------------------------------------------------------------------- - -// Breakpoint viewport sizes and media queries. -// -// Breakpoints are defined as a map of (name: minimum width), order from small to large: -// -// (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px) -// -// The map defined in the `$screen-breakpoints` global variable is used as the `$breakpoints` argument by default. - -// --------------------------------------------------------------------------------- - -// Minimum breakpoint width. Null for the smallest (first) breakpoint. -// -// >> breakpoint-min(sm, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px)) -// 576px -@function breakpoint-min($name, $breakpoints: $screen-breakpoints) { - $min: map-get($breakpoints, $name); - - @return if($name != index-to-key($breakpoints, 1), $min, null); -} - -// Returns a blank string if smallest breakpoint, otherwise returns the name with a dash infront. -// Useful for making responsive utilities. -// -// >> breakpoint-infix(xs, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px)) -// "" (Returns a blank string) -// >> breakpoint-infix(sm, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px)) -// "-sm" -@function breakpoint-infix($name, $breakpoints: $screen-breakpoints) { - @return if(breakpoint-min($name, $breakpoints) == null, "", "-#{$name}"); -} - -// Media of at least the minimum breakpoint width. No query for the smallest breakpoint. -// Makes the @content apply to the given breakpoint and wider. -@mixin media-breakpoint-up($name, $breakpoints: $screen-breakpoints) { - $min: breakpoint-min($name, $breakpoints); - @if $min { - @media (min-width: $min) { - @content; - } - } @else { - @content; - } -} - -// Name of the next breakpoint, or null for the last breakpoint. -// -// >> breakpoint-next(sm) -// md -// >> breakpoint-next(sm, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px)) -// md -// >> breakpoint-next(sm, $breakpoint-names: (xs sm md lg xl)) -// md -@function breakpoint-next($name, $breakpoints: $screen-breakpoints, $breakpoint-names: map-keys($breakpoints)) { - $n: index($breakpoint-names, $name); - @return if($n < length($breakpoint-names), nth($breakpoint-names, $n + 1), null); -} - -// Maximum breakpoint width. Null for the smallest (first) breakpoint. -// The maximum value is reduced by 0.02px to work around the limitations of -// `min-` and `max-` prefixes and viewports with fractional widths. -// -// See https://www.w3.org/TR/mediaqueries-4/#mq-min-max -// Uses 0.02px rather than 0.01px to work around a current rounding bug in Safari. // Uses 0.02px rather than 0.01px to work around a current rounding bug in Safari. -// See https://bugs.webkit.org/show_bug.cgi?id=178261 // See https://bugs.webkit.org/show_bug.cgi?id=178261 -// -// >> breakpoint-max(md, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px)) -// 767.98px -@function breakpoint-max($name, $breakpoints: $screen-breakpoints) { - $max: map-get($breakpoints, $name); - @return if($max and $max > 0, $max - .02, null); -} - -// Media of at most the maximum breakpoint width. No query for the largest breakpoint. -// Makes the @content apply to the given breakpoint and narrower. -@mixin media-breakpoint-down($name, $breakpoints: $screen-breakpoints) { - $max: breakpoint-max($name, $breakpoints); - @if $max { - @media (max-width: $max) { - @content; - } - } @else { - @content; - } -} - - -// Text Direction - ltr / rtl -// -// CSS defaults to use the ltr css, and adds [dir=rtl] selectors -// to override ltr defaults. -// ---------------------------------------------------------- - -@mixin multi-dir() { - @content; - - // $root: #{&}; - // @at-root [dir] { - // #{$root} { - // @content; - // } - // } -} - -@mixin rtl() { - $root: #{&}; - - @at-root [dir=rtl] { - #{$root} { - @content; - } - } -} - -@mixin ltr() { - @content; -} - - -// SVG Background Image Mixin -// @param {string} $svg -// ---------------------------------------------------------- -@mixin svg-background-image($svg, $flip-rtl: false) { - $url: url-encode($svg); - $viewBox: str-split(str-extract($svg, "viewBox='", "'"), " "); - - @if $flip-rtl != true or $viewBox == null { - @include multi-dir() { - background-image: url("data:image/svg+xml;charset=utf-8,#{$url}"); - } - } @else { - $transform: "transform='translate(#{nth($viewBox, 3)}, 0) scale(-1, 1)'"; - $flipped-url: $svg; - $flipped-url: str-replace($flipped-url, "