From 35d8ab3b5aa66ced790af812360c5071e763dec4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pau=20Ferrer=20Oca=C3=B1a?= Date: Wed, 27 Jan 2021 17:04:21 +0100 Subject: [PATCH] MOBILE-3659 course: Style fixes --- .../components/calendar/calendar.scss | 3 + .../core-block-course-blocks.html | 3 +- .../course-blocks/course-blocks.scss | 1 + .../components/format/core-course-format.html | 50 +- .../course/components/format/format.scss | 9 +- .../course-module-description.scss | 3 +- .../components/module/core-course-module.html | 6 +- .../course/components/module/module.scss | 4 +- .../section-selector/section-selector.html | 4 +- .../services/handlers/default-module.ts | 2 +- .../core-editor-rich-text-editor.html | 28 +- .../grades/services/handlers/course-option.ts | 4 +- .../h5p-player/core-h5p-player.html | 2 +- src/theme/app.scss | 77 +- src/theme/format-text.scss | 83 +++ src/theme/global.scss | 1 + src/theme/mixins.scss | 697 ++++++++++++++++++ src/theme/variables.scss | 19 + 18 files changed, 934 insertions(+), 62 deletions(-) create mode 100644 src/theme/format-text.scss create mode 100644 src/theme/mixins.scss diff --git a/src/addons/calendar/components/calendar/calendar.scss b/src/addons/calendar/components/calendar/calendar.scss index 1c3433c6c..1575f794f 100644 --- a/src/addons/calendar/components/calendar/calendar.scss +++ b/src/addons/calendar/components/calendar/calendar.scss @@ -149,6 +149,9 @@ display: inline-block; vertical-align: bottom; } + .core-module-icon[slot="start"] { + padding: 6px; + } } :host-context([dir=rtl]) { diff --git a/src/core/features/block/components/course-blocks/core-block-course-blocks.html b/src/core/features/block/components/course-blocks/core-block-course-blocks.html index a875f46e4..3743bb42d 100644 --- a/src/core/features/block/components/course-blocks/core-block-course-blocks.html +++ b/src/core/features/block/components/course-blocks/core-block-course-blocks.html @@ -7,7 +7,8 @@ - + diff --git a/src/core/features/block/components/course-blocks/course-blocks.scss b/src/core/features/block/components/course-blocks/course-blocks.scss index 96774170f..04f290e4f 100644 --- a/src/core/features/block/components/course-blocks/course-blocks.scss +++ b/src/core/features/block/components/course-blocks/course-blocks.scss @@ -21,6 +21,7 @@ max-width: var(--side-blocks-max-width); min-width: var(--side-blocks-min-width); box-shadow: -4px 0px 16px rgba(0, 0, 0, 0.18); + z-index: 2; // @todo @include core-split-area-end(); } diff --git a/src/core/features/course/components/format/core-course-format.html b/src/core/features/course/components/format/core-course-format.html index 54732cec4..74738d626 100644 --- a/src/core/features/course/components/format/core-course-format.html +++ b/src/core/features/course/components/format/core-course-format.html @@ -19,17 +19,17 @@
- - + {{ 'core.course.sections' | translate }} - +
@@ -93,17 +93,17 @@
- - - + - + @@ -120,21 +120,23 @@ - - - -

- - {{ 'core.course.hiddenfromstudents' | translate }} - - - {{ 'core.notavailable' | translate }} - - - - - -

+ + + + +

+ + {{ 'core.course.hiddenfromstudents' | translate }} + + + {{ 'core.notavailable' | translate }} + + + + + +

+
@@ -163,4 +165,4 @@ [loading]="section.isDownloading || section.isCalculating" [canTrustDownload]="section.canCheckUpdates"> - \ No newline at end of file + diff --git a/src/core/features/course/components/format/format.scss b/src/core/features/course/components/format/format.scss index 672fc732d..bd62cd001 100644 --- a/src/core/features/course/components/format/format.scss +++ b/src/core/features/course/components/format/format.scss @@ -45,6 +45,7 @@ } } +// @todo // .item-divider { // .label { // margin-top: 0; @@ -73,12 +74,4 @@ // @include safe-area-padding-start($content-padding !important, $content-padding); // } -// .core-course-section-nav-buttons { -// .button-inner core-format-text { -// white-space: nowrap; -// text-overflow: ellipsis; -// overflow: hidden; -// text-transform: none; -// } -// } } diff --git a/src/core/features/course/components/module-description/course-module-description.scss b/src/core/features/course/components/module-description/course-module-description.scss index ca2d02d73..7ba1e696e 100644 --- a/src/core/features/course/components/module-description/course-module-description.scss +++ b/src/core/features/course/components/module-description/course-module-description.scss @@ -1,3 +1,4 @@ +// @todo Review commented styles. // ion-app.app-root { // .safe-area-page, // .safe-padding-horizontal { @@ -13,4 +14,4 @@ // } // } // } -// } \ No newline at end of file +// } diff --git a/src/core/features/course/components/module/core-course-module.html b/src/core/features/course/components/module/core-course-module.html index 1eedc171a..28ebf7165 100644 --- a/src/core/features/course/components/module/core-course-module.html +++ b/src/core/features/course/components/module/core-course-module.html @@ -1,5 +1,5 @@ @@ -31,7 +31,7 @@ [hidden]="button.hidden || spinner || module.handlerData.spinner" class="core-animate-show-hide" (click)="buttonClicked($event, button)" [attr.aria-label]="button.label | translate:{$a: module.handlerData.title}"> - +
@@ -70,4 +70,4 @@ class="ion-text-wrap" id="core-course-module-{{module.id}}" [title]="module.handlerData.a11yTitle" [ngClass]="['core-course-module-handler', 'core-module-loading', module.handlerData.class]" detail="false"> - \ No newline at end of file + diff --git a/src/core/features/course/components/module/module.scss b/src/core/features/course/components/module/module.scss index 78439793e..5ded99475 100644 --- a/src/core/features/course/components/module/module.scss +++ b/src/core/features/course/components/module/module.scss @@ -1,4 +1,6 @@ :host { + // @todo Review commented styles. + background: white; display: block; @@ -159,4 +161,4 @@ // ion-app.app-root .core-course-module-handler.item [item-start] + .item-inner { // @include margin-horizontal(4px, null); -// } \ No newline at end of file +// } diff --git a/src/core/features/course/components/section-selector/section-selector.html b/src/core/features/course/components/section-selector/section-selector.html index 92b0ba8fa..f0997453a 100644 --- a/src/core/features/course/components/section-selector/section-selector.html +++ b/src/core/features/course/components/section-selector/section-selector.html @@ -12,7 +12,7 @@ @@ -36,4 +36,4 @@ - \ No newline at end of file + diff --git a/src/core/features/course/services/handlers/default-module.ts b/src/core/features/course/services/handlers/default-module.ts index b764f7d1c..95f9d7b5e 100644 --- a/src/core/features/course/services/handlers/default-module.ts +++ b/src/core/features/course/services/handlers/default-module.ts @@ -72,7 +72,7 @@ export class CoreCourseModuleDefaultHandler implements CoreCourseModuleHandler { if ('url' in module && module.url) { defaultData.buttons = [{ - icon: 'open', + icon: 'fas-external-link-alt', label: 'core.openinbrowser', action: (e: Event): void => { e.preventDefault(); diff --git a/src/core/features/editor/components/rich-text-editor/core-editor-rich-text-editor.html b/src/core/features/editor/components/rich-text-editor/core-editor-rich-text-editor.html index a409f709c..d2187aefc 100644 --- a/src/core/features/editor/components/rich-text-editor/core-editor-rich-text-editor.html +++ b/src/core/features/editor/components/rich-text-editor/core-editor-rich-text-editor.html @@ -24,85 +24,85 @@ diff --git a/src/core/features/grades/services/handlers/course-option.ts b/src/core/features/grades/services/handlers/course-option.ts index 5f5f050c7..9dcb7cb61 100644 --- a/src/core/features/grades/services/handlers/course-option.ts +++ b/src/core/features/grades/services/handlers/course-option.ts @@ -15,7 +15,7 @@ import { Injectable } from '@angular/core'; import { CoreCourseProvider } from '@features/course/services/course'; import { - CoreCourseAccessData, + CoreCourseAccess, CoreCourseOptionsHandler, CoreCourseOptionsHandlerData, } from '@features/course/services/course-options-delegate'; @@ -68,7 +68,7 @@ export class CoreGradesCourseOptionHandlerService implements CoreCourseOptionsHa */ isEnabledForCourse( courseId: number, - accessData: CoreCourseAccessData, + accessData: CoreCourseAccess, navOptions?: CoreCourseUserAdminOrNavOptionIndexed, ): boolean | Promise { if (accessData && accessData.type == CoreCourseProvider.ACCESS_GUEST) { diff --git a/src/core/features/h5p/components/h5p-player/core-h5p-player.html b/src/core/features/h5p/components/h5p-player/core-h5p-player.html index cb510fd5d..e6ad42431 100644 --- a/src/core/features/h5p/components/h5p-player/core-h5p-player.html +++ b/src/core/features/h5p/components/h5p-player/core-h5p-player.html @@ -1,6 +1,6 @@
- +
diff --git a/src/theme/app.scss b/src/theme/app.scss index 1e88bf9ee..63c199dad 100644 --- a/src/theme/app.scss +++ b/src/theme/app.scss @@ -1,3 +1,31 @@ + // Common styles. + .text-left { text-align: left; } + .text-right { text-align: right; } + .text-center { text-align: center; } + .text-justify { text-align: justify; } + .clearfix { + &:after { + content: ""; + display: table; + clear: both; + } + } + .img-responsive { + display: block; + max-width: 100%; + &[height] { + height: auto; + } + } + + .opacity-hide { opacity: 0; } + .core-big { font-size: 115%; } + .invisible { visibility: hidden; } + + .button-no-uppercase { + text-transform: none; + } + // Correctly inherit ion-text-wrap onto labels. ion-item.ion-text-wrap ion-label { white-space: normal !important; @@ -170,7 +198,8 @@ ion-toolbar { --border-color: var(--ion-color-danger); } .item-dimmed { - opacity: 0.71; + opacity: 0.7; + --background: var(--gray-lighter); } // Extra text colors. @@ -301,15 +330,53 @@ ion-item img.core-module-icon[slot="start"] { // Select. ion-select.core-button-select, .core-button-select { - background: var(--ion-color-primary-contrast); - color: var(--ion-color-primary); - white-space: normal; + --background: var(--core-button-select-background); + background: var(--background); + --color: var(--ion-color-primary); + color: var(--color); + text-overflow: ellipsis; + white-space: nowrap; min-height: 45px; + overflow: hidden; margin: 8px; box-shadow: 0 3px 1px -2px rgba(0, 0, 0, .2), 0 2px 2px 0 rgba(0, 0, 0, .14), 0 1px 5px 0 rgba(0, 0, 0, .12); &::part(icon) { margin: 0 8px; } + .core-button-select-text { + margin-inline-end: auto; + } + +} +ion-button.core-button-select { + &::part(native) { + text-transform: none; + font-weight: 400; + font-size: 16px; + } + ion-icon { + margin: 0 8px; + } + .select-icon { + width: 19px; + height: 19px; + position: relative; + opacity: 0.33; + + .select-icon-inner { + left: 5px; + top: 50%; + margin-top: -2px; + position: absolute; + width: 0px; + height: 0px; + color: currentcolor; + pointer-events: none; + border-top: 5px solid; + border-right: 5px solid transparent; + border-left: 5px solid transparent; + } + } } // File uploader. @@ -346,3 +413,5 @@ ion-select.core-button-select, font-weight: normal; font-size: 1em; } + +@import "./format-text.scss"; diff --git a/src/theme/format-text.scss b/src/theme/format-text.scss new file mode 100644 index 000000000..149e2e807 --- /dev/null +++ b/src/theme/format-text.scss @@ -0,0 +1,83 @@ +@import "./mixins.scss"; + +/** Format Text - Show more styles. */ +/** Styles of elements inside the directive should be placed in format-text.scss */ +core-format-text { + user-select: text; + word-break: break-word; + word-wrap: break-word; + + &[maxHeight], + &[ng-reflect-max-height] { + display: block; + position: relative; + width: 100%; + overflow: hidden; + + /* Force display inline */ + &.inline { + display: inline-block; + width: auto; + } + + // This is to allow clicks in radio/checkbox content. + &.core-text-formatted { + cursor: pointer; + pointer-events: auto; + + .core-show-more { + display: none; + } + + &:not(.core-shortened) { + max-height: none !important; + } + + &.core-shortened { + overflow: hidden; + min-height: 50px; + + .core-show-more { + text-align: end; + font-size: 14px; + display: block; + position: absolute; + @include position(null, 0, 0, null); + z-index: 7; + background-color: var(--background); + color: var(--color); + padding-left: 10px; // RTL + /*@include darkmode() { + color: var(--white); + background-color: $core-dark-item-bg-color; + }*/ + } + + &:before { + content: ''; + height: 100%; + position: absolute; + right: 0; + bottom: 0; + left: 0; + background: -moz-linear-gradient(top, rgba(0, 0, 0, 0) calc(100% - 50px), var(--background) calc(100% - 15px)); + background: -webkit-gradient(left top, left bottom, color-stop(calc(100% - 50px), rgba(0, 0, 0, 0)), color-stop(calc(100% - 15px), var(--background))); + background: -webkit-linear-gradient(top, rgba(0, 0, 0, 0) calc(100% - 50px), var(--background) calc(100% - 15px)); + background: linear-gradient(to bottom, rgba(0, 0, 0, 0) calc(100% - 50px), var(--background) calc(100% - 15px)); + z-index: 6; + } + } + } + + &.core-expand-in-fullview { + .core-show-more { + @include push-arrow-color(dedede, true); + @include padding-horizontal(null, 18px); + @include background-position(end, 0, center); + + background-repeat: no-repeat; + background-size: 14px 14px; + } + } + } +} diff --git a/src/theme/global.scss b/src/theme/global.scss index 44997bd1f..54f8ccf5d 100644 --- a/src/theme/global.scss +++ b/src/theme/global.scss @@ -11,6 +11,7 @@ /* Application styles */ @import "./variables.scss"; +@import "./mixins.scss"; /* Core CSS required for Ionic components to work properly */ @import "~@ionic/angular/css/core.css"; diff --git a/src/theme/mixins.scss b/src/theme/mixins.scss new file mode 100644 index 000000000..93c952668 --- /dev/null +++ b/src/theme/mixins.scss @@ -0,0 +1,697 @@ +// 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, "