_chip.scss 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605
  1. //
  2. // Copyright 2020 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. // Selector '.mdc-*' should only be used in this project.
  23. // stylelint-disable selector-class-pattern --
  24. // Internal styling for Chip MDC component.
  25. @use '@material/animation/animation';
  26. @use '@material/dom/dom';
  27. @use '@material/elevation/elevation-theme';
  28. @use '@material/focus-ring/focus-ring';
  29. @use '@material/feature-targeting/feature-targeting';
  30. @use '@material/ripple/ripple';
  31. @use '@material/ripple/ripple-theme';
  32. @use '@material/rtl/rtl';
  33. @use '@material/theme/theme-color';
  34. @use '@material/touch-target/touch-target';
  35. @use './chip-theme';
  36. @mixin core-styles($query: feature-targeting.all()) {
  37. @include without-ripple-styles($query);
  38. @include ripple-styles($query);
  39. }
  40. @mixin without-ripple-styles($query: feature-targeting.all()) {
  41. @include static-styles($query);
  42. @include _theme-styles($query);
  43. }
  44. @mixin ripple-styles($query: feature-targeting.all()) {
  45. $feat-structure: feature-targeting.create-target($query, structure);
  46. @include chip-theme.ripple-color(chip-theme.$ripple-color, $query: $query);
  47. @include chip-theme.trailing-action-ripple-color(
  48. chip-theme.$ripple-color,
  49. $query: $query
  50. );
  51. @include chip-theme.trailing-action-ripple-size(
  52. chip-theme.$trailing-action-size,
  53. $query: $query
  54. );
  55. .mdc-evolution-chip__action {
  56. @include ripple.surface(
  57. $query: $query,
  58. $ripple-target: chip-theme.$ripple-target,
  59. $include-will-change: false
  60. );
  61. @include ripple.radius-bounded(
  62. $query: $query,
  63. $ripple-target: chip-theme.$ripple-target
  64. );
  65. }
  66. #{chip-theme.$ripple-target} {
  67. @include feature-targeting.targets($feat-structure) {
  68. position: absolute;
  69. // Ripple needs content-box as the box sizing and box-sizing: border-box
  70. // is often set as a default, so we override that here.
  71. box-sizing: content-box;
  72. overflow: hidden;
  73. pointer-events: none;
  74. }
  75. }
  76. #{chip-theme.$ripple-target-primary} {
  77. @include feature-targeting.targets($feat-structure) {
  78. height: 100%;
  79. width: 100%;
  80. top: 0;
  81. @include rtl.ignore-next-line();
  82. left: 0;
  83. }
  84. }
  85. #{chip-theme.$ripple-target-trailing} {
  86. @include feature-targeting.targets($feat-structure) {
  87. top: 50%;
  88. transform: translateY(-50%);
  89. }
  90. }
  91. }
  92. @mixin static-styles($query: feature-targeting.all()) {
  93. $feat-animation: feature-targeting.create-target($query, animation);
  94. $feat-color: feature-targeting.create-target($query, color);
  95. $feat-structure: feature-targeting.create-target($query, structure);
  96. .mdc-evolution-chip,
  97. .mdc-evolution-chip__cell,
  98. .mdc-evolution-chip__action {
  99. @include feature-targeting.targets($feat-structure) {
  100. display: inline-flex;
  101. align-items: center;
  102. }
  103. }
  104. .mdc-evolution-chip {
  105. @include feature-targeting.targets($feat-structure) {
  106. position: relative;
  107. max-width: 100%;
  108. }
  109. @include elevation-theme.overlay-dimensions(100%, $query: $query);
  110. }
  111. .mdc-evolution-chip__cell,
  112. .mdc-evolution-chip__action {
  113. @include feature-targeting.targets($feat-structure) {
  114. height: 100%;
  115. }
  116. }
  117. .mdc-evolution-chip__cell--primary {
  118. @include feature-targeting.targets($feat-structure) {
  119. overflow-x: hidden;
  120. }
  121. }
  122. .mdc-evolution-chip__cell--trailing {
  123. @include feature-targeting.targets($feat-structure) {
  124. flex: 1 0 auto;
  125. }
  126. }
  127. .mdc-evolution-chip__action {
  128. @include feature-targeting.targets($feat-structure) {
  129. align-items: center;
  130. background: none;
  131. border: none;
  132. box-sizing: content-box;
  133. cursor: pointer;
  134. display: inline-flex;
  135. justify-content: center;
  136. outline: none;
  137. padding: 0;
  138. text-decoration: none;
  139. }
  140. @include feature-targeting.targets($feat-color) {
  141. color: inherit;
  142. }
  143. }
  144. .mdc-evolution-chip__action--presentational {
  145. @include feature-targeting.targets($feat-structure) {
  146. cursor: auto;
  147. }
  148. }
  149. .mdc-evolution-chip--disabled,
  150. .mdc-evolution-chip__action:disabled {
  151. @include feature-targeting.targets($feat-structure) {
  152. pointer-events: none;
  153. }
  154. }
  155. .mdc-evolution-chip__action--primary {
  156. @include feature-targeting.targets($feat-structure) {
  157. overflow-x: hidden;
  158. }
  159. }
  160. .mdc-evolution-chip__action--trailing {
  161. @include feature-targeting.targets($feat-structure) {
  162. position: relative;
  163. overflow: visible;
  164. }
  165. }
  166. .mdc-evolution-chip__action--primary:before {
  167. @include feature-targeting.targets($feat-structure) {
  168. box-sizing: border-box;
  169. content: '';
  170. height: 100%;
  171. left: 0;
  172. position: absolute;
  173. pointer-events: none;
  174. top: 0;
  175. width: 100%;
  176. z-index: 1; // Position above touch target
  177. }
  178. }
  179. .mdc-evolution-chip--touch {
  180. @include touch-target.margin(
  181. $component-height: chip-theme.$height,
  182. $query: $query
  183. );
  184. }
  185. .mdc-evolution-chip__action-touch {
  186. @include touch-target.touch-target($query: $query);
  187. }
  188. .mdc-evolution-chip__text-label {
  189. @include feature-targeting.targets($feat-structure) {
  190. white-space: nowrap;
  191. user-select: none;
  192. text-overflow: ellipsis;
  193. overflow: hidden;
  194. }
  195. }
  196. .mdc-evolution-chip__graphic {
  197. @include feature-targeting.targets($feat-structure) {
  198. align-items: center;
  199. display: inline-flex;
  200. justify-content: center;
  201. overflow: hidden;
  202. pointer-events: none;
  203. position: relative;
  204. flex: 1 0 auto;
  205. }
  206. }
  207. .mdc-evolution-chip__checkmark {
  208. @include feature-targeting.targets($feat-structure) {
  209. position: absolute;
  210. opacity: 0;
  211. top: 50%;
  212. @include rtl.ignore-next-line();
  213. left: 50%;
  214. }
  215. }
  216. .mdc-evolution-chip--selectable:not(.mdc-evolution-chip--selected) {
  217. &:not(.mdc-evolution-chip--with-primary-icon) .mdc-evolution-chip__graphic {
  218. @include feature-targeting.targets($feat-structure) {
  219. width: 0;
  220. }
  221. }
  222. }
  223. .mdc-evolution-chip__checkmark-background {
  224. @include feature-targeting.targets($feat-structure) {
  225. opacity: 0;
  226. }
  227. }
  228. .mdc-evolution-chip__checkmark-svg {
  229. @include feature-targeting.targets($feat-structure) {
  230. display: block;
  231. }
  232. }
  233. .mdc-evolution-chip__checkmark-path {
  234. @include feature-targeting.targets($feat-structure) {
  235. stroke-width: 2px;
  236. stroke-dasharray: 29.7833385;
  237. stroke-dashoffset: 29.7833385;
  238. }
  239. @include feature-targeting.targets($feat-color) {
  240. stroke: currentColor;
  241. }
  242. }
  243. .mdc-evolution-chip--selecting {
  244. .mdc-evolution-chip__graphic {
  245. @include feature-targeting.targets($feat-animation) {
  246. transition: animation.standard(width, 150ms);
  247. }
  248. }
  249. .mdc-evolution-chip__checkmark {
  250. @include feature-targeting.targets($feat-animation) {
  251. transition: animation.standard(transform, 150ms);
  252. @include rtl.ignore-next-line();
  253. transform: translate(-75%, -50%);
  254. }
  255. }
  256. .mdc-evolution-chip__checkmark-path {
  257. @include feature-targeting.targets($feat-animation) {
  258. transition: animation.standard(stroke-dashoffset, 150ms, $delay: 45ms);
  259. }
  260. }
  261. }
  262. .mdc-evolution-chip--deselecting {
  263. .mdc-evolution-chip__graphic {
  264. @include feature-targeting.targets($feat-animation) {
  265. transition: animation.standard(width, 100ms);
  266. }
  267. }
  268. .mdc-evolution-chip__checkmark {
  269. @include feature-targeting.targets($feat-animation) {
  270. transition: animation.linear(opacity, 50ms),
  271. animation.standard(transform, 100ms);
  272. @include rtl.ignore-next-line();
  273. transform: translate(-75%, -50%);
  274. }
  275. }
  276. .mdc-evolution-chip__checkmark-path {
  277. @include feature-targeting.targets($feat-animation) {
  278. // Ensure the checkmark path stays visible
  279. stroke-dashoffset: 0;
  280. }
  281. }
  282. }
  283. .mdc-evolution-chip--selecting-with-primary-icon {
  284. .mdc-evolution-chip__icon--primary {
  285. @include feature-targeting.targets($feat-animation) {
  286. transition: animation.standard(opacity, 75ms);
  287. }
  288. }
  289. .mdc-evolution-chip__checkmark-path {
  290. @include feature-targeting.targets($feat-animation) {
  291. transition: animation.standard(stroke-dashoffset, 150ms, $delay: 75ms);
  292. }
  293. }
  294. }
  295. .mdc-evolution-chip--deselecting-with-primary-icon {
  296. .mdc-evolution-chip__icon--primary {
  297. @include feature-targeting.targets($feat-animation) {
  298. transition: animation.standard(opacity, 150ms, $delay: 75ms);
  299. }
  300. }
  301. .mdc-evolution-chip__checkmark {
  302. @include feature-targeting.targets($feat-animation) {
  303. transition: animation.standard(opacity, 75ms);
  304. // Ensure the checkmark stays statically positioned
  305. @include rtl.ignore-next-line();
  306. transform: translate(-50%, -50%);
  307. }
  308. }
  309. .mdc-evolution-chip__checkmark-path {
  310. @include feature-targeting.targets($feat-animation) {
  311. // Ensure the checkmark path stays visible
  312. stroke-dashoffset: 0;
  313. }
  314. }
  315. }
  316. .mdc-evolution-chip--selected {
  317. .mdc-evolution-chip__icon--primary {
  318. @include feature-targeting.targets($feat-structure) {
  319. opacity: 0;
  320. }
  321. }
  322. .mdc-evolution-chip__checkmark {
  323. @include feature-targeting.targets($feat-structure) {
  324. @include rtl.ignore-next-line();
  325. transform: translate(-50%, -50%);
  326. opacity: 1;
  327. }
  328. }
  329. .mdc-evolution-chip__checkmark-path {
  330. @include feature-targeting.targets($feat-structure) {
  331. stroke-dashoffset: 0;
  332. }
  333. }
  334. }
  335. @include feature-targeting.targets($feat-animation) {
  336. @keyframes mdc-evolution-chip-enter {
  337. from {
  338. transform: scale(0.8);
  339. opacity: 0.4;
  340. }
  341. to {
  342. transform: scale(1);
  343. opacity: 1;
  344. }
  345. }
  346. }
  347. .mdc-evolution-chip--enter {
  348. @include feature-targeting.targets($feat-animation) {
  349. animation: animation.enter(mdc-evolution-chip-enter, 100ms);
  350. }
  351. }
  352. @include feature-targeting.targets($feat-animation) {
  353. @keyframes mdc-evolution-chip-exit {
  354. from {
  355. opacity: 1;
  356. }
  357. to {
  358. opacity: 0;
  359. }
  360. }
  361. }
  362. .mdc-evolution-chip--exit {
  363. @include feature-targeting.targets($feat-animation) {
  364. animation: animation.exit-permanent(mdc-evolution-chip-exit, 75ms);
  365. }
  366. }
  367. .mdc-evolution-chip--hidden {
  368. @include feature-targeting.targets($feat-animation) {
  369. opacity: 0;
  370. pointer-events: none;
  371. transition: animation.exit-permanent(width, 150ms);
  372. }
  373. }
  374. }
  375. @mixin _high-contrast-mode($query: feature-targeting.all()) {
  376. $feat-structure: feature-targeting.create-target($query, structure);
  377. @include dom.forced-colors-mode {
  378. &.mdc-evolution-chip {
  379. @include chip-theme.outline-color(
  380. (
  381. default: CanvasText,
  382. disabled: GrayText,
  383. ),
  384. $query: $query
  385. );
  386. @include chip-theme.selected-outline-color(
  387. (
  388. default: CanvasText,
  389. disabled: GrayText,
  390. ),
  391. $query: $query
  392. );
  393. @include chip-theme.text-label-color(
  394. (
  395. disabled: GrayText,
  396. ),
  397. $query: $query
  398. );
  399. @include chip-theme.selected-text-label-color(
  400. (
  401. disabled: GrayText,
  402. ),
  403. $query: $query
  404. );
  405. @include chip-theme.icon-color(
  406. (
  407. disabled: GrayText,
  408. ),
  409. $query: $query
  410. );
  411. @include chip-theme.checkmark-color(
  412. (
  413. disabled: GrayText,
  414. ),
  415. $query: $query
  416. );
  417. @include chip-theme.trailing-action-color(
  418. (
  419. disabled: GrayText,
  420. ),
  421. $query: $query
  422. );
  423. @include chip-theme.container-color(
  424. (
  425. disabled: Canvas,
  426. ),
  427. $query: $query
  428. );
  429. @include chip-theme.selected-container-color(
  430. (
  431. disabled: Canvas,
  432. ),
  433. $query: $query
  434. );
  435. }
  436. }
  437. ///
  438. /// Renders a transparent border on focus in Windows high-contrast mode.
  439. ///
  440. .mdc-evolution-chip__focus-ring {
  441. display: none;
  442. }
  443. .mdc-evolution-chip__action--primary:not(.mdc-evolution-chip__action--presentational) {
  444. @include ripple-theme.focus() {
  445. .mdc-evolution-chip__focus-ring {
  446. z-index: 1;
  447. display: block;
  448. @include focus-ring.focus-ring($query: $query);
  449. }
  450. }
  451. }
  452. .mdc-evolution-chip__action--trailing:not(.mdc-evolution-chip__action--presentational) {
  453. @include ripple-theme.focus() {
  454. .mdc-evolution-chip__focus-ring {
  455. z-index: 1;
  456. display: block;
  457. @include focus-ring.focus-ring(
  458. $container-outer-padding-vertical: 2px,
  459. $container-outer-padding-horizontal: -2px,
  460. $query: $query
  461. );
  462. }
  463. }
  464. }
  465. }
  466. @mixin _theme-styles($query: feature-targeting.all()) {
  467. .mdc-evolution-chip {
  468. @include chip-theme.height(chip-theme.$height, $query);
  469. @include chip-theme.shape-radius(chip-theme.$radius, $query);
  470. @include chip-theme.horizontal-padding(
  471. chip-theme.$leading-padding,
  472. chip-theme.$trailing-padding,
  473. $query
  474. );
  475. @include chip-theme.with-graphic-horizontal-padding(
  476. chip-theme.$graphic-leading-padding,
  477. chip-theme.$graphic-trailing-padding,
  478. chip-theme.$trailing-padding
  479. );
  480. @include chip-theme.with-trailing-action-horizontal-padding(
  481. chip-theme.$leading-padding,
  482. chip-theme.$trailing-action-leading-padding,
  483. chip-theme.$trailing-action-trailing-padding,
  484. $query
  485. );
  486. @include chip-theme.with-graphic-and-trailing-action-horizontal-padding(
  487. chip-theme.$graphic-leading-padding,
  488. chip-theme.$graphic-trailing-padding,
  489. chip-theme.$trailing-action-leading-padding,
  490. chip-theme.$trailing-action-trailing-padding,
  491. $query
  492. );
  493. @include chip-theme.container-color(chip-theme.$container-color, $query);
  494. @include chip-theme.text-label-color(chip-theme.$text-label-color, $query);
  495. @include chip-theme.icon-color(chip-theme.$icon-color, $query);
  496. @include chip-theme.checkmark-color(chip-theme.$checkmark-color, $query);
  497. @include chip-theme.trailing-action-color(
  498. chip-theme.$trailing-action-color,
  499. $query
  500. );
  501. @include chip-theme.text-label-type-scale(chip-theme.$type-scale, $query);
  502. @include chip-theme.graphic-size(chip-theme.$leading-icon-size, $query);
  503. @include chip-theme.icon-size(chip-theme.$leading-icon-size, $query);
  504. @include chip-theme.checkmark-size(chip-theme.$checkmark-size, $query);
  505. @include chip-theme.trailing-action-size(
  506. chip-theme.$trailing-action-size,
  507. $query
  508. );
  509. @include _high-contrast-mode($query);
  510. }
  511. .mdc-evolution-chip--filter {
  512. @include chip-theme.selected-container-color(
  513. chip-theme.$filter-selected-container-color,
  514. $query
  515. );
  516. }
  517. .mdc-evolution-chip--with-avatar {
  518. @include chip-theme.with-graphic-horizontal-padding(
  519. chip-theme.$avatar-leading-padding,
  520. chip-theme.$avatar-trailing-padding,
  521. chip-theme.$trailing-padding
  522. );
  523. @include chip-theme.with-graphic-and-trailing-action-horizontal-padding(
  524. chip-theme.$avatar-leading-padding,
  525. chip-theme.$avatar-trailing-padding,
  526. chip-theme.$trailing-action-leading-padding,
  527. chip-theme.$trailing-action-trailing-padding
  528. );
  529. @include chip-theme.graphic-size(chip-theme.$avatar-size, $query);
  530. @include chip-theme.icon-size(chip-theme.$avatar-size, $query);
  531. }
  532. }