// // Copyright 2017 Google Inc. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // /** * 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 works by checking for [dir="rtl"] on an ancestor element. While this will work * in most cases, it will in some cases lead to false negatives, e.g. * * ```html * * *
*
Styled incorrectly as RTL!
*
* * ``` * * In the future, selectors such as :dir (http://mdn.io/:dir) will help us mitigate this. */ @mixin mdc-rtl($root-selector: null) { @if ($root-selector) { @at-root { [dir="rtl"] #{$root-selector} &, #{$root-selector}[dir="rtl"] & { @content; } } } @else { [dir="rtl"] &, &[dir="rtl"] { @content; } } } /** * Takes a base box-model property - e.g. margin / border / padding - along with a default * direction and value, and emits rules which apply the value to the * "-" property by default, but flips the direction * when within an RTL context. * * For example: * * ```scss * .mdc-foo { * @include mdc-rtl-reflexive-box(margin, left, 8px); * } * ``` * is equivalent to: * * ```scss * .mdc-foo { * margin-left: 8px; * * @include mdc-rtl { * margin-right: 8px; * margin-left: 0; * } * } * ``` * whereas: * * ```scss * .mdc-foo { * @include mdc-rtl-reflexive-box(margin, right, 8px); * } * ``` * is equivalent to: * * ```scss * .mdc-foo { * margin-right: 8px; * * @include mdc-rtl { * margin-right: 0; * margin-left: 8px; * } * } * ``` * * You can also pass a 4th optional $root-selector argument which will be forwarded to `mdc-rtl`, * e.g. `@include mdc-rtl-reflexive-box-property(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(). */ @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; * } * } * ``` * * A 4th optional $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); * position: absolute; * } * ``` * is equivalent to: * * ```scss * .mdc-foo { * position: absolute; * left: 0; * right: initial; * * @include mdc-rtl { * right: 0; * left: initial; * } * } * ``` * An optional third $root-selector argument may also be given, which is passed to `mdc-rtl`. */ @mixin mdc-rtl-reflexive-position($pos, $value, $root-selector: null) { @if (index((right, left), $pos) == null) { @error "Invalid position #{pos}. Please specifiy either right or left"; } $left-value: $value; $right-value: initial; @if ($pos == right) { $right-value: $value; $left-value: initial; } @include mdc-rtl-reflexive_(left, $left-value, right, $right-value, $root-selector); } @mixin mdc-rtl-reflexive_( $left-property, $left-value, $right-property, $right-value, $root-selector: null ) { #{$left-property}: $left-value; #{$right-property}: $right-value; @include mdc-rtl($root-selector) { #{$left-property}: $right-value; #{$right-property}: $left-value; } }