// // Copyright 2017 Google Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. // @import "./variables"; // Creates a rule that will be applied when an MDC Web component is within the context of an RTL layout. // // Usage Example: // // ```scss // .mdc-foo { // position: absolute; // left: 0; // // @include mdc-rtl { // left: auto; // right: 0; // } // // &__bar { // margin-left: 4px; // @include mdc-rtl(".mdc-foo") { // margin-left: auto; // margin-right: 4px; // } // } // } // // .mdc-foo--mod { // padding-left: 4px; // // @include mdc-rtl { // padding-left: auto; // padding-right: 4px; // } // } // ``` // // Note that this mixin works by checking for an ancestor element with `[dir="rtl"]`. // As a result, nested `dir` values are not supported: // // ```html // // //
//
Styled incorrectly as RTL!
//
// // ``` // // In the future, selectors such as the `:dir` pseudo-class (http://mdn.io/css/:dir) will help us mitigate this. @mixin mdc-rtl($root-selector: null) { @if ($mdc-rtl-include) { @if ($root-selector) { @at-root { #{$root-selector}[dir="rtl"] &, [dir="rtl"] #{$root-selector} & { @content; } } } @else { [dir="rtl"] &, &[dir="rtl"] { @content; } } } } // Takes a base box-model property name (`margin`, `border`, `padding`, etc.) along with a // default direction (`left` or `right`) and value, and emits rules which apply the given value to the // specified direction by default and the opposite direction in RTL. // // For example: // // ```scss // .mdc-foo { // @include mdc-rtl-reflexive-box(margin, left, 8px); // } // ``` // // is equivalent to: // // ```scss // .mdc-foo { // margin-left: 8px; // margin-right: 0; // // @include mdc-rtl { // margin-left: 0; // margin-right: 8px; // } // } // ``` // // whereas: // // ```scss // .mdc-foo { // @include mdc-rtl-reflexive-box(margin, right, 8px); // } // ``` // // is equivalent to: // // ```scss // .mdc-foo { // margin-left: 0; // margin-right: 8px; // // @include mdc-rtl { // margin-left: 8px; // margin-right: 0; // } // } // ``` // // You can also pass an optional 4th `$root-selector` argument which will be forwarded to `mdc-rtl`, // e.g. `@include mdc-rtl-reflexive-box(margin, left, 8px, ".mdc-component")`. // // Note that this function will always zero out the original value in an RTL context. // If you're trying to flip the values, use `mdc-rtl-reflexive-property()` instead. @mixin mdc-rtl-reflexive-box($base-property, $default-direction, $value, $root-selector: null) { @if (index((right, left), $default-direction) == null) { @error "Invalid default direction: '#{$default-direction}'. Please specifiy either 'right' or 'left'."; } $left-value: $value; $right-value: 0; @if ($default-direction == right) { $left-value: 0; $right-value: $value; } @include mdc-rtl-reflexive-property($base-property, $left-value, $right-value, $root-selector); } // Takes a base property and emits rules that assign -left to and // -right to in a LTR context, and vice versa in a RTL context. // For example: // // ```scss // .mdc-foo { // @include mdc-rtl-reflexive-property(margin, auto, 12px); // } // ``` // // is equivalent to: // // ```scss // .mdc-foo { // margin-left: auto; // margin-right: 12px; // // @include mdc-rtl { // margin-left: 12px; // margin-right: auto; // } // } // ``` // // An optional 4th `$root-selector` argument can be given, which will be passed to `mdc-rtl`. @mixin mdc-rtl-reflexive-property($base-property, $left-value, $right-value, $root-selector: null) { $prop-left: #{$base-property}-left; $prop-right: #{$base-property}-right; @include mdc-rtl-reflexive($prop-left, $left-value, $prop-right, $right-value, $root-selector); } // Takes an argument specifying a horizontal position property (either "left" or "right") as well // as a value, and applies that value to the specified position in a LTR context, and flips it in a // RTL context. For example: // // ```scss // .mdc-foo { // @include mdc-rtl-reflexive-position(left, 0); // } // ``` // // is equivalent to: // // ```scss // .mdc-foo { // left: 0; // right: initial; // // @include mdc-rtl { // left: initial; // right: 0; // } // } // ``` // // An optional third $root-selector argument may also be given, which is passed to `mdc-rtl`. @mixin mdc-rtl-reflexive-position($position-property, $value, $root-selector: null) { @if (index((right, left), $position-property) == null) { @error "Invalid position #{position-property}. Please specifiy either right or left"; } // TODO: "initial" is not supported in IE 11. https://caniuse.com/#feat=css-initial-value $left-value: $value; $right-value: initial; @if ($position-property == right) { $right-value: $value; $left-value: initial; } @include mdc-rtl-reflexive(left, $left-value, right, $right-value, $root-selector); } // Takes pair of properties with values as arguments and flips it in RTL context. // For example: // // ```scss // .mdc-foo { // @include mdc-rtl-reflexive(left, 2px, right, 5px); // } // ``` // // is equivalent to: // // ```scss // .mdc-foo { // left: 2px; // right: 5px; // // @include mdc-rtl { // right: 2px; // left: 5px; // } // } // ``` // // An optional fifth `$root-selector` argument may also be given, which is passed to `mdc-rtl`. @mixin mdc-rtl-reflexive( $left-property, $left-value, $right-property, $right-value, $root-selector: null ) { @include mdc-rtl-property_($left-property, $left-value); @include mdc-rtl-property_($right-property, $right-value); @include mdc-rtl($root-selector) { @include mdc-rtl-property_($left-property, $right-value); @include mdc-rtl-property_($right-property, $left-value); } } /// /// Adds `@noflip` annotation when `$mdc-rtl-include` is true. /// /// @param {String} $property /// @param {String} $value /// @access private /// @mixin mdc-rtl-property_($property, $value) { @if $mdc-rtl-include { /* @noflip */ } #{$property}: #{$value}; }