_linear-progress-theme.scss 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265
  1. //
  2. // Copyright 2017 Google Inc.
  3. //
  4. // Permission is hereby granted, free of charge, to any person obtaining a copy
  5. // of this software and associated documentation files (the "Software"), to deal
  6. // in the Software without restriction, including without limitation the rights
  7. // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  8. // copies of the Software, and to permit persons to whom the Software is
  9. // furnished to do so, subject to the following conditions:
  10. //
  11. // The above copyright notice and this permission notice shall be included in
  12. // all copies or substantial portions of the Software.
  13. //
  14. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  19. // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  20. // THE SOFTWARE.
  21. //
  22. // stylelint-disable selector-class-pattern --
  23. // Selector '.mdc-*' should only be used in this project.
  24. @use 'sass:map';
  25. @use 'sass:math';
  26. @use 'sass:string';
  27. @use '@material/dom/dom';
  28. @use '@material/feature-targeting/feature-targeting';
  29. @use '@material/rtl/rtl';
  30. @use '@material/theme/custom-properties';
  31. @use '@material/theme/theme';
  32. @use '@material/theme/theme-color';
  33. @use '@material/theme/keys';
  34. $baseline-buffer-color: #e6e6e6 !default;
  35. $height: 4px;
  36. $custom-property-prefix: 'linear-progress';
  37. // TODO(b/254889918): Support all linear progress tokens.
  38. $light-theme: (
  39. active-indicator-color: theme-color.$primary,
  40. active-indicator-height: 4px,
  41. track-color: $baseline-buffer-color,
  42. track-height: 4px,
  43. track-shape: 0px,
  44. );
  45. @mixin theme($theme) {
  46. @include theme.validate-theme($light-theme, $theme);
  47. @include keys.declare-custom-properties(
  48. $theme,
  49. $prefix: $custom-property-prefix
  50. );
  51. }
  52. @mixin theme-styles($theme, $query: feature-targeting.all()) {
  53. $feat-structure: feature-targeting.create-target($query, structure);
  54. @include theme.validate-theme-styles($light-theme, $theme);
  55. $theme: keys.create-theme-properties(
  56. $theme,
  57. $prefix: $custom-property-prefix
  58. );
  59. @include buffering-keyframes(map.get($theme, track-height), $query);
  60. @include bar-color(map.get($theme, active-indicator-color), $query);
  61. @include buffer-color(map.get($theme, track-color), $query);
  62. .mdc-linear-progress {
  63. @include feature-targeting.targets($feat-structure) {
  64. @include theme.property(
  65. height,
  66. 'max(track-height, bar-height)',
  67. $replace: (
  68. track-height: map.get($theme, track-height),
  69. bar-height: map.get($theme, active-indicator-height)
  70. )
  71. );
  72. @include dom.ie11-support() {
  73. $track-height: map.get($theme, track-height);
  74. $track-height: if(
  75. custom-properties.is-custom-prop($track-height),
  76. custom-properties.get-fallback($track-height),
  77. $track-height
  78. );
  79. $bar-height: map.get($theme, active-indicator-height);
  80. $bar-height: if(
  81. custom-properties.is-custom-prop($bar-height),
  82. custom-properties.get-fallback($bar-height),
  83. $bar-height
  84. );
  85. @if ($track-height != null) and
  86. ($bar-height != null) and
  87. (not custom-properties.is-custom-prop-string($track-height)) and
  88. (not custom-properties.is-custom-prop-string($bar-height))
  89. {
  90. @include theme.property(height, math.max($track-height, $bar-height));
  91. }
  92. }
  93. }
  94. }
  95. @include _bar-height(map.get($theme, active-indicator-height), $query);
  96. @include _track-height(map.get($theme, track-height), $query);
  97. @include _track-shape(map.get($theme, track-shape), $query);
  98. // TODO(b/155129310): Add styles for 4-color linear progress once this variant
  99. // is supported.
  100. }
  101. @mixin bar-color($color, $query: feature-targeting.all()) {
  102. $feat-color: feature-targeting.create-target($query, color);
  103. .mdc-linear-progress__bar-inner {
  104. @include feature-targeting.targets($feat-color) {
  105. // Border is used rather than background-color to ensure that the
  106. // bar is visible in Windows High Contrast Mode.
  107. @include theme.property(border-color, $color);
  108. }
  109. }
  110. }
  111. @mixin buffer-color($color, $query: feature-targeting.all()) {
  112. // We need to escape the '#' character as "%23" for SVG because '#' is a reserved character in URIs.
  113. $concrete-color: $color;
  114. @if custom-properties.is-custom-prop($color) {
  115. $concrete-color: custom-properties.get-fallback($color);
  116. }
  117. $concrete-color-for-svg: str-replace_(
  118. string.unquote('#{$concrete-color}'),
  119. '#',
  120. '%23'
  121. );
  122. $feat-color: feature-targeting.create-target($query, color);
  123. .mdc-linear-progress__buffer-dots {
  124. @include feature-targeting.targets($feat-color) {
  125. @include theme.property(background-color, $color);
  126. @media (forced-colors: active) {
  127. background-color: ButtonBorder;
  128. }
  129. @include dom.ie11-support() {
  130. background-color: transparent;
  131. // stylelint-disable function-url-quotes -- SVG data URI
  132. // SVG is optimized for data URI (https://codepen.io/tigt/post/optimizing-svgs-in-data-uris)
  133. @include theme.property(
  134. background-image,
  135. url("data:image/svg+xml,%3Csvg version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' x='0px' y='0px' enable-background='new 0 0 5 2' xml:space='preserve' viewBox='0 0 5 2' preserveAspectRatio='none slice'%3E%3Ccircle cx='1' cy='1' r='1' fill='concrete-color-for-svg'/%3E%3C/svg%3E"),
  136. $replace: (concrete-color-for-svg: $concrete-color-for-svg)
  137. );
  138. // stylelint-enable function-url-quotes
  139. }
  140. }
  141. }
  142. .mdc-linear-progress__buffer-bar {
  143. @include feature-targeting.targets($feat-color) {
  144. @include theme.property(background-color, $color);
  145. }
  146. }
  147. }
  148. /// @deprecated Use Theming API instead.
  149. @mixin bar-and-track-height($height, $query: feature-targeting.all()) {
  150. $feat-structure: feature-targeting.create-target($query, structure);
  151. .mdc-linear-progress {
  152. @include feature-targeting.targets($feat-structure) {
  153. @include theme.property(height, $height);
  154. }
  155. }
  156. @include _bar-height($height, $query);
  157. @include _track-height($height, $query);
  158. }
  159. @mixin buffering-keyframes($track-height, $query: feature-targeting.all()) {
  160. $feat-animation: feature-targeting.create-target($query, animation);
  161. @include feature-targeting.targets($feat-animation) {
  162. @keyframes mdc-linear-progress-buffering {
  163. from {
  164. // Normally the buffer dots start from the left and overflow to the right.
  165. // We rotate by 180deg so that the buffer dots start on the right when
  166. // in non-reversed mode and overflow to the left.
  167. @include rtl.ignore-next-line();
  168. @include theme.property(
  169. transform,
  170. 'rotate(180deg) translateX(calc(track-height * -2.5))',
  171. $replace: (track-height: $track-height)
  172. );
  173. }
  174. }
  175. }
  176. }
  177. // Based on https://css-tricks.com/snippets/sass/str-replace-function/
  178. @function str-replace_($string, $search, $replace) {
  179. $index: string.index($string, $search);
  180. @if $index {
  181. $head: string.slice($string, 1, $index - 1);
  182. $tail: str-replace_(
  183. string.slice($string, $index + string.length($search)),
  184. $search,
  185. $replace
  186. );
  187. @return $head + $replace + $tail;
  188. }
  189. @return $string;
  190. }
  191. @mixin _bar-height($height, $query: feature-targeting.all()) {
  192. $feat-structure: feature-targeting.create-target($query, structure);
  193. @include feature-targeting.targets($feat-structure) {
  194. .mdc-linear-progress__bar {
  195. @include theme.property(height, $height);
  196. }
  197. .mdc-linear-progress__bar-inner {
  198. @include theme.property(border-top-width, $height);
  199. }
  200. }
  201. }
  202. @mixin _track-height($height, $query: feature-targeting.all()) {
  203. $feat-structure: feature-targeting.create-target($query, structure);
  204. @include feature-targeting.targets($feat-structure) {
  205. .mdc-linear-progress__buffer {
  206. @include theme.property(height, $height);
  207. }
  208. .mdc-linear-progress__buffer-dots {
  209. @include dom.ie11-support() {
  210. @include theme.property(
  211. background-size,
  212. 10px height,
  213. $replace: (height: $height)
  214. );
  215. }
  216. }
  217. }
  218. }
  219. @mixin _track-shape($shape, $query: feature-targeting.all()) {
  220. $feat-structure: feature-targeting.create-target($query, structure);
  221. @include feature-targeting.targets($feat-structure) {
  222. .mdc-linear-progress__buffer {
  223. @include theme.property(border-radius, $shape);
  224. }
  225. }
  226. }