[6a3a178] | 1 | @use 'sass:map';
|
---|
| 2 | @use 'sass:math';
|
---|
| 3 | @use 'sass:meta';
|
---|
| 4 | @use 'variables';
|
---|
| 5 |
|
---|
| 6 |
|
---|
| 7 | // A collection of mixins and CSS classes that can be used to apply elevation to a material
|
---|
| 8 | // element.
|
---|
| 9 | // See: https://material.io/design/environment/elevation.html
|
---|
| 10 | // Examples:
|
---|
| 11 | //
|
---|
| 12 | //
|
---|
| 13 | // .mat-foo {
|
---|
| 14 | // @include $mat-elevation(2);
|
---|
| 15 | //
|
---|
| 16 | // &:active {
|
---|
| 17 | // @include $mat-elevation(8);
|
---|
| 18 | // }
|
---|
| 19 | // }
|
---|
| 20 | //
|
---|
| 21 | // <div id="external-card" class="mat-elevation-z2"><p>Some content</p></div>
|
---|
| 22 | //
|
---|
| 23 | // For an explanation of the design behind how elevation is implemented, see the design doc at
|
---|
| 24 | // https://goo.gl/Kq0k9Z.
|
---|
| 25 |
|
---|
| 26 | // Colors for umbra, penumbra, and ambient shadows. As described in the design doc, each elevation
|
---|
| 27 | // level is created using a set of 3 shadow values, one for umbra (the shadow representing the
|
---|
| 28 | // space completely obscured by an object relative to its light source), one for penumbra (the
|
---|
| 29 | // space partially obscured by an object), and one for ambient (the space which contains the object
|
---|
| 30 | // itself). For a further explanation of these terms and their meanings, see
|
---|
| 31 | // https://en.wikipedia.org/wiki/Umbra,_penumbra_and_antumbra.
|
---|
| 32 |
|
---|
| 33 | // Maps for the different shadow sets and their values within each z-space. These values were
|
---|
| 34 | // created by taking a few reference shadow sets created by Google's Designers and interpolating
|
---|
| 35 | // all of the values between them.
|
---|
| 36 |
|
---|
| 37 | @function _get-umbra-map($color, $opacity) {
|
---|
| 38 | $shadow-color: if(meta.type-of($color) == color, rgba($color, $opacity * 0.2), $color);
|
---|
| 39 |
|
---|
| 40 | @return (
|
---|
| 41 | 0: '0px 0px 0px 0px #{$shadow-color}',
|
---|
| 42 | 1: '0px 2px 1px -1px #{$shadow-color}',
|
---|
| 43 | 2: '0px 3px 1px -2px #{$shadow-color}',
|
---|
| 44 | 3: '0px 3px 3px -2px #{$shadow-color}',
|
---|
| 45 | 4: '0px 2px 4px -1px #{$shadow-color}',
|
---|
| 46 | 5: '0px 3px 5px -1px #{$shadow-color}',
|
---|
| 47 | 6: '0px 3px 5px -1px #{$shadow-color}',
|
---|
| 48 | 7: '0px 4px 5px -2px #{$shadow-color}',
|
---|
| 49 | 8: '0px 5px 5px -3px #{$shadow-color}',
|
---|
| 50 | 9: '0px 5px 6px -3px #{$shadow-color}',
|
---|
| 51 | 10: '0px 6px 6px -3px #{$shadow-color}',
|
---|
| 52 | 11: '0px 6px 7px -4px #{$shadow-color}',
|
---|
| 53 | 12: '0px 7px 8px -4px #{$shadow-color}',
|
---|
| 54 | 13: '0px 7px 8px -4px #{$shadow-color}',
|
---|
| 55 | 14: '0px 7px 9px -4px #{$shadow-color}',
|
---|
| 56 | 15: '0px 8px 9px -5px #{$shadow-color}',
|
---|
| 57 | 16: '0px 8px 10px -5px #{$shadow-color}',
|
---|
| 58 | 17: '0px 8px 11px -5px #{$shadow-color}',
|
---|
| 59 | 18: '0px 9px 11px -5px #{$shadow-color}',
|
---|
| 60 | 19: '0px 9px 12px -6px #{$shadow-color}',
|
---|
| 61 | 20: '0px 10px 13px -6px #{$shadow-color}',
|
---|
| 62 | 21: '0px 10px 13px -6px #{$shadow-color}',
|
---|
| 63 | 22: '0px 10px 14px -6px #{$shadow-color}',
|
---|
| 64 | 23: '0px 11px 14px -7px #{$shadow-color}',
|
---|
| 65 | 24: '0px 11px 15px -7px #{$shadow-color}'
|
---|
| 66 | );
|
---|
| 67 | }
|
---|
| 68 |
|
---|
| 69 | @function _get-penumbra-map($color, $opacity) {
|
---|
| 70 | $shadow-color: if(meta.type-of($color) == color, rgba($color, $opacity * 0.14), $color);
|
---|
| 71 |
|
---|
| 72 | @return (
|
---|
| 73 | 0: '0px 0px 0px 0px #{$shadow-color}',
|
---|
| 74 | 1: '0px 1px 1px 0px #{$shadow-color}',
|
---|
| 75 | 2: '0px 2px 2px 0px #{$shadow-color}',
|
---|
| 76 | 3: '0px 3px 4px 0px #{$shadow-color}',
|
---|
| 77 | 4: '0px 4px 5px 0px #{$shadow-color}',
|
---|
| 78 | 5: '0px 5px 8px 0px #{$shadow-color}',
|
---|
| 79 | 6: '0px 6px 10px 0px #{$shadow-color}',
|
---|
| 80 | 7: '0px 7px 10px 1px #{$shadow-color}',
|
---|
| 81 | 8: '0px 8px 10px 1px #{$shadow-color}',
|
---|
| 82 | 9: '0px 9px 12px 1px #{$shadow-color}',
|
---|
| 83 | 10: '0px 10px 14px 1px #{$shadow-color}',
|
---|
| 84 | 11: '0px 11px 15px 1px #{$shadow-color}',
|
---|
| 85 | 12: '0px 12px 17px 2px #{$shadow-color}',
|
---|
| 86 | 13: '0px 13px 19px 2px #{$shadow-color}',
|
---|
| 87 | 14: '0px 14px 21px 2px #{$shadow-color}',
|
---|
| 88 | 15: '0px 15px 22px 2px #{$shadow-color}',
|
---|
| 89 | 16: '0px 16px 24px 2px #{$shadow-color}',
|
---|
| 90 | 17: '0px 17px 26px 2px #{$shadow-color}',
|
---|
| 91 | 18: '0px 18px 28px 2px #{$shadow-color}',
|
---|
| 92 | 19: '0px 19px 29px 2px #{$shadow-color}',
|
---|
| 93 | 20: '0px 20px 31px 3px #{$shadow-color}',
|
---|
| 94 | 21: '0px 21px 33px 3px #{$shadow-color}',
|
---|
| 95 | 22: '0px 22px 35px 3px #{$shadow-color}',
|
---|
| 96 | 23: '0px 23px 36px 3px #{$shadow-color}',
|
---|
| 97 | 24: '0px 24px 38px 3px #{$shadow-color}'
|
---|
| 98 | );
|
---|
| 99 | }
|
---|
| 100 |
|
---|
| 101 | @function _get-ambient-map($color, $opacity) {
|
---|
| 102 | $shadow-color: if(meta.type-of($color) == color, rgba($color, $opacity * 0.12), $color);
|
---|
| 103 |
|
---|
| 104 | @return (
|
---|
| 105 | 0: '0px 0px 0px 0px #{$shadow-color}',
|
---|
| 106 | 1: '0px 1px 3px 0px #{$shadow-color}',
|
---|
| 107 | 2: '0px 1px 5px 0px #{$shadow-color}',
|
---|
| 108 | 3: '0px 1px 8px 0px #{$shadow-color}',
|
---|
| 109 | 4: '0px 1px 10px 0px #{$shadow-color}',
|
---|
| 110 | 5: '0px 1px 14px 0px #{$shadow-color}',
|
---|
| 111 | 6: '0px 1px 18px 0px #{$shadow-color}',
|
---|
| 112 | 7: '0px 2px 16px 1px #{$shadow-color}',
|
---|
| 113 | 8: '0px 3px 14px 2px #{$shadow-color}',
|
---|
| 114 | 9: '0px 3px 16px 2px #{$shadow-color}',
|
---|
| 115 | 10: '0px 4px 18px 3px #{$shadow-color}',
|
---|
| 116 | 11: '0px 4px 20px 3px #{$shadow-color}',
|
---|
| 117 | 12: '0px 5px 22px 4px #{$shadow-color}',
|
---|
| 118 | 13: '0px 5px 24px 4px #{$shadow-color}',
|
---|
| 119 | 14: '0px 5px 26px 4px #{$shadow-color}',
|
---|
| 120 | 15: '0px 6px 28px 5px #{$shadow-color}',
|
---|
| 121 | 16: '0px 6px 30px 5px #{$shadow-color}',
|
---|
| 122 | 17: '0px 6px 32px 5px #{$shadow-color}',
|
---|
| 123 | 18: '0px 7px 34px 6px #{$shadow-color}',
|
---|
| 124 | 19: '0px 7px 36px 6px #{$shadow-color}',
|
---|
| 125 | 20: '0px 8px 38px 7px #{$shadow-color}',
|
---|
| 126 | 21: '0px 8px 40px 7px #{$shadow-color}',
|
---|
| 127 | 22: '0px 8px 42px 7px #{$shadow-color}',
|
---|
| 128 | 23: '0px 9px 44px 8px #{$shadow-color}',
|
---|
| 129 | 24: '0px 9px 46px 8px #{$shadow-color}'
|
---|
| 130 | );
|
---|
| 131 | }
|
---|
| 132 |
|
---|
| 133 | // The default duration value for elevation transitions.
|
---|
| 134 | $transition-duration: 280ms !default;
|
---|
| 135 |
|
---|
| 136 | // The default easing value for elevation transitions.
|
---|
| 137 | $transition-timing-function: variables.$fast-out-slow-in-timing-function;
|
---|
| 138 |
|
---|
| 139 | // The default color for elevation shadows.
|
---|
| 140 | $color: black !default;
|
---|
| 141 |
|
---|
| 142 | // The default opacity scaling value for elevation shadows.
|
---|
| 143 | $opacity: 1 !default;
|
---|
| 144 |
|
---|
| 145 | // Prefix for elevation-related selectors.
|
---|
| 146 | $prefix: 'mat-elevation-z';
|
---|
| 147 |
|
---|
| 148 | // Applies the correct css rules to an element to give it the elevation specified by $zValue.
|
---|
| 149 | // The $zValue must be between 0 and 24.
|
---|
| 150 | @mixin elevation($zValue, $color: $color, $opacity: $opacity) {
|
---|
| 151 | @if meta.type-of($zValue) != number or not math.is-unitless($zValue) {
|
---|
| 152 | @error '$zValue must be a unitless number';
|
---|
| 153 | }
|
---|
| 154 | @if $zValue < 0 or $zValue > 24 {
|
---|
| 155 | @error '$zValue must be between 0 and 24';
|
---|
| 156 | }
|
---|
| 157 |
|
---|
| 158 | box-shadow: #{map.get(_get-umbra-map($color, $opacity), $zValue)},
|
---|
| 159 | #{map.get(_get-penumbra-map($color, $opacity), $zValue)},
|
---|
| 160 | #{map.get(_get-ambient-map($color, $opacity), $zValue)};
|
---|
| 161 | }
|
---|
| 162 |
|
---|
| 163 | // Applies the elevation to an element in a manner that allows
|
---|
| 164 | // consumers to override it via the Material elevation classes.
|
---|
| 165 | @mixin overridable-elevation(
|
---|
| 166 | $zValue,
|
---|
| 167 | $color: $color,
|
---|
| 168 | $opacity: $opacity) {
|
---|
| 169 | &:not([class*='#{$prefix}']) {
|
---|
| 170 | @include elevation($zValue, $color, $opacity);
|
---|
| 171 | }
|
---|
| 172 | }
|
---|
| 173 |
|
---|
| 174 | // Returns a string that can be used as the value for a transition property for elevation.
|
---|
| 175 | // Calling this function directly is useful in situations where a component needs to transition
|
---|
| 176 | // more than one property.
|
---|
| 177 | //
|
---|
| 178 | // .foo {
|
---|
| 179 | // transition: mat-elevation-transition-property-value(), opacity 100ms ease;
|
---|
| 180 | // }
|
---|
| 181 | @function private-transition-property-value(
|
---|
| 182 | $duration: $transition-duration,
|
---|
| 183 | $easing: $transition-timing-function) {
|
---|
| 184 | @return box-shadow #{$duration} #{$easing};
|
---|
| 185 | }
|
---|
| 186 |
|
---|
| 187 | // Applies the correct css rules needed to have an element transition between elevations.
|
---|
| 188 | // This mixin should be applied to elements whose elevation values will change depending on their
|
---|
| 189 | // context (e.g. when active or disabled).
|
---|
| 190 | //
|
---|
| 191 | // NOTE(traviskaufman): Both this mixin and the above function use default parameters so they can
|
---|
| 192 | // be used in the same way by clients.
|
---|
| 193 | @mixin elevation-transition(
|
---|
| 194 | $duration: $transition-duration,
|
---|
| 195 | $easing: $transition-timing-function) {
|
---|
| 196 | transition: private-transition-property-value($duration, $easing);
|
---|
| 197 | }
|
---|