_text-field.scss 80 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669
  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:math';
  25. @use 'sass:list';
  26. @use 'sass:meta';
  27. @use 'sass:map';
  28. @use '@material/animation/animation';
  29. @use '@material/theme/css';
  30. @use '@material/density/functions' as density-functions;
  31. @use '@material/dom/dom';
  32. @use '@material/floating-label/mixins' as floating-label-mixins;
  33. @use '@material/floating-label/variables' as floating-label-variables;
  34. @use '@material/line-ripple/mixins' as line-ripple-mixins;
  35. @use '@material/notched-outline/mixins' as notched-outline-mixins;
  36. @use '@material/notched-outline/variables' as notched-outline-variables;
  37. @use '@material/ripple/ripple';
  38. @use '@material/ripple/ripple-theme';
  39. @use '@material/theme/custom-properties';
  40. @use '@material/theme/theme';
  41. @use '@material/shape/mixins' as shape-mixins;
  42. @use '@material/shape/functions' as shape-functions;
  43. @use '@material/feature-targeting/feature-targeting';
  44. @use '@material/typography/typography';
  45. @use 'helper-text/mixins' as helper-text-mixins;
  46. @use 'character-counter/mixins' as character-counter-mixins;
  47. @use 'icon/mixins' as icon-mixins;
  48. @use 'icon/variables' as icon-variables;
  49. @use './variables';
  50. @use '@material/rtl/rtl';
  51. $_density-config: map.merge(
  52. variables.$density-config,
  53. (
  54. minimum: math.min(variables.$minimum-height, 36px),
  55. )
  56. );
  57. @mixin core-styles($query: feature-targeting.all()) {
  58. @include ripple($query);
  59. @include static-styles($query);
  60. @include helper-text-mixins.helper-text-core-styles($query);
  61. @include character-counter-mixins.character-counter-core-styles($query);
  62. @include icon-mixins.icon-core-styles($query);
  63. }
  64. /// @deprecated Use static-styles() instead.
  65. @mixin without-ripple($query: feature-targeting.all()) {
  66. @include static-styles($query);
  67. }
  68. @mixin static-styles($query: feature-targeting.all()) {
  69. $feat-structure: feature-targeting.create-target($query, structure);
  70. // Baseline
  71. // postcss-bem-linter: define text-field
  72. .mdc-text-field {
  73. @include _base($query);
  74. }
  75. .mdc-text-field__input {
  76. @include _input($query);
  77. @include placeholder-selector_ {
  78. @include _input-placeholder($query);
  79. }
  80. // Always show placeholder for text fields that has no
  81. // label and show only on focused state when label is present.
  82. .mdc-text-field--no-label &,
  83. .mdc-text-field--focused & {
  84. @include placeholder-selector_ {
  85. @include _input-placeholder-visible($query);
  86. }
  87. }
  88. }
  89. .mdc-text-field__affix {
  90. @include _affix($query: $query);
  91. .mdc-text-field--label-floating &,
  92. .mdc-text-field--no-label & {
  93. @include _affix-visible($query: $query);
  94. }
  95. // Safari only
  96. @supports (-webkit-hyphens: none) {
  97. .mdc-text-field--outlined & {
  98. @include _centered-affix-safari-support($query: $query);
  99. }
  100. }
  101. }
  102. .mdc-text-field__affix--prefix {
  103. @include _prefix($query: $query);
  104. .mdc-text-field--end-aligned & {
  105. @include _prefix-end-aligned($query: $query);
  106. }
  107. }
  108. .mdc-text-field__affix--suffix {
  109. @include _suffix($query: $query);
  110. .mdc-text-field--end-aligned & {
  111. @include _suffix-end-aligned($query: $query);
  112. }
  113. }
  114. // Variants
  115. .mdc-text-field--filled {
  116. @include _filled($query);
  117. &.mdc-text-field--no-label {
  118. @include filled-no-label($query);
  119. }
  120. }
  121. .mdc-text-field--outlined {
  122. @include outlined_($query);
  123. .mdc-notched-outline {
  124. @include _outlined-notched-outline($query);
  125. }
  126. }
  127. // Other Variations
  128. .mdc-text-field--textarea {
  129. @include textarea_($query);
  130. .mdc-text-field__input {
  131. @include _textarea-input($query);
  132. }
  133. &.mdc-text-field--filled {
  134. @include _textarea-filled($query);
  135. .mdc-text-field__input {
  136. @include _textarea-filled-input($query);
  137. }
  138. &.mdc-text-field--no-label {
  139. .mdc-text-field__input {
  140. @include _textarea-filled-no-label-input($query);
  141. }
  142. }
  143. }
  144. &.mdc-text-field--outlined {
  145. @include _textarea-outlined($query);
  146. .mdc-text-field__input {
  147. @include _textarea-outlined-input($query);
  148. }
  149. .mdc-floating-label {
  150. @include _textarea-outlined-floating-label($query);
  151. }
  152. }
  153. &.mdc-text-field--with-internal-counter {
  154. .mdc-text-field__input {
  155. @include _textarea-input-with-internal-counter($query);
  156. }
  157. .mdc-text-field-character-counter {
  158. @include _textarea-internal-counter($query);
  159. }
  160. }
  161. }
  162. // Resizer element does not need to be under mdc-text-field--textarea, that
  163. // just adds specificity
  164. .mdc-text-field__resizer {
  165. @include _textarea-resizer($query);
  166. .mdc-text-field--filled & {
  167. @include _textarea-filled-resizer($query);
  168. .mdc-text-field__input,
  169. .mdc-text-field-character-counter {
  170. @include _textarea-filled-resizer-children($query);
  171. }
  172. }
  173. .mdc-text-field--outlined & {
  174. @include _textarea-outlined-resizer($query);
  175. .mdc-text-field__input,
  176. .mdc-text-field-character-counter {
  177. @include _textarea-outlined-resizer-children($query);
  178. }
  179. }
  180. }
  181. .mdc-text-field--with-leading-icon {
  182. @include _padding-horizontal-with-leading-icon($query);
  183. &.mdc-text-field--filled {
  184. @include with-leading-icon_($query);
  185. }
  186. &.mdc-text-field--outlined {
  187. @include outlined-with-leading-icon_($query);
  188. }
  189. }
  190. .mdc-text-field--with-trailing-icon {
  191. @include _padding-horizontal-with-trailing-icon($query);
  192. &.mdc-text-field--filled {
  193. @include _with-trailing-icon($query);
  194. }
  195. &.mdc-text-field--outlined {
  196. @include _outlined-with-trailing-icon($query);
  197. }
  198. }
  199. .mdc-text-field--with-leading-icon.mdc-text-field--with-trailing-icon {
  200. @include _padding-horizontal-with-both-icons($query);
  201. &.mdc-text-field--filled {
  202. @include _with-leading-and-trailing-icon($query);
  203. }
  204. }
  205. // postcss-bem-linter: define text-field-helper-text
  206. .mdc-text-field-helper-line {
  207. @include feature-targeting.targets($feat-structure) {
  208. display: flex;
  209. justify-content: space-between;
  210. box-sizing: border-box;
  211. }
  212. .mdc-text-field + & {
  213. @include feature-targeting.targets($feat-structure) {
  214. padding-right: variables.$helper-line-padding;
  215. padding-left: variables.$helper-line-padding;
  216. }
  217. }
  218. }
  219. // postcss-bem-linter: end
  220. // mdc-form-field tweaks to align text field label correctly
  221. // stylelint-disable selector-max-type --
  222. // TODO: document why this disable is neccessary
  223. .mdc-form-field > .mdc-text-field + label {
  224. @include feature-targeting.targets($feat-structure) {
  225. align-self: flex-start;
  226. }
  227. }
  228. // stylelint-enable selector-max-type
  229. // States
  230. .mdc-text-field--focused {
  231. @include focused_($query);
  232. &.mdc-text-field--outlined {
  233. @include _focused-outlined($query);
  234. &.mdc-text-field--textarea {
  235. @include _focused-outlined-textarea($query);
  236. }
  237. }
  238. }
  239. .mdc-text-field--invalid {
  240. @include invalid_($query);
  241. }
  242. .mdc-text-field--disabled {
  243. @include disabled_($query);
  244. &.mdc-text-field--filled {
  245. @include _disabled-filled($query);
  246. }
  247. .mdc-text-field__input {
  248. @include _disabled-input($query);
  249. }
  250. }
  251. .mdc-text-field--end-aligned {
  252. @include end-aligned_($query);
  253. }
  254. .mdc-text-field--ltr-text {
  255. @include _ltr-text($query);
  256. &.mdc-text-field--end-aligned {
  257. @include _ltr-text-end-aligned($query);
  258. }
  259. }
  260. }
  261. // This API is intended for use by frameworks that may want to separate the ripple-related styles
  262. // from the other text field styles. It is recommended that most users use `mdc-text-field-core-styles` instead.
  263. @mixin ripple($query: feature-targeting.all()) {
  264. @include ripple.common($query); // COPYBARA_COMMENT_THIS_LINE
  265. .mdc-text-field--filled {
  266. @include ripple.surface(
  267. $query: $query,
  268. $ripple-target: variables.$ripple-target
  269. );
  270. @include ripple.radius-bounded(
  271. $query: $query,
  272. $ripple-target: variables.$ripple-target
  273. );
  274. }
  275. #{variables.$ripple-target} {
  276. @include ripple.target-common($query: $query);
  277. }
  278. }
  279. ///
  280. /// Sets density scale for default text field variant.
  281. ///
  282. /// @param {Number | String} $density-scale - Density scale value for component. Supported density scale values `-4`,
  283. /// `-3`, `-2`, `-1`, `0`. Default is `0`.
  284. /// @param {Number} $minimum-height-for-filled-label Sets the minimum height for
  285. /// filled textfields at which to allow floating labels.
  286. ///
  287. @mixin density(
  288. $density-scale,
  289. $minimum-height-for-filled-label: variables.$minimum-height-for-filled-label,
  290. $query: feature-targeting.all()
  291. ) {
  292. $height: density-functions.prop-value(
  293. $density-config: $_density-config,
  294. $density-scale: $density-scale,
  295. $property-name: height,
  296. );
  297. @include height(
  298. $height,
  299. $minimum-height-for-filled-label: $minimum-height-for-filled-label,
  300. $query: $query
  301. );
  302. // TODO(b/151839219): resize icons and adjust label position
  303. // @if $density-scale < 0 {
  304. // @include icon-mixins.size(icon-variables.$dense-icon-size);
  305. // }
  306. }
  307. ///
  308. /// Sets density scale for outlined text field (Excluding outlined text field with leading icon).
  309. ///
  310. /// @param {Number | String} $density-scale - Density scale value for component. Supported density scale values `-4`,
  311. /// `-3`, `-2`, `-1`, `0`. Default is `0`.
  312. ///
  313. @mixin outlined-density($density-scale, $query: feature-targeting.all()) {
  314. $height: density-functions.prop-value(
  315. $density-config: $_density-config,
  316. $density-scale: $density-scale,
  317. $property-name: height,
  318. );
  319. @include outlined-height($height, $query: $query);
  320. // TODO(b/151839219): resize icons and adjust label position
  321. // @if $density-scale < 0 {
  322. // @include icon-mixins.size(icon-variables.$dense-icon-size);
  323. // }
  324. }
  325. ///
  326. /// Sets density scale for outlined text field with leading icon.
  327. ///
  328. /// @param {Number | String} $density-scale - Density scale value for component. Supported density scale values `-4`,
  329. /// `-3`, `-2`, `-1`, `0`. Default is `0`.
  330. ///
  331. @mixin outlined-with-leading-icon-density(
  332. $density-scale,
  333. $query: feature-targeting.all()
  334. ) {
  335. $height: density-functions.prop-value(
  336. $density-config: $_density-config,
  337. $density-scale: $density-scale,
  338. $property-name: height,
  339. );
  340. @include outlined-with-leading-icon-height($height, $query: $query);
  341. // TODO(b/151839219): resize icons and adjust label position
  342. // @if $density-scale < 0 {
  343. // @include icon-mixins.size(icon-variables.$dense-icon-size);
  344. // }
  345. }
  346. ///
  347. /// Sets density scale for filled textarea.
  348. ///
  349. /// @param {Number | String} $density-scale - Density scale value for component. Supported density scale values `-4`,
  350. /// `-3`, `-2`, `-1`, `0`. Default is `0`.
  351. ///
  352. @mixin filled-textarea-density(
  353. $density-scale,
  354. $query: feature-targeting.all()
  355. ) {
  356. $feat-structure: feature-targeting.create-target($query, structure);
  357. $textfield-height: density-functions.prop-value(
  358. $density-config: $_density-config,
  359. $density-scale: $density-scale,
  360. $property-name: height,
  361. );
  362. $no-label-margin-top: density-functions.prop-value(
  363. $density-config: variables.$textarea-filled-no-label-density-config,
  364. $density-scale: math.div($density-scale, 2),
  365. $property-name: margin-top,
  366. );
  367. $no-label-margin-bottom: density-functions.prop-value(
  368. $density-config: variables.$textarea-filled-no-label-density-config,
  369. $density-scale: math.div($density-scale, 2),
  370. $property-name: margin-bottom,
  371. );
  372. // Textarea mixins require two modifier classes since two are used internally
  373. // for styles (textarea and filled). An extra class is added for the public
  374. // mixin so that only a single public class is needed for specificity.
  375. &.mdc-text-field--filled {
  376. .mdc-text-field__resizer {
  377. @include feature-targeting.targets($feat-structure) {
  378. min-height: $textfield-height;
  379. }
  380. }
  381. @if $density-scale >= -1 {
  382. $keyframe-suffix: text-field-filled-#{$density-scale};
  383. $label-top: density-functions.prop-value(
  384. $density-config: variables.$textarea-filled-label-density-config,
  385. $density-scale: math.div($density-scale, 2),
  386. $property-name: top,
  387. );
  388. // Adjust the floating position and animation/keyframes of the floating
  389. // label by the new position of the resting label
  390. $label-top-difference: variables.$textarea-outlined-label-top -
  391. $label-top;
  392. // Floating label position
  393. @include floating-label-mixins.float-position(
  394. variables.$textarea-filled-label-position-y - $label-top-difference,
  395. $query: $query
  396. );
  397. // Floating label animation
  398. @include floating-label-mixins.shake-animation(
  399. $keyframe-suffix,
  400. $query: $query
  401. );
  402. @at-root {
  403. @include floating-label-mixins.shake-keyframes(
  404. $keyframe-suffix,
  405. variables.$textarea-filled-label-position-y - $label-top-difference,
  406. 0%,
  407. $query: $query
  408. );
  409. }
  410. // Resting label position
  411. .mdc-floating-label {
  412. @include feature-targeting.targets($feat-structure) {
  413. top: $label-top;
  414. }
  415. }
  416. $margin-bottom: density-functions.prop-value(
  417. $density-config: variables.$textarea-filled-density-config,
  418. $density-scale: $density-scale,
  419. $property-name: margin-bottom,
  420. );
  421. .mdc-text-field__input {
  422. @include feature-targeting.targets($feat-structure) {
  423. margin-bottom: $margin-bottom;
  424. }
  425. }
  426. } @else {
  427. // The textarea is too dense to show a floating label
  428. .mdc-floating-label {
  429. @include feature-targeting.targets($feat-structure) {
  430. display: none;
  431. }
  432. }
  433. .mdc-text-field__input {
  434. @include feature-targeting.targets($feat-structure) {
  435. margin-top: $no-label-margin-top;
  436. margin-bottom: $no-label-margin-bottom;
  437. }
  438. }
  439. }
  440. &.mdc-text-field--no-label {
  441. .mdc-text-field__input {
  442. @include feature-targeting.targets($feat-structure) {
  443. margin-top: $no-label-margin-top;
  444. margin-bottom: $no-label-margin-bottom;
  445. }
  446. }
  447. }
  448. &.mdc-text-field--with-internal-counter {
  449. .mdc-text-field__input {
  450. // Space between textarea and internal counter should not be affected
  451. @include _textarea-input-with-internal-counter($query);
  452. }
  453. }
  454. }
  455. }
  456. ///
  457. /// Sets density scale for outlined textarea.
  458. ///
  459. /// @param {Number | String} $density-scale - Density scale value for component. Supported density scale values `-4`,
  460. /// `-3`, `-2`, `-1`, `0`. Default is `0`.
  461. ///
  462. @mixin outlined-textarea-density(
  463. $density-scale,
  464. $query: feature-targeting.all()
  465. ) {
  466. $feat-structure: feature-targeting.create-target($query, structure);
  467. $keyframe-suffix: text-field-outlined-#{$density-scale};
  468. $label-top: density-functions.prop-value(
  469. $density-config: variables.$textarea-outlined-label-density-config,
  470. $density-scale: math.div($density-scale, 2),
  471. $property-name: top,
  472. );
  473. $textfield-height: density-functions.prop-value(
  474. $density-config: $_density-config,
  475. $density-scale: $density-scale,
  476. $property-name: height,
  477. );
  478. $margin-top: density-functions.prop-value(
  479. $density-config: variables.$textarea-outlined-density-config,
  480. $density-scale: math.div($density-scale, 2),
  481. $property-name: margin-top,
  482. );
  483. $margin-bottom: density-functions.prop-value(
  484. $density-config: variables.$textarea-outlined-density-config,
  485. $density-scale: math.div($density-scale, 2),
  486. $property-name: margin-bottom,
  487. );
  488. // Textarea mixins require two modifier classes since two are used internally
  489. // for styles (textarea and outlined). An extra class is added for the public
  490. // mixin so that only a single public class is needed for specificity.
  491. &.mdc-text-field--outlined {
  492. // Adjust the floating position and animation/keyframes of the floating
  493. // label by the new position of the resting label
  494. $label-top-difference: variables.$textarea-outlined-label-top - $label-top;
  495. // Floating label position
  496. @include notched-outline-mixins.floating-label-float-position-absolute(
  497. variables.$textarea-outlined-label-position-y - $label-top-difference,
  498. $query: $query
  499. );
  500. // Floating label animation
  501. @include floating-label-mixins.shake-animation(
  502. $keyframe-suffix,
  503. $query: $query
  504. );
  505. @at-root {
  506. @include floating-label-mixins.shake-keyframes(
  507. $keyframe-suffix,
  508. variables.$textarea-outlined-label-position-y - $label-top-difference,
  509. 0%,
  510. $query: $query
  511. );
  512. }
  513. // Resting label position
  514. .mdc-floating-label {
  515. @include feature-targeting.targets($feat-structure) {
  516. top: $label-top;
  517. }
  518. }
  519. .mdc-text-field__resizer {
  520. @include feature-targeting.targets($feat-structure) {
  521. min-height: $textfield-height;
  522. }
  523. }
  524. .mdc-text-field__input {
  525. @include feature-targeting.targets($feat-structure) {
  526. margin-top: $margin-top;
  527. margin-bottom: $margin-bottom;
  528. }
  529. }
  530. &.mdc-text-field--with-internal-counter {
  531. .mdc-text-field__input {
  532. // Space between textarea and internal counter should not be affected
  533. @include _textarea-input-with-internal-counter($query);
  534. }
  535. }
  536. }
  537. }
  538. ///
  539. /// Sets the minimum number of rows for a textarea a textarea may be resized to.
  540. ///
  541. /// For IE11 this mixin can be used instead of the rows attribute.
  542. ///
  543. /// @param {Number} $rows - The minimum number of rows for a textarea.
  544. /// @param {Number} $line-height - The line-height of the textarea.
  545. ///
  546. @mixin textarea-min-rows(
  547. $rows,
  548. $line-height: variables.$textarea-line-height,
  549. $query: feature-targeting.all()
  550. ) {
  551. $feat-structure: feature-targeting.create-target($query, structure);
  552. .mdc-text-field__input {
  553. @include feature-targeting.targets($feat-structure) {
  554. min-height: $rows * $line-height;
  555. }
  556. }
  557. }
  558. ///
  559. /// Sets height of default text field variant.
  560. ///
  561. /// @param {Number} $height
  562. /// @param {Number} $minimum-height-for-filled-label Sets the minimum height for
  563. /// filled textfields at which to allow floating labels.
  564. /// @access public
  565. ///
  566. @mixin height(
  567. $height,
  568. $minimum-height-for-filled-label: variables.$minimum-height-for-filled-label,
  569. $query: feature-targeting.all()
  570. ) {
  571. $feat-structure: feature-targeting.create-target($query, structure);
  572. @include feature-targeting.targets($feat-structure) {
  573. @include theme.property(height, $height);
  574. }
  575. // We can only hide the label (when there's not enough vertical space for it)
  576. // if we know the container height at compilation time.
  577. // That's not the case when $height is a custom property.
  578. @if not custom-properties.is-custom-prop($height) {
  579. @if $height < $minimum-height-for-filled-label {
  580. @include filled-no-label($query: $query);
  581. }
  582. }
  583. }
  584. ///
  585. /// Sets height of outlined text field variant (Excluding outlined text field with leading icon).
  586. ///
  587. /// @param {Number} $height
  588. /// @param {String} $keyframe-suffix - Optional suffix to use for generated
  589. /// floating label keyframes
  590. /// @access public
  591. ///
  592. @mixin outlined-height(
  593. $height,
  594. $keyframe-suffix: text-field-outlined-#{$height},
  595. $query: feature-targeting.all()
  596. ) {
  597. $feat-structure: feature-targeting.create-target($query, structure);
  598. $positionY: variables.get-outlined-label-position-y($height);
  599. // Floating label position
  600. @include notched-outline-mixins.floating-label-float-position-absolute(
  601. $positionY,
  602. $query: $query
  603. );
  604. // Floating label animation
  605. @include floating-label-mixins.shake-animation(
  606. $keyframe-suffix,
  607. $query: $query
  608. );
  609. @at-root {
  610. @include floating-label-mixins.shake-keyframes(
  611. $keyframe-suffix,
  612. $positionY,
  613. $query: $query
  614. );
  615. }
  616. @include feature-targeting.targets($feat-structure) {
  617. height: $height;
  618. }
  619. }
  620. ///
  621. /// Sets height of outlined text field with leading icon variant.
  622. ///
  623. /// @param {Number} $height
  624. /// @param {String} $keyframe-suffix - Optional suffix to use for generated
  625. /// floating label keyframes
  626. /// @access public
  627. ///
  628. @mixin outlined-with-leading-icon-height(
  629. $height,
  630. $keyframe-suffix: null,
  631. $query: feature-targeting.all()
  632. ) {
  633. $feat-structure: feature-targeting.create-target($query, structure);
  634. // This extra specificity is needed because textfield applies the below mixin
  635. // already to two selectors (outlined + with-leading-icon). To override
  636. // them with a new label position and animation, another selector is needed.
  637. &.mdc-text-field--outlined {
  638. @include _outlined-with-leading-icon-floating-label-position-animation(
  639. $height,
  640. $keyframe-suffix,
  641. $query
  642. );
  643. }
  644. @include feature-targeting.targets($feat-structure) {
  645. height: $height;
  646. }
  647. }
  648. // Mixin that sets the floating label position and animations for a given height.
  649. // This mixin is separate to allow outlined-with-leading-icon-height() to
  650. // provide greater specificity over the default mixin that adds styles for
  651. // outlined with leading icons.
  652. @mixin _outlined-with-leading-icon-floating-label-position-animation(
  653. $height,
  654. $keyframe-suffix: text-field-outlined-with-leading-icon-#{$height},
  655. $query: feature-targeting.all()
  656. ) {
  657. $positionY: variables.get-outlined-label-position-y($height);
  658. // Floating label position
  659. @include notched-outline-mixins.floating-label-float-position-absolute(
  660. $positionY,
  661. variables.$outlined-with-leading-icon-label-position-x,
  662. $query: $query
  663. );
  664. // Floating label animation
  665. @include floating-label-mixins.shake-animation(
  666. $keyframe-suffix,
  667. $query: $query
  668. );
  669. @at-root {
  670. @include floating-label-mixins.shake-keyframes(
  671. $keyframe-suffix,
  672. $positionY,
  673. variables.$outlined-with-leading-icon-label-position-x,
  674. $query: $query
  675. );
  676. }
  677. $keyframe-suffix-rtl: #{$keyframe-suffix}-rtl;
  678. @include rtl.rtl {
  679. @include floating-label-mixins.shake-animation(
  680. $keyframe-suffix,
  681. $query: $query
  682. );
  683. }
  684. @at-root {
  685. @include floating-label-mixins.shake-keyframes(
  686. $keyframe-suffix-rtl,
  687. $positionY,
  688. -(variables.$outlined-with-leading-icon-label-position-x),
  689. $query: $query
  690. );
  691. }
  692. }
  693. ///
  694. /// Sets shape radius of default text field variant.
  695. ///
  696. /// @param {Number} $radius Shape radius value in `px` or in percentage.
  697. /// @param {Number} $text-field-height Height of default text field variant. Required only when `$radius` is in
  698. /// percentage unit and if text field has custom height. Defaults to `variables.$height`.
  699. /// @param {Boolean} $rtl-reflexive Set to true to flip shape radius in RTL context. Defaults to `false`.
  700. ///
  701. @mixin shape-radius(
  702. $radius,
  703. $density-scale: variables.$density-scale,
  704. $rtl-reflexive: false,
  705. $query: feature-targeting.all()
  706. ) {
  707. @if (meta.type-of($radius) == 'list') and
  708. (list.length($radius) > 2) and
  709. (list.nth($radius, 3) != 0 or list.nth($radius, 4) != 0)
  710. {
  711. @error "mdc-textfield: Invalid radius #{$radius}. Only top-left and top-right corners may be customized.";
  712. }
  713. $height: density-functions.prop-value(
  714. $density-config: $_density-config,
  715. $density-scale: $density-scale,
  716. $property-name: height,
  717. );
  718. $masked-radius: shape-functions.mask-radius($radius, 1 1 0 0);
  719. $fallback: if(
  720. custom-properties.is-custom-prop($radius),
  721. custom-properties.get-fallback($radius),
  722. null
  723. );
  724. @if meta.type-of($fallback) == 'list' {
  725. $fallback: css.unpack-value($fallback);
  726. $first: list.nth($masked-radius, 1);
  727. $second: list.nth($masked-radius, 2);
  728. $third: list.nth($masked-radius, 3);
  729. $fourth: list.nth($masked-radius, 4);
  730. $masked-radius: (
  731. if(
  732. custom-properties.is-custom-prop($first),
  733. custom-properties.set-fallback($first, list.nth($fallback, 1)),
  734. $first
  735. ),
  736. if(
  737. custom-properties.is-custom-prop($second),
  738. custom-properties.set-fallback($second, list.nth($fallback, 2)),
  739. $second
  740. ),
  741. if(
  742. custom-properties.is-custom-prop($third),
  743. custom-properties.set-fallback($third, list.nth($fallback, 3)),
  744. $third
  745. ),
  746. if(
  747. custom-properties.is-custom-prop($fourth),
  748. custom-properties.set-fallback($fourth, list.nth($fallback, 4)),
  749. $fourth
  750. )
  751. );
  752. }
  753. @include shape-mixins.radius(
  754. $masked-radius,
  755. $rtl-reflexive,
  756. $component-height: $height,
  757. $query: $query
  758. );
  759. }
  760. @mixin textarea-shape-radius(
  761. $radius,
  762. $rtl-reflexive: false,
  763. $query: feature-targeting.all()
  764. ) {
  765. @include notched-outline-mixins.shape-radius(
  766. $radius,
  767. $rtl-reflexive,
  768. $query: $query
  769. );
  770. }
  771. ///
  772. /// Customizes the color of the text entered into an enabled text field.
  773. /// @param {Color} $color - The desired input text color.
  774. ///
  775. @mixin ink-color($color, $query: feature-targeting.all()) {
  776. @include if-enabled_ {
  777. @include ink-color_($color, $query: $query);
  778. }
  779. }
  780. ///
  781. /// Customizes the color of the entered text in a disabled text field.
  782. /// @param {Color} $color - The desired input text color.
  783. ///
  784. @mixin disabled-ink-color($color, $query: feature-targeting.all()) {
  785. @include if-disabled_ {
  786. @include ink-color_($color, $query: $query);
  787. }
  788. }
  789. ///
  790. /// Customizes the color of the placeholder in an enabled text field.
  791. /// @param {Color} $color - The desired placeholder text color.
  792. ///
  793. @mixin placeholder-color($color, $query: feature-targeting.all()) {
  794. @include if-enabled_ {
  795. @include placeholder-color_($color, $query: $query);
  796. }
  797. }
  798. ///
  799. /// Customizes the color of the placeholder in a disabled text field.
  800. /// @param {Color} $color - The desired placeholder text color.
  801. ///
  802. @mixin disabled-placeholder-color($color, $query: feature-targeting.all()) {
  803. @include if-disabled_ {
  804. @include placeholder-color_($color, $query: $query);
  805. }
  806. }
  807. ///
  808. /// Customizes the background color of the text field or textarea when enabled.
  809. /// @param {Color} $color - The desired background color.
  810. ///
  811. @mixin fill-color($color, $query: feature-targeting.all()) {
  812. @include if-enabled_ {
  813. @include fill-color_($color, $query: $query);
  814. }
  815. }
  816. ///
  817. /// Customizes the background color of the text field or textarea when disabled.
  818. /// @param {Color} $color - The desired background color.
  819. ///
  820. @mixin disabled-fill-color($color, $query: feature-targeting.all()) {
  821. @include if-disabled_ {
  822. @include fill-color_($color, $query: $query);
  823. }
  824. }
  825. ///
  826. /// Customizes the text field bottom line color for the filled variant.
  827. /// @param {Color} $color - The desired bottom line color.
  828. ///
  829. @mixin bottom-line-color($color, $query: feature-targeting.all()) {
  830. @include if-enabled_ {
  831. @include bottom-line-color_($color, $query: $query);
  832. }
  833. }
  834. ///
  835. /// Customizes the disabled text field bottom line color for the filled variant.
  836. /// @param {Color} $color - The desired bottom line color.
  837. ///
  838. @mixin disabled-bottom-line-color($color, $query: feature-targeting.all()) {
  839. @include if-disabled_ {
  840. @include bottom-line-color_($color, $query: $query);
  841. }
  842. }
  843. ///
  844. /// Customizes the hover text field bottom line color for the filled variant.
  845. /// @param {Color} $color - The desired bottom line color.
  846. ///
  847. @mixin hover-bottom-line-color($color, $query: feature-targeting.all()) {
  848. @include if-enabled_ {
  849. @include hover-bottom-line-color_($color, $query: $query);
  850. }
  851. }
  852. ///
  853. /// Customizes the color of the default line ripple of the text field.
  854. /// @param {Color} $color - The desired line ripple color.
  855. ///
  856. @mixin line-ripple-color($color, $query: feature-targeting.all()) {
  857. @include if-enabled_ {
  858. @include line-ripple-color_($color, $query: $query);
  859. }
  860. }
  861. ///
  862. /// Customizes the text color of the label in an enabled text field.
  863. /// @param {Color} $color - The desired label text color.
  864. ///
  865. @mixin label-color($color, $query: feature-targeting.all()) {
  866. @include if-enabled_ {
  867. @include label-ink-color_($color, $query: $query);
  868. }
  869. }
  870. ///
  871. /// Customizes the text color of the label in a disabled text field.
  872. /// @param {Color} $color - The desired label text color.
  873. ///
  874. @mixin disabled-label-color($color, $query: feature-targeting.all()) {
  875. @include if-disabled_ {
  876. @include label-ink-color_($color, $query: $query);
  877. }
  878. }
  879. ///
  880. /// Customizes the border color of the outlined text field or textarea.
  881. /// @param {Color} $color - The desired outline border color.
  882. ///
  883. @mixin outline-color($color, $query: feature-targeting.all()) {
  884. @include if-enabled_ {
  885. @include notched-outline-mixins.color($color, $query: $query);
  886. }
  887. }
  888. ///
  889. /// Customizes the outline border color when the text field or textarea is hovered.
  890. /// @param {Color} $color - The desired outline border color.
  891. ///
  892. @mixin hover-outline-color($color, $query: feature-targeting.all()) {
  893. @include if-enabled_ {
  894. @include hover-outline-color_($color, $query: $query);
  895. }
  896. }
  897. ///
  898. /// Customizes the outline border color when the text field or textarea is focused.
  899. /// @param {Color} $color - The desired outline border color.
  900. ///
  901. @mixin focused-outline-color($color, $query: feature-targeting.all()) {
  902. @include if-enabled_ {
  903. @include focused-outline-color_($color, $query: $query);
  904. }
  905. }
  906. ///
  907. /// Customizes the outline border color when the text field or textarea is disabled.
  908. /// @param {Color} $color - The desired outline border color.
  909. ///
  910. @mixin disabled-outline-color($color, $query: feature-targeting.all()) {
  911. @include if-disabled_ {
  912. @include notched-outline-mixins.color($color, $query: $query);
  913. }
  914. }
  915. ///
  916. /// Customizes the caret color of the text field or textarea.
  917. /// @param {Color} $color - The desired caret color.
  918. ///
  919. @mixin caret-color($color, $query: feature-targeting.all()) {
  920. $feat-color: feature-targeting.create-target($query, color);
  921. .mdc-text-field__input {
  922. @include feature-targeting.targets($feat-color) {
  923. @include theme.property(caret-color, $color);
  924. }
  925. }
  926. }
  927. ///
  928. /// Customizes the color of the prefix text for an enabled text field.
  929. /// @param {Color} $color - The desired prefix text color.
  930. ///
  931. @mixin prefix-color($color, $query: feature-targeting.all()) {
  932. @include if-enabled_ {
  933. @include _prefix-color($color, $query: $query);
  934. }
  935. }
  936. ///
  937. /// Customizes the color of the prefix text for a disabled text field.
  938. /// @param {Color} $color - The desired prefix text color.
  939. ///
  940. @mixin disabled-prefix-color($color, $query: feature-targeting.all()) {
  941. @include if-disabled_ {
  942. @include _prefix-color($color, $query: $query);
  943. }
  944. }
  945. ///
  946. /// Customizes the color of the suffix text for an enabled text field.
  947. /// @param {Color} $color - The desired suffix text color.
  948. ///
  949. @mixin suffix-color($color, $query: feature-targeting.all()) {
  950. @include if-enabled_ {
  951. @include _suffix-color($color, $query: $query);
  952. }
  953. }
  954. ///
  955. /// Customizes the color of the suffix text for a disabled text field.
  956. /// @param {Color} $color - The desired suffix text color.
  957. ///
  958. @mixin disabled-suffix-color($color, $query: feature-targeting.all()) {
  959. @include if-disabled_ {
  960. @include _suffix-color($color, $query: $query);
  961. }
  962. }
  963. ///
  964. /// Sets shape radius of outlined text field variant.
  965. ///
  966. /// @param {Number} $radius Shape radius value in `px` or in percentage.
  967. /// @param {Number} $text-field-height Height of outlined text field variant. Required only when `$radius` is in
  968. /// percentage unit and if text field has custom height. Defaults to `variables.$height`.
  969. /// @param {Boolean} $rtl-reflexive Set to true to flip shape radius in RTL context. Defaults to `false`.
  970. ///
  971. @mixin outline-shape-radius(
  972. $radius,
  973. $density-scale: variables.$density-scale,
  974. $rtl-reflexive: false,
  975. $query: feature-targeting.all()
  976. ) {
  977. $feat-structure: feature-targeting.create-target($query, structure);
  978. $height: density-functions.prop-value(
  979. $density-config: $_density-config,
  980. $density-scale: $density-scale,
  981. $property-name: height,
  982. );
  983. .mdc-notched-outline {
  984. @include notched-outline-mixins.shape-radius(
  985. $radius,
  986. $rtl-reflexive,
  987. $component-height: $height,
  988. $query: $query
  989. );
  990. }
  991. $resolved-radius: shape-functions.resolve-radius(
  992. $radius,
  993. $component-height: $height
  994. );
  995. $unpacked-radius: shape-functions.unpack-radius($resolved-radius);
  996. $top-left-radius: list.nth($unpacked-radius, 1);
  997. $top-left-is-custom-prop: custom-properties.is-custom-prop($top-left-radius);
  998. $top-left-radius-px: $top-left-radius;
  999. @if ($top-left-is-custom-prop) {
  1000. $top-left-radius-px: custom-properties.get-fallback($top-left-radius);
  1001. }
  1002. $top-right-radius: list.nth($unpacked-radius, 2);
  1003. $top-right-is-custom-prop: custom-properties.is-custom-prop(
  1004. $top-right-radius
  1005. );
  1006. @if (
  1007. $top-left-is-custom-prop or
  1008. $top-right-is-custom-prop or
  1009. $top-left-radius-px >
  1010. notched-outline-variables.$leading-width
  1011. ) {
  1012. // The horizontal padding only needs to be overriden from the base padding
  1013. // if the radius is a custom property, or if the top-left radius is a value
  1014. // that is large than that default notched outline's leading width.
  1015. @include _outline-shape-radius-horizontal-padding(
  1016. $top-left-radius,
  1017. $top-right-radius,
  1018. $query: $query
  1019. );
  1020. + .mdc-text-field-helper-line {
  1021. @include _outline-shape-radius-horizontal-padding(
  1022. $top-left-radius,
  1023. $top-right-radius,
  1024. $query: $query
  1025. );
  1026. }
  1027. // Ensure that leading/trailing icon padding is overriden. Even if the
  1028. // top left/right isn't a custom property or the leading isn't larger, we
  1029. // still need to override. The above left/right padding rules have more
  1030. // specificty than the original leading/trailing icon rules, so we need to
  1031. // re-apply them.
  1032. // Additionally, if the top left/right radii _are_ custom properties, we
  1033. // should use those instead.
  1034. &.mdc-text-field--with-leading-icon {
  1035. @if ($top-right-is-custom-prop) {
  1036. @include feature-targeting.targets($feat-structure) {
  1037. @include rtl.ignore-next-line();
  1038. padding-left: 0;
  1039. }
  1040. @include _apply-outline-shape-padding(
  1041. padding-right,
  1042. $top-right-radius,
  1043. $query: $query
  1044. );
  1045. @include rtl.rtl {
  1046. @include _apply-outline-shape-padding(
  1047. padding-left,
  1048. $top-right-radius,
  1049. $query: $query
  1050. );
  1051. @include feature-targeting.targets($feat-structure) {
  1052. @include rtl.ignore-next-line();
  1053. padding-right: 0;
  1054. }
  1055. }
  1056. } @else {
  1057. @include _padding-horizontal-with-leading-icon($query);
  1058. }
  1059. }
  1060. &.mdc-text-field--with-trailing-icon {
  1061. @if (
  1062. $top-left-is-custom-prop or
  1063. $top-left-radius-px >
  1064. notched-outline-variables.$leading-width
  1065. ) {
  1066. @include _apply-outline-shape-padding(
  1067. padding-left,
  1068. $top-left-radius,
  1069. $add-label-padding: true,
  1070. $query: $query
  1071. );
  1072. @include feature-targeting.targets($feat-structure) {
  1073. @include rtl.ignore-next-line();
  1074. padding-right: 0;
  1075. }
  1076. @include rtl.rtl {
  1077. @include feature-targeting.targets($feat-structure) {
  1078. @include rtl.ignore-next-line();
  1079. padding-left: 0;
  1080. }
  1081. @include _apply-outline-shape-padding(
  1082. padding-right,
  1083. $top-left-radius,
  1084. $add-label-padding: true,
  1085. $query: $query
  1086. );
  1087. }
  1088. } @else {
  1089. @include _padding-horizontal-with-trailing-icon($query);
  1090. }
  1091. }
  1092. &.mdc-text-field--with-leading-icon.mdc-text-field--with-trailing-icon {
  1093. @include _padding-horizontal-with-both-icons($query);
  1094. }
  1095. }
  1096. }
  1097. @mixin _outline-shape-radius-horizontal-padding(
  1098. $top-left-radius,
  1099. $top-right-radius,
  1100. $query: feature-targeting.all()
  1101. ) {
  1102. @include _apply-outline-shape-padding(
  1103. padding-left,
  1104. $top-left-radius,
  1105. $add-label-padding: true,
  1106. $query: $query
  1107. );
  1108. @include _apply-outline-shape-padding(
  1109. padding-right,
  1110. $top-right-radius,
  1111. $query: $query
  1112. );
  1113. $top-left-is-custom-prop: custom-properties.is-custom-prop($top-left-radius);
  1114. $top-left-radius-px: $top-left-radius;
  1115. @if ($top-left-is-custom-prop) {
  1116. $top-left-radius-px: custom-properties.get-fallback($top-left-radius);
  1117. }
  1118. $top-right-is-custom-prop: custom-properties.is-custom-prop(
  1119. $top-right-radius
  1120. );
  1121. $top-right-radius-px: $top-right-radius;
  1122. @if ($top-right-is-custom-prop) {
  1123. $top-right-radius-px: custom-properties.get-fallback($top-right-radius);
  1124. }
  1125. @if (
  1126. (
  1127. $top-left-is-custom-prop and
  1128. $top-right-is-custom-prop and not
  1129. custom-properties.are-equal($top-left-radius, $top-right-radius)
  1130. ) or
  1131. $top-left-radius-px !=
  1132. $top-right-radius-px
  1133. ) {
  1134. // Normally base horizontal padding doesn't need RTL, but if the values
  1135. // are different or they are two different custom properties, they need to
  1136. // be reversed.
  1137. @include rtl.rtl {
  1138. @include _apply-outline-shape-padding(
  1139. padding-right,
  1140. $top-left-radius,
  1141. $add-label-padding: true,
  1142. $query: $query
  1143. );
  1144. @include _apply-outline-shape-padding(
  1145. padding-left,
  1146. $top-right-radius,
  1147. $query: $query
  1148. );
  1149. }
  1150. }
  1151. }
  1152. @mixin _apply-outline-shape-padding(
  1153. $property,
  1154. $padding,
  1155. $add-label-padding: false,
  1156. $query: feature-targeting.all()
  1157. ) {
  1158. $feat-structure: feature-targeting.create-target($query, structure);
  1159. $padding-is-custom-prop: custom-properties.is-custom-prop($padding);
  1160. $padding-px: $padding;
  1161. @if ($padding-is-custom-prop) {
  1162. $padding-px: custom-properties.get-fallback($padding);
  1163. }
  1164. @include feature-targeting.targets($feat-structure) {
  1165. // The shape should only change the padding if the radius becomes greater
  1166. // than the default padding. That means we need to add more padding.
  1167. @if ($padding-px > variables.$padding-horizontal) {
  1168. // Set a px value if it's greater. This is either the only value (if
  1169. // we're given an exact value), or an IE11 fallback if we're given a
  1170. // custom property and the fallback value is greater than the padding.
  1171. $value: $padding-px;
  1172. @if ($add-label-padding) {
  1173. // If this is for the top-left leading, add the notched outline padding
  1174. // to keep it aligned with the label
  1175. $value: $padding-px + notched-outline-variables.$padding;
  1176. }
  1177. @include rtl.ignore-next-line();
  1178. #{$property}: $value;
  1179. @if ($padding-is-custom-prop) {
  1180. // Add an alternate GSS tag b/c this was an IE11 fallback and we're
  1181. // going to add another property with the var() value
  1182. /* @alternate */
  1183. }
  1184. }
  1185. @if ($padding-is-custom-prop) {
  1186. // If it's a custom property, always add it since the value may change
  1187. // to be greater than the padding at runtime, even if the fallback is
  1188. // not currently greater than the default padding.
  1189. $value: custom-properties.create-var($padding);
  1190. @if ($add-label-padding) {
  1191. $value: calc(#{$value} + #{notched-outline-variables.$padding});
  1192. }
  1193. // Interpolation is a workaround for sass/sass#3259.
  1194. @supports (top: max(#{0%})) {
  1195. // A max() function makes this runtime dynamic. The padding will be
  1196. // whichever is greater: the default horizontal padding, or the calculated
  1197. // custom property plus extra padding.
  1198. @include rtl.ignore-next-line();
  1199. #{$property}: max(#{variables.$padding-horizontal}, #{$value});
  1200. }
  1201. }
  1202. }
  1203. }
  1204. ///
  1205. /// Sets the CSS transition for the floating label's 'float' animation.
  1206. ///
  1207. /// @param {Number} $duration-ms - Duration (in ms) of the animation.
  1208. /// @param {String} $timing-function - Optionally overrides the default animation timing function.
  1209. ///
  1210. @mixin floating-label-float-transition(
  1211. $duration-ms,
  1212. $timing-function: null,
  1213. $query: feature-targeting.all()
  1214. ) {
  1215. .mdc-floating-label {
  1216. @include floating-label-mixins.float-transition(
  1217. $duration-ms,
  1218. $timing-function,
  1219. $query: $query
  1220. );
  1221. }
  1222. }
  1223. ///
  1224. /// Sets custom font size of the input.
  1225. ///
  1226. /// @param {number} $font-size - Overrides the font size.
  1227. ///
  1228. @mixin input-font-size($font-size, $query: feature-targeting.all()) {
  1229. $feat-typography: feature-targeting.create-target($query, typography);
  1230. .mdc-text-field__input,
  1231. .mdc-text-field__affix--suffix,
  1232. .mdc-text-field__affix--prefix {
  1233. @include feature-targeting.targets($feat-typography) {
  1234. font-size: $font-size;
  1235. }
  1236. }
  1237. }
  1238. ///
  1239. /// Sets custom font family of the input.
  1240. ///
  1241. /// @param {String} $font-family - Selected font family.
  1242. ///
  1243. @mixin input-font-family($font-family, $query: feature-targeting.all()) {
  1244. $feat-typography: feature-targeting.create-target($query, typography);
  1245. .mdc-text-field__input {
  1246. @include feature-targeting.targets($feat-typography) {
  1247. font-family: $font-family;
  1248. }
  1249. }
  1250. }
  1251. // Private mixins
  1252. // Base shared styles
  1253. @mixin _base($query: feature-targeting.all()) {
  1254. $feat-structure: feature-targeting.create-target($query, structure);
  1255. // Shape
  1256. @include shape-radius(variables.$shape-radius, $query: $query);
  1257. // Colors
  1258. @include label-color(variables.$label, $query: $query);
  1259. @include ink-color(variables.$ink-color, $query: $query);
  1260. @include placeholder-color(variables.$placeholder-ink-color, $query: $query);
  1261. @include caret-color(primary, $query: $query);
  1262. @include helper-text-mixins.helper-text-color(
  1263. variables.$helper-text-color,
  1264. $query: $query
  1265. );
  1266. @include character-counter-mixins.character-counter-color(
  1267. variables.$helper-text-color,
  1268. $query: $query
  1269. );
  1270. @include icon-mixins.leading-icon-color(
  1271. variables.$icon-color,
  1272. $query: $query
  1273. );
  1274. @include icon-mixins.trailing-icon-color(
  1275. variables.$icon-color,
  1276. $query: $query
  1277. );
  1278. @include prefix-color(variables.$affix-color, $query: $query);
  1279. @include suffix-color(variables.$affix-color, $query: $query);
  1280. // Floating Label
  1281. @include floating-label_($query);
  1282. @include feature-targeting.targets($feat-structure) {
  1283. // display and align-items are necessary to make the text field participate
  1284. // in baseline alignment, even though some variants are 'centered'. Those
  1285. // variants should use the _baseline-center-aligned() mixin
  1286. display: inline-flex;
  1287. align-items: baseline;
  1288. padding: 0 variables.$padding-horizontal;
  1289. position: relative;
  1290. box-sizing: border-box;
  1291. overflow: hidden;
  1292. /* @alternate */
  1293. will-change: opacity, transform, color;
  1294. }
  1295. }
  1296. // This mixin adds styles to visually center the text within the text field.
  1297. // Sibling text will align to the baseline and appear centered next to the
  1298. // text field.
  1299. @mixin _baseline-center-aligned($query: feature-targeting.all()) {
  1300. $feat-structure: feature-targeting.create-target($query, structure);
  1301. @include feature-targeting.targets($feat-structure) {
  1302. // In order for a flexbox container to participate in baseline alignment,
  1303. // it follows these rules to determine where its baseline is:
  1304. // https://www.w3.org/TR/css-flexbox-1/#flex-baselines
  1305. //
  1306. // In order to avoid leading icons 'controlling' the baseline (since they
  1307. // are the first child), flexbox will generate a baseline from any child
  1308. // flex items that participate in baseline alignment.
  1309. //
  1310. // Icons are set to "align-self: center", while all other children are
  1311. // aligned to baseline. The next problem is deciding which child is
  1312. // used to determine the baseline.
  1313. //
  1314. // According to spec, the item with the largest distance between its
  1315. // baseline and the edge of the cross axis is placed flush with that edge,
  1316. // making it the baseline of the container.
  1317. // https://www.w3.org/TR/css-flexbox-1/#baseline-participation
  1318. //
  1319. // For the filled variant, the pseudo ::before strut is the 'largest'
  1320. // child since the input has a height of 28px and the strut is 40px. We
  1321. // can emulate center alignment and force the baseline to use the input
  1322. // text by making the input the full height of the container and removing
  1323. // the baseline strut.
  1324. // IE11 does not respect this, and makes the leading icon (if present) the
  1325. // baseline. This is a gap with IE11 that we have accepted.
  1326. .mdc-text-field__input {
  1327. height: 100%;
  1328. }
  1329. }
  1330. }
  1331. @mixin _padding-horizontal-with-leading-icon($query: feature-targeting.all()) {
  1332. $feat-structure: feature-targeting.create-target($query, structure);
  1333. @include feature-targeting.targets($feat-structure) {
  1334. @include rtl.reflexive-property(padding, 0, variables.$padding-horizontal);
  1335. }
  1336. }
  1337. @mixin _padding-horizontal-with-trailing-icon($query: feature-targeting.all()) {
  1338. $feat-structure: feature-targeting.create-target($query, structure);
  1339. @include feature-targeting.targets($feat-structure) {
  1340. @include rtl.reflexive-property(padding, variables.$padding-horizontal, 0);
  1341. }
  1342. }
  1343. @mixin _padding-horizontal-with-both-icons($query: feature-targeting.all()) {
  1344. $feat-structure: feature-targeting.create-target($query, structure);
  1345. @include feature-targeting.targets($feat-structure) {
  1346. @include rtl.ignore-next-line();
  1347. padding-left: 0;
  1348. @include rtl.ignore-next-line();
  1349. padding-right: 0;
  1350. }
  1351. }
  1352. @mixin floating-label_($query: feature-targeting.all()) {
  1353. $feat-structure: feature-targeting.create-target($query, structure);
  1354. .mdc-floating-label {
  1355. @include feature-targeting.targets($feat-structure) {
  1356. top: 50%;
  1357. transform: translateY(-50%);
  1358. pointer-events: none;
  1359. }
  1360. }
  1361. }
  1362. // Filled
  1363. @mixin _filled($query: feature-targeting.all()) {
  1364. // Text Field intentionally omits press ripple, so each state needs to be specified individually.
  1365. @include ripple-theme.states-base-color(
  1366. variables.$ink-color,
  1367. $query: $query,
  1368. $ripple-target: variables.$ripple-target
  1369. );
  1370. @include ripple-theme.states-hover-opacity(
  1371. ripple-theme.states-opacity(variables.$ink-color, hover),
  1372. $query: $query,
  1373. $ripple-target: variables.$ripple-target
  1374. );
  1375. @include ripple-theme.states-focus-opacity(
  1376. ripple-theme.states-opacity(variables.$ink-color, focus),
  1377. $query: $query,
  1378. $ripple-target: variables.$ripple-target
  1379. );
  1380. @include height(variables.$height, $query: $query);
  1381. @include typography.baseline-top(
  1382. variables.$filled-baseline-top,
  1383. $query: $query
  1384. );
  1385. @include fill-color(variables.$background, $query: $query);
  1386. @include bottom-line-color(variables.$bottom-line-idle, $query: $query);
  1387. @include hover-bottom-line-color(
  1388. variables.$bottom-line-hover,
  1389. $query: $query
  1390. );
  1391. @include line-ripple-color_(primary, $query: $query);
  1392. @include _filled-floating-label($query);
  1393. }
  1394. @mixin _filled-floating-label($query: feature-targeting.all()) {
  1395. $feat-structure: feature-targeting.create-target($query, structure);
  1396. .mdc-floating-label {
  1397. @include feature-targeting.targets($feat-structure) {
  1398. @include rtl.reflexive-position(left, variables.$label-offset);
  1399. }
  1400. }
  1401. @include floating-label-mixins.float-position(
  1402. variables.$label-position-y,
  1403. $query: $query
  1404. );
  1405. }
  1406. // Filled variant with no label. This variant centers the text elements and
  1407. // hides the label and is used with there is explicitly no label provided or
  1408. // when the height of the text field is too small for a label to be allowed.
  1409. @mixin filled-no-label($query: feature-targeting.all()) {
  1410. $feat-structure: feature-targeting.create-target($query, structure);
  1411. @include _baseline-center-aligned($query);
  1412. @include feature-targeting.targets($feat-structure) {
  1413. .mdc-floating-label {
  1414. display: none;
  1415. }
  1416. &::before {
  1417. // Remove baseline-top strut
  1418. display: none;
  1419. }
  1420. }
  1421. // Safari only
  1422. @supports (-webkit-hyphens: none) {
  1423. .mdc-text-field__affix {
  1424. @include _centered-affix-safari-support($query: $query);
  1425. }
  1426. }
  1427. }
  1428. // Outlined
  1429. @mixin outlined_($query: feature-targeting.all()) {
  1430. $feat-structure: feature-targeting.create-target($query, structure);
  1431. @include outlined-height(
  1432. $height: variables.$height,
  1433. $keyframe-suffix: text-field-outlined,
  1434. $query: $query
  1435. );
  1436. @include _baseline-center-aligned($query: $query);
  1437. @include outline-color(variables.$outlined-idle-border, $query: $query);
  1438. @include hover-outline-color(
  1439. variables.$outlined-hover-border,
  1440. $query: $query
  1441. );
  1442. @include focused-outline-color(primary, $query: $query);
  1443. @include outline-shape-radius(variables.$shape-radius, $query: $query);
  1444. @include notched-outline-mixins.notch-offset(
  1445. notched-outline-variables.$border-width,
  1446. $query: $query
  1447. );
  1448. @include ripple-theme.states-base-color(
  1449. transparent,
  1450. $query: $query,
  1451. $ripple-target: variables.$ripple-target
  1452. );
  1453. @include _outlined-floating-label($query);
  1454. @include feature-targeting.targets($feat-structure) {
  1455. overflow: visible;
  1456. }
  1457. .mdc-text-field__input {
  1458. @include feature-targeting.targets($feat-structure) {
  1459. // TODO(b/154349735): Investigate the neccessity of these styles
  1460. display: flex;
  1461. // stylelint-disable-next-line declaration-no-important --
  1462. // FF adds unwanted border in HC mode on windows.
  1463. border: none !important;
  1464. background-color: transparent;
  1465. }
  1466. }
  1467. }
  1468. @mixin _outlined-floating-label($query: feature-targeting.all()) {
  1469. $feat-structure: feature-targeting.create-target($query, structure);
  1470. .mdc-floating-label {
  1471. @include feature-targeting.targets($feat-structure) {
  1472. @include rtl.reflexive-position(left, notched-outline-variables.$padding);
  1473. }
  1474. }
  1475. }
  1476. @mixin _outlined-notched-outline($query: feature-targeting.all()) {
  1477. $feat-structure: feature-targeting.create-target($query, structure);
  1478. @include feature-targeting.targets($feat-structure) {
  1479. // Force the outline to appear "above" the textfield elements, even though
  1480. // it is absolutely positioned and comes before the input in the DOM. This
  1481. // is primarily for the textarea scrollbar and resize elements, which may
  1482. // clip with with outline border.
  1483. z-index: 1;
  1484. }
  1485. }
  1486. // States
  1487. @mixin disabled_($query: feature-targeting.all()) {
  1488. $feat-structure: feature-targeting.create-target($query, structure);
  1489. @include ink-color_(variables.$disabled-ink-color, $query: $query);
  1490. @include placeholder-color_(
  1491. variables.$disabled-placeholder-ink-color,
  1492. $query: $query
  1493. );
  1494. @include label-ink-color_(variables.$disabled-label-color, $query: $query);
  1495. @include helper-text-mixins.helper-text-color_(
  1496. variables.$disabled-helper-text-color,
  1497. $query: $query
  1498. );
  1499. @include character-counter-mixins.character-counter-color_(
  1500. variables.$disabled-helper-text-color,
  1501. $query: $query
  1502. );
  1503. @include icon-mixins.leading-icon-color_(
  1504. variables.$disabled-icon,
  1505. $query: $query
  1506. );
  1507. @include icon-mixins.trailing-icon-color_(
  1508. variables.$disabled-icon,
  1509. $query: $query
  1510. );
  1511. @include _prefix-color(variables.$disabled-affix-color, $query: $query);
  1512. @include _suffix-color(variables.$disabled-affix-color, $query: $query);
  1513. // Mixins that are ok to include since they target variant-specific elements
  1514. @include bottom-line-color_(variables.$disabled-border, $query: $query);
  1515. @include notched-outline-mixins.color(
  1516. variables.$outlined-disabled-border,
  1517. $query: $query
  1518. );
  1519. @include dom.forced-colors-mode {
  1520. @include placeholder-color_(GrayText, $query: $query);
  1521. @include label-ink-color_(GrayText, $query: $query);
  1522. @include helper-text-mixins.helper-text-color_(GrayText, $query: $query);
  1523. @include character-counter-mixins.character-counter-color_(
  1524. GrayText,
  1525. $query: $query
  1526. );
  1527. @include icon-mixins.leading-icon-color_(GrayText, $query: $query);
  1528. @include icon-mixins.trailing-icon-color_(GrayText, $query: $query);
  1529. @include _prefix-color(GrayText, $query: $query);
  1530. @include _suffix-color(GrayText, $query: $query);
  1531. // Mixins that are ok to include since they target variant-specific elements
  1532. @include bottom-line-color_(GrayText, $query: $query);
  1533. @include notched-outline-mixins.color(GrayText, $query: $query);
  1534. }
  1535. @include dom.forced-colors-mode($exclude-ie11: true) {
  1536. .mdc-text-field__input {
  1537. @include feature-targeting.targets($feat-structure) {
  1538. background-color: Window;
  1539. }
  1540. }
  1541. .mdc-floating-label {
  1542. @include feature-targeting.targets($feat-structure) {
  1543. z-index: 1;
  1544. }
  1545. }
  1546. }
  1547. @include feature-targeting.targets($feat-structure) {
  1548. pointer-events: none;
  1549. }
  1550. .mdc-floating-label {
  1551. @include feature-targeting.targets($feat-structure) {
  1552. cursor: default;
  1553. }
  1554. }
  1555. }
  1556. @mixin _disabled-input($query: feature-targeting.all()) {
  1557. $feat-structure: feature-targeting.create-target($query, structure);
  1558. @include feature-targeting.targets($feat-structure) {
  1559. // disabled inputs should still allow users to interact with them to select
  1560. // text and scroll for textareas
  1561. pointer-events: auto;
  1562. }
  1563. }
  1564. @mixin _disabled-filled($query: feature-targeting.all()) {
  1565. $feat-structure: feature-targeting.create-target($query, structure);
  1566. @include fill-color_(variables.$disabled-background, $query: $query);
  1567. #{variables.$ripple-target} {
  1568. @include feature-targeting.targets($feat-structure) {
  1569. // prevent ripple from displaying on hover when some interactible
  1570. // elements like input and resize handles are hovered
  1571. display: none;
  1572. }
  1573. }
  1574. }
  1575. @mixin invalid_($query: feature-targeting.all()) {
  1576. $feat-structure: feature-targeting.create-target($query, structure);
  1577. @include hover-bottom-line-color(variables.$error, $query: $query);
  1578. @include line-ripple-color(variables.$error, $query: $query);
  1579. @include label-color(variables.$error, $query: $query);
  1580. @include helper-text-mixins.helper-text-validation-color(
  1581. variables.$error,
  1582. $query: $query
  1583. );
  1584. @include caret-color(variables.$error, $query: $query);
  1585. @include icon-mixins.trailing-icon-color(variables.$error, $query: $query);
  1586. // Mixins that are ok to include since they target variant-specific elements
  1587. @include bottom-line-color(variables.$error, $query: $query);
  1588. @include outline-color(variables.$error, $query: $query);
  1589. @include hover-outline-color(variables.$error, $query: $query);
  1590. @include focused-outline-color(variables.$error, $query: $query);
  1591. + .mdc-text-field-helper-line .mdc-text-field-helper-text--validation-msg {
  1592. @include feature-targeting.targets($feat-structure) {
  1593. opacity: 1;
  1594. }
  1595. }
  1596. }
  1597. @mixin focused_($query: feature-targeting.all()) {
  1598. $feat-structure: feature-targeting.create-target($query, structure);
  1599. @include label-color(variables.$focused-label-color, $query: $query);
  1600. // Mixins that are ok to include since they target variant-specific elements
  1601. @include notched-outline-mixins.stroke-width(
  1602. variables.$outlined-stroke-width,
  1603. $query: $query
  1604. );
  1605. + .mdc-text-field-helper-line
  1606. .mdc-text-field-helper-text:not(
  1607. .mdc-text-field-helper-text--validation-msg
  1608. ) {
  1609. @include feature-targeting.targets($feat-structure) {
  1610. opacity: 1;
  1611. }
  1612. }
  1613. }
  1614. @mixin _focused-outlined($query: feature-targeting.all()) {
  1615. @include notched-outline-mixins.notch-offset(
  1616. variables.$outlined-stroke-width,
  1617. $query: $query
  1618. );
  1619. }
  1620. @mixin _focused-outlined-textarea($query: feature-targeting.all()) {
  1621. @include notched-outline-mixins.notch-offset(0, $query: $query);
  1622. }
  1623. // Icons
  1624. @mixin with-leading-icon_($query: feature-targeting.all()) {
  1625. $feat-structure: feature-targeting.create-target($query, structure);
  1626. $icon-padding: icon-variables.$leading-icon-padding-left +
  1627. icon-variables.$icon-size + icon-variables.$leading-icon-padding-right;
  1628. .mdc-floating-label {
  1629. @include _truncate-floating-label-max-width($icon-padding, $query: $query);
  1630. @include feature-targeting.targets($feat-structure) {
  1631. @include rtl.reflexive-position(left, $icon-padding);
  1632. }
  1633. }
  1634. $truncation: $icon-padding + variables.$padding-horizontal;
  1635. .mdc-floating-label--float-above {
  1636. @include _truncate-floating-label-floated-max-width(
  1637. $truncation,
  1638. $query: $query
  1639. );
  1640. }
  1641. }
  1642. @mixin _with-trailing-icon($query: feature-targeting.all()) {
  1643. $truncation: icon-variables.$trailing-icon-padding-left +
  1644. icon-variables.$icon-size + icon-variables.$trailing-icon-padding-right +
  1645. variables.$label-offset;
  1646. .mdc-floating-label {
  1647. @include _truncate-floating-label-max-width($truncation, $query: $query);
  1648. }
  1649. .mdc-floating-label--float-above {
  1650. @include _truncate-floating-label-floated-max-width(
  1651. $truncation,
  1652. $query: $query
  1653. );
  1654. }
  1655. }
  1656. @mixin _with-leading-and-trailing-icon($query: feature-targeting.all()) {
  1657. $leading-icon: icon-variables.$leading-icon-padding-left +
  1658. icon-variables.$icon-size + icon-variables.$leading-icon-padding-right;
  1659. $trailing-icon: icon-variables.$trailing-icon-padding-left +
  1660. icon-variables.$icon-size + icon-variables.$trailing-icon-padding-right;
  1661. $truncation: $leading-icon + $trailing-icon;
  1662. .mdc-floating-label {
  1663. @include _truncate-floating-label-max-width($truncation, $query: $query);
  1664. }
  1665. .mdc-floating-label--float-above {
  1666. @include _truncate-floating-label-floated-max-width(
  1667. $truncation,
  1668. $query: $query
  1669. );
  1670. }
  1671. }
  1672. @mixin outlined-with-leading-icon_($query: feature-targeting.all()) {
  1673. $feat-structure: feature-targeting.create-target($query, structure);
  1674. // Resting label position
  1675. $icon-padding: icon-variables.$leading-icon-padding-left +
  1676. icon-variables.$icon-size + icon-variables.$leading-icon-padding-right;
  1677. $left-spacing: $icon-padding - notched-outline-variables.$leading-width;
  1678. .mdc-floating-label {
  1679. @include feature-targeting.targets($feat-structure) {
  1680. @include rtl.reflexive-position(left, $left-spacing);
  1681. }
  1682. }
  1683. // Notch width
  1684. $notch-truncation: $icon-padding + notched-outline-variables.$leading-width;
  1685. @include _truncate-notched-outline-max-width(
  1686. $notch-truncation,
  1687. $query: $query
  1688. );
  1689. // Floating label position and animation
  1690. @include _outlined-with-leading-icon-floating-label-position-animation(
  1691. $height: variables.$height,
  1692. $keyframe-suffix: text-field-outlined-leading-icon,
  1693. $query: $query
  1694. );
  1695. }
  1696. ///
  1697. /// Applied to the outlined text field with a trailing icon
  1698. ///
  1699. @mixin _outlined-with-trailing-icon($query: feature-targeting.all()) {
  1700. // Resting label position
  1701. $icon-padding: icon-variables.$trailing-icon-padding-left +
  1702. icon-variables.$icon-size + icon-variables.$trailing-icon-padding-right;
  1703. // Notch width
  1704. $notch-truncation: $icon-padding + notched-outline-variables.$leading-width;
  1705. @include _truncate-notched-outline-max-width(
  1706. $notch-truncation,
  1707. $query: $query
  1708. );
  1709. }
  1710. ///
  1711. /// Truncates the max-width of the notched outline by the given amount
  1712. ///
  1713. /// @param {Number} $truncation - Amount to truncate the notched outline max-width
  1714. ///
  1715. @mixin _truncate-notched-outline-max-width(
  1716. $truncation,
  1717. $query: feature-targeting.all()
  1718. ) {
  1719. @include notched-outline-mixins.notch-max-width(
  1720. calc(100% - #{$truncation}),
  1721. $query: $query
  1722. );
  1723. }
  1724. ///
  1725. /// Truncates the max-width of the floating label by the given amount
  1726. ///
  1727. /// @param {Number} $truncation - Amount to truncate the floating label max-width
  1728. ///
  1729. @mixin _truncate-floating-label-max-width(
  1730. $truncation,
  1731. $query: feature-targeting.all()
  1732. ) {
  1733. @include floating-label-mixins.max-width(
  1734. calc(100% - #{$truncation}),
  1735. $query: $query
  1736. );
  1737. }
  1738. ///
  1739. /// Truncates the max-width of the floating label by the given amount while scaling by the given scale value
  1740. ///
  1741. /// @param {Number} $truncation - Amount to truncate the floating label max-width
  1742. ///
  1743. @mixin _truncate-floating-label-floated-max-width(
  1744. $truncation,
  1745. $query: feature-targeting.all()
  1746. ) {
  1747. $scale: floating-label-variables.$float-scale;
  1748. @include floating-label-mixins.max-width(
  1749. calc(100% / #{$scale} - #{$truncation} / #{$scale}),
  1750. $query: $query
  1751. );
  1752. }
  1753. // Textarea
  1754. @mixin textarea_($query: feature-targeting.all()) {
  1755. $feat-structure: feature-targeting.create-target($query, structure);
  1756. $feat-animation: feature-targeting.create-target($query, animation);
  1757. @include _textarea-floating-label($query);
  1758. @include feature-targeting.targets($feat-structure) {
  1759. flex-direction: column;
  1760. align-items: center;
  1761. width: auto;
  1762. height: auto;
  1763. padding: 0; // see below for explanation
  1764. }
  1765. @include feature-targeting.targets($feat-animation) {
  1766. transition: none;
  1767. }
  1768. }
  1769. @mixin _textarea-resizer($query: feature-targeting.all()) {
  1770. $feat-structure: feature-targeting.create-target($query, structure);
  1771. @include feature-targeting.targets($feat-structure) {
  1772. align-self: stretch;
  1773. display: inline-flex;
  1774. flex-direction: column;
  1775. flex-grow: 1;
  1776. max-height: 100%;
  1777. max-width: 100%;
  1778. min-height: variables.$height;
  1779. // 'stretch' is the preferred rule here. It will allow the textarea to grow
  1780. // to the min/max width of the container, but if an explicit width is set,
  1781. // it cannot be resized horizontally.
  1782. // Stretch is still a working draft. Chrome and Firefox have it implemented
  1783. // with 'available' prefixes. fit-content is another good target for
  1784. // Safari since it works in almost all use cases except when an explicit
  1785. // width is set (the user can make the textarea smaller than the container).
  1786. // None of this matters for IE11, which doesn't support resize.
  1787. min-width: fit-content;
  1788. /* @alternate */
  1789. min-width: -moz-available;
  1790. /* @alternate */
  1791. min-width: -webkit-fill-available;
  1792. overflow: hidden;
  1793. resize: both;
  1794. }
  1795. }
  1796. @mixin _textarea-filled-resizer($query: feature-targeting.all()) {
  1797. $feat-structure: feature-targeting.create-target($query, structure);
  1798. // Shift the resizer element up by a margin amount to make space for the
  1799. // resize handle. For filled elements, the resize handle directly touches
  1800. // the bottom line and is hard to see.
  1801. // Using a margin affects the width and positioning of the overall component
  1802. // and underlying textarea, which is why a transform is used instead.
  1803. $y: -1 * variables.$textarea-input-handle-margin;
  1804. @include feature-targeting.targets($feat-structure) {
  1805. transform: translateY($y);
  1806. }
  1807. }
  1808. @mixin _textarea-filled-resizer-children($query: feature-targeting.all()) {
  1809. $feat-structure: feature-targeting.create-target($query, structure);
  1810. // See above. After shifting the resize wrapper element, all of its children
  1811. // should be shifted in the opposite direction (down) to compensate.
  1812. $y: variables.$textarea-input-handle-margin;
  1813. @include feature-targeting.targets($feat-structure) {
  1814. transform: translateY($y);
  1815. }
  1816. }
  1817. @mixin _textarea-outlined-resizer($query: feature-targeting.all()) {
  1818. $feat-structure: feature-targeting.create-target($query, structure);
  1819. // Shift the resizer element left/up by a margin amount to make space for the
  1820. // resize handle. For outlined elements, the resize handle directly touches
  1821. // the outline and is hard to see.
  1822. // Using a margin affects the width and positioning of the overall component
  1823. // and underlying textarea, which is why a transform is used instead.
  1824. $x: -1 * variables.$textarea-input-handle-margin;
  1825. $y: -1 * variables.$textarea-input-handle-margin;
  1826. @include feature-targeting.targets($feat-structure) {
  1827. @include rtl.ignore-next-line();
  1828. transform: translateX($x) translateY($y);
  1829. @include rtl.rtl {
  1830. // Flip the horizontal shifting direction for RTL
  1831. @include rtl.ignore-next-line();
  1832. transform: translateX(-1 * $x) translateY($y);
  1833. }
  1834. }
  1835. }
  1836. @mixin _textarea-outlined-resizer-children($query: feature-targeting.all()) {
  1837. $feat-structure: feature-targeting.create-target($query, structure);
  1838. // See above. After shifting the resize wrapper element, all of its children
  1839. // should be shifted in the opposite direction (right and down) to compensate.
  1840. $x: variables.$textarea-input-handle-margin;
  1841. $y: variables.$textarea-input-handle-margin;
  1842. @include feature-targeting.targets($feat-structure) {
  1843. @include rtl.ignore-next-line();
  1844. transform: translateX($x) translateY($y);
  1845. @include rtl.rtl {
  1846. // Flip the horizontal shifting direction for RTL
  1847. @include rtl.ignore-next-line();
  1848. transform: translateX(-1 * $x) translateY($y);
  1849. }
  1850. }
  1851. }
  1852. @mixin _textarea-floating-label($query: feature-targeting.all()) {
  1853. $feat-structure: feature-targeting.create-target($query, structure);
  1854. // Resting label position
  1855. .mdc-floating-label {
  1856. @include feature-targeting.targets($feat-structure) {
  1857. top: variables.$textarea-label-top;
  1858. }
  1859. // Resets center aligning the floating label.
  1860. &:not(.mdc-floating-label--float-above) {
  1861. @include feature-targeting.targets($feat-structure) {
  1862. transform: none;
  1863. }
  1864. }
  1865. }
  1866. }
  1867. @mixin _textarea-input($query: feature-targeting.all()) {
  1868. $feat-structure: feature-targeting.create-target($query, structure);
  1869. $feat-typography: feature-targeting.create-target($query, typography);
  1870. @include feature-targeting.targets($feat-structure) {
  1871. flex-grow: 1;
  1872. height: auto;
  1873. min-height: variables.$textarea-line-height;
  1874. overflow-x: hidden; // https://bugzilla.mozilla.org/show_bug.cgi?id=33654
  1875. overflow-y: auto;
  1876. box-sizing: border-box;
  1877. resize: none;
  1878. // Textarea has horizontal padding instead of the container. This allows the
  1879. // resize handle to extend to the edge of the container.
  1880. padding: 0 variables.$padding-horizontal;
  1881. }
  1882. @include feature-targeting.targets($feat-typography) {
  1883. line-height: variables.$textarea-line-height;
  1884. }
  1885. }
  1886. @mixin _textarea-internal-counter($query: feature-targeting.all()) {
  1887. $feat-structure: feature-targeting.create-target($query, structure);
  1888. @include typography.baseline-bottom(
  1889. variables.$textarea-internal-counter-baseline-bottom,
  1890. $query: $query
  1891. );
  1892. @include feature-targeting.targets($feat-structure) {
  1893. align-self: flex-end;
  1894. // Needed since padding is on the textarea and not the container
  1895. padding: 0 variables.$padding-horizontal;
  1896. &::before {
  1897. // Remove baseline-top
  1898. display: none;
  1899. }
  1900. }
  1901. }
  1902. @mixin _textarea-input-with-internal-counter($query: feature-targeting.all()) {
  1903. $feat-structure: feature-targeting.create-target($query, structure);
  1904. @include feature-targeting.targets($feat-structure) {
  1905. margin-bottom: variables.$textarea-internal-counter-input-margin-bottom;
  1906. }
  1907. }
  1908. @mixin _textarea-filled($query: feature-targeting.all()) {
  1909. $feat-structure: feature-targeting.create-target($query, structure);
  1910. @include feature-targeting.targets($feat-structure) {
  1911. &::before {
  1912. // <textarea> does not align to baseline when it does not have a value,
  1913. // unlike <input>, so we have to use padding to fake it instead
  1914. display: none;
  1915. }
  1916. }
  1917. // Floating label position
  1918. @include floating-label-mixins.float-position(
  1919. variables.$textarea-filled-label-position-y,
  1920. $query: $query
  1921. );
  1922. // Floating label animation
  1923. @include floating-label-mixins.shake-animation(
  1924. textarea-filled,
  1925. $query: $query
  1926. );
  1927. @at-root {
  1928. @include floating-label-mixins.shake-keyframes(
  1929. textarea-filled,
  1930. variables.$textarea-filled-label-position-y,
  1931. 0%,
  1932. $query: $query
  1933. );
  1934. }
  1935. }
  1936. @mixin _textarea-filled-input($query: feature-targeting.all()) {
  1937. $feat-structure: feature-targeting.create-target($query, structure);
  1938. @include feature-targeting.targets($feat-structure) {
  1939. margin-top: variables.$textarea-filled-input-margin-top;
  1940. margin-bottom: variables.$textarea-filled-input-margin-bottom;
  1941. }
  1942. }
  1943. @mixin _textarea-filled-no-label-input($query: feature-targeting.all()) {
  1944. $feat-structure: feature-targeting.create-target($query, structure);
  1945. @include feature-targeting.targets($feat-structure) {
  1946. margin-top: variables.$textarea-filled-no-label-input-margin-top;
  1947. margin-bottom: variables.$textarea-filled-no-label-input-margin-bottom;
  1948. }
  1949. }
  1950. @mixin _textarea-outlined($query: feature-targeting.all()) {
  1951. @include notched-outline-mixins.notch-offset(0, $query: $query);
  1952. // Floating label position
  1953. @include notched-outline-mixins.floating-label-float-position-absolute(
  1954. variables.$textarea-outlined-label-position-y,
  1955. $query: $query
  1956. );
  1957. // Floating label animation
  1958. @include floating-label-mixins.shake-animation(
  1959. textarea-outlined,
  1960. $query: $query
  1961. );
  1962. @at-root {
  1963. @include floating-label-mixins.shake-keyframes(
  1964. textarea-outlined,
  1965. variables.$textarea-outlined-label-position-y,
  1966. 0%,
  1967. $query: $query
  1968. );
  1969. }
  1970. }
  1971. @mixin _textarea-outlined-floating-label($query: feature-targeting.all()) {
  1972. $feat-structure: feature-targeting.create-target($query, structure);
  1973. @include feature-targeting.targets($feat-structure) {
  1974. top: variables.$textarea-outlined-label-top;
  1975. }
  1976. }
  1977. @mixin _textarea-outlined-input($query: feature-targeting.all()) {
  1978. $feat-structure: feature-targeting.create-target($query, structure);
  1979. @include feature-targeting.targets($feat-structure) {
  1980. margin-top: variables.$textarea-outlined-input-margin-top;
  1981. margin-bottom: variables.$textarea-outlined-input-margin-bottom;
  1982. }
  1983. }
  1984. // Text, Prefix and Suffix
  1985. // Common styles for the text of the text field, including the prefix, suffix,
  1986. // and input.
  1987. @mixin _text($query: feature-targeting.all()) {
  1988. $feat-animation: feature-targeting.create-target($query, animation);
  1989. $feat-structure: feature-targeting.create-target($query, structure);
  1990. // Exclude setting line-height to keep caret (text cursor) same height as the input text in iOS browser.
  1991. @include typography.typography(
  1992. subtitle1,
  1993. $exclude-props: (line-height),
  1994. $query: $query
  1995. );
  1996. @include feature-targeting.targets($feat-structure) {
  1997. height: variables.$input-height;
  1998. }
  1999. @include feature-targeting.targets($feat-animation) {
  2000. transition: animation.standard(opacity, 150ms);
  2001. }
  2002. }
  2003. @mixin _input($query: feature-targeting.all()) {
  2004. $feat-structure: feature-targeting.create-target($query, structure);
  2005. @include _text($query: $query);
  2006. @include feature-targeting.targets($feat-structure) {
  2007. width: 100%;
  2008. min-width: 0; // Fixes flex issues on Firefox
  2009. border: none;
  2010. border-radius: 0;
  2011. background: none;
  2012. appearance: none;
  2013. padding: 0;
  2014. // Remove built-in trailing clear icon on IE11. IE vendor prefixes cannot
  2015. // be combined with other vendor prefixes like the webkit one below.
  2016. &::-ms-clear {
  2017. display: none;
  2018. }
  2019. // Remove built-in datepicker icon on Chrome
  2020. &::-webkit-calendar-picker-indicator {
  2021. display: none;
  2022. }
  2023. &:focus {
  2024. outline: none;
  2025. }
  2026. // Remove red outline on firefox
  2027. &:invalid {
  2028. box-shadow: none;
  2029. }
  2030. }
  2031. }
  2032. @mixin _input-placeholder($query: feature-targeting.all()) {
  2033. $feat-animation: feature-targeting.create-target($query, animation);
  2034. $feat-structure: feature-targeting.create-target($query, structure);
  2035. @include feature-targeting.targets($feat-animation) {
  2036. transition: animation.standard(opacity, 67ms);
  2037. }
  2038. @include feature-targeting.targets($feat-structure) {
  2039. opacity: 0;
  2040. }
  2041. }
  2042. @mixin _input-placeholder-visible($query: feature-targeting.all()) {
  2043. $feat-animation: feature-targeting.create-target($query, animation);
  2044. $feat-structure: feature-targeting.create-target($query, structure);
  2045. @include feature-targeting.targets($feat-animation) {
  2046. transition-delay: 40ms;
  2047. transition-duration: 110ms;
  2048. }
  2049. @include feature-targeting.targets($feat-structure) {
  2050. opacity: 1;
  2051. }
  2052. }
  2053. @mixin _affix($query: feature-targeting.all()) {
  2054. $feat-structure: feature-targeting.create-target($query, structure);
  2055. @include _text($query: $query);
  2056. @include feature-targeting.targets($feat-structure) {
  2057. opacity: 0;
  2058. white-space: nowrap;
  2059. }
  2060. }
  2061. // TODO(b/155467610): Remove when Safari supports baseline alignment
  2062. // https://github.com/material-components/material-components-web/issues/5879
  2063. @mixin _centered-affix-safari-support($query: feature-targeting.all()) {
  2064. $feat-structure: feature-targeting.create-target($query, structure);
  2065. @include feature-targeting.targets($feat-structure) {
  2066. align-items: center;
  2067. align-self: center;
  2068. display: inline-flex;
  2069. height: 100%;
  2070. }
  2071. }
  2072. @mixin _affix-visible($query: feature-targeting.all()) {
  2073. $feat-structure: feature-targeting.create-target($query, structure);
  2074. @include feature-targeting.targets($feat-structure) {
  2075. opacity: 1;
  2076. }
  2077. }
  2078. @mixin _prefix($query: feature-targeting.all()) {
  2079. $feat-structure: feature-targeting.create-target($query, structure);
  2080. @include feature-targeting.targets($feat-structure) {
  2081. @include rtl.reflexive-box(padding, right, variables.$prefix-padding);
  2082. }
  2083. }
  2084. @mixin _prefix-end-aligned($query: feature-targeting.all()) {
  2085. $feat-structure: feature-targeting.create-target($query, structure);
  2086. @include feature-targeting.targets($feat-structure) {
  2087. @include rtl.reflexive-box(
  2088. padding,
  2089. right,
  2090. variables.$prefix-end-aligned-padding
  2091. );
  2092. }
  2093. }
  2094. @mixin _suffix($query: feature-targeting.all()) {
  2095. $feat-structure: feature-targeting.create-target($query, structure);
  2096. @include feature-targeting.targets($feat-structure) {
  2097. @include rtl.reflexive-box(padding, left, variables.$suffix-padding);
  2098. }
  2099. }
  2100. @mixin _suffix-end-aligned($query: feature-targeting.all()) {
  2101. $feat-structure: feature-targeting.create-target($query, structure);
  2102. @include feature-targeting.targets($feat-structure) {
  2103. @include rtl.reflexive-box(
  2104. padding,
  2105. left,
  2106. variables.$suffix-end-aligned-padding
  2107. );
  2108. }
  2109. }
  2110. // End aligned
  2111. @mixin end-aligned_($query: feature-targeting.all()) {
  2112. $feat-structure: feature-targeting.create-target($query, structure);
  2113. .mdc-text-field__input {
  2114. @include feature-targeting.targets($feat-structure) {
  2115. // IE11 does not support text-align: end
  2116. @include rtl.ignore-next-line();
  2117. text-align: right;
  2118. }
  2119. @include rtl.rtl {
  2120. @include feature-targeting.targets($feat-structure) {
  2121. @include rtl.ignore-next-line();
  2122. text-align: left;
  2123. }
  2124. }
  2125. }
  2126. }
  2127. // Forces input, prefix, and suffix to be LTR when in an RTL environment. Other
  2128. // elements such as labels and icons will remain RTL.
  2129. @mixin _ltr-text($query: feature-targeting.all()) {
  2130. $feat-structure: feature-targeting.create-target($query, structure);
  2131. @include feature-targeting.targets($feat-structure) {
  2132. @include rtl.rtl {
  2133. .mdc-text-field__input,
  2134. .mdc-text-field__affix {
  2135. @include rtl.ignore-next-line();
  2136. direction: ltr;
  2137. }
  2138. .mdc-text-field__affix--prefix {
  2139. @include rtl.ignore-next-line();
  2140. padding-left: 0;
  2141. @include rtl.ignore-next-line();
  2142. padding-right: variables.$prefix-padding;
  2143. }
  2144. .mdc-text-field__affix--suffix {
  2145. @include rtl.ignore-next-line();
  2146. padding-left: variables.$suffix-padding;
  2147. @include rtl.ignore-next-line();
  2148. padding-right: 0;
  2149. }
  2150. // Need to specify an order for all elements since icons maintain their
  2151. // original positions. We can't just reverse the container.
  2152. .mdc-text-field__icon--leading {
  2153. order: 1;
  2154. }
  2155. .mdc-text-field__affix--suffix {
  2156. order: 2;
  2157. }
  2158. .mdc-text-field__input {
  2159. order: 3;
  2160. }
  2161. .mdc-text-field__affix--prefix {
  2162. order: 4;
  2163. }
  2164. .mdc-text-field__icon--trailing {
  2165. order: 5;
  2166. }
  2167. }
  2168. }
  2169. }
  2170. // Forces input, prefix, and suffix that are already forced to LTR to also be
  2171. // end-aligned. This mixin should be used alongside the styles provided in
  2172. // _ltr-text().
  2173. @mixin _ltr-text-end-aligned($query: feature-targeting.all()) {
  2174. $feat-structure: feature-targeting.create-target($query, structure);
  2175. @include feature-targeting.targets($feat-structure) {
  2176. @include rtl.rtl {
  2177. .mdc-text-field__input {
  2178. // IE11 does not support text-align: end, so we need to duplicate
  2179. // the LTR end-aligned style here.
  2180. @include rtl.ignore-next-line();
  2181. text-align: right;
  2182. }
  2183. .mdc-text-field__affix--prefix {
  2184. // padding-left: 0 provided by _ltr-text mixin
  2185. @include rtl.ignore-next-line();
  2186. padding-right: variables.$prefix-end-aligned-padding;
  2187. }
  2188. .mdc-text-field__affix--suffix {
  2189. @include rtl.ignore-next-line();
  2190. padding-left: variables.$suffix-end-aligned-padding;
  2191. // padding-right: 0 provided by _ltr-text mixin
  2192. }
  2193. }
  2194. }
  2195. }
  2196. // Customization
  2197. @mixin ink-color_($color, $query: feature-targeting.all()) {
  2198. $feat-color: feature-targeting.create-target($query, color);
  2199. .mdc-text-field__input {
  2200. @include feature-targeting.targets($feat-color) {
  2201. @include theme.property(color, $color);
  2202. }
  2203. }
  2204. }
  2205. @mixin placeholder-color_($color, $query: feature-targeting.all()) {
  2206. $feat-color: feature-targeting.create-target($query, color);
  2207. @include feature-targeting.targets($feat-color) {
  2208. .mdc-text-field__input {
  2209. @include placeholder-selector_ {
  2210. @include theme.property(color, $color);
  2211. }
  2212. }
  2213. }
  2214. }
  2215. @mixin fill-color_(
  2216. $color,
  2217. $query: feature-targeting.all(),
  2218. $addAlternate: false
  2219. ) {
  2220. $feat-color: feature-targeting.create-target($query, color);
  2221. @include feature-targeting.targets($feat-color) {
  2222. @if ($addAlternate) {
  2223. /* @alternate */
  2224. }
  2225. @include theme.property(background-color, $color);
  2226. }
  2227. }
  2228. @mixin bottom-line-color_($color, $query: feature-targeting.all()) {
  2229. .mdc-line-ripple {
  2230. @include line-ripple-mixins.inactive-color($color, $query: $query);
  2231. }
  2232. }
  2233. @mixin hover-bottom-line-color_($color, $query: feature-targeting.all()) {
  2234. $feat-color: feature-targeting.create-target($query, color);
  2235. &:hover .mdc-line-ripple {
  2236. @include line-ripple-mixins.inactive-color($color, $query: $query);
  2237. }
  2238. }
  2239. @mixin line-ripple-color_($color, $query: feature-targeting.all()) {
  2240. .mdc-line-ripple {
  2241. @include line-ripple-mixins.active-color($color, $query: $query);
  2242. }
  2243. }
  2244. @mixin hover-outline-color_($color, $query: feature-targeting.all()) {
  2245. &:not(.mdc-text-field--focused):hover {
  2246. .mdc-notched-outline {
  2247. @include notched-outline-mixins.color($color, $query: $query);
  2248. }
  2249. }
  2250. }
  2251. @mixin focused-outline-color_($color, $query: feature-targeting.all()) {
  2252. &.mdc-text-field--focused {
  2253. @include notched-outline-mixins.color($color, $query: $query);
  2254. }
  2255. }
  2256. @mixin label-ink-color_($color, $query: feature-targeting.all()) {
  2257. .mdc-floating-label {
  2258. @include floating-label-mixins.ink-color($color, $query: $query);
  2259. }
  2260. }
  2261. @mixin _prefix-color($color, $query: feature-targeting.all()) {
  2262. $feat-color: feature-targeting.create-target($query, color);
  2263. @include feature-targeting.targets($feat-color) {
  2264. .mdc-text-field__affix--prefix {
  2265. @include theme.property(color, $color);
  2266. }
  2267. }
  2268. }
  2269. @mixin _suffix-color($color, $query: feature-targeting.all()) {
  2270. $feat-color: feature-targeting.create-target($query, color);
  2271. @include feature-targeting.targets($feat-color) {
  2272. .mdc-text-field__affix--suffix {
  2273. @include theme.property(color, $color);
  2274. }
  2275. }
  2276. }
  2277. // Selectors
  2278. @mixin placeholder-selector_ {
  2279. // GSS will combine selectors with the same content, and some browsers have a
  2280. // CSS quirk where it drops a rule if it does not recognize one of the
  2281. // selectors.
  2282. // To avoid GSS combining the ::placeholder and :-ms-input-placeholder
  2283. // selectors, we wrap them in `@media all`.
  2284. // TODO(b/142329051)
  2285. @media all {
  2286. // ::placeholder needs to be wrapped because IE11 will drop other selectors
  2287. // with the same content
  2288. &::placeholder {
  2289. @content;
  2290. }
  2291. }
  2292. @media all {
  2293. // :-ms-input-placeholder needs to be wrapped because Firefox will drop
  2294. // other selectors with the same content
  2295. &:-ms-input-placeholder {
  2296. @content;
  2297. }
  2298. }
  2299. }
  2300. // State qualifiers
  2301. ///
  2302. /// Helps style the text-field only when it's enabled.
  2303. /// @access private
  2304. ///
  2305. @mixin if-enabled_ {
  2306. &:not(.mdc-text-field--disabled) {
  2307. @content;
  2308. }
  2309. }
  2310. ///
  2311. /// Helps style the text-field only when it's disabled.
  2312. /// @access private
  2313. ///
  2314. @mixin if-disabled_ {
  2315. &.mdc-text-field--disabled {
  2316. @content;
  2317. }
  2318. }