/* * 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 */ // Responsive Mixins // -------------------------------------------------- // Creates a fixed width for the grid based on the screen size // --------------------------------------------------------------------------------- @mixin make-grid-widths($widths: $grid-widths, $breakpoints: $screen-breakpoints) { @each $breakpoint, $width in $widths { @include media-breakpoint-up($breakpoint, $breakpoints) { width: $width; } } max-width: 100%; } // Adds padding to the element based on breakpoints // --------------------------------------------------------------------------------- @mixin make-breakpoint-padding($paddings) { @each $breakpoint in map-keys($paddings) { @include media-breakpoint-up($breakpoint) { $padding: map-get($paddings, $breakpoint); @include padding($padding); } } } // Gets the active color's css variable from a variation. Alpha is optional. // -------------------------------------------------------------------------------------------- // Example usage: // current-color(base) => var(--ion-color-base) // current-color(contrast, 0.1) => rgba(var(--ion-color-contrast-rgb), 0.1) // -------------------------------------------------------------------------------------------- @function current-color($variation, $alpha: null) { @if $alpha == null { @return var(--ion-color-#{$variation}); } @else { @return rgba(var(--ion-color-#{$variation}-rgb), #{$alpha}); } } // Gets the specific color's css variable from the name and variation. Alpha/rgb are optional. // -------------------------------------------------------------------------------------------- // Example usage: // ion-color(primary, base) => var(--ion-color-primary, #3880ff) // ion-color(secondary, contrast) => var(--ion-color-secondary-contrast) // ion-color(primary, base, 0.5) => rgba(var(--ion-color-primary-rgb, 56, 128, 255), 0.5) // -------------------------------------------------------------------------------------------- @function ion-color($name, $variation, $alpha: null, $rgb: null) { $values: map-get($colors, $name); $value: map-get($values, $variation); $variable: --ion-color-#{$name}-#{$variation}; @if ($variation == base) { $variable: --ion-color-#{$name}; } @if ($alpha) { $value: color-to-rgb-list($value); @return rgba(var(#{$variable}-rgb, $value), $alpha); } @if ($rgb) { $value: color-to-rgb-list($value); $variable: #{$variable}-rgb; } @return var(#{$variable}, $value); } // Mixes a color with black to create its shade. // -------------------------------------------------------------------------------------------- @function get-color-shade($color) { @return mix(#000, $color, 12%); } // Mixes a color with white to create its tint. // -------------------------------------------------------------------------------------------- @function get-color-tint($color) { @return mix(#fff, $color, 10%); } // Converts a color to a comma separated rgb. // -------------------------------------------------------------------------------------------- @function color-to-rgb-list($color) { @return #{red($color)},#{green($color)},#{blue($color)}; } // Ionic Colors // -------------------------------------------------- // Generates the color classes and variables based on the // colors map @mixin generate-color($color-name, $colors) { $value: map-get($colors, $color-name); $base: map-get($value, base); $contrast: map-get($value, contrast); $shade: map-get($value, shade); $tint: map-get($value, tint); --ion-color-#{$color-name}: #{$base}; --ion-color-#{$color-name}-base: #{$base}; --ion-color-#{$color-name}-rgb: #{color-to-rgb-list($base)}; --ion-color-#{$color-name}-contrast: #{$contrast}; --ion-color-#{$color-name}-contrast-rgb: #{color-to-rgb-list($contrast)}; --ion-color-#{$color-name}-shade: #{$shade}; --ion-color-#{$color-name}-tint: #{$tint}; .ion-color-#{$color-name} { --ion-color: #{$base}; --ion-color-base: #{$base}; --ion-color-rgb: #{color-to-rgb-list($base)}; --ion-color-contrast: #{$contrast}; --ion-color-contrast-rgb: #{color-to-rgb-list($contrast)}; --ion-color-shade: #{$shade}; --ion-color-tint: #{$tint}; } } @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, "<path", "<path #{$transform}"); $flipped-url: str-replace($flipped-url, "<line", "<line #{$transform}"); $flipped-url: str-replace($flipped-url, "<polygon", "<polygon #{$transform}"); $flipped-url: url-encode($flipped-url); @include ltr () { background-image: url("data:image/svg+xml;charset=utf-8,#{$url}"); } @include rtl() { background-image: url("data:image/svg+xml;charset=utf-8,#{$flipped-url}"); } } } // Add property horizontal // @param {string} $start // @param {string} $end // ---------------------------------------------------------- @mixin property-horizontal($prop, $start, $end: $start) { @if $start == 0 and $end == 0 { #{$prop}-left: $start; #{$prop}-right: $end; } @else { #{$prop}-left: $start; #{$prop}-right: $end; @at-root { @supports ((margin-inline-start: 0) or (-webkit-margin-start: 0)) { & { @if $start != null { #{$prop}-left: unset; } @if $end != null { #{$prop}-right: unset; } -webkit-#{$prop}-start: $start; #{$prop}-inline-start: $start; -webkit-#{$prop}-end: $end; #{$prop}-inline-end: $end; } } } } } // Add property for all directions // @param {string} $prop // @param {string} $top // @param {string} $end // @param {string} $bottom // @param {string} $start // @param {boolean} $content include content or use default // ---------------------------------------------------------- @mixin property($prop, $top, $end: $top, $bottom: $top, $start: $end) { @include property-horizontal($prop, $start, $end); #{$prop}-top: $top; #{$prop}-bottom: $bottom; } // Add padding horizontal // @param {string} $start // @param {string} $end // ---------------------------------------------------------- @mixin padding-horizontal($start, $end: $start) { @include property-horizontal(padding, $start, $end); } // Add padding for all directions // @param {string} $top // @param {string} $end // @param {string} $bottom // @param {string} $start // ---------------------------------------------------------- @mixin padding($top, $end: $top, $bottom: $top, $start: $end) { @include property(padding, $top, $end, $bottom, $start); } // Add margin horizontal // @param {string} $start // @param {string} $end // ---------------------------------------------------------- @mixin margin-horizontal($start, $end: $start) { @include property-horizontal(margin, $start, $end); } // Add margin for all directions // @param {string} $top // @param {string} $end // @param {string} $bottom // @param {string} $start // ---------------------------------------------------------- @mixin margin($top, $end: $top, $bottom: $top, $start: $end) { @include property(margin, $top, $end, $bottom, $start); } // Add position horizontal // @param {string} $start - amount to position start // @param {string} $end - amount to left: 0; end // ---------------------------------------------------------- @mixin position-horizontal($start: null, $end: null) { @if $start == $end { @include multi-dir() { left: $start; right: $end; } } @else { @include ltr() { left: $start; right: $end; } @include rtl() { left: unset; right: unset; left: $end; right: $start; } } } // Add position for all directions // @param {string} $top // @param {string} $end // @param {string} $bottom // @param {string} $start // ---------------------------------------------------------- @mixin position($top: null, $end: null, $bottom: null, $start: null) { @include position-horizontal($start, $end); top: $top; bottom: $bottom; } // Add border for all directions // @param {string} $top // @param {string} $end // @param {string} $bottom // @param {string} $start // ---------------------------------------------------------- @mixin border($top, $end: $top, $bottom: $top, $start: $end) { @include property(border, $top, $end, $bottom, $start); } // Add border radius for all directions // @param {string} $top-start // @param {string} $top-end // @param {string} $bottom-end // @param {string} $bottom-start // ---------------------------------------------------------- @mixin border-radius($top-start, $top-end: $top-start, $bottom-end: $top-start, $bottom-start: $top-end) { @if $top-start == $top-end and $top-start == $bottom-end and $top-start == $bottom-start { @include multi-dir() { border-radius: $top-start; } } @else { @include ltr() { border-top-left-radius: $top-start; border-top-right-radius: $top-end; border-bottom-right-radius: $bottom-end; border-bottom-left-radius: $bottom-start; } @include rtl() { border-top-left-radius: $top-end; border-top-right-radius: $top-start; border-bottom-right-radius: $bottom-start; border-bottom-left-radius: $bottom-end; } } } // Add direction for all directions // @param {string} $dir - Direction on LTR @mixin direction($dir) { $other-dir: null; @if $dir == ltr { $other-dir: rtl; } @else { $other-dir: ltr; } @include ltr() { direction: $dir; } @include rtl() { direction: $other-dir; } } // Add float for all directions // @param {string} $side // @param {string} $decorator - !important @mixin float($side, $decorator: null) { @if $side == start { @include ltr() { float: left $decorator; } @include rtl() { float: right $decorator; } } @else if $side == end { @include ltr() { float: right $decorator; } @include rtl() { float: left $decorator; } } @else { @include multi-dir() { float: $side $decorator; } } } @mixin background-position($horizontal, $horizontal-amount: null, $vertical: null, $vertical-amount: null) { @if $horizontal == start or $horizontal == end { $horizontal-ltr: null; $horizontal-rtl: null; @if $horizontal == start { $horizontal-ltr: left; $horizontal-rtl: right; } @else { $horizontal-ltr: right; $horizontal-rtl: left; } @include ltr() { background-position: $horizontal-ltr $horizontal-amount $vertical $vertical-amount; } @include rtl() { background-position: $horizontal-rtl $horizontal-amount $vertical $vertical-amount; } } @else { @include multi-dir() { background-position: $horizontal $horizontal-amount $vertical $vertical-amount; } } } @mixin transform-origin($x-axis, $y-axis: null) { @if $x-axis == start { @include ltr() { transform-origin: left $y-axis; } @include rtl() { transform-origin: right $y-axis; } } @else if $x-axis == end { @include ltr() { transform-origin: right $y-axis; } @include rtl() { transform-origin: left $y-axis; } } @else if $x-axis == left or $x-axis == right { @include multi-dir() { transform-origin: $x-axis $y-axis; } } @else { @include ltr() { transform-origin: $x-axis $y-axis; } @include rtl() { transform-origin: calc(100% - #{$x-axis}) $y-axis; } } } // Add transform for all directions // @param {string} $transforms - comma separated list of transforms @mixin transform($transforms...) { $extra: null; $x: null; $ltr-translate: null; $rtl-translate: null; @each $transform in $transforms { @if (str-index($transform, translate3d)) { $transform: str-replace($transform, 'translate3d('); $transform: str-replace($transform, ')'); $coordinates: str-split($transform, ','); $x: nth($coordinates, 1); $y: nth($coordinates, 2); $z: nth($coordinates, 3); $ltr-translate: translate3d($x, $y, $z); $rtl-translate: translate3d(calc(-1 * #{$x}), $y, $z); } @else { @if $extra == null { $extra: $transform; } @else { $extra: $extra $transform; } } } @if $x == '0' or $x == null { @include multi-dir() { transform: $ltr-translate $extra; } } @else { @include ltr() { transform: $ltr-translate $extra; } @include rtl() { transform: $rtl-translate $extra; } } }