_button-shared-theme.scss 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752
  1. //
  2. // Copyright 2021 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:meta';
  27. @use '@material/density/functions' as density-functions;
  28. @use '@material/density/variables' as density-variables;
  29. @use '@material/dom/mixins' as dom-mixins;
  30. @use '@material/elevation/elevation-theme';
  31. @use '@material/feature-targeting/feature-targeting';
  32. @use '@material/focus-ring/focus-ring';
  33. @use '@material/ripple/ripple-theme';
  34. @use '@material/shape/mixins' as shape-mixins;
  35. @use '@material/theme/custom-properties';
  36. @use '@material/theme/state';
  37. @use '@material/theme/theme';
  38. @use '@material/theme/theme-color';
  39. @use '@material/typography/typography';
  40. @use './button-ripple';
  41. $height: 36px !default;
  42. $horizontal-padding: 8px !default;
  43. $contained-horizontal-padding: 16px !default;
  44. // For a contained button with an icon, the padding on the side of the
  45. // button with the icon.
  46. $contained-horizontal-padding-icon: 12px !default;
  47. $minimum-height: 24px !default;
  48. $maximum-height: $height !default;
  49. $density-scale: density-variables.$default-scale !default;
  50. $density-config: (
  51. height: (
  52. default: $height,
  53. maximum: $maximum-height,
  54. minimum: $minimum-height,
  55. ),
  56. ) !default;
  57. $shape-radius: small !default;
  58. $disabled-ink-color: rgba(theme-color.prop-value(on-surface), 0.38) !default;
  59. $disabled-container-color: rgba(
  60. theme-color.prop-value(on-surface),
  61. 0.12
  62. ) !default;
  63. @mixin theme-styles($theme, $resolver, $query: feature-targeting.all()) {
  64. @include _label-text-typography(
  65. (
  66. family: map.get($theme, label-text-font),
  67. size: map.get($theme, label-text-size),
  68. tracking: map.get($theme, label-text-tracking),
  69. weight: map.get($theme, label-text-weight),
  70. transform: map.get($theme, label-text-transform),
  71. ),
  72. $query: $query
  73. );
  74. @include container-fill-color(
  75. (
  76. default: map.get($theme, container-color),
  77. disabled: map.get($theme, disabled-container-color),
  78. ),
  79. $query: $query
  80. );
  81. @include ink-color(
  82. (
  83. default: map.get($theme, label-text-color),
  84. hover: map.get($theme, hover-label-text-color),
  85. focus: map.get($theme, focus-label-text-color),
  86. pressed: map.get($theme, pressed-label-text-color),
  87. disabled: map.get($theme, disabled-label-text-color),
  88. ),
  89. $query: $query
  90. );
  91. @include icon-color(
  92. (
  93. default: map.get($theme, with-icon-icon-color),
  94. hover: map.get($theme, with-icon-hover-icon-color),
  95. focus: map.get($theme, with-icon-focus-icon-color),
  96. pressed: map.get($theme, with-icon-pressed-icon-color),
  97. disabled: map.get($theme, with-icon-disabled-icon-color),
  98. ),
  99. $query: $query
  100. );
  101. $icon-size: map.get($theme, with-icon-icon-size);
  102. @include _icon-size($icon-size, $query: $query);
  103. @include _states-colors(
  104. (
  105. focus: map.get($theme, focus-state-layer-color),
  106. hover: map.get($theme, hover-state-layer-color),
  107. pressed: map.get($theme, pressed-state-layer-color),
  108. ),
  109. $query: $query
  110. );
  111. $hover-state-layer-opacity: map.get($theme, hover-state-layer-opacity);
  112. $focus-state-layer-opacity: map.get($theme, focus-state-layer-opacity);
  113. $pressed-state-layer-opacity: map.get($theme, pressed-state-layer-opacity);
  114. @include ripple-theme.states-opacities(
  115. $opacity-map: (
  116. focus: $focus-state-layer-opacity,
  117. hover: $hover-state-layer-opacity,
  118. press: $pressed-state-layer-opacity,
  119. ),
  120. $ripple-target: button-ripple.$ripple-target,
  121. $query: $query
  122. );
  123. $container-height: map.get($theme, container-height);
  124. @include height($container-height, $query: $query);
  125. $container-height-value: if(
  126. custom-properties.is-custom-prop($container-height),
  127. custom-properties.get-fallback($container-height),
  128. $container-height
  129. );
  130. /// Token "keep-touch-target":
  131. /// Prevent the increased touch target from being reseted if the
  132. /// container-height differs from the default (36px)
  133. $keep-touch-target: map.get($theme, keep-touch-target);
  134. @if (not $keep-touch-target) and
  135. ($container-height-value != null) and
  136. ($container-height-value != $height)
  137. {
  138. @include _touch-target-reset($query: $query);
  139. }
  140. $shape: map.get($theme, container-shape);
  141. @if $shape {
  142. $container-height: if(
  143. $container-height != null,
  144. $container-height,
  145. $height
  146. );
  147. @include _shape-radius-with-height(
  148. $shape,
  149. $height: $container-height,
  150. $query: $query
  151. );
  152. }
  153. @include _elevation(
  154. $resolver,
  155. $elevation-map: (
  156. default: map.get($theme, container-elevation),
  157. disabled: map.get($theme, disabled-container-elevation),
  158. focus: map.get($theme, focus-container-elevation),
  159. hover: map.get($theme, hover-container-elevation),
  160. pressed: map.get($theme, pressed-container-elevation)
  161. ),
  162. $shadow-color: map.get($theme, container-shadow-color),
  163. $query: $query
  164. );
  165. }
  166. @function resolve-theme-elevation-keys($theme, $resolver) {
  167. $elevation-resolver: map.get($resolver, elevation);
  168. $shadow-color: map.get($theme, container-shadow-color);
  169. @if $elevation-resolver == null or $shadow-color == null {
  170. @return $theme;
  171. }
  172. $elevation-keys: (
  173. container-elevation,
  174. hover-container-elevation,
  175. focus-container-elevation,
  176. pressed-container-elevation,
  177. disabled-container-elevation
  178. );
  179. @each $key in $elevation-keys {
  180. $elevation: map.get($theme, $key);
  181. @if $elevation != null {
  182. $resolved-value: meta.call(
  183. $resolver,
  184. $elevation: $elevation,
  185. $shadow-color: $shadow-color
  186. );
  187. // Update the key with the resolved value.
  188. $theme: map.set($theme, $key, $resolved-value);
  189. }
  190. }
  191. @return $theme;
  192. }
  193. ///
  194. /// Sets ripple color for button.
  195. ///
  196. @mixin ripple-states(
  197. $color,
  198. $opacity-map: null,
  199. $query: feature-targeting.all()
  200. ) {
  201. @include ripple-theme.states(
  202. $color: $color,
  203. $opacity-map: $opacity-map,
  204. $query: $query,
  205. $ripple-target: button-ripple.$ripple-target
  206. );
  207. }
  208. @mixin filled-accessible(
  209. $container-fill-color,
  210. $query: feature-targeting.all()
  211. ) {
  212. $fill-tone: theme-color.tone($container-fill-color);
  213. @include container-fill-color($container-fill-color, $query);
  214. @if ($fill-tone == 'dark') {
  215. @include ink-color(text-primary-on-dark, $query);
  216. @include ripple-states($color: text-primary-on-dark, $query: $query);
  217. } @else {
  218. @include ink-color(text-primary-on-light, $query);
  219. @include ripple-states($color: text-primary-on-light, $query: $query);
  220. }
  221. }
  222. ///
  223. /// Sets the container fill color to the given color for an enabled button.
  224. /// @param {Color|map} $color-or-map - The desired container fill color,
  225. /// specified either as a flat value or a map of colors with states
  226. /// {default, hover, focus, pressed, disabled} as keys.
  227. ///
  228. @mixin container-fill-color($color-or-map, $query: feature-targeting.all()) {
  229. // :not(:disabled) is used to support link styled as button
  230. // as link does not support :enabled style
  231. &:not(:disabled) {
  232. @include _container-fill-color(
  233. state.get-default-state($color-or-map),
  234. $query: $query
  235. );
  236. &:hover {
  237. @include _container-fill-color(
  238. state.get-hover-state($color-or-map),
  239. $query: $query
  240. );
  241. }
  242. @include ripple-theme.focus() {
  243. @include _container-fill-color(
  244. state.get-focus-state($color-or-map),
  245. $query: $query
  246. );
  247. }
  248. @include ripple-theme.active {
  249. @include _container-fill-color(
  250. state.get-pressed-state($color-or-map),
  251. $query: $query
  252. );
  253. }
  254. }
  255. &:disabled {
  256. @include _container-fill-color(
  257. state.get-disabled-state($color-or-map),
  258. $query: $query
  259. );
  260. }
  261. }
  262. ///
  263. /// Sets the container fill color to the given color for a disabled button.
  264. /// @param {Color} $color - The desired container fill color.
  265. /// @deprecated - call `container-fill-color` instead with `disabled` as a map
  266. /// key.
  267. ///
  268. @mixin disabled-container-fill-color($color, $query: feature-targeting.all()) {
  269. @include container-fill-color(
  270. (
  271. disabled: $color,
  272. ),
  273. $query: $query
  274. );
  275. }
  276. ///
  277. /// Sets the icon color to the given color for an enabled button.
  278. /// @param {Color} $color-or-map - The desired icon color, specified either
  279. /// as a flat value or a map of colors with states
  280. /// {default, hover, focus, pressed, disabled} as keys.
  281. ///
  282. @mixin icon-color($color-or-map, $query: feature-targeting.all()) {
  283. &:not(:disabled) {
  284. @include _icon-color(
  285. state.get-default-state($color-or-map),
  286. $query: $query
  287. );
  288. &:hover {
  289. @include _icon-color(
  290. state.get-hover-state($color-or-map),
  291. $query: $query
  292. );
  293. }
  294. @include ripple-theme.focus() {
  295. @include _icon-color(
  296. state.get-focus-state($color-or-map),
  297. $query: $query
  298. );
  299. }
  300. @include ripple-theme.active {
  301. @include _icon-color(
  302. state.get-pressed-state($color-or-map),
  303. $query: $query
  304. );
  305. }
  306. }
  307. &:disabled {
  308. @include _icon-color(
  309. state.get-disabled-state($color-or-map),
  310. $query: $query
  311. );
  312. }
  313. }
  314. ///
  315. /// Sets the icon color to the given color for a disabled button.
  316. /// @param {Color} $color - The desired icon color.
  317. /// @deprecated - call `icon-color` instead with `disabled` as a map key.
  318. ///
  319. @mixin disabled-icon-color($color, $query: feature-targeting.all()) {
  320. @include icon-color(
  321. (
  322. disabled: $color,
  323. ),
  324. $query: $query
  325. );
  326. }
  327. ///
  328. /// Sets the ink color to the given color for an enabled button,
  329. /// and sets the icon color to the given color unless `mdc-button-icon-color`
  330. /// is also used.
  331. /// @param {Color} $color-or-map - The desired ink color, specified either
  332. /// as a flat value or a map of colors with states
  333. /// {default, hover, focus, pressed, disabled} as keys.
  334. ///
  335. @mixin ink-color($color-or-map, $query: feature-targeting.all()) {
  336. &:not(:disabled) {
  337. @include _ink-color(state.get-default-state($color-or-map), $query: $query);
  338. &:hover {
  339. @include _ink-color(state.get-hover-state($color-or-map), $query: $query);
  340. }
  341. @include ripple-theme.focus() {
  342. @include _ink-color(state.get-focus-state($color-or-map), $query: $query);
  343. }
  344. @include ripple-theme.active {
  345. @include _ink-color(
  346. state.get-pressed-state($color-or-map),
  347. $query: $query
  348. );
  349. }
  350. }
  351. &:disabled {
  352. @include _ink-color(
  353. state.get-disabled-state($color-or-map),
  354. $query: $query
  355. );
  356. }
  357. }
  358. ///
  359. /// Sets the ink color to the given color for a disabled button,
  360. /// and sets the icon color to the given color unless `mdc-button-icon-color`
  361. /// is also used.
  362. /// @param {Color} $color - The desired ink color.
  363. /// @deprecated - call `ink-color` instead with `disabled` as a map key.
  364. ///
  365. @mixin disabled-ink-color($color, $query: feature-targeting.all()) {
  366. @include ink-color(
  367. (
  368. disabled: $color,
  369. ),
  370. $query: $query
  371. );
  372. }
  373. ///
  374. /// Sets density scale for button.
  375. ///
  376. /// @param {Number | String} $density-scale - Density scale value for component. Supported density scale values `-3`,
  377. /// `-2`, `-1`, `0`.
  378. ///
  379. @mixin density($density-scale, $query: feature-targeting.all()) {
  380. $height: density-functions.prop-value(
  381. $density-config: $density-config,
  382. $density-scale: $density-scale,
  383. $property-name: height,
  384. );
  385. @include height($height, $query: $query);
  386. @if $density-scale != 0 {
  387. @include _touch-target-reset($query: $query);
  388. }
  389. }
  390. ///
  391. /// Resets touch target-related styles. This is called from the density mixin to
  392. /// automatically remove the increased touch target, since dense components
  393. /// don't have the same default a11y requirements.
  394. /// @access private
  395. ///
  396. @mixin _touch-target-reset($query: feature-targeting.all()) {
  397. $feat-structure: feature-targeting.create-target($query, structure);
  398. @include feature-targeting.targets($feat-structure) {
  399. margin-top: 0;
  400. margin-bottom: 0;
  401. }
  402. .mdc-button__touch {
  403. @include feature-targeting.targets($feat-structure) {
  404. // Do not set display: none in case the touch target is <a> element.
  405. height: 100%;
  406. }
  407. }
  408. }
  409. ///
  410. /// Sets custom height for button.
  411. /// @param {Number} $height - Height of button in `px`.
  412. ///
  413. @mixin height($height, $query: feature-targeting.all()) {
  414. $feat-structure: feature-targeting.create-target($query, structure);
  415. @include feature-targeting.targets($feat-structure) {
  416. @include theme.property(height, $height);
  417. }
  418. }
  419. @mixin shape-radius(
  420. $radius,
  421. $rtl-reflexive: false,
  422. $density-scale: $density-scale,
  423. $query: feature-targeting.all()
  424. ) {
  425. $height: density-functions.prop-value(
  426. $density-config: $density-config,
  427. $density-scale: $density-scale,
  428. $property-name: height,
  429. );
  430. @include _shape-radius-with-height($radius, $rtl-reflexive, $height, $query);
  431. }
  432. @mixin _shape-radius-with-height(
  433. $radius,
  434. $rtl-reflexive: false,
  435. $height: $height,
  436. $query: feature-targeting.all()
  437. ) {
  438. @include shape-mixins.radius(
  439. $radius,
  440. $rtl-reflexive,
  441. $component-height: $height,
  442. $query: $query
  443. );
  444. #{button-ripple.$ripple-target} {
  445. @include shape-mixins.radius(
  446. $radius,
  447. $rtl-reflexive,
  448. $component-height: $height,
  449. $query: $query
  450. );
  451. }
  452. }
  453. ///
  454. /// Sets horizontal padding to the given number.
  455. /// @param {Number} $padding
  456. /// @param {Number} $padding-icon [null] For buttons with an icon, the
  457. /// horizontal padding on the side with the icon, if different from
  458. /// $padding.
  459. ///
  460. @mixin horizontal-padding(
  461. $padding,
  462. $padding-icon: null,
  463. $query: feature-targeting.all()
  464. ) {
  465. $feat-structure: feature-targeting.create-target($query, structure);
  466. @include feature-targeting.targets($feat-structure) {
  467. // $padding should be a single value; enforce it by specifying all 4 sides in the output
  468. padding: 0 $padding 0 $padding;
  469. }
  470. @if $padding-icon != null {
  471. &.mdc-button--icon-trailing {
  472. @include feature-targeting.targets($feat-structure) {
  473. // $padding should be a single value; enforce it by specifying all 4
  474. // sides in the output.
  475. padding: 0 $padding-icon 0 $padding;
  476. }
  477. }
  478. &.mdc-button--icon-leading {
  479. @include feature-targeting.targets($feat-structure) {
  480. // $padding should be a single value; enforce it by specifying all 4
  481. // sides in the output.
  482. padding: 0 $padding 0 $padding-icon;
  483. }
  484. }
  485. }
  486. }
  487. ///
  488. /// Sets the button label to overflow as ellipsis
  489. ///
  490. @mixin label-overflow-ellipsis($query: feature-targeting.all()) {
  491. .mdc-button__label {
  492. @include typography.overflow-ellipsis($query: $query);
  493. }
  494. }
  495. ///
  496. /// Add a visible outline to the button in high contrast mode.
  497. ///
  498. @mixin outline-hcm-shim($query: feature-targeting.all()) {
  499. &::before {
  500. @include dom-mixins.transparent-border($query: $query);
  501. }
  502. }
  503. ///
  504. /// Includes ad-hoc high contrast mode support.
  505. /// @deprecated Use `outline-hcm-shim` for the outline button. The focus ring
  506. /// is provided by default.
  507. ///
  508. @mixin high-contrast-mode-shim($query: feature-targeting.all()) {
  509. @include outline-hcm-shim($query: $query);
  510. // Link buttons apply focus to the contained link. Focus is indicated via the
  511. // link since focus-within isn't supported by IE.
  512. & .mdc-button__link:focus,
  513. &:focus {
  514. &::before {
  515. @include focus-ring.focus-ring($query: $query);
  516. }
  517. }
  518. }
  519. ///
  520. /// Sets the container fill color to the given color. This mixin should be
  521. /// wrapped in a selector that qualifies button state.
  522. /// @access private
  523. ///
  524. @mixin _container-fill-color($color, $query: feature-targeting.all()) {
  525. $feat-color: feature-targeting.create-target($query, color);
  526. @if $color {
  527. @include feature-targeting.targets($feat-color) {
  528. @include theme.property(background-color, $color);
  529. }
  530. }
  531. }
  532. ///
  533. /// Sets the icon color to the given color. This mixin should be
  534. /// wrapped in a selector that qualifies button state.
  535. /// @access private
  536. ///
  537. @mixin _icon-color($color, $query: feature-targeting.all()) {
  538. $feat-color: feature-targeting.create-target($query, color);
  539. @if $color {
  540. .mdc-button__icon {
  541. @include feature-targeting.targets($feat-color) {
  542. @include theme.property(color, $color);
  543. }
  544. }
  545. }
  546. }
  547. @mixin _icon-size($size-px, $query: feature-targeting.all()) {
  548. $feat-structure: feature-targeting.create-target($query, structure);
  549. @if $size-px != null {
  550. $size-rem: typography.px-to-rem($size-px);
  551. .mdc-button__icon {
  552. @include feature-targeting.targets($feat-structure) {
  553. @include theme.property(font-size, $size-rem);
  554. @include theme.property(width, $size-rem);
  555. @include theme.property(height, $size-rem);
  556. }
  557. }
  558. }
  559. }
  560. ///
  561. /// Sets the ink color to the given color. This mixin should be
  562. /// wrapped in a selector that qualifies button state.
  563. /// @access private
  564. ///
  565. @mixin _ink-color($color, $query: feature-targeting.all()) {
  566. $feat-color: feature-targeting.create-target($query, color);
  567. @if $color {
  568. @include feature-targeting.targets($feat-color) {
  569. @include theme.property(color, $color);
  570. }
  571. }
  572. }
  573. @mixin _states-colors($color-map, $query: feature-targeting.all()) {
  574. $hover: map.get($color-map, hover);
  575. $hover-value: if(
  576. custom-properties.is-custom-prop($hover),
  577. custom-properties.get-fallback($hover),
  578. $hover
  579. );
  580. // TODO(b/191298796): support focused & pressed key colors.
  581. @if $hover-value != null {
  582. @include ripple-theme.states-base-color(
  583. $color: $hover,
  584. $ripple-target: button-ripple.$ripple-target,
  585. $query: $query
  586. );
  587. }
  588. }
  589. @mixin _label-text-typography(
  590. $typography-map,
  591. $query: feature-targeting.all()
  592. ) {
  593. $feat-typography: feature-targeting.create-target($query, typography);
  594. $family: map.get($typography-map, family);
  595. $size: map.get($typography-map, size);
  596. $tracking: map.get($typography-map, tracking);
  597. $weight: map.get($typography-map, weight);
  598. $transform: map.get($typography-map, transform);
  599. @include feature-targeting.targets($feat-typography) {
  600. @include theme.property(font-family, $family);
  601. @include theme.property(font-size, $size);
  602. @include theme.property(letter-spacing, $tracking);
  603. @include theme.property(font-weight, $weight);
  604. @include theme.property(text-transform, $transform);
  605. }
  606. }
  607. @mixin _elevation(
  608. $resolver,
  609. $elevation-map,
  610. $shadow-color,
  611. $query: feature-targeting.all()
  612. ) {
  613. $elevation-resolver: map.get($resolver, elevation);
  614. @if $shadow-color {
  615. $default: state.get-default-state($elevation-map);
  616. @if $default != null {
  617. @include elevation-theme.with-resolver(
  618. $elevation-resolver,
  619. $elevation: $default,
  620. $shadow-color: $shadow-color,
  621. $query: $query
  622. );
  623. }
  624. $focus: state.get-focus-state($elevation-map);
  625. @if $focus != null {
  626. @include ripple-theme.focus {
  627. @include elevation-theme.with-resolver(
  628. $elevation-resolver,
  629. $elevation: $focus,
  630. $shadow-color: $shadow-color,
  631. $query: $query
  632. );
  633. }
  634. }
  635. $hover: state.get-hover-state($elevation-map);
  636. @if $hover != null {
  637. &:hover {
  638. @include elevation-theme.with-resolver(
  639. $elevation-resolver,
  640. $elevation: $hover,
  641. $shadow-color: $shadow-color,
  642. $query: $query
  643. );
  644. }
  645. }
  646. $pressed: state.get-pressed-state($elevation-map);
  647. @if $pressed != null {
  648. @include ripple-theme.active {
  649. @include elevation-theme.with-resolver(
  650. $elevation-resolver,
  651. $elevation: $pressed,
  652. $shadow-color: $shadow-color,
  653. $query: $query
  654. );
  655. }
  656. }
  657. $disabled: state.get-disabled-state($elevation-map);
  658. @if $disabled != null {
  659. &:disabled {
  660. @include elevation-theme.with-resolver(
  661. $elevation-resolver,
  662. $elevation: $disabled,
  663. $shadow-color: $shadow-color,
  664. $query: $query
  665. );
  666. }
  667. }
  668. }
  669. }